<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AWeather%2Fsandbox</id>
	<title>Module:Weather/sandbox - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AWeather%2Fsandbox"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Weather/sandbox&amp;action=history"/>
	<updated>2026-04-17T02:46:36Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Weather/sandbox&amp;diff=147627&amp;oldid=prev</id>
		<title>imported&gt;WOSlinker: use require(&#039;strict&#039;) instead of require(&#039;Module:No globals&#039;)</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Weather/sandbox&amp;diff=147627&amp;oldid=prev"/>
		<updated>2022-10-21T10:06:22Z</updated>

		<summary type="html">&lt;p&gt;use require(&amp;#039;strict&amp;#039;) instead of require(&amp;#039;Module:No globals&amp;#039;)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local degree = &amp;quot;°&amp;quot; -- used by addUnitNames()&lt;br /&gt;
local minus = &amp;quot;−&amp;quot; -- used by makeRow() and makeTable()&lt;br /&gt;
local thinSpace = mw.ustring.char(0x2009) -- used by makeCell()&lt;br /&gt;
&lt;br /&gt;
local precision, decimals&lt;br /&gt;
&lt;br /&gt;
-- if not empty&lt;br /&gt;
local function ine(var)&lt;br /&gt;
	var = tostring(var)&lt;br /&gt;
	if var == &amp;quot;&amp;quot; then&lt;br /&gt;
		return nil&lt;br /&gt;
	else&lt;br /&gt;
		return var&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Error message handling&lt;br /&gt;
local message = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local function addMessage(newMessage)&lt;br /&gt;
	if ine(message) then&lt;br /&gt;
		message = message .. &amp;quot; &amp;quot; .. newMessage&lt;br /&gt;
	else&lt;br /&gt;
		message = &amp;quot;Notices: &amp;quot; .. newMessage&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function monospace(str)&lt;br /&gt;
	return &amp;#039;&amp;lt;span style=&amp;quot;background-color: #EEE; font-family: monospace;&amp;quot;&amp;gt;&amp;#039; .. str .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Input and output parameters&lt;br /&gt;
local function getFormat(inputParameter, outputParameter, palette, messages)&lt;br /&gt;
	local length, inputUnit, outputUnit, palette, show, cellFormat&lt;br /&gt;
	&lt;br /&gt;
	if inputParameter == nil then&lt;br /&gt;
		error(&amp;#039;Please provide the number of values and a unit in the input parameter&amp;#039;)&lt;br /&gt;
	else&lt;br /&gt;
		-- Find as many as two digits in the input parameter.&lt;br /&gt;
		length = tonumber(string.match(inputParameter, &amp;quot;(%d%d?)&amp;quot;)) &lt;br /&gt;
		if not length then&lt;br /&gt;
			length = 13&lt;br /&gt;
			addMessage(&amp;#039;getFormat has not found a length value in the input parameter; length defaults to &amp;quot;13&amp;quot;&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Find C or F, but not both&lt;br /&gt;
		if string.find(inputParameter, &amp;quot;C&amp;quot;) and string.find(inputParameter, &amp;quot;F&amp;quot;) then&lt;br /&gt;
			error(&amp;quot;Input unit must be either C (Celsius) or F (Fahrenheit)&amp;quot;)&lt;br /&gt;
		else&lt;br /&gt;
			inputUnit = string.match(inputParameter, &amp;quot;([CF])&amp;quot;) or error(&amp;quot;Please provide an input unit in the input parameter: F for Fahrenheit or C for Celsius&amp;quot;, 0)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if inputUnit == &amp;quot;C&amp;quot; then&lt;br /&gt;
			outputUnit = &amp;quot;F&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			outputUnit = &amp;quot;C&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Make sure nothing except C, F, numbers, or spaces is in the input parameter.&lt;br /&gt;
		if string.find(inputParameter, &amp;quot;[^CF%d%s]&amp;quot;) then&lt;br /&gt;
			addMessage(&amp;quot;There are extraneous characters in the &amp;quot; .. monospace(&amp;quot;output&amp;quot;) .. &amp;quot; parameter.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if outputParameter == nil then&lt;br /&gt;
		-- Since there are default values, the module will still generate output with an empty output parameter.&lt;br /&gt;
		addMessage(&amp;quot;No output format has been provided in the &amp;quot; .. monospace(&amp;quot;output&amp;quot;) .. &amp;quot; parameter, so default values will be used.&amp;quot;)&lt;br /&gt;
	else&lt;br /&gt;
		cellFormat = {}&lt;br /&gt;
		for i, unit in require(&amp;quot;Module:StringTools&amp;quot;).imatch(outputParameter, &amp;quot;[CF]&amp;quot;) do&lt;br /&gt;
			cellFormat[i] = unit&lt;br /&gt;
			if i &amp;gt; 2 then&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local function setFormat(key, variable, value)&lt;br /&gt;
			if string.find(outputParameter, key) then&lt;br /&gt;
				cellFormat[variable] = value&lt;br /&gt;
			else&lt;br /&gt;
				cellFormat[variable] = not value&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if cellFormat[1] then&lt;br /&gt;
			cellFormat.first = cellFormat[1]&lt;br /&gt;
		else&lt;br /&gt;
			error(&amp;#039;C or F not found in output parameter&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		if cellFormat[2] == nil then&lt;br /&gt;
			cellFormat[&amp;quot;convertUnits&amp;quot;] = false&lt;br /&gt;
		else&lt;br /&gt;
			if cellFormat[2] == cellFormat[1] then&lt;br /&gt;
				error(&amp;#039;There should not be two of the same unit name in the output parameter.&amp;#039;)&lt;br /&gt;
			else&lt;br /&gt;
				cellFormat[&amp;quot;convertUnits&amp;quot;] = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		setFormat(&amp;quot;unit&amp;quot;, &amp;quot;unitNames&amp;quot;, true)&lt;br /&gt;
		setFormat(&amp;quot;no ?color&amp;quot;, &amp;quot;color&amp;quot;, false)&lt;br /&gt;
		setFormat(&amp;quot;sort&amp;quot;, &amp;quot;sortable&amp;quot;, true)&lt;br /&gt;
		setFormat(&amp;quot;full ?size&amp;quot;, &amp;quot;smallFont&amp;quot;, false)&lt;br /&gt;
		setFormat(&amp;quot;no ?brackets&amp;quot;, &amp;quot;brackets&amp;quot;, false)&lt;br /&gt;
		setFormat(&amp;quot;round&amp;quot;, &amp;quot;decimals&amp;quot;, &amp;quot;0&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
		if string.find(outputParameter, &amp;quot;line break&amp;quot;) then&lt;br /&gt;
			cellFormat[&amp;quot;lineBreak&amp;quot;] = true&lt;br /&gt;
		elseif string.find(outputParameter, &amp;quot;one line&amp;quot;) then&lt;br /&gt;
			cellFormat[&amp;quot;lineBreak&amp;quot;] = false&lt;br /&gt;
		else&lt;br /&gt;
			cellFormat[&amp;quot;lineBreak&amp;quot;] = &amp;quot;auto&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		if string.find(outputParameter, &amp;quot;one line&amp;quot;) and&lt;br /&gt;
			string.find(outputParameter, &amp;quot;line break&amp;quot;) then&lt;br /&gt;
			error(&amp;#039;Place either &amp;quot;one line&amp;quot; or &amp;quot;line break&amp;quot; in the output parameter, not both&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	palette = palette or &amp;quot;cool2avg&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	show = messages == &amp;quot;show&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	return {&lt;br /&gt;
		length = length, inputUnit = inputUnit, outputUnit = outputUnit,&lt;br /&gt;
		cellFormat = cellFormat, show = show, palette = palette&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Math functions&lt;br /&gt;
&lt;br /&gt;
local function round(value, decimals)&lt;br /&gt;
	value = tonumber(value)&lt;br /&gt;
	if type(value) == &amp;quot;number&amp;quot; then&lt;br /&gt;
		return string.format(&amp;quot;%.&amp;quot; .. decimals .. &amp;quot;f&amp;quot;, value)&lt;br /&gt;
	else&lt;br /&gt;
		error(&amp;quot;Format was asked to operate on &amp;quot; .. tostring(value) .. &amp;quot;, which cannot be converted to a number.&amp;quot;, 2)&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function convert(value, unit, decimals) -- Unit is the unit being converted from.&lt;br /&gt;
	if not unit then&lt;br /&gt;
		error(&amp;quot;No unit supplied to convert.&amp;quot;, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if tonumber(value) then&lt;br /&gt;
		local value = tonumber(value)&lt;br /&gt;
		if unit == &amp;quot;C&amp;quot; then&lt;br /&gt;
			return round(value * 9/5 + 32, decimals)&lt;br /&gt;
		elseif unit == &amp;quot;F&amp;quot; then&lt;br /&gt;
			return round((value - 32) * 5/9, decimals)&lt;br /&gt;
		else&lt;br /&gt;
			error(&amp;quot;Input unit not recognized&amp;quot;, 2)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		-- to avoid concatenation errors&lt;br /&gt;
		return &amp;quot;&amp;quot; &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Stick numbers into array. Find out if any have decimals.&lt;br /&gt;
-- Throw an error if any are invalid.&lt;br /&gt;
local function _makeArray(format)&lt;br /&gt;
	return function(parameter)&lt;br /&gt;
		if not parameter then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		local array = {}&lt;br /&gt;
		-- If there are multiple parameters for numbers, and the first doesn&amp;#039;t have&lt;br /&gt;
		-- decimals, the rest will have their decimals rounded off.&lt;br /&gt;
		format.precision = format.precision or parameter:find(&amp;quot;%d%.%d&amp;quot;) and &amp;quot;1&amp;quot; or &amp;quot;0&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		local numbers = mw.text.split(parameter, &amp;quot;%s+&amp;quot;)&lt;br /&gt;
		if #numbers ~= format.length then&lt;br /&gt;
			addMessage(&amp;#039;There are not &amp;#039; .. format.length .. &amp;#039; values in the &amp;#039; .. parameter .. &amp;#039; parameter.&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		for i, number in ipairs(numbers) do&lt;br /&gt;
			if not number:find(&amp;quot;^%-?%d%d?%d?.?(%d?)$&amp;quot;) then&lt;br /&gt;
				error(&amp;#039;The number &amp;quot;&amp;#039; .. number .. &amp;#039;&amp;quot; does not fit the expected pattern.&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			table.insert(array, number)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		return array&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Color generation&lt;br /&gt;
&lt;br /&gt;
p.palettes = {&lt;br /&gt;
	--[[&lt;br /&gt;
		The first three arrays in each palette defines background color using a&lt;br /&gt;
		table of four numbers, say { 11, 22, 33, 44 } (values in °C).&lt;br /&gt;
		That means that, on the scale from 0 (black) to 255 (saturated), the color&lt;br /&gt;
		is 0 below 11°C and above 44°C, and is 255 from 22°C to 33°C.&lt;br /&gt;
		The color rises from 0 to 255 between 11°C and 22°C, and falls from 255 to 0&lt;br /&gt;
		between 33°C and 44°C.&lt;br /&gt;
	]]&lt;br /&gt;
	cool = {&lt;br /&gt;
		{ -42.75,   4.47, 41.5, 60   }, -- red&lt;br /&gt;
		{ -42.75,   4.47,  4.5, 41.5 }, -- green&lt;br /&gt;
		{ -90   , -42.78,  4.5, 23   }, -- blue&lt;br /&gt;
		white = { -23.3, 37.8 },		-- background&lt;br /&gt;
	},&lt;br /&gt;
	cool2 = {&lt;br /&gt;
		{ -42.75,   4.5 , 41.5, 56   },&lt;br /&gt;
		{ -42.75,   4.5 ,  4.5, 41.5 },&lt;br /&gt;
		{ -90   , -42.78,  4.5, 23   },&lt;br /&gt;
		white = { -23.3, 35 },&lt;br /&gt;
	},&lt;br /&gt;
	cool2avg = {&lt;br /&gt;
		{ -38,   4.5, 25  , 45   },&lt;br /&gt;
		{ -38,   4.5,  4.5, 30   },&lt;br /&gt;
		{ -70, -38  ,  4.5, 23   },&lt;br /&gt;
		white = { -23.3, 25 },&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--[[ Return style for a table cell based on the given value which&lt;br /&gt;
	should be a temperature in °C. ]]&lt;br /&gt;
local function temperatureColor(palette, value, outRGB)&lt;br /&gt;
	local backgroundColor, textColor&lt;br /&gt;
	value = tonumber(value)&lt;br /&gt;
	if not value then&lt;br /&gt;
		backgroundColor, textColor = &amp;#039;FFF&amp;#039;, &amp;#039;000&amp;#039;&lt;br /&gt;
		addMessage(&amp;quot;Value supplied to &amp;quot; .. monospace(&amp;quot;temperatureColor&amp;quot;) .. &amp;quot; is not recognized.&amp;quot;)&lt;br /&gt;
	else&lt;br /&gt;
		local min, max = unpack(palette.white or { -23, 35 })&lt;br /&gt;
		if value &amp;lt; min or value &amp;gt;= max then&lt;br /&gt;
			textColor = &amp;#039;FFF&amp;#039;&lt;br /&gt;
			-- Else nil.&lt;br /&gt;
			-- This assumes that black text color is the default for most readers.&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local backgroundRGB = outRGB or {}&lt;br /&gt;
		for i, v in ipairs(palette) do&lt;br /&gt;
			local a, b, c, d = unpack(v)&lt;br /&gt;
			if value &amp;lt;= a then&lt;br /&gt;
				backgroundRGB[i] = 0&lt;br /&gt;
			elseif value &amp;lt; b then&lt;br /&gt;
				backgroundRGB[i] = (value - a) * 255 / (b - a)&lt;br /&gt;
			elseif value &amp;lt;= c then&lt;br /&gt;
				backgroundRGB[i] = 255&lt;br /&gt;
			elseif value &amp;lt; d then&lt;br /&gt;
				backgroundRGB[i] = 255 - ( (value - c) * 255 / (d - c) )&lt;br /&gt;
			else&lt;br /&gt;
				backgroundRGB[i] = 0&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		backgroundColor = string.format(&amp;#039;%02X%02X%02X&amp;#039;, unpack(backgroundRGB))&lt;br /&gt;
	end&lt;br /&gt;
	return backgroundColor, textColor&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function colorCSS(backgroundColor, textColor)&lt;br /&gt;
	if backgroundColor and textColor then&lt;br /&gt;
		return &amp;#039;background: #&amp;#039; .. backgroundColor .. &amp;#039;; color: #&amp;#039; .. textColor .. &amp;#039;;&amp;#039;&lt;br /&gt;
	elseif backgroundColor then&lt;br /&gt;
		return &amp;#039;background: #&amp;#039; .. backgroundColor .. &amp;#039;;&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function temperatureColorCSS(palette, value, outRGB)&lt;br /&gt;
	return colorCSS(temperatureColor(palette, value, outRGB))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function temperatureCSS(value, unit, palette)&lt;br /&gt;
	local palette = p.palettes[palette] or p.palettes.cool&lt;br /&gt;
	local value = tonumber(value)&lt;br /&gt;
	if value == nil then&lt;br /&gt;
		error(&amp;quot;The function &amp;quot; .. monospace(&amp;quot;temperatureCSS&amp;quot;) .. &amp;quot; is receiving a nil value&amp;quot;)&lt;br /&gt;
	else&lt;br /&gt;
		if unit == &amp;#039;F&amp;#039; then&lt;br /&gt;
			value = convert(value, &amp;#039;F&amp;#039;, decimals)&lt;br /&gt;
		elseif unit ~= &amp;#039;C&amp;#039; then&lt;br /&gt;
			unitError(unit or &amp;quot;nil&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		return colorCSS(temperatureColor(palette, value))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function styleAttribute(palette, value, outRGB)&lt;br /&gt;
	local fontSize = &amp;quot;font-size: 85%;&amp;quot;&lt;br /&gt;
	local color = temperatureColorCSS(palette, value, outRGB)&lt;br /&gt;
	return &amp;#039;style=\&amp;quot;&amp;#039; .. color .. &amp;#039; &amp;#039; .. fontSize .. &amp;#039;\&amp;quot;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local style_attribute = styleAttribute&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
	Used by {{Average temperature table/row/C/sandbox}},&lt;br /&gt;
	{{Average temperature table/row/F/sandbox}},&lt;br /&gt;
	{{Average temperature table/row/C/sandbox}},&lt;br /&gt;
	{{Template:Avg temp row F/sandbox2}},&lt;br /&gt;
	{{Template:Avg temp row C/sandbox2}}.&lt;br /&gt;
]=]&lt;br /&gt;
function p.temperatureStyle(frame)&lt;br /&gt;
	local palette = p.palettes[frame.args.palette] or p.palettes.cool&lt;br /&gt;
	local unit = frame.args.unit or &amp;#039;C&amp;#039;&lt;br /&gt;
	local value = tonumber(frame.args[1])&lt;br /&gt;
	if unit == &amp;#039;F&amp;#039; then&lt;br /&gt;
		value = convert(value, &amp;#039;F&amp;#039;, 1)&lt;br /&gt;
	elseif unit ~= &amp;#039;C&amp;#039; then&lt;br /&gt;
		error(&amp;#039;Unrecognized unit: &amp;#039; .. unit)&lt;br /&gt;
	end&lt;br /&gt;
	return styleAttribute(palette, value)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.temperature_style = p.temperatureStyle&lt;br /&gt;
&lt;br /&gt;
--[[ ==== Cell, row, table generation ==== ]]&lt;br /&gt;
local outputFormats = {&lt;br /&gt;
	high_low_average_F =&lt;br /&gt;
		{ first = &amp;quot;F&amp;quot;,&lt;br /&gt;
		convertUnits = true,&lt;br /&gt;
		unitNames = false,&lt;br /&gt;
		color = true,&lt;br /&gt;
		smallFont = true,&lt;br /&gt;
		sortable = true,&lt;br /&gt;
		decimals = &amp;quot;0&amp;quot;,&lt;br /&gt;
		brackets = true,&lt;br /&gt;
		lineBreak = &amp;quot;auto&amp;quot;, },&lt;br /&gt;
	high_low_average_C =&lt;br /&gt;
		{ first = &amp;quot;C&amp;quot;,&lt;br /&gt;
		convertUnits = true,&lt;br /&gt;
		unitNames = false,&lt;br /&gt;
		color = true,&lt;br /&gt;
		smallFont = true,&lt;br /&gt;
		sortable = true,&lt;br /&gt;
		decimals = &amp;quot;0&amp;quot;,&lt;br /&gt;
		brackets = true,&lt;br /&gt;
		lineBreak = &amp;quot;auto&amp;quot;, },&lt;br /&gt;
	high_low_F =&lt;br /&gt;
		{ first = &amp;quot;F&amp;quot;,&lt;br /&gt;
		convertUnits = true,&lt;br /&gt;
		unitNames = false,&lt;br /&gt;
		color = false,&lt;br /&gt;
		smallFont = true,&lt;br /&gt;
		sortable = false,&lt;br /&gt;
		decimals = &amp;quot;&amp;quot;,&lt;br /&gt;
		brackets = true,&lt;br /&gt;
		lineBreak = &amp;quot;auto&amp;quot;, },&lt;br /&gt;
	high_low_C =&lt;br /&gt;
		{ first = &amp;quot;C&amp;quot;,&lt;br /&gt;
		convertUnits = true,&lt;br /&gt;
		unitNames = false,&lt;br /&gt;
		color = false,&lt;br /&gt;
		smallFont = true,&lt;br /&gt;
		sortable = false,&lt;br /&gt;
		decimals = &amp;quot;0&amp;quot;,&lt;br /&gt;
		brackets = true,&lt;br /&gt;
		lineBreak = &amp;quot;auto&amp;quot;, },&lt;br /&gt;
	average_F =&lt;br /&gt;
		{ first = &amp;quot;F&amp;quot;,&lt;br /&gt;
		convertUnits = true,&lt;br /&gt;
		unitNames = false,&lt;br /&gt;
		color = true,&lt;br /&gt;
		smallFont = true,&lt;br /&gt;
		sortable = false,&lt;br /&gt;
		decimals = &amp;quot;0&amp;quot;,&lt;br /&gt;
		brackets = true,&lt;br /&gt;
		lineBreak = &amp;quot;auto&amp;quot;, },&lt;br /&gt;
	average_C =&lt;br /&gt;
		{ first = &amp;quot;C&amp;quot;,&lt;br /&gt;
		convertUnits = true,&lt;br /&gt;
		unitNames = false,&lt;br /&gt;
		color = true,&lt;br /&gt;
		smallFont = true,&lt;br /&gt;
		sortable = false,&lt;br /&gt;
		decimals = &amp;quot;0&amp;quot;,&lt;br /&gt;
		brackets = true,&lt;br /&gt;
		lineBreak = &amp;quot;auto&amp;quot;, },&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
local outputFormat&lt;br /&gt;
&lt;br /&gt;
local function addUnitNames(value, yesOrNo, unit)&lt;br /&gt;
	if not unit then&lt;br /&gt;
		error(&amp;quot;No unit supplied as argument 3 to addUnitNames&amp;quot;, 2)&lt;br /&gt;
	end&lt;br /&gt;
	-- Don&amp;#039;t add a unit name to an empty string&lt;br /&gt;
	value = yesOrNo == true and ine(value) and value .. &amp;quot;&amp;amp;nbsp;&amp;quot; .. degree .. unit or value&lt;br /&gt;
	return value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ifYes(parameter, realization1, realization2)&lt;br /&gt;
	local result&lt;br /&gt;
	if realization1 then&lt;br /&gt;
		if realization2 then&lt;br /&gt;
			result = parameter == true and { realization1, realization2 } or { &amp;quot;&amp;quot;, &amp;quot;&amp;quot; }&lt;br /&gt;
		else&lt;br /&gt;
			result = parameter == true and realization1 or &amp;quot;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		result = &amp;quot;&amp;quot;&lt;br /&gt;
		addMessage(monospace(&amp;quot;ifYes&amp;quot;) .. &amp;quot; needs at least one realization.&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeCell(outputFormat, a, b, c, format)&lt;br /&gt;
	local cell, cellContent = &amp;quot;&amp;quot;, &amp;quot;&amp;quot;&lt;br /&gt;
	local colorCSS, otherCSS, titleAttribute, sortkey, attributeSeparator, convertedUnitsSeparator =&lt;br /&gt;
		&amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	-- Distinguish styleAttribute variable from styleAttribute function above.&lt;br /&gt;
	local styleAttribute, highLowSeparator, brackets, values, convertedUnits =&lt;br /&gt;
		{&amp;quot;&amp;quot;, &amp;quot;&amp;quot;}, {&amp;quot;&amp;quot;, &amp;quot;&amp;quot;}, {&amp;quot;&amp;quot;, &amp;quot;&amp;quot;}, {&amp;quot;&amp;quot;, &amp;quot;&amp;quot;}, {&amp;quot;&amp;quot;, &amp;quot;&amp;quot;}&lt;br /&gt;
	&lt;br /&gt;
	-- Precision is 1 if any number has one or more decimals.&lt;br /&gt;
	decimals = tonumber(outputFormat.decimals) and outputFormat.decimals or format.precision&lt;br /&gt;
	&lt;br /&gt;
	if tonumber(b) and tonumber(a) then&lt;br /&gt;
		values, highLowSeparator = { round(a, decimals), round(b, decimals) },&lt;br /&gt;
			{ thinSpace .. &amp;quot;/&amp;quot; .. thinSpace, ifYes(outputFormat.convertUnits, thinSpace .. &amp;quot;/&amp;quot; .. thinSpace) }&lt;br /&gt;
	elseif tonumber(a) then&lt;br /&gt;
		values = { round(a, decimals), &amp;quot;&amp;quot; }&lt;br /&gt;
	elseif tonumber(c) then&lt;br /&gt;
		values = { round(c, decimals), &amp;quot;&amp;quot; }&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if outputFormat.first == format.inputUnit then&lt;br /&gt;
		if outputFormat.convertUnits == true then&lt;br /&gt;
			convertedUnits = { addUnitNames(convert(values[1], format.inputUnit, decimals), outputFormat.unitNames, format.outputUnit), addUnitNames(convert(values[2], format.inputUnit, decimals), outputFormat.unitNames, format.outputUnit) }&lt;br /&gt;
		end&lt;br /&gt;
		values = { addUnitNames(values[1], outputFormat.unitNames, format.inputUnit), addUnitNames(values[2], outputFormat.unitNames, format.inputUnit) }&lt;br /&gt;
	elseif outputFormat.first == &amp;quot;C&amp;quot; or outputFormat.first == &amp;quot;F&amp;quot; then&lt;br /&gt;
		if outputFormat.convertUnits == true then&lt;br /&gt;
			convertedUnits = { addUnitNames(values[1], outputFormat.unitNames, format.inputUnit), addUnitNames(values[2], outputFormat.unitNames, format.inputUnit) }&lt;br /&gt;
		end&lt;br /&gt;
		values = { addUnitNames(convert(values[1], format.inputUnit, decimals), outputFormat.unitNames, format.outputUnit), addUnitNames(convert(values[2], format.inputUnit, decimals), outputFormat.unitNames, format.outputUnit) }&lt;br /&gt;
	else&lt;br /&gt;
		addMessage(monospace(tostring(outputFormat.first)) .. &amp;quot;, the value for &amp;quot; .. monospace(&amp;quot;first&amp;quot;) .. &amp;quot; in &amp;quot; .. monospace(&amp;quot;outputFormat&amp;quot;) .. &amp;quot; is not recognized.&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	--[[&lt;br /&gt;
		Regarding line breaks:&lt;br /&gt;
		If there are two values, there will be at least three characters: 9/1.&lt;br /&gt;
		If there is one decimal, numbers will be three to five characters long&lt;br /&gt;
		and there will be 3 to 10 characters total even without unit conversion:&lt;br /&gt;
			1.1, 116.5/88.0.&lt;br /&gt;
		If there are units, that adds three characters per number: 25 °C/20 °C.&lt;br /&gt;
		In each of these cases, a line break is needed so that table cells are not too wide;&lt;br /&gt;
		even more so when more than one of these things are true.&lt;br /&gt;
		]]&lt;br /&gt;
	if outputFormat.convertUnits == true then&lt;br /&gt;
		brackets = outputFormat.brackets == true and { &amp;quot;(&amp;quot;, &amp;quot;)&amp;quot; } or { &amp;quot;&amp;quot;, &amp;quot;&amp;quot; }&lt;br /&gt;
		if outputFormat.lineBreak == &amp;quot;auto&amp;quot; then&lt;br /&gt;
			convertedUnitsSeparator = ( ine(values[2]) or decimals ~= &amp;quot;0&amp;quot; or outputFormat.showUnits == true ) and &amp;quot;&amp;lt;br&amp;gt;&amp;quot; or &amp;quot;&amp;amp;nbsp;&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			convertedUnitsSeparator = outputFormat.lineBreak == true and &amp;quot;&amp;lt;br&amp;gt;&amp;quot; or outputFormat.lineBreak == false and &amp;quot;&amp;amp;nbsp;&amp;quot; or error(&amp;#039;Value for lineBreak not recognized&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	cellContent = values[1] .. highLowSeparator[1] .. values[2] .. convertedUnitsSeparator .. brackets[1] .. convertedUnits[1] .. highLowSeparator[2] .. convertedUnits[2] .. brackets[2]&lt;br /&gt;
	&lt;br /&gt;
	if tonumber(c) then&lt;br /&gt;
		colorCSS = outputFormat.color == true and temperatureCSS(c, format.inputUnit, format.palette, format.inputUnit) or &amp;quot;&amp;quot;&lt;br /&gt;
		if tonumber(b) and tonumber(a) then&lt;br /&gt;
			local attributeValue = outputFormat.first == format.inputUnit and c or convert(c, format.inputUnit, decimals)&lt;br /&gt;
			sortkey = outputFormat.sortable == true and &amp;quot; data-sort-value=\&amp;quot;&amp;quot; .. attributeValue .. &amp;quot;\&amp;quot;&amp;quot; or &amp;quot;&amp;quot;&lt;br /&gt;
			titleAttribute = &amp;quot; title=\&amp;quot;Average temperature: &amp;quot; .. attributeValue .. &amp;quot; &amp;quot; .. degree .. outputFormat.first .. &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	elseif tonumber(b) then&lt;br /&gt;
		colorCSS = &amp;quot;&amp;quot;&lt;br /&gt;
	elseif tonumber(a) then&lt;br /&gt;
		colorCSS = outputFormat.color == true and temperatureCSS(a, format.inputUnit, format.palette) or &amp;quot;&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		addMessage(&amp;#039;Neither a nor b nor c are strings.&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	otherCSS = outputFormat.smallFont == true and &amp;quot;font-size: 85%;&amp;quot; or &amp;quot;&amp;quot;&lt;br /&gt;
	if ine(colorCSS) or ine(otherCSS) then&lt;br /&gt;
		styleAttribute = { &amp;quot;style=\&amp;quot;&amp;quot;, &amp;quot;\&amp;quot;&amp;quot; }&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if ine(otherCSS) or ine(colorCSS) or ine(titleAttribute) or ine(sortkey) then&lt;br /&gt;
		attributeSeparator = &amp;quot; | &amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	cell = &amp;quot;\n| &amp;quot; .. styleAttribute[1] .. colorCSS .. otherCSS .. styleAttribute[2] .. titleAttribute .. sortkey .. attributeSeparator .. cellContent&lt;br /&gt;
	return cell&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Replaces hyphens that have a punctuation or space character before them and a number after them,&lt;br /&gt;
	making sure that hyphens in &amp;quot;data-sort-type&amp;quot; are not replaced with minuses.&lt;br /&gt;
	If Lua had (?&amp;lt;=), a capture would not be necessary. &lt;br /&gt;
]]&lt;br /&gt;
local function hyphenToMinus(str)&lt;br /&gt;
	return str:gsub(&amp;quot;([%p%s])-(%d)&amp;quot;, &amp;quot;%1&amp;quot; .. minus .. &amp;quot;%2&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeRow(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local format = getFormat(args.input, args.output, args.palette, args.messages)&lt;br /&gt;
	local makeArray = _makeArray(format)&lt;br /&gt;
	local a, b, c = makeArray(args.a), makeArray(args.b), makeArray(args.c)&lt;br /&gt;
	local output = {}&lt;br /&gt;
	if args[1] then&lt;br /&gt;
		table.insert(output, &amp;quot;\n|-&amp;quot;)&lt;br /&gt;
		table.insert(output, &amp;quot;\n! &amp;quot; .. args[1])&lt;br /&gt;
		if args[2] then&lt;br /&gt;
			table.insert(output, &amp;quot; !! &amp;quot; .. args[2])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if format.cellFormat then&lt;br /&gt;
		outputFormat = format.cellFormat&lt;br /&gt;
	end&lt;br /&gt;
	-- Assumes that if c is defined, b and a are, and if b is defined, a is.&lt;br /&gt;
	if c then&lt;br /&gt;
		if not outputFormat then&lt;br /&gt;
			outputFormat = outputFormats.high_low_average_F&lt;br /&gt;
		end&lt;br /&gt;
		for i = 1, format.length do&lt;br /&gt;
			table.insert(output, makeCell(outputFormat, a[i], b[i], c[i], format))&lt;br /&gt;
		end&lt;br /&gt;
	elseif b then&lt;br /&gt;
		if not outputFormat then&lt;br /&gt;
			outputFormat = outputFormats.high_low_F&lt;br /&gt;
		end&lt;br /&gt;
		for i = 1, format.length do&lt;br /&gt;
			table.insert(output, makeCell(outputFormat, a[i], b[i], nil, format))&lt;br /&gt;
		end&lt;br /&gt;
	elseif a then&lt;br /&gt;
		if not outputFormat then&lt;br /&gt;
			outputFormat = outputFormats.average_F&lt;br /&gt;
		end&lt;br /&gt;
		for i = 1, format.length do&lt;br /&gt;
			table.insert(output, makeCell(outputFormat, a[i], nil, nil, format))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	output = table.concat(output)&lt;br /&gt;
	output = hyphenToMinus(output)&lt;br /&gt;
	return output&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeTable(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local format = getFormat(args.input, args.output, args.palette, args.messages)&lt;br /&gt;
	local makeArray = _makeArray(format)&lt;br /&gt;
	local a, b, c = makeArray(args.a), makeArray(args.b), makeArray(args.c)&lt;br /&gt;
	local output = { &amp;quot;{| class=\&amp;quot;wikitable center nowrap\&amp;quot;&amp;quot; }&lt;br /&gt;
	if format.cellFormat then&lt;br /&gt;
		outputFormat = format.cellFormat&lt;br /&gt;
	end&lt;br /&gt;
	-- Assumes that if c is defined, b and a are, and if b is defined, a is.&lt;br /&gt;
	if c then&lt;br /&gt;
		for i = 1, format.length do&lt;br /&gt;
			if not outputFormat then&lt;br /&gt;
				outputFormat = outputFormats.high_low_average_F&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(output, makeCell(outputFormat, a[i], b[i], c[i], format))&lt;br /&gt;
		end&lt;br /&gt;
	elseif b then&lt;br /&gt;
		for i = 1, format.length do&lt;br /&gt;
			if not outputFormat then&lt;br /&gt;
				outputFormat = outputFormats.high_low_F&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(output, makeCell(outputFormat, a[i], b[i], nil, format))&lt;br /&gt;
		end&lt;br /&gt;
	elseif a then&lt;br /&gt;
		for i = 1, format.length do&lt;br /&gt;
			if not outputFormat then&lt;br /&gt;
				outputFormat = outputFormats.average_F&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(output, makeCell(outputFormat, a[i], nil, nil, format))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(output, &amp;quot;\n|}&amp;quot;)&lt;br /&gt;
	if format.show then&lt;br /&gt;
		table.insert(output, &amp;quot;\n\n&amp;lt;span style=\&amp;quot;color: red; font-size: 80%; line-height: 100%;\&amp;quot;&amp;gt;&amp;quot; .. message .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	output = table.concat(output)&lt;br /&gt;
	&lt;br /&gt;
	output = hyphenToMinus(output)&lt;br /&gt;
	&lt;br /&gt;
	return output&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local chart = [[&lt;br /&gt;
{{Graph:Chart&lt;br /&gt;
|width=600&lt;br /&gt;
|height=180&lt;br /&gt;
|xAxisTitle=Celsius&lt;br /&gt;
|yAxisTitle=__COLOR&lt;br /&gt;
|type=line&lt;br /&gt;
|x=__XVALUES&lt;br /&gt;
|y=__YVALUES&lt;br /&gt;
|colors=__COLOR&lt;br /&gt;
}}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function p.show(frame)&lt;br /&gt;
	-- For testing, return wikitext to show graphs of how the red/green/blue colors&lt;br /&gt;
	-- vary with temperature, and a table of the resulting colors.&lt;br /&gt;
	local function collection()&lt;br /&gt;
		-- Return a table to hold items.&lt;br /&gt;
		return {&lt;br /&gt;
			n = 0,&lt;br /&gt;
			add = function (self, item)&lt;br /&gt;
				if item then&lt;br /&gt;
					self.n = self.n + 1&lt;br /&gt;
					self[self.n] = item&lt;br /&gt;
				end&lt;br /&gt;
			end,&lt;br /&gt;
			join = function (self, sep)&lt;br /&gt;
				return table.concat(self, sep)&lt;br /&gt;
			end,&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	local function make_chart(result, color, xvalues, yvalues)&lt;br /&gt;
		result:add(&amp;#039;\n&amp;#039;)&lt;br /&gt;
		result:add(frame:preprocess((chart:gsub(&amp;#039;__[A-Z]+&amp;#039;, {&lt;br /&gt;
			__COLOR = color,&lt;br /&gt;
			__XVALUES = xvalues:join(&amp;#039;,&amp;#039;),&lt;br /&gt;
			__YVALUES = yvalues:join(&amp;#039;,&amp;#039;),&lt;br /&gt;
		}))))&lt;br /&gt;
	end&lt;br /&gt;
	local function with_minus(value)&lt;br /&gt;
		if value &amp;lt; 0 then&lt;br /&gt;
			return minus .. tostring(-value)&lt;br /&gt;
		end&lt;br /&gt;
		return tostring(value)&lt;br /&gt;
	end&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local first = args[1] or -90&lt;br /&gt;
	local last = args[2] or 59&lt;br /&gt;
	local palette = p.palettes[args.palette] or p.palettes.cool&lt;br /&gt;
	local xvals, reds, greens, blues = collection(), collection(), collection(), collection()&lt;br /&gt;
	local wikitext = collection()&lt;br /&gt;
	wikitext:add(&amp;#039;{| class=&amp;quot;wikitable&amp;quot;\n|-\n&amp;#039;)&lt;br /&gt;
	local columns = 0&lt;br /&gt;
	for celsius = first, last do&lt;br /&gt;
		local backgroundRGB = {}&lt;br /&gt;
		local style = styleAttribute(palette, celsius, backgroundRGB)&lt;br /&gt;
		local R = math.floor(backgroundRGB[1])&lt;br /&gt;
		local G = math.floor(backgroundRGB[2])&lt;br /&gt;
		local B = math.floor(backgroundRGB[3])&lt;br /&gt;
		xvals:add(celsius)&lt;br /&gt;
		reds:add(R)&lt;br /&gt;
		greens:add(G)&lt;br /&gt;
		blues:add(B)&lt;br /&gt;
		wikitext:add(&amp;#039;| &amp;#039; .. style .. &amp;#039; | &amp;#039; .. with_minus(celsius) .. &amp;#039;\n&amp;#039;)&lt;br /&gt;
		columns = columns + 1&lt;br /&gt;
		if columns &amp;gt;= 10 then&lt;br /&gt;
			columns = 0&lt;br /&gt;
			wikitext:add(&amp;#039;|-\n&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	wikitext:add(&amp;#039;|}\n&amp;#039;)&lt;br /&gt;
	make_chart(wikitext, &amp;#039;Red&amp;#039;, xvals, reds)&lt;br /&gt;
	make_chart(wikitext, &amp;#039;Green&amp;#039;, xvals, greens)&lt;br /&gt;
	make_chart(wikitext, &amp;#039;Blue&amp;#039;, xvals, blues)&lt;br /&gt;
	return wikitext:join()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;WOSlinker</name></author>
	</entry>
</feed>