local p = {}  
local data_title = mw.title.new(
'Template:COVID-19 data/data'
local data_content = data_title:getContent
local data = mw.text.jsonDecode(data_content)  
local function format_num(number)
if not number then
return ''
end
local _, _, minus, int, _ = tostring(number):find('([-]?)(%d+)([.]?%d*)')
int = int:reverse:gsub("(%d%d%d)", "%1,")
int = int:reverse:gsub("^,", "")
int = minus .. int
return int
end  
function p.main
local out = ''
local data_s = {}
local has_notelist = false
local count_row = 0
local count_col = 0
-- Build new table
local locations = {}
if mw.getCurrentFrame.args['locations'] then
for location in string.gmatch(
mw.getCurrentFrame.args['locations'],
'([^,]+)'
) do
locations[location] = true
end
else
locations = nil
end
for key, value in pairs(data) do
local index
if mw.getCurrentFrame.args['sort'] then
if value[mw.getCurrentFrame.args['sort']] then
index = value[mw.getCurrentFrame.args['sort']]
else
index = 0
end
else
if value.cases then
index = value.cases
elseif value.deaths then
index = value.deaths
elseif value.vaccine_doses then
index = value.vaccine_doses
elseif value.total_vaccinated then
index = value.total_vaccinated
elseif value.fully_vaccinated then
index = value.fully_vaccinated
else index = 0
end
end
if (not locations) or locations[key] then
data_s[#data_s+1] = value
data_s[#data_s]['_index'] = index
data_s[#data_s]['_code'] = key
end
end
-- Sort the new table
table.sort(
data_s,
function(x, y)
if x._code == 'XW' then
return true
elseif y._code == 'XW' then
return false
else
return (x._index > y._index)
end
end
-- Get columns
local columns = {
cases = false,
deaths = false,
total_vaccinated = false,
vaccine_doses = false,
fully_vaccinated = false,
percent_vaccinated = false,
percent_fully_vaccinated = false,
deaths_per_million = false,
population = false
}
local columns_index = {}
if mw.getCurrentFrame.args['columns'] then
for column in string.gmatch(
mw.getCurrentFrame.args['columns'],
'([^,]+)'
) do
columns[column] = true
columns_index[#columns_index+1] = column
end
else
columns = {
cases = true,
deaths = true,
total_vaccinated = true,
vaccine_doses = true,
fully_vaccinated = true,
percent_vaccinated = false,
percent_fully_vaccinated = false,
deaths_per_million = false,
population = false
}
columns_index = {
'cases',
'deaths',
'total_vaccinated',
'vaccine_doses',
'fully_vaccinated',
'percent_vaccinated',
'percent_fully_vaccinated',
'deaths_per_million',
'population'
}
end
-- Check if should show note_vaccination
local show_note_vaccination = false
if columns['total_vaccinated'] or columns['vaccine_doses'] or columns['fully_vaccinated'] or columns['percent_vaccinated'] or columns['percent_fully_vaccinated'] then
show_note_vaccination = true
end
-- Generate wikitext content
for _, row in ipairs(data_s) do
-- Test for empty rows
local has_data = false
for _, column in pairs(columns_index) do
if columns[column] and row[column] then
has_data = true
end
end
if has_data then -- Only add row if it has data
count_row = count_row + 1
out = out .. '\n|-'
if row._code == 'XW' then
out = out .. ''
end
-- Add the flag
if not mw.getCurrentFrame.args['noflag'] then
if count_row == 1 then
count_col = count_col + 1
end
out = out .. '\n| data-sort-value="' .. row.name .. '" | '
if row._code == 'XW' then
out = out ..
''
else
flag_params = {row.name}
-- So that it's not too large
if row.name == 'New Caledonia' then
flag_params[2] = 'merged'
end
out = out ..
mw.getCurrentFrame:expandTemplate{
title = 'Flagicon',
args = flag_params
}
end
end
-- Add country name
if count_row == 1 then
count_col = count_col + 1
end
if mw.getCurrentFrame.args['noflag'] then
out = out .. '\n! scope="row" data-sort-value="' .. row.name .. '" | '
else
out = out .. '\n! scope="row" |'
end
if row._code == 'XW' then
out = out .. * .. row.name .. *
elseif row._code == 'GE' then
out = out ..
* .. row.name .. *
elseif row._code == 'IM' then
out = out ..
* .. row.name .. *
else
out = out ..
* .. row.name .. *
end
-- Add notes
if row.note then
has_notelist = true
out = out ..
mw.getCurrentFrame:expandTemplate{
title = 'Efn',
args = {row.note}
}
end
if row.note_vaccination and show_note_vaccination then
has_notelist = true
out = out ..
mw.getCurrentFrame:expandTemplate{
title = 'Efn',
args = {'Vaccination note: ' .. row.note_vaccination}
}
end
-- Fill out columns
for _, column in ipairs(columns_index) do
if columns[column] then
if count_row == 1 then
count_col = count_col + 1
end
if row[column] then
out = out .. '\n| data-sort-value=' ..
tostring(row[column]) ..
'|'
if column:find('^percent') then
out = out .. string.format('%.2f', row[column]) .. '%'
else
out = out .. format_num(row[column])
end
else
out = out .. '\n| data-sort-value=0 | —'
end
end
end
end
end
if has_notelist then
out = out .. '\n|-' ..
'\n| |' ..
mw.getCurrentFrame:expandTemplate{
title = 'Notelist'
}
end
return out
end  
function p.vac
local out = ''
local data_s = {}
local has_country_num_doses = false
local has_country_num_fully = false
local count_row = 0
local count_col = 0
-- Build new table
for key, value in pairs(data) do
if value.total_vaccinated then
data_s[#data_s+1] = value
data_s[#data_s]['index'] = value.total_vaccinated
elseif value.vaccine_doses then
data_s[#data_s+1] = value
data_s[#data_s]['index'] = value.vaccine_doses
elseif value.fully_vaccinated then
data_s[#data_s+1] = value
data_s[#data_s]['index'] = value.fully_vaccinated
end
end
-- Sort the new table
table.sort(
data_s,
function(x, y)
return (x.index > y.index)
end
-- Generate wikitext content
for _, row in pairs(data_s) do
count_row = count_row + 1
out = out .. '\n|-'
-- Add the flag
if count_row == 1 then
count_col = count_col + 2
end
if row.name == 'World' then
out = out ..
'' ..
'\n| data-sort-value="' .. row.name .. '" | ' ..
'' ..
'\n! scope="row" data-sort-value="' .. row.name .. '" | ' ..
'World'
else
flag_params = {row.name}
-- So that it's not too large
if row.name == 'New Caledonia' then
flag_params[2] = 'merged'
end
out = out ..
'\n| data-sort-value="' .. row.name .. '" | ' ..
mw.getCurrentFrame:expandTemplate{
title = 'Flagicon',
args = flag_params
} ..
'\n! scope="row" data-sort-value="' .. row.name .. '" | ' ..
* .. row.name .. *
end
-- Add note
if row.note_vaccination then
out = out ..
mw.getCurrentFrame:expandTemplate{
title = 'Efn',
args = {row.note_vaccination}
}
end
-- Add the number
if count_row == 1 then
count_col = count_col + 1
end
if row.total_vaccinated then
out = out .. '\n| data-sort-value=' ..
tostring(row.total_vaccinated) ..
'|' .. format_num(row.total_vaccinated)
elseif row.vaccine_doses then
has_country_num_doses = true
out = out .. '\n| data-sort-value=' ..
tostring(row.vaccine_doses) ..
'|' ..
mw.getCurrentFrame:expandTemplate{
title = 'Font color',
args = {'darkred', format_num(row.vaccine_doses)}
} ..
mw.getCurrentFrame:expandTemplate{
title = 'Efn',
args = {name = 'country_num_doses'}
}
elseif row.fully_vaccinated then
has_country_num_fully = true
out = out .. '\n| data-sort-value=' ..
tostring(row.fully_vaccinated) ..
'|' ..
mw.getCurrentFrame:expandTemplate{
title = 'Font color',
args = {'darkorange', format_num(row.fully_vaccinated)}
} ..
mw.getCurrentFrame:expandTemplate{
title = 'Efn',
args = {name = 'country_num_fully'}
}
end
-- Add the percentage
if count_row == 1 then
count_col = count_col + 1
end
if row.percent_vaccinated then
out = out .. '\n| data-sort-value=' ..
tostring(row.percent_vaccinated) ..
'|' .. string.format("%.1f", row.percent_vaccinated) .. '%'
else
out = out .. '\n| data-sort-value=0 | —'
end
end
if has_country_num_doses or has_country_num_fully then
notelist_refs = ''
if has_country_num_doses then
notelist_refs = notelist_refs ..
mw.getCurrentFrame:expandTemplate{
title = 'Efn',
args = {
name = 'country_num_doses',
'This country\'s data are the ' ..
mw.getCurrentFrame:expandTemplate{
title = 'Font color',
args = {
'darkred',
'number of vaccine doses administered'
}
} ..
', not the first dose only.'
}
}
end
if has_country_num_fully then