Difference between revisions of "Module:Sandbox/Arcangelus"

From RimWorld Wiki
Jump to navigation Jump to search
m
m
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
local yesno, getArgs -- lazily initialized
+
--[[
local p = {}
+
-- A proper solution needs to consider PC, PlayStation 4 and Xbox One. Maybe Steam deck as well.
local wrap = {} -- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua.
 
 
 
--Copied from https://en.wikipedia.org/wiki/Module:Math
 
local function err(msg)
 
-- Generates wikitext error messages.
 
return mw.ustring.format('<strong class="error">Formatting error: %s</strong>', msg)
 
end
 
 
 
local function unpackNumberArgs(args)
 
-- Returns an unpacked list of arguments specified with numerical keys.
 
local ret = {}
 
for k, v in pairs(args) do
 
if type(k) == 'number' then
 
table.insert(ret, v)
 
end
 
end
 
return unpack(ret)
 
end
 
  
local function makeArgArray(...)
+
-- This solution uses images: https://splatoonwiki.org/wiki/Module:Button
-- Makes an array of arguments from a list of arguments that might include nils.
+
-- Switch: https://splatoonwiki.org/w/index.php?title=Special%3APrefixIndex&prefix=Switch_Icon_&namespace=6
local args = {...} -- Table of arguments. It might contain nils or non-number values, so we can't use ipairs.
+
--
local nums = {} -- Stores the numbers of valid numerical arguments.
+
-- Possible to get icons from wikipedia, if needed.
local ret = {}
+
-- For Xbox:
for k, v in pairs(args) do
+
-- https://commons.wikimedia.org/wiki/Category:Xbox_controller_buttons
v = p._cleanNumber(v)
+
-- https://commons.wikimedia.org/wiki/Category:Xbox_Series_Controller_icons
if v then
+
-- For PlayStation 4:
nums[#nums + 1] = k
+
-- https://commons.wikimedia.org/wiki/Category:PlayStation_controller_buttons
args[k] = v
+
--
end
+
-- Other possible sources (Creative Commons Attribution):
end
+
-- https://zacksly.itch.io/ps5-button-icons-and-controls ; https://zacksly.itch.io/xbox-series-button-icons-and-controls
table.sort(nums)
 
for i, num in ipairs(nums) do
 
ret[#ret + 1] = args[num]
 
end
 
return ret
 
end
 
  
local function fold(func, ...)
+
-- Below this line was taken from https://en.wikipedia.org/wiki/Module:Key. As the CSS was was not copied ovee, this is incomplete and only kinda works. Not properly implemented as I'm not happy on the handling of console inputs (controller)
-- Use a function on all supplied arguments, and return the result. The function must accept two numbers as parameters,
+
-- Aditionally, there seems to be some kind of issue with dark mode. See here to avoid it: https://www.mediawiki.org/wiki/Recommendations_for_night_mode_compatibility_on_Wikimedia_wikis?minervanightmode=1 ]]
-- and must return a number as an output. This number is then supplied as input to the next function call.
+
--------------------------------------------------
local vals = makeArgArray(...)
+
-- This module implements {{key press}}.
local count = #vals -- The number of valid arguments
 
if count == 0 then return
 
-- Exit if we have no valid args, otherwise removing the first arg would cause an error.
 
nil, 0
 
end
 
local ret = table.remove(vals, 1)
 
for _, val in ipairs(vals) do
 
ret = func(ret, val)
 
end
 
return ret, count
 
end
 
  
function p.test(frame)
+
local kbdPrefix = '<kbd class="keyboard-key nowrap">'
parent=frame:getParent()--equal to frame.getParent(frame)
 
return parent.args
 
end
 
  
--[[
+
local kbdSuffix = '</kbd>'
function p.hello()
 
    return 'Hola'
 
end
 
  
aname=string.match("Blood Filtration Limit",' %(.*)% ')
+
local keyText = {
 +
['caps lock'] = '⇪ Caps Lock',
 +
['[[caps lock]]'] = '⇪ [[Caps Lock]]',
 +
['shift'] = '⇧ Shift',
 +
['[[shift key|shift]]'] = '⇧ [[Shift key|Shift]]',
 +
['enter'] = '↵ Enter',
 +
['[[enter key|enter]]'] = '↵ [[Enter key|Enter]]',
 +
['cmd'] = '⌘ Cmd',
 +
['[[command key|cmd]]'] = '⌘ [[Command key|Cmd]]',
 +
['command'] = '⌘ Command',
 +
['[[command key|command]]'] = '⌘ [[Command key|Command]]',
 +
['opt'] = '⌥ Opt',
 +
['[[option key|opt]]'] = '⌥ [[Option key|Opt]]',
 +
['option'] = '⌥ Option',
 +
['[[option key|option]]'] = '⌥ [[Option key|Option]]',
 +
['tab'] = 'Tab ↹',
 +
['[[tab key|tab]]'] = '[[Tab key|Tab]] ↹',
 +
['backspace'] = '← Backspace',
 +
['[[backspace]]'] = '← [[Backspace]]',
 +
['win'] = '⊞ Win',
 +
['[[windows key|win]]'] = '⊞ [[Windows key|Win]]',
 +
['menu'] = '≣ Menu',
 +
['[[menu key|menu]]'] = '≣ [[Menu key|Menu]]',
 +
['up'] = '↑',
 +
['[[arrow keys|up]]'] = '[[Arrow keys|↑]]',
 +
['down'] = '↓',
 +
['[[arrow keys|down]]'] = '[[Arrow keys|↓]]',
 +
['left'] = '←',
 +
['[[arrow keys|left]]'] = '[[Arrow keys|←]]',
 +
['right'] = '→',
 +
['[[arrow keys|right]]'] = '[[Arrow keys|→]]',
 +
['asterisk'] = '&#42;',
 +
['hash'] = '&#35;',
 +
['[[#]]'] = '[[Number sign|#]]',
 +
['colon'] = '&#58;',
 +
['[[:]]'] = '[[Colon (punctuation)|:]]',
 +
['pipe'] = '&#124;',
 +
['[[|]]'] = '[[Pipe symbol|&#124;]]',
 +
['semicolon'] = '&#59;',
 +
['[[;]]'] = '[[Semi-colon|&#59;]]',
 +
['equals'] = '&#61;',
  
return p
+
-- Left & right analog sticks.
]]
+
['l up'] = 'L↑',
 +
['l down'] = 'L↓',
 +
['l left'] = 'L←',
 +
['l right'] = 'L→',
 +
['l ne'] = 'L↗',
 +
['l se'] = 'L↘',
 +
['l nw'] = 'L↖',
 +
['l sw'] = 'L↙',
  
--[[
+
['r up'] = 'R↑',
Fold arguments by selectively choosing values (func should return when to choose the current "dominant" value).
+
['r down'] = 'R↓',
]]
+
['r left'] = 'R←',
local function binary_fold(func, ...)
+
['r right'] = 'R→',
local value = fold((function(a, b) if func(a, b) then return a else return b end end), ...)
+
['r ne'] = 'R↗',
return value
+
['r se'] = 'R↘',
end
+
['r nw'] = 'R↖',
 +
['r sw'] = 'R↙',
  
--TEST AREA
+
-- PlayStation.
Quality={ Quality_general, Quality_building, Quality_Apparel, Quality_Weapons }
+
['ex'] = '×',
 +
['circle'] = '○',
 +
['square'] = '□',
 +
['triangle'] = '△',
  
Quality_general={
+
-- Nintendo 64 and GameCube.
--{ Beauty, Market Value, Max Increment, Deterioration Rate, Psychic Sensitivity }
+
['c up'] = 'C↑',
awful={ -0.1, 0.50, 0, 2.00, 0.5 },
+
['c down'] = 'C↓',
poor={ 0.5, 0.75, 0, 1.50, 0.66 },
+
['c left'] = 'C←',
normal={ 1.0, 1.00, 0, 1.00, 0.83 },
+
['c right'] = 'C→',
good={ 2.0, 1.25, 500, 0.80, 1.00 },
+
['c ne'] = 'C↗',
excellent={ 3.0, 1.5, 1000, 0.60, 1.16 },
+
['c se'] = 'C↘',
masterwork={ 5.0, 2.5, 2000, 0.30, 1.32 },
+
['c nw'] = 'C↖',
legendary={ 8.0, 5, 3000, 0.10, 1.50 }
+
['c sw'] = 'C↙',
 
}
 
}
  
Quality_building={
+
local keyAlias = {
--{ Comfort, Rest Effectiveness, Surgery Success, Recreation Power, Meditation Psyfocus+, Meditation Psyfocus+ }
+
-- ['alternate name for key (alias)'] = 'name for key used in key table'
awful={ 0.76, 0.86, 0.90, 0.76, 0.12, 0 },
+
['[[cmd key|cmd]]'] = '[[command key|cmd]]',
poor={ 0.88, 0.92, 0.95, 0.88, 0.16, 0 },
+
['[[cmd key|command]]'] = '[[command key|command]]',
normal={ 1.00, 1.00, 1.00, 1.00, 0.20, 0.01 },
+
['[[opt key|opt]]'] = '[[option key|opt]]',
good={ 1.12, 1.08, 1.05, 1.12, 0.22, 0.01 },
+
['[[option key]]'] = '[[option key|option]]',
excellent={ 1.24, 1.14, 1.10, 1.24, 0.24, 0.01 },
+
['[[opt key|option]]'] = '[[option key|option]]',
masterwork={ 1.45, 1.25, 1.15, 1.40, 0.26, 0.02 },
+
['[[win key|win]]'] = '[[windows key|win]]',
legendary={ 1.70, 1.60, 1.30, 1.80, 0.28, 0.02 }
+
['*'] = 'asterisk',
 +
['#'] = 'hash',
 +
[':'] = 'colon',
 +
[';'] = 'semicolon',
 +
['l-up'] = 'l up',
 +
['l-down'] = 'l down',
 +
['l-left'] = 'l left',
 +
['l-right'] = 'l right',
 +
['l-ne'] = 'l ne',
 +
['l-se'] = 'l se',
 +
['l-nw'] = 'l nw',
 +
['l-sw'] = 'l sw',
 +
['r-up'] = 'r up',
 +
['r-down'] = 'r down',
 +
['r-left'] = 'r left',
 +
['r-right'] = 'r right',
 +
['r-ne'] = 'r ne',
 +
['r-se'] = 'r se',
 +
['r-nw'] = 'r nw',
 +
['r-sw'] = 'r sw',
 +
['ps x'] = 'ex',
 +
['ps c'] = 'circle',
 +
['ps s'] = 'square',
 +
['ps t'] = 'triangle',
 +
['c-up'] = 'c up',
 +
['c-down'] = 'c down',
 +
['c-left'] = 'c left',
 +
['c-right'] = 'c right',
 +
['c-ne'] = 'c ne',
 +
['c-se'] = 'c se',
 +
['c-nw'] = 'c nw',
 +
['c-sw'] = 'c sw',
 
}
 
}
  
Quality_Apparel={
+
local Collection = {}
--{ Protection, Insulation, Smokepop Pack Radius, Shield Max Energy, Shield Recharge Rate, Jump Range }
+
Collection.__index = Collection
awful={ 0.60, 0.80, 0.84, 0.60, 0.90, 0.75 },
+
do
poor={ 0.80, 0.90, 0.92, 0.80, 0.95, 0.90 },
+
function Collection:add(item)
normal={ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 },
+
if item ~= nil then
good={ 1.15, 1.10, 1.08, 1.20, 1.05, 1.06 },
+
self.n = self.n + 1
excellent={ 1.30, 1.20, 1.16, 1.40, 1.10, 1.13 },
+
self[self.n] = item
masterwork={ 1.45, 1.50, 1.30, 1.70, 1.20, 1.19 },
 
legendary={ 1.80, 1.80, 1.50, 2.10, 1.30, 1.25 }
 
}
 
 
 
Quality_Weapons={
 
--{ Melee Damage, Melee AP, Ranged Accuracy, Ranged Damage, Ranged AP }
 
awful={ 0.80, 0.80, 0.80, 0.9, 0.90 },
 
poor={ 0.90, 0.90, 0.90, 1, 1 },
 
normal={ 1.00, 1.00, 1, 1, 1 },
 
good={ 1.10, 1.10, 1.1, 1, 1 },
 
excellent={ 1.20, 1.20, 1.2, 1, 1 },
 
masterwork={ 1.45, 1.45, 1.35, 1.25, 1.25 },
 
legendary={ 1.65, 1.65, 1.5, 1.5, 1.5 }
 
}
 
 
 
--Stat Factors Table Row
 
function wrap.TableRow(args)
 
return p._TableRow(unpackNumberArgs(args))
 
end
 
function p._TableRow(skillBase, skillBonus, statMin, statMax, capImportance, capLimit, resultCols, LV, Ln)
 
local argumentos={skillBase,skillBonus,statMin,statMax,capImportance,capLimit,resultCols,LV,Ln}
 
 
for i = 1,8 do --This should prevent errors if a number is not defined.
 
if type(argumentos[i])~='number' then
 
argumentos[i]=0
 
 
end
 
end
 
end
 
end
-- Do note that statMin, statMax are handled by "Template:Stat Factors Table".
+
function Collection:join(sep)
-- While I could set fallbacks, I decided against it.
+
return table.concat(self, sep)
+
end
if tonumber(Ln)==nil then --Sanitizes input and allows for 0.
+
function Collection:sort(comp)
factor = skillBase + skillBonus * LV
+
table.sort(self, comp)
else
 
factor = Ln
 
 
end
 
end
 
+
function Collection.new()
local Pval = math.min(math.max(factor,statMin),statMax)
+
return setmetatable({n = 0}, Collection)
R_Pval = tostring(math.floor(Pval*10000+0.5)/100).."%" -- This formats the number as a 2 digit percent value, rounded up.
 
if tonumber(resultCols)>1 then
 
Pval = factor * ( 1 + capImportance * math.min(capLimit-1, 0.25))
 
Pval = math.min(math.max(Pval,statMin),statMax)
 
R_Sval="<td>"..tostring(math.floor(Pval*10000+0.5)/100).."% </td>"
 
else
 
R_Sval=""
 
 
end
 
end
 +
end
  
if tonumber(resultCols)>2 then
+
local function keyPress(args)
Pval = factor * ( 1 + capImportance * math.min(capLimit-1, 0.5))
+
local chainNames = {
Pval = math.min(math.max(Pval,statMin),statMax)
+
'chain first',
R_Tval="<td>"..tostring(math.floor(Pval*10000+0.5)/100).."% </td>"
+
'chain second',
else
+
'chain third',
R_Tval=""
+
'chain fourth',
 +
'chain fifth',
 +
'chain sixth',
 +
'chain seventh',
 +
'chain eighth',
 +
'chain ninth',
 +
}
 +
local result = Collection.new()
 +
local chainDefault = args.chain or '+'
 +
for i, id in ipairs(args) do
 +
if i > 1 then
 +
result:add(args[chainNames[i - 1]] or chainDefault)
 +
end
 +
local lc = id:lower()
 +
local text = keyText[lc] or keyText[keyAlias[lc]] or id
 +
result:add(kbdPrefix .. text .. kbdSuffix)
 
end
 
end
 +
return result:join()
 +
--mw.getCurrentFrame():extensionTag{
 +
-- name = 'templatestyles', args = { src = 'Template:Key press/styles.css'}
 +
-- }..result:join()
 
 
return "|-\r\n!"..LV.."\r\n|"..R_Pval..R_Sval..R_Tval
 
-- There are more efficient ways, but this works.
 
 
end
 
end
----------------
+
 
----------------
+
local function keypress(frame)
--Inspired by some fandom site.
+
-- Called by "{{key press|...}}".
----------------
+
-- Using the template doubles the post‐expand include size.
function spliting(frame)
+
return keyPress(frame:getParent().args)
local texto = frame.args[1]
 
local sep = frame.args[2]
 
local N = frame.args[3]
 
sep = sep or "%s"
 
local A = {}
 
for str in string.gmatch(texto, "([^"..sep.."]+)") do
 
table.insert(A, str)
 
end
 
N=N or 0
 
return A[N]
 
 
end
 
end
 
--[[ Taken from some fandom site
 
local text = "And if you tolerate this"
 
local tab = mw.text.split( text, " ")
 
print(tab[3])
 
]]
 
  
--[[
+
local function press(frame)
Wrapper function that does basic argument processing. This ensures that all functions from #invoke can use either the current
+
-- Called by "{{#invoke:key|press|...}}".
frame or the parent frame, and it also trims whitespace for all arguments and removes blank arguments.
+
return keyPress(frame.args)
]]
+
end
  
--[[ Comented out to test some things.
+
return {
local mt = { __index = function(t, k)
+
keypress = keypress,
return function(frame)
+
press = press,
if not getArgs then
+
}
getArgs = require('Module:Arguments').getArgs
 
end
 
return wrap[k](getArgs(frame))  -- Argument processing is left to Module:Arguments. Whitespace is trimmed and blank arguments are removed.
 
end
 
end }
 
 
 
return setmetatable(p, mt)
 
]]
 

Latest revision as of 20:50, 21 August 2024

Welcome to the RimWorld Wiki sandbox!
This sandbox is where you can experiment and practice working on a wiki page. This page will usually have little or no content. Feel free to add content or to make changes and save them to see the results.

To learn about editing and formatting start here: Help:Contents. Just start with the basics... enter some text, and learn the other pieces as you go.

Your content contributions are welcome and important. The wiki is a collaborative effort and others can help with formatting and other improvements.]

Best wishes!

Description[edit]

This is a doc attached to my sandbox. I'll use it to see the effects of my changes W/o messing something important

NOTE: LUA is usually slower than ParserFunctions for short statements. The factor varies from 7-1 to 2-1.
Lua only is an advantage to long statements, nested logic, loops (maybe others case i don't see right now).

expr only uses 1 Preprocessor visited node count, in general. Variables may change that.


function p._TableRow(skillBase, skillBonus, statMin, statMax, capImportance, capLimit, resultCols, LV, Ln)



--[[
-- A proper solution needs to consider PC, PlayStation 4 and Xbox One. Maybe Steam deck as well.

-- This solution uses images: https://splatoonwiki.org/wiki/Module:Button
-- Switch: https://splatoonwiki.org/w/index.php?title=Special%3APrefixIndex&prefix=Switch_Icon_&namespace=6
--
-- Possible to get icons from wikipedia, if needed.
-- For Xbox:
--	https://commons.wikimedia.org/wiki/Category:Xbox_controller_buttons
--	https://commons.wikimedia.org/wiki/Category:Xbox_Series_Controller_icons
-- For PlayStation 4:
--	https://commons.wikimedia.org/wiki/Category:PlayStation_controller_buttons
--
-- Other possible sources (Creative Commons Attribution):
-- https://zacksly.itch.io/ps5-button-icons-and-controls ; https://zacksly.itch.io/xbox-series-button-icons-and-controls

-- Below this line was taken from https://en.wikipedia.org/wiki/Module:Key. As the CSS was was not copied ovee, this is incomplete and only kinda works. Not properly implemented as I'm not happy on the handling of console inputs (controller)
-- Aditionally, there seems to be some kind of issue with dark mode. See here to avoid it: https://www.mediawiki.org/wiki/Recommendations_for_night_mode_compatibility_on_Wikimedia_wikis?minervanightmode=1 ]]
--------------------------------------------------
-- This module implements {{key press}}.

local kbdPrefix = '<kbd class="keyboard-key nowrap">'

local kbdSuffix = '</kbd>'

local keyText = {
	['caps lock'] = '⇪ Caps Lock',
	['[[caps lock]]'] = '⇪ [[Caps Lock]]',
	['shift'] = '⇧ Shift',
	['[[shift key|shift]]'] = '⇧ [[Shift key|Shift]]',
	['enter'] = '↵ Enter',
	['[[enter key|enter]]'] = '↵ [[Enter key|Enter]]',
	['cmd'] = '⌘ Cmd',
	['[[command key|cmd]]'] = '⌘ [[Command key|Cmd]]',
	['command'] = '⌘ Command',
	['[[command key|command]]'] = '⌘ [[Command key|Command]]',
	['opt'] = '⌥ Opt',
	['[[option key|opt]]'] = '⌥ [[Option key|Opt]]',
	['option'] = '⌥ Option',
	['[[option key|option]]'] = '⌥ [[Option key|Option]]',
	['tab'] = 'Tab ↹',
	['[[tab key|tab]]'] = '[[Tab key|Tab]] ↹',
	['backspace'] = '← Backspace',
	['[[backspace]]'] = '← [[Backspace]]',
	['win'] = '⊞ Win',
	['[[windows key|win]]'] = '⊞ [[Windows key|Win]]',
	['menu'] = '≣ Menu',
	['[[menu key|menu]]'] = '≣ [[Menu key|Menu]]',
	['up'] = '↑',
	['[[arrow keys|up]]'] = '[[Arrow keys|↑]]',
	['down'] = '↓',
	['[[arrow keys|down]]'] = '[[Arrow keys|↓]]',
	['left'] = '←',
	['[[arrow keys|left]]'] = '[[Arrow keys|←]]',
	['right'] = '→',
	['[[arrow keys|right]]'] = '[[Arrow keys|→]]',
	['asterisk'] = '&#42;',
	['hash'] = '&#35;',
	['[[#]]'] = '[[Number sign|#]]',
	['colon'] = '&#58;',
	['[[:]]'] = '[[Colon (punctuation)|:]]',
	['pipe'] = '&#124;',
	['[[|]]'] = '[[Pipe symbol|&#124;]]',
	['semicolon'] = '&#59;',
	['[[;]]'] = '[[Semi-colon|&#59;]]',
	['equals'] = '&#61;',

	-- Left & right analog sticks.
	['l up'] = 'L↑',
	['l down'] = 'L↓',
	['l left'] = 'L←',
	['l right'] = 'L→',
	['l ne'] = 'L↗',
	['l se'] = 'L↘',
	['l nw'] = 'L↖',
	['l sw'] = 'L↙',

	['r up'] = 'R↑',
	['r down'] = 'R↓',
	['r left'] = 'R←',
	['r right'] = 'R→',
	['r ne'] = 'R↗',
	['r se'] = 'R↘',
	['r nw'] = 'R↖',
	['r sw'] = 'R↙',

	-- PlayStation.
	['ex'] = '×',
	['circle'] = '○',
	['square'] = '□',
	['triangle'] = '△',

	-- Nintendo 64 and GameCube.
	['c up'] = 'C↑',
	['c down'] = 'C↓',
	['c left'] = 'C←',
	['c right'] = 'C→',
	['c ne'] = 'C↗',
	['c se'] = 'C↘',
	['c nw'] = 'C↖',
	['c sw'] = 'C↙',
}

local keyAlias = {
	-- ['alternate name for key (alias)'] = 'name for key used in key table'
	['[[cmd key|cmd]]'] = '[[command key|cmd]]',
	['[[cmd key|command]]'] = '[[command key|command]]',
	['[[opt key|opt]]'] = '[[option key|opt]]',
	['[[option key]]'] = '[[option key|option]]',
	['[[opt key|option]]'] = '[[option key|option]]',
	['[[win key|win]]'] = '[[windows key|win]]',
	['*'] = 'asterisk',
	['#'] = 'hash',
	[':'] = 'colon',
	[';'] = 'semicolon',
	['l-up'] = 'l up',
	['l-down'] = 'l down',
	['l-left'] = 'l left',
	['l-right'] = 'l right',
	['l-ne'] = 'l ne',
	['l-se'] = 'l se',
	['l-nw'] = 'l nw',
	['l-sw'] = 'l sw',
	['r-up'] = 'r up',
	['r-down'] = 'r down',
	['r-left'] = 'r left',
	['r-right'] = 'r right',
	['r-ne'] = 'r ne',
	['r-se'] = 'r se',
	['r-nw'] = 'r nw',
	['r-sw'] = 'r sw',
	['ps x'] = 'ex',
	['ps c'] = 'circle',
	['ps s'] = 'square',
	['ps t'] = 'triangle',
	['c-up'] = 'c up',
	['c-down'] = 'c down',
	['c-left'] = 'c left',
	['c-right'] = 'c right',
	['c-ne'] = 'c ne',
	['c-se'] = 'c se',
	['c-nw'] = 'c nw',
	['c-sw'] = 'c sw',
}

local Collection = {}
Collection.__index = Collection
do
	function Collection:add(item)
		if item ~= nil then
			self.n = self.n + 1
			self[self.n] = item
		end
	end
	function Collection:join(sep)
		return table.concat(self, sep)
	end
	function Collection:sort(comp)
		table.sort(self, comp)
	end
	function Collection.new()
		return setmetatable({n = 0}, Collection)
	end
end

local function keyPress(args)
	local chainNames = {
		'chain first',
		'chain second',
		'chain third',
		'chain fourth',
		'chain fifth',
		'chain sixth',
		'chain seventh',
		'chain eighth',
		'chain ninth',
	}
	local result = Collection.new()
	local chainDefault = args.chain or '+'
	for i, id in ipairs(args) do
		if i > 1 then
			result:add(args[chainNames[i - 1]] or chainDefault)
		end
		local lc = id:lower()
		local text = keyText[lc] or keyText[keyAlias[lc]] or id
		result:add(kbdPrefix .. text .. kbdSuffix)
	end
	return result:join()
	--mw.getCurrentFrame():extensionTag{
--		name = 'templatestyles', args = { src = 'Template:Key press/styles.css'} 
--	}..result:join()
	
end

local function keypress(frame)
	-- Called by "{{key press|...}}".
	-- Using the template doubles the post‐expand include size.
	return keyPress(frame:getParent().args)
end

local function press(frame)
	-- Called by "{{#invoke:key|press|...}}".
	return keyPress(frame.args)
end

return {
	keypress = keypress,
	press = press,
}