local horizontal_timeline = {};  
local getArgs = require('Module:Arguments').getArgs
local builder = mw.html.create  
local function defaultInvokeFunc(funcName)
return function
args = getArgs(, {
trim = true,
removeBlanks = true,
parentFirst = true
})  
local from = getNotNilValue(tonumber(args['from']))
local to = getNotNilValue(tonumber(args['to']))  
if not from or not to or from == to then
return ("<strong><code>from</code> and <code>to</code> cannot be <code>nil</code> or equal.</strong>")
else
return horizontal_timeline[funcName](args)
end
end
end  
horizontal_timeline.showTimeLine = defaultInvokeFunc('_showTimeLine')
function horizontal_timeline._showTimeLine(args)
local wdth = getNotNilValue(args['width'], '100%' )
local bordr = getNotNilValue(args[''], ' solid rgb(170, 170, 170)' )
local bgCol = getNotNilValue(args['plot-color'], args['plot-colour'], 'transparent')
local mrgn = getNotNilValue(args['margin'], '1em')  
local div_root = builder
:tag('div')
:cssText('float:;:'..bordr .. ';width:'..wdth)  
local cntnt = div_root
:tag('div')
:cssText('text-align:; padding:1em; font-size:95%; margin:' ..mrgn.. '; background:'..bgCol)  
local rowNums = affixNums(args, 'row') -- Gets numbers for row1, row2, etc. with nil arguments removed.
for _, num in ipairs(rowNums) do
local rowType = args['row' .. num] -- Gets args.rowtype1, args.rowtype2, etc. with nil arguments removed.
if rowType == 'scale' then
cntnt:wikitext(horizontal_timeline.scaleRow(args))
elseif rowType == 'note' then
cntnt:wikitext(horizontal_timeline.noteRow(num, args))
elseif rowType == 'timeline' then
cntnt:wikitext(horizontal_timeline.timelineRow(num, args))
else
cntnt:wikitext(rowType)
end
end
if args.caption then
cntnt:tag('p')
:cssText('clear:both; text-align:')
:wikitext(args.caption)
:done
end
return tostring(div_root) .. "<div></div>"
end  
horizontal_timeline.showOneRow = defaultInvokeFunc('_showOneRow')
function horizontal_timeline._showOneRow(args)
local rowNums = affixNums(args, 'row') -- Gets numbers for row1, row2, etc. with nil arguments removed.
for _, num in ipairs(rowNums) do
local rowType = args['row' .. num] -- Gets args.rowtype1, args.rowtype2, etc. with nil arguments removed.
if rowType == 'scale' then
return horizontal_timeline.scaleRow(args)
elseif rowType == 'note' then
return horizontal_timeline.noteRow(num, args)
elseif rowType == 'timeline' then
return horizontal_timeline.timelineRow(num, args)
else
return wikitext(rowType)
end
end
return "?"
end  
function horizontal_timeline.timelineRow(num, args)
local root = mw.html.create  
local from = getNotNilValue(tonumber(args['from']))
local to = getNotNilValue(tonumber(args['to']))  
local style = getNotNilValue(args['row' .. num .. '-style'], '')
local hght = getNotNilValue (args['row' .. num .. '-height'],
args[style .. '-height'],
'2.5em')
local bordrTop = getNotNilValue (args['row' .. num .. '-bordertop'],
args[style .. '-bordertop'],
'')
local bordrBtm = getNotNilValue (args['row' .. num .. '-borderbottom'],
args[style .. '-borderbottom'],
'')
local txtTop = getNotNilValue (args['row' .. num .. '-texttop'],
args[style .. '-texttop'],
'0em')
local colr = getNotNilValue (args['row' .. num .. '-colour'],
args['row' .. num .. '-color'],
args[style .. '-colour'],
args[style .. '-color'],
'transparent')  
if bordrTop ~= '' then
bordrTop = '-top:' .. bordrTop .. ';'
else
bordrTop = ''
end  
if bordrBtm ~= '' then
bordrBtm = '-bottom:' .. bordrBtm .. ';'
else
bordrBtm = ''
end  
local p = root
:tag('div')
:cssText("clear:both;width:100%; padding:; height:".. hght)
:cssText(bordrTop.. bordrBtm .. "background-color:"..colr)  
local rowDat = affixNums(args, 'row'..num..'%-', '%-[a-zA-Z]*')
local lastTo = from
local firstNode = true
for _, vals in ipairs(rowDat) do  
local styleL = getNotNilValue(args['row' .. num .. '-'.. vals .. '-style'], style)  
--These vars should be initialized every iteration. Do not move outside of loop
local bar_to = tonumber(getNotNilValue(args['row' .. num .. '-'.. vals .. '-to'],
args[styleL .. '-to'],
args[style.. '-'.. vals .. '-to'], to ) )
local bar_fontsize =getNotNilValue(args['row' .. num .. '-'.. vals .. '-fontsize'],
args[styleL .. '-fontsize'],
args[style..'-'.. vals .. '-fontsize'], '0.9em' )
local bar_bordr= getNotNilValue(args['row' .. num .. '-'.. vals .. '-'],
args[styleL .. '-'],
args[style..'-'.. vals .. '-'],
'')
local bar_txtTop= getNotNilValue(args['row' .. num .. '-'.. vals .. '-texttop'],
args[styleL .. '-texttop'],
args[style..'-'.. vals .. '-texttop'], txtTop )
local bar_text = getNotNilValue(args['row' .. num .. '-'.. vals .. '-text'],
args[styleL .. '-text'],
args[style..'-'.. vals .. '-text'], '')
local bar_colour = getNotNilValue(args['row' .. num .. '-'.. vals .. '-colour'],
args['row' .. num .. '-'.. vals .. '-color'],
args[styleL .. '-boxcolour'],
args[styleL .. '-boxcolor'],
args[style..'-'.. vals .. '-colour'],
args[style..'-'.. vals .. '-color'],
'transparent' )  
if from < to then
if bar_to > to then bar_to = to end
if lastTo < from then lastTo = from end
else
if bar_to < to then bar_to = to end
if lastTo > from then lastTo = from end
end  
local width =( (bar_to-lastTo)*100 / (to-from) ) --math.abs  
if width > 0 and width <= 100 then
if bar_bordr == '' then
if firstNode then -- for first box both and needed
bar_bordr = " solid #000; -: solid #000"
firstNode = false
else
bar_bordr = " solid #000"
end
end
p:tag('div')
:cssText("float:; height:100%; text-align:; overflow: hidden; background-color:"..bar_colour)
:cssText("width:"..width .."%")
:tag('div')
:cssText("-moz-box-sizing: -box; -webkit-box-sizing: -box;box-sizing: -box;")
:cssText("float:; height:100%; width:100%; -:"..bar_bordr)
:tag('div')
:cssText('position: relative; top:'..bar_txtTop .. '; font-size:'.. bar_fontsize)
:wikitext(bar_text)
:done
:done
:done
end  
lastTo = bar_to
end
return tostring(root)
end  
function horizontal_timeline.noteRow(num, args)
local root = mw.html.create  
local from = getNotNilValue(tonumber(args['from']))
local to = getNotNilValue(tonumber(args['to']))  
local hght = getNotNilValue(args['row' .. num .. '-height'], '2.5em')  
local p = root
:tag('div')
:cssText("width:100%; position:relative; :-0.2em; top:0.8em; clear:both; height:".. hght)  
local rowDat = affixNums(args, 'row'..num..'%-', '%-at')
if not rowDat then
return ("<strong>Please specify location for note at <code>"..'row' .. num .. '-'.. vals .. '-at'.."</code> parameter.</strong>")
end
for _, vals in ipairs(rowDat) do
local note_at =args['row' .. num .. '-'.. vals .. '-at'] --will never be nil as it is what is sued to recieve rowDat
local note_text =getNotNilValue(args['row' .. num .. '-'.. vals .. '-text'], '' )
local note_shift=getNotNilValue(args['row' .. num .. '-'.. vals .. '-shift'], '0em' )
local note_lift =getNotNilValue(args['row' .. num .. '-'.. vals .. '-lift'], '0em' )
local note_arrow=getNotNilValue(args['row' .. num .. '-'.. vals .. '-arrow'], '↓' )  
local note_sft = 100*(note_at - from) / (to-from)  
p:tag('div')
:cssText("position:absolute; top:; width:100%")
:tag('div')
:cssText("margin-:".. note_sft .."%; margin-top:0; position:relative")
:tag('span')
:cssText("position:relative; top:0.25em; :-1.")
:wikitext(note_arrow)
:done
:tag('span')
:cssText("font-size:smaller; position:relative; line-height:; overflow:visible")
:cssText(":"..note_shift.."; top:"..note_lift.."; z-index:".. (1000- tonumber(num)))
:wikitext(note_text)
:done
:done
:done
:done
end
return tostring(root)
end  
function horizontal_timeline.scaleRow(args)
local from = getNotNilValue(tonumber(args['from']))
local to = getNotNilValue(tonumber(args['to']))
local inc = getNotNilValue( tonumber(args['inc']), (math.floor( (from - to) / 5 ) * -1) )
local negativeFmt = getNotNilValue(args['axis-negativeFmt'], '−%s')
local positiveFmt = getNotNilValue(args['axis-positiveFmt'], '%s')
local zeroFmt = getNotNilValue(args['axis-zeroFmt'], '%s')
local nudge = getNotNilValue(args['axis-nudge'], '-1.8em')