모듈:Episode list

local p = {}
-- This module requires the use of the following modules:
local colorContrastModule = require('Module:Color contrast')
local htmlColor = mw.loadData('Module:Color contrast/colors')
local langModule = require("Module:Lang")
local mathModule = require('Module:Math')
local tableEmptyCellModule = require('Module:Table empty cell')
local yesNoModule = require('Module:Yesno')
-- mw.html object for the generated row.
local row
-- Variable that will decide the colspan= of the Short Summary cell.
local nonNilParams = 0
-- Variable that will keep track if a TBA value was entered.
local cellValueTBA = false
-- Variable that handles the assigned tracking categories.
local trackingCategories = ""
-- List of tracking categories.
local trackingCategoryList = {
	"air_dates" = "분류:시작 날짜 틀 없이 방송날짜를 이용한 에피소드 목록", -- Category:Episode lists with unformatted air dates
	"alt_air_dates" = "분류:시작 날짜 틀과 함께 방송날짜2를 이용한 에피소드 목록", -- Category:Episode lists with incorrectly formatted alternate air dates
	"faulty_line_colors" = "분류:잘못된 선색을 이용한 에피소드 목록", -- Category:Episode lists with faulty line colors
	"non_compliant_line_colors" = "분류:접근성 기준을 준수하지 않는 선색을 이용한 에피소드 목록", -- Category:Episode lists with non-compliant line colors
	"default_line_colors" = "분류:기본 선색을 이용한 에피소드 목록", -- Category:Episode list using the default LineColor
	"row_deviations" = "분류:윗색을 이용한 에피소드 목록", -- Category:Episode lists with row deviations
	"invalid_top_colors" = "분류:잘못된 윗색을 이용한 에피소드 목록", -- Category:Episode lists with invalid top colors
	"tba_values" = "분류:추후 공개 값을 이용한 에피소드 목록", -- Category:Episode lists with TBA values
	"nonmatching_numbered_parameters" = "분류:짝이 맞지 않는 숫자 변수를 지정한 에피소드 목록", -- Category:Episode lists with a non-matching set of numbered parameters
--	"raw_unformatted_storyteleplay" = "Category:Episode lists with unformatted story or teleplay credits",
}
-- List of parameter names in this order.
local cellNameList = {
	'EpisodeNumber', '번호',
	'EpisodeNumber2', '번호2',
	'Title', '제목',
	'Aux1', '예비1',
	'DirectedBy', '감독',
	'WrittenBy', '작가',
	'Aux2', '예비2',
	'Aux3', '예비3',
	'OriginalAirDate', '방송날짜',
	'AltDate', '방송날짜2',
	'Guests', '게스트',
	'MusicalGuests', '뮤지컬게스트',
	'ProdCode', '제작번호',
	'Viewers', '시청자',
	'Aux4', '예비4'
}
-- List of pairs which cannot be used together
local excludeList = {
	'Guests' = 'Aux1',
	'게스트' = '예비1',
	'MusicalGuests' = 'Aux2',
	'뮤지컬게스트' = '예비2'
}
-- List of cells that have parameter groups
local parameterGroupCells = {}
local firstParameterGroupCell
local parameterGroupCellsAny = false
-- List of title parameter names in this order.
-- List used for multi title lists.
local titleList = {
	'Title', '제목',
	'RTitle', '제목R',
	'AltTitle', '제목2',
	'RAltTitle', '제목2R',
	'NativeTitle', '원어제목',
	'TranslitTitle', '발음제목'
}
-- Local function which is used to retrieve the episode number or production code number,
-- without any additional text.
local function idTrim(val, search)
	local valFind = string.find(val, search)
	if (valFind == nil) then
		return val
	else
		return string.sub(val, 0, valFind-1)
	end
end
-- Local function which is used to validate that a parameter has an actual value.
local function hasValue(param)
	if (param ~= nil and param ~= "") then
		return true
	else
		return false
	end
end
-- Local function which is used to create a table data cell.
local function createTableData(text, rowSpan, textAlign)
	if (rowSpan ~= nil and tonumber(rowSpan) > 1) then
		row:tag('td')
			:attr('rowspan', rowSpan)
			:wikitext(text)
	else
		row:tag('td')
			:css('text-align', textAlign)
			:wikitext(text)
	end
end
-- Local function which is used to add a tracking category to the page.
local function addTrackingCategory(category)
	trackingCategories = trackingCategories .. category
end
-- Local function which is used to create a Short Summary row.
local function createShortSummaryRow(args, lineColor)
	-- fix for lists in the Short Summary
	local shortSummaryText = args.ShortSummary or args'요약'
	if (shortSummaryText:match('^*:;#') or shortSummaryText:match('^
		shortSummaryText = '\n' .. shortSummaryText
	end
	if (shortSummaryText:match('\n*:;#')) then
		shortSummaryText = shortSummaryText .. '\n'
	end
	
	local shortSummaryDiv = mw.html.create('div')
				:addClass('shortSummaryText')
				:css('max-width', '90vw')
				:css('position', 'sticky')
				:css('left', '0.2em')
				:newline()
				:wikitext(shortSummaryText)
	local shortSummaryCell = mw.html.create('td')
				:addClass('description')
				:css('border-bottom', 'solid 3px ' .. lineColor)
				:attr('colspan', nonNilParams)
				:newline()
				:node(shortSummaryDiv)
	return mw.html.create('tr')
					:addClass('expand-child')
					:node(shortSummaryCell)
end
-- Local function which is used to add tracking categories for Top Color issues.
local function addTopColorTrackingCategories(args)
	if (hasValue(args.TopColor) or hasValue(args'윗색')) then
		addTrackingCategory(trackingCategoryList"row_deviations")
local textContrastRatio = 0
local linkContrastRatio = 0
local visitedLinkContrastRatio = 0
		-- Track top colors that have a color contrast rating below AAA with
		-- respect to text color, link color, or visited link color. See
		-- WP:COLOR for more about color contrast requirements.
		if (hasValue(args.TopColor)) then
		local textContrastRatio = colorContrastModule._ratio{args.TopColor, 'black', 'error' = 0}
		local linkContrastRatio = colorContrastModule._ratio{args.TopColor, '#0B0080', 'error' = 0}
		local visitedLinkContrastRatio = colorContrastModule._ratio{args.TopColor, '#0645AD', 'error' = 0}
		end
		
		if (hasValue(args'윗색')) then
		local textContrastRatio = colorContrastModule._ratio{args'윗색', 'black', 'error' = 0}
		local linkContrastRatio = colorContrastModule._ratio{args'윗색', '#0B0080', 'error' = 0}
		local visitedLinkContrastRatio = colorContrastModule._ratio{args'윗색', '#0645AD', 'error' = 0}
		end
		
		if (textContrastRatio = 60 * 60 * 24 * 7 * weeks) then
			return tableEmptyCellModule._main({alt_text = expiredText, title_text = expiredText})
		else
			return tableEmptyCellModule._main({alt_text = awaitingText, title_text = awaitingText})
		end
	end
end
-- Local function which is used to create an empty cell.
local function createEmptyCell(args, v, unsetParameterGroup)
	if (unsetParameterGroup) then
		argsv = tableEmptyCellModule._main({alt_text = "정보 없음"})
	elseif ((v == 'Viewers' or v == '시청자') and (hasValue(args.OriginalAirDate or args'방송날짜'))) then
		argsv = setTBDStatus(args, "추후 결정", "정보 없음", 4)
	elseif (v == 'DirectedBy' or v == '감독' or v == 'WrittenBy' or v == '작가') then
		argsv = setTBDStatus(args, "추후 공개", "알 수 없음", 4)
	else
		argsv = tableEmptyCellModule._main({})
	end
end
-- Air dates that don't use 
local function checkUsageOfDateTemplates(args, v, onInitialPage, title)
	if (v == 'OriginalAirDate'
		and argsv ~= 
		and string.match(argsv, '%d%d%d%d') ~= nil
		and string.match(argsv, '2C2C2C') == nil
		and string.find(argsv, 'itvstart') == nil -- itvstart is a  unique class.
--		and string.find(argsv, "film%-date") ~= nil -- Checks that  isn't used as it uses .
		and onInitialPage
		and title.namespace == 0)
	then
		addTrackingCategory(trackingCategoryList"air_dates")
	end
	
	if (v == '방송날짜'
		and argsv ~= 
		and string.match(argsv, '%d%d%d%d') ~= nil
		and string.match(argsv, '2C2C2C') == nil
		and string.find(argsv, 'itvstart') == nil -- itvstart is a  unique class.
--		and string.find(argsv, "영화%-날짜") ~= nil -- Checks that  isn't used as it uses .
		and onInitialPage
		and title.namespace == 0)
	then
		addTrackingCategory(trackingCategoryList"air_dates")
	end
	-- Alternate air dates that do use 
	if (v == 'AltDate' and argsv ~=  and string.find(argsv, 'dtstart') ~= nil and onInitialPage and title.namespace == 0) then
		addTrackingCategory(trackingCategoryList"alt_air_dates")
	elseif (v == '방송날짜2' and argsv ~=  and string.find(argsv, 'dtstart') ~= nil and onInitialPage and title.namespace == 0) then
		addTrackingCategory(trackingCategoryList"alt_air_dates")
	end
end
-- Local function which is used to create a Production Code cell.
local function createProductionCodeCell(args, v, numberOfParameterGroups)
	local thisRowspan
	if (not parameterGroupCellsv and parameterGroupCellsAny) then
		thisRowspan = numberOfParameterGroups
	else
		thisRowspan = 1
	end
	if (hasValue(args.ProdCode) and string.find(args.ProdCode, 'TBA') == nil and string.find(args.ProdCode, '추후 공개') == nil) then
		row:tag('td')
			:attr('id', 'pc' .. idTrim(idTrim(args.ProdCode, ' ----'), ' (with no space between)
	Line 2:  (with no space between) OR
	Line 2: Transliteration:  (: ) (with space between first two parameters)
	If  or  are empty,
	then the values of line 2 will be placed on line 1 instead.
--
local function createTitleText(args)
	local title = args.Title or args'제목'
	local rTitle = args.RTitle or args'제목R'
	local altTitle = args.AltTitle or args'제목2'
	local rAltTitle = args.RAltTitle or args'제목2R'
	local nativeTitle = args.NativeTitle or args'원어제목'
	local translitTitle = args.TranslitTitle or args'발음제목'
	local nativeTitleLangCode = args.NativeTitleLangCode or args'원어제목언어코드'
	local titleString = 
	local isCellPresent = false
	local useSecondLine = false
	local lineBreakUsed = false
	-- Surround the Title with quotes; No quotes if empty.
	if (title ~= nil) then
		if (title == "") then
			isCellPresent = true
		else
			titleString = '"' .. title .. '"'
			useSecondLine = true
			isCellPresent = true
		end
	end
	if (rTitle ~= nil) then
		if (rTitle == "") then
			isCellPresent = true
		else
			titleString = titleString .. rTitle
			useSecondLine = true
			isCellPresent = true
		end
	end
	if (nativeTitle ~= nil) then
		if (nativeTitle == "") then
			isCellPresent = true
		else
			isCellPresent = true
			if (useSecondLine and lineBreakUsed == false) then
				titleString = titleString .. ""
			end
			if (hasValue(nativeTitleLangCode)) then
				local languageCode = "Lang-" .. nativeTitleLangCode
				titleString = titleString .. '"' .. langModule._lang({code = nativeTitleLangCode, text=nativeTitle, italic = "no"}) .. '"'
			else
				titleString = titleString .. '"' .. nativeTitle .. '"'
			end
		end
	end
	if (translitTitle ~= nil) then
		if (translitTitle == "") then
			isCellPresent = true
		else
			titleString = titleString .. ' (' .. translitTitle .. ')'
			useSecondLine = true
			isCellPresent = true
		end
	end
	
	if (altTitle) then
		isCellPresent = true
		if (useSecondLine) then
			titleString = titleString .. ""
			lineBreakUsed = true
		end
		if (hasValue(altTitle)) then
			titleString = titleString .. '"' .. altTitle .. '"'
		end
	end
	if (rAltTitle ~= nil) then
		if (rAltTitle == "") then
			isCellPresent = true
		else
			isCellPresent = true
			if (useSecondLine and lineBreakUsed == false) then
				titleString = titleString .. ""
			end
			titleString = titleString .. (rAltTitle)
		end
	end
	return titleString, isCellPresent
end
--
Local function which is used to extract data
from the numbered title parameters (Title1, RTitle2, etc.), and then convert them to
use the non-numbered prameter names (Title, RTitle).
The function returns two results:
	-- The args parameter table.
	-- A boolean indicating if the title group has data.
--
local function extractDataFromNumberedTitleArgs(args, i)
	local nextGroupValid = false
	for _, v in ipairs(titleList) do
		local parameter = v
		local numberedParameter = v .. "_" .. i
		argsparameter = argsnumberedParameter
		if (nextGroupValid == false and hasValue(argsnumberedParameter)) then
			nextGroupValid = true
		end
	end
	return args, nextGroupValid
end
-- Local function which is used to create a Title cell.
local function createTitleCell(args, numberOfParameterGroups, currentRow, isSerial)
	local titleText
	local isCellPresent
	
	if (isSerial and (args.Title or args'제목') and currentRow > 1) then
		return nil
	end
	if (args.Title_2 or args'제목_2') then
		local args, nextGroupValid = extractDataFromNumberedTitleArgs(args, currentRow)
	end
	titleText, isCellPresent = createTitleText(args)
	if (isCellPresent == false) then
		return nil
	end
	local textAlign = "left"
	-- If Title is blank, then set Raw Title to TBA
	if (hasValue(titleText) == false) then
		titleText = tableEmptyCellModule._main({})
		textAlign = "left"
	end
	-- If title is the first cell, create it with a !scope="row"
	if (nonNilParams == 0) then
		if (isSerial) then
			row:tag('th')
				:addClass('summary')
				:attr('scope', 'row')
				:attr('rowspan', numberOfParameterGroups)
				:css('text-align', textAlign)
				:wikitext(titleText)
		else
			row:tag('th')
				:addClass('summary')
				:attr('scope', 'row')
				:css('text-align', textAlign)
				:wikitext(titleText)
		end
	else
		if (isSerial) then
			row:tag('td')
				:addClass('summary')
				:attr('rowspan', numberOfParameterGroups)
				:css('text-align', textAlign)
				:wikitext(titleText)
		else
			row:tag('td')
				:addClass('summary')
				:css('text-align', textAlign)
				:wikitext(titleText)
		end
	end
	nonNilParams = nonNilParams + 1
end
--
Local function which is used to create column cells.
EpisodeNumber, EpisodeNumber2 are created in different functions
as they require some various if checks.
See:
	-- createEpisodeNumberCell()
	-- createEpisodeNumberCellSecondary()
--
local function createCells(args, isSerial, currentRow, onInitialPage, title, numberOfParameterGroups)
	local title_2 = args.Title_2 or args'제목_2'
	local isSerial = not title_2 and true or false
	for k, v in ipairs(cellNameList) do
		if (v == 'ProdCode') then
			if (currentRow == 1 or (currentRow > 1 and parameterGroupCellsv)) then
				if args.ProdCode then
					createProductionCodeCell(args, v, numberOfParameterGroups)
				end
			end
		elseif (v == '제작번호') then
			if (currentRow == 1 or (currentRow > 1 and parameterGroupCellsv)) then
				if args'제작번호' then
					createProductionCodeCell(args, v, numberOfParameterGroups)
				end
			end
		elseif (v == 'Title') then
			if (currentRow == 1 or (currentRow > 1 and parameterGroupCellsv)) then
				if (hasValue(args.Title) == true) or (hasValue(args.AltTitle) == true) or (hasValue(args.RTitle) == true) or (hasValue(args.RAltTitle) == true) then
				createTitleCell(args, numberOfParameterGroups, currentRow, isSerial)
				end
			end
		elseif (v == '제목') then
			if (currentRow == 1 or (currentRow > 1 and parameterGroupCellsv)) then
				if (hasValue(args'제목') == true) or (hasValue(args'제목2') == true) or (hasValue(args'제목R') == true) or (hasValue(args'제목2R') == true) then
				createTitleCell(args, numberOfParameterGroups, currentRow, isSerial)
				end
			end
		elseif excludeListv and argsexcludeListv then
			-- Ignore this parameter set as multiple conflicting parameters were used
		elseif argsv and (v ~= 'EpisodeNumber' and v ~= 'EpisodeNumber2' and v ~= '번호' and v ~= '번호2') then
			-- Set empty cells to TBA/TBD
			if argsv ==  then
				createEmptyCell(args, v, false)
--			elseif (v == 'WrittenBy' and title.namespace == 0) then
--				if ((string.find(argsv, "Story") ~= nil or string.find(argsv, "Teleplay") ~= nil) and string.find(argsv, "8202") == nil) then
--					--   is the hairspace added through 
--					addTrackingCategory(trackingCategoryList"raw_unformatted_storyteleplay")
--				end
			end
		-- If serial titles need to be centered and not left, then this should be removed.
			local textAlign = "center"
			if v == 'Aux1' and isSerial then
				textAlign = "left"
			elseif v == '예비1' and isSerial then
				textAlign = "left"
			end
			local thisRowspan
			if (not parameterGroupCellsv and parameterGroupCellsAny) then
				thisRowspan = numberOfParameterGroups
			else
				thisRowspan = 1
			end
			if (currentRow == 1 or (currentRow > 1 and parameterGroupCellsv)) then
				createTableData(argsv, thisRowspan, textAlign)
			end
			nonNilParams = nonNilParams + 1
			checkUsageOfDateTemplates(args, v, onInitialPage, title)
		end
		if (argsv == "TBA" or argsv == "추후 공개") then
			cellValueTBA = true
		end
	end
end
-- Local function which is used to create a table row header for either the
-- EpisodeNumber or EpisodeNumber2 column cells.
local function createTableRowEpisodeNumberHeader(episodeNumber, numberOfParameterGroups, episodeText, separateEpisodeNumbers)
		local epID = string.match(episodeNumber, "^%w+")
		row:tag('th')
			:attr('scope', 'row')
			:attr('rowspan', not separateEpisodeNumbers and numberOfParameterGroups or 1)
			:attr('id', epID and 'ep' .. epID or )
			:css('text-align', 'center')
			:wikitext(episodeText)
end
--
Local function which is used to extract the text from the EpisodeNumber or EpisodeNumber2
parameters and format them into a correct MoS compliant version.
Styles supported:
	-- A number range of two numbers, indicating the start and end of the range,
	seperated by an en-dash (–) with no spaces in between.
		Example: "1 - 2" -> "1–2"; "1-2-3" -> "1–3".
	-- An alphanumeric or letter range, similar to the above.
		Example: "A - B" -> "A–B"; "A-B-C" -> "A–C".
		Example: "A1 - B1" -> "A1–B1"; "A1-B1-C1" -> "A1–C1".
	-- A number range of two numbers, indicating the start and end of the range,
	seperated by a visual  (divider line).
	-- An alphanumeric or letter range, similar to the above.
--
local function getEpisodeText(episodeNumber)
	if (episodeNumber == ) then
		return tableEmptyCellModule._main({})
	else
		local episodeNumber1
		local episodeNumber2
		-- Used for double episodes that need a visual "–"" or """ added.
		local divider
		episodeNumber = episodeNumber:gsub('%s*%s*', )
		if (episodeNumber:match('^(%w+)%s*%s*(%w+)$')) then
			episodeNumber1, episodeNumber2 = episodeNumber:match('^(%w+)%s*%s*(%w+)$')
			divider = ""
		elseif (episodeNumber:match('^(%w+)%s*.-%s*(%w+)$')) then  -- 3 or more elements
			episodeNumber1, episodeNumber2 = episodeNumber:match('^(%w+)%s*.-%s*(%w+)$')
			divider = ""
		elseif (mw.ustring.match(episodeNumber, '^(%w+)%s*%s%-–/&%s*(%w+)$')) then
			episodeNumber1, episodeNumber2 = mw.ustring.match(episodeNumber, '^(%w+)%s*%s%-–/&%s*(%w+)$')
			divider = "–"
		else
			episodeNumber1, episodeNumber2 = mw.ustring.match(episodeNumber, '^(%w+)%s*%s%-–/&.-%s%-–/&%s*(%w+)$')  -- 3 or more elements
			divider = "–"
		end
		if (not episodeNumber1) then
			return episodeNumber
		elseif (not episodeNumber2) then
			return string.match(episodeNumber, '%w+')
		else
			return episodeNumber1 .. divider .. episodeNumber2
		end
	end
end
-- Local function which is used to create EpisodeNumber2 and EpisodeNumber3 cells.
local function _createEpisodeNumberCellSecondary(episodeValue, numberOfParameterGroups, separateEpisodeNumbers)
	if (episodeValue) then
		local episodeText = getEpisodeText(episodeValue)
		if (nonNilParams == 0) then
			createTableRowEpisodeNumberHeader(episodeValue, numberOfParameterGroups, episodeText, separateEpisodeNumbers)
		else
			createTableData(episodeText, not separateEpisodeNumbers and numberOfParameterGroups or 1, "center")
		end
		nonNilParams = nonNilParams + 1
	end
end
-- Local function which is used to create seconday episode number cells.
local function createEpisodeNumberCellSecondary(args, numberOfParameterGroups, separateEpisodeNumbers)
	_createEpisodeNumberCellSecondary(args.EpisodeNumber2, numberOfParameterGroups, separateEpisodeNumbers)
	_createEpisodeNumberCellSecondary(args'번호2', numberOfParameterGroups, separateEpisodeNumbers)
	_createEpisodeNumberCellSecondary(args.EpisodeNumber3, numberOfParameterGroups, separateEpisodeNumbers)
	_createEpisodeNumberCellSecondary(args'번호3', numberOfParameterGroups, separateEpisodeNumbers)
end
-- Local function which is used to create an EpisodeNumber cell.
local function createEpisodeNumberCell(args, numberOfParameterGroups, separateEpisodeNumbers)
	if (args.EpisodeNumber or args'번호') then
		local episodeText = getEpisodeText(args.EpisodeNumber or args'번호')
		createTableRowEpisodeNumberHeader((args.EpisodeNumber or args'번호'), numberOfParameterGroups, episodeText, separateEpisodeNumbers)
		nonNilParams = nonNilParams + 1
	end
end
-- Local function which is used to create a single row of cells.
-- This is the standard function called.
local function createSingleRowCells(args, numberOfParameterGroups, multiTitleListEnabled, onInitialPage, title)
	createEpisodeNumberCell(args, 1, false)
	createEpisodeNumberCellSecondary(args, 1, false)
	createCells(args, false, 1, onInitialPage, title, numberOfParameterGroups)
end
-- Local function which is used to create a multiple row of cells.
-- This function is called when part of the row is rowspaned.
local function createMultiRowCells(args, numberOfParameterGroups, onInitialPage, title, topColor)
	local EpisodeNumberSplit = ((args.EpisodeNumber_1 or args'번호_1') and true or false)
	
	for i = 1, numberOfParameterGroups do
		args = extractDataFromNumberedSerialArgs(args, i, numberOfParameterGroups, title)
		
		if (EpisodeNumberSplit or (not EpisodeNumberSplit and i == 1)) then
			createEpisodeNumberCell(args, numberOfParameterGroups, EpisodeNumberSplit)
			createEpisodeNumberCellSecondary(args, numberOfParameterGroups, EpisodeNumberSplit)
		end
		
		createCells(args, true, i, onInitialPage, title, numberOfParameterGroups)
		if (i ~= numberOfParameterGroups) then
			local textColor = '#333'
			if topColor == 'inherit' then
				textColor = 'inherit'
			end
			
			row = row:done()  -- Use done() to close the 'tr' tag in rowspaned rows.
				:tag('tr')
				:addClass('vevent')
				:addClass('module-episode-list-row')
				:css('text-align', 'center')
				:css('background', topColor)
				:css('color', textColor)
		end
	end
end
-- Local function which is used to retrieve the NumParts value.
local function getnumberOfParameterGroups(args)
	for k, v in ipairs(cellNameList) do
		local numberedParameter = v .. "_" .. 1
		if (argsnumberedParameter) then
			parameterGroupCellsv = true
			parameterGroupCellsAny = true
			if not firstParameterGroupCell then
				firstParameterGroupCell = k
			end
		end
	end
	if (hasValue(args.NumParts)) then
		return args.NumParts, true
	elseif (hasValue(args'번호분할')) then
		return args'번호분할', true
	else
		return 1, false
	end
end
-- Local function which is used to retrieve the Top Color value.
local function getTopColor(args, rowColorEnabled, onInitialPage)
	local episodeNumber = mathModule._cleanNumber(args.EpisodeNumber) or mathModule._cleanNumber(args'번호') or 1
	if (args.TopColor) then
		if (string.find(args.TopColor, "#")) then
			return args.TopColor
		else
			return '#' .. args.TopColor
		end
	elseif (args'윗색') then
		if (string.find(args'윗색', "#")) then
			return args'윗색'
		else
			return '#' .. args'윗색'
		end
	else
		return 'inherit'
	end
end
-- Local function which is used to retrieve the Row Color value.
local function isRowColorEnabled(args)
	local rowColorEnabled = yesNoModule(args.RowColor or args'열색', false)
	if (args.RowColor and string.lower(args.RowColor) == 'on') or (args'열색' and string.lower(args'열색') == 'on') then
		rowColorEnabled = true
	end
	return rowColorEnabled
end
-- Local function which is used to retrieve the Line Color value.
local function getLineColor(args)
	-- Default color to light blue
	local lineColor = args.LineColor or args'선색' or 'CCCCFF'
	-- Add # to color if necessary, and set to default color if invalid
	if (htmlColorlineColor == nil) then
		lineColor = '#' .. (mw.ustring.match(lineColor, '^%s#*(a-fA-F0-9*)%s*$') or )
		if (lineColor == '#') then
			lineColor = '#CCCCFF'
		end
	end
	return lineColor
end
-- Local function which is used to check if the table is located on the page
-- currently viewed, or on a transcluded page instead.
-- If it is on a transcluded page, the episode summary should not be shown.
local function isOnInitialPage(args, sublist, pageTitle, initiallistTitle)
	-- This should be the only check needed, however, it was previously implemented with two templates
	-- with one of them not requiring an article name, so for backward compatability, the whole sequence is kept.
	local onInitialPage
	local onInitialPageCheck = (mw.uri.anchorEncode(pageTitle) == mw.uri.anchorEncode(initiallistTitle))
	-- Only sublist had anything about hiding, so only it needs to even check
	if (sublist) then
		onInitialPage = onInitialPageCheck
		-- avoid processing ghost references
		if (not onInitialPage) then
			args.ShortSummary = nil
			args'요약' = nil
		end
	else
		if (initiallistTitle == "") then
			onInitialPage = true
		else
			onInitialPage = onInitialPageCheck
		end
	end
	return onInitialPage
end
-- Local function which does the actual main process.
local function _main(args, sublist)
	local title = mw.title.getCurrentTitle()
	local pageTitle = title.text
	local initiallistTitle = args'1' or 
	-- Is this list on the same page as the page directly calling the template?
	local onInitialPage = isOnInitialPage(args, sublist, pageTitle, initiallistTitle)
	-- Need just this parameter removed if blank, no others
	if (hasValue(args.ShortSummary) == false) then
		args.ShortSummary = nil
	end
		if (hasValue(args'요약') == false) then
		args'요약' = nil
	end
	local lineColor = getLineColor(args)
	local rowColorEnabled = isRowColorEnabled(args)
	local topColor = getTopColor(args, rowColorEnabled, onInitialPage)
	local root = mw.html.create()							-- Create the root mw.html object to return
	local textColor = '#333'
	if topColor == 'inherit' then
		textColor = 'inherit'
	end
	row = root:tag('tr')									-- Create the table row and store it globally
				:addClass('vevent')
				:addClass('module-episode-list-row')
				:css('text-align', 'center')
				:css('background', topColor)
				:css('color', textColor)
	local numberOfParameterGroups, multiTitleListEnabled = getnumberOfParameterGroups(args)
	if (multiTitleListEnabled) then
		createMultiRowCells(args, numberOfParameterGroups, onInitialPage, title, topColor)
	else
		createSingleRowCells(args, numberOfParameterGroups, multiTitleListEnabled, onInitialPage, title)
	end
	-- add these categories only in the mainspace and only if they are on the page where the template is used
	if (onInitialPage and title.namespace == 0) then
		addLineColorTrackingCategories(args)
		addTopColorTrackingCategories(args)
	end
	if (cellValueTBA == true and title.namespace == 0) then
		addTrackingCategory(trackingCategoryList"tba_values")
	end
	-- Do not show the summary if this is being transcluded on the initial list page
	-- Do include it on all other lists
	if (onInitialPage and args.ShortSummary) or (onInitialPage and args'요약') then
		local bottomWrapper = createShortSummaryRow(args, lineColor)
		return tostring(root) .. tostring(bottomWrapper) .. trackingCategories
	else
		return tostring(root) .. trackingCategories
	end
end
-- Local function which handles both module entry points.
local function main(frame, sublist)
	local getArgs = require('Module:Arguments').getArgs
	local args
	-- Most parameters should still display when blank, so don't remove blanks
	if (sublist) then
		args = getArgs(frame, {removeBlanks = false, wrappers = '틀:에피소드 목록/보조목록'})
	else
		args = getArgs(frame, {removeBlanks = false, wrappers = '틀:에피소드 목록'})
	end
	-- args'1' = mw.getCurrentFrame():getParent():getTitle()
	return _main(args, sublist, frame)
end
--RowColor=			— optional; Switch parameter that must only be defined when the EpisodeNumber= entry is not a regular number
											(e.g. "12–13" for two episodes described in one table entry).
											If the first episode number is even, define pass "on". If the first episode number is odd, pass "off".
--
function p.sublist(frame)
	return main(frame, true)
end
--
Public function which is used to create an Episode row
for an Episode Table used for lists of episodes where all tables are on the same page.
For tables which are on different pages see p.sublist().
For complete parameter documentation, see the documentation at p.sublist().
--
function p.list(frame)
	return main(frame, false)
end
return p