mNo edit summary |
mNo edit summary |
||
(47 intermediate revisions by 3 users not shown) | |||
Line 3: | Line 3: | ||
local sosData = require("Module:Datatable/SoS") |
local sosData = require("Module:Datatable/SoS") |
||
local utils = require("Module:Utils") |
local utils = require("Module:Utils") |
||
+ | local mPerks = require("Module:Perks") |
||
local frame = mw.getCurrentFrame() |
local frame = mw.getCurrentFrame() |
||
local nl = "\n" |
local nl = "\n" |
||
local ntl = "|-" -- new table line |
local ntl = "|-" -- new table line |
||
local inception = {year = 2016, month = 10, day = 26} |
local inception = {year = 2016, month = 10, day = 26} |
||
− | local |
+ | local _day = 24 * 60 * 60 --hours * minutes * seconds |
− | local |
+ | local _week = 7 * _day |
+ | local _soSCountTableColumns = 6 |
||
local inceptionColor = "3bg" --clr template value |
local inceptionColor = "3bg" --clr template value |
||
+ | local CountOfPerksWithHigherPrice = 12 |
||
+ | local strings = { |
||
− | function sos.last() |
||
+ | file = "File", --[[File:...]] |
||
− | return sos[#sos] |
||
+ | teachable = "Teachable", --[[File:Teachable ...]] |
||
+ | |||
+ | foreignLang = false, --not used |
||
+ | wrongCharType = "Error: There's an invalid CharType in [[Module:DataTable]] - table perks", |
||
+ | icon = "Icon", |
||
+ | name = "Name", |
||
+ | weeksOf = "Weeks of", |
||
+ | shrineCount = "Shrine Count", |
||
+ | week = "Week", |
||
+ | weeks = "weeks", |
||
+ | weeksAgo = "ago", |
||
+ | weekAgoString = "#result #weekString #weeksAgo", |
||
+ | --weekAgoString = "#weeksAgo #result #weekString", --example for foreign language with different wording order |
||
+ | currentlyInSoS = "Currently in Shrine of Secrets!", |
||
+ | lastOcc = "Last occ", |
||
+ | |||
+ | cost = "Cost", |
||
+ | tPerk = "Teachable Perk", |
||
+ | uPerkOf = "Unique Perk of", |
||
+ | refreshes = "refreshes in", |
||
+ | hours = "hours", |
||
+ | hour = "hour", |
||
+ | days = "days", |
||
+ | --day = "day", --not used |
||
+ | unknownPerk = "Uknown Perk", |
||
+ | unknown = "Unknown", |
||
+ | } |
||
+ | |||
+ | regexTable = { |
||
+ | ["#weeksAgo"] = strings.weeksAgo, |
||
+ | ["#week"] = strings.week:lower(), |
||
+ | ["#weeks"] = strings.weeks |
||
+ | } |
||
+ | |||
+ | price = { |
||
+ | normal = 2000, |
||
+ | high = 2700 |
||
+ | } |
||
+ | |||
+ | function p.convertSoSIds() -- this is ust helping function generating a SoS list increased by 32 common and unused perks (it's not uused in any other function) |
||
+ | local modulePerks = require("Module:Perks") |
||
+ | local result = {} |
||
+ | for _, week in ipairs(sos) do |
||
+ | local newWeek = {} |
||
+ | for i = 1, 4, 1 do |
||
+ | table.insert(newWeek, week[i] + modulePerks._nonUniquePerksCount) |
||
+ | end |
||
+ | table.insert(result, newWeek) |
||
+ | end |
||
+ | for _, week in ipairs(result) do |
||
+ | mw.log("{" .. week[1] .. ", " .. week[2] .. ", " .. week[3] .. ", " .. week[4] .. "},") |
||
+ | end |
||
end |
end |
||
+ | -- Assembling SoS Table -- |
||
− | function p.HelloSoS() |
||
− | local result = "" |
||
+ | function p.AssembleSoSTable(sosPerks) |
||
− | for i, sosWeek in ipairs(sos) do |
||
+ | local result = "" |
||
− | for j, perk in ipairs(sosWeek) do |
||
+ | |||
− | if j > 4 then break end |
||
− | + | result = result .. '{| class = "wikitable"' ..nl .. ntl .. nl |
|
+ | result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.tPerk .. nl |
||
− | if sosWeek[j+1] then result = result .. ", " end |
||
+ | result = result .. '! class = "sosHeader" width = "64px" | ' .. strings.cost .. nl |
||
+ | result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.uPerkOf .. nl |
||
+ | |||
+ | for i, perk in ipairs(sosPerks) do |
||
+ | if type(perk) == "table" and perk.character ~= nil and perk.charType ~= nil then |
||
+ | result = result .. ntl .. ' style="text-align:center"' .. nl |
||
+ | result = result .. '! [[' .. strings.file .. ':' .. GetSoSPerkImageByPerk(perk) .. '|64px|frameless|center]]' .. nl |
||
+ | result = result .. '| [[' .. perk.name .. ']]' .. nl |
||
+ | result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div>' .. GetPerkCostByPerk(perk) .. '</div><div>[[' ..strings.file .. ':' .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl |
||
+ | result = result .. '| [[' .. mPerks.getPerksOwnerNameByPerk(perk) .. ']]' .. nl |
||
+ | result = result .. '! [[' .. strings.file .. ':' .. mPerks.getPortraitOfPerkOwnerByPerk(perk) .. '|64px|frameless|center]]' .. nl |
||
+ | else |
||
+ | result = result .. ntl .. ' style="text-align:center"' .. nl |
||
+ | result = result .. '! [[' .. strings.file .. ':Dbd-perks-teachable.png|64px|frameless|center]]' .. nl |
||
+ | result = result .. '| ' .. strings.unknownPerk .. nl |
||
+ | result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div> - </div><div>[[' ..strings.file .. ':' .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl |
||
+ | result = result .. '| - ' .. nl |
||
+ | result = result .. '! - ' .. nl |
||
end |
end |
||
− | result = result .. nl .. nl |
||
end |
end |
||
+ | result = result .. ntl .. nl |
||
+ | result = result .. '! class = "sosHeader" colspan= 5 | ' .. strings.refreshes .. ' '.. utils.clr(p.GetSoSRemaningTime(), 4) .. nl |
||
+ | result = result .. '|}' |
||
+ | |||
+ | mw.log(result) |
||
return result |
return result |
||
end |
end |
||
− | function p. |
+ | function p.GetSoSRemaningTime() |
+ | local currentWeekDay = tonumber(os.date("%w")) |
||
− | return frame:expandTemplate{title = "sos", args = {sosWeek[1], sosWeek[2], sosWeek[3], sosWeek[4]}} |
||
+ | local result = "" |
||
+ | |||
+ | mw.log(os.date("Current weekday: %w")) |
||
+ | if currentWeekDay == 2 then |
||
+ | local remainingHours = 24 - os.date("%H") |
||
+ | return remainingHours .. " " .. remainingHours == 1 and strings.hours or strings.hour |
||
+ | elseif currentWeekDay > 2 then |
||
+ | result = 10 - currentWeekDay .. " " .. strings.days |
||
+ | --3 4 5 6 --weekday |
||
+ | --7 6 5 4 --days remaining |
||
+ | else |
||
+ | result = 3 - currentWeekDay .. " " .. strings.days --day/days |
||
+ | --0 1 --weekday |
||
+ | --3 2 --days remaining |
||
+ | end |
||
+ | mw.log(result) |
||
+ | return result |
||
+ | end |
||
+ | |||
+ | function GetPerkCostByPerk(perk) |
||
+ | if perk == 0 then return "-" end |
||
+ | if perk.id <= mPerks._allPerksCount - CountOfPerksWithHigherPrice then return price.normal |
||
+ | else return price.high end |
||
+ | end |
||
+ | |||
+ | function GetSoSPerkImageByPerk(perk) |
||
+ | if perk == 0 then return "Dbd-perks-template.png" end |
||
+ | local name = utils.FirstLetterLower(utils.resolveFileName(perk.name, false)) |
||
+ | return strings.teachable .. "_" .. name .. ".png" |
||
+ | end |
||
+ | |||
+ | function GetSoSPerks(sos) |
||
+ | result = {} |
||
+ | |||
+ | for i = 1, 4, 1 do |
||
+ | table.insert(result, GetPerkById(sos[i])) |
||
+ | end |
||
+ | |||
+ | mw.log(mw.dumpObject(result)) |
||
+ | return result |
||
+ | end |
||
+ | |||
+ | function GetPerkById(id) |
||
+ | local dataPerks = require("Module:Datatable/Perks") |
||
+ | local modulePerks = require("Module:Perks") |
||
+ | --mw.log(mw.dumpObject(modulePerks)) |
||
+ | --mw.log('Type: ' .. type(perks)) |
||
+ | |||
+ | for _, perk in ipairs(perks) do |
||
+ | if perk.id == id then return perk end --TODO: Remove the tomporary variable. Before that the IDs in Module:Datatable/SoS must by raised by this constant!! (32) |
||
+ | end |
||
+ | return 0 |
||
+ | end |
||
+ | |||
+ | -- #END# Assembling SoS Table #END# -- |
||
+ | |||
+ | function sos.last() |
||
+ | return sos[#sos] |
||
end |
end |
||
function p.SoS(index) |
function p.SoS(index) |
||
− | return p.AssembleSoSTable(sos[#sos - tonumber(index.args[1])]) |
+ | return p.AssembleSoSTable(GetSoSPerks(sos[#sos - tonumber(index.args[1])])) |
+ | end |
||
+ | |||
+ | function SoS(index) |
||
+ | return p.AssembleSoSTable(GetSoSPerks(sos[index])) |
||
end |
end |
||
function p.CurrentSoS() |
function p.CurrentSoS() |
||
− | return p.AssembleSoSTable(sos[1]) |
+ | return p.AssembleSoSTable(GetSoSPerks(sos[1])) |
end |
end |
||
− | function p.ManualSoS(args) |
+ | function p.ManualSoS(args) --Unused? |
args = args.args |
args = args.args |
||
+ | p.AssembleSoSTable(GetSoSPerks(args)) |
||
− | return frame:expandTemplate{title = "sos", args = {args[1], args[2], args[3], args[4]}} |
||
end |
end |
||
Line 51: | Line 189: | ||
--If it is on a Saturday, it is part of the last week of the previous year which is numbered W52 in a common year and W53 in a leap year. |
--If it is on a Saturday, it is part of the last week of the previous year which is numbered W52 in a common year and W53 in a leap year. |
||
--If it is on a Sunday, it is part of W52 of the previous year. |
--If it is on a Sunday, it is part of W52 of the previous year. |
||
− | function GetWeekNumber(dateStamp) |
+ | function GetWeekNumber(dateStamp) --in milliseconds, os.time() |
firstWeekDayOfYear = tonumber(os.date("%w", os.time({year = os.date("%Y", dateStamp), month = 1, day = 1}))) |
firstWeekDayOfYear = tonumber(os.date("%w", os.time({year = os.date("%Y", dateStamp), month = 1, day = 1}))) |
||
firstWeekOfYear = tonumber(os.date("%W", os.time({year = os.date("%Y", dateStamp), month = 1, day = 1}))) |
firstWeekOfYear = tonumber(os.date("%W", os.time({year = os.date("%Y", dateStamp), month = 1, day = 1}))) |
||
Line 64: | Line 202: | ||
end |
end |
||
− | function |
+ | function p.GetCurrentWeekNumber() |
+ | return GetWeekNumber(os.time()) |
||
+ | end |
||
+ | |||
+ | function GetEmptyPerkTable() |
||
local result = {} |
local result = {} |
||
if not emptyTable then for i = 1, #perks do result[i] = 0 end --make empty table with 0 values for every perk in sos table |
if not emptyTable then for i = 1, #perks do result[i] = 0 end --make empty table with 0 values for every perk in sos table |
||
Line 71: | Line 213: | ||
end |
end |
||
− | function GetCountOfPerks( |
+ | function GetCountOfPerks() |
local perkList = GetEmptyPerkTable() |
local perkList = GetEmptyPerkTable() |
||
Line 77: | Line 219: | ||
for j, sosPerk in ipairs(sosWeek) do |
for j, sosPerk in ipairs(sosWeek) do |
||
if type(sosPerk) ~= "table" then |
if type(sosPerk) ~= "table" then |
||
+ | mw.logObject("sosPerk: " .. sosPerk) |
||
if perkList[sosPerk] == nil then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable()) |
if perkList[sosPerk] == nil then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable()) |
||
perkList[sosPerk] = 1 --DEV TODO check if possible to remove it |
perkList[sosPerk] = 1 --DEV TODO check if possible to remove it |
||
Line 90: | Line 233: | ||
function p.AssembleSoSPerkCountTable() |
function p.AssembleSoSPerkCountTable() |
||
local SoSPerkCountTable = GetCountOfPerks() |
local SoSPerkCountTable = GetCountOfPerks() |
||
− | local result = "" |
||
local maxOccurrence = math.max(unpack(SoSPerkCountTable)) |
local maxOccurrence = math.max(unpack(SoSPerkCountTable)) |
||
+ | local result = "" |
||
local number |
local number |
||
utils.sortItemsByName(perks) |
utils.sortItemsByName(perks) |
||
Line 97: | Line 240: | ||
result = result .. "{| class=\"wikitable unsortable\"" .. nl |
result = result .. "{| class=\"wikitable unsortable\"" .. nl |
||
+ | local i = 1 |
||
− | for i, perk in ipairs(perks) do |
||
+ | for _, perk in ipairs(perks) do |
||
− | if (i - 1) % soSCountTableColumns == 0 then |
||
+ | if perk.character ~= nil then |
||
− | result = result .. ntl .. nl |
||
+ | if (i - 1) % _soSCountTableColumns == 0 then |
||
+ | result = result .. ntl .. nl |
||
+ | end |
||
+ | number = SoSPerkCountTable[perk.id] |
||
+ | result = result .. "! [[" .. strings.file .. ":" .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName(perk.name)) .. ".png|64px|center]]" .. nl |
||
+ | result = result .. "! [[" .. perk.name .. "]]" .. nl |
||
+ | if number ~= 0 then |
||
+ | result = result .. "<div class='noticeText' title='" .. GetTextWeeksAgoOfLastOccurrenceById(perk.id) .. "'>" .. strings.lastOcc .. ": " .. GetLastPerkOccurrenceById(perk.id) .. "</div>" .. nl |
||
+ | end |
||
+ | result = result .. "| <center>'''" .. GetColoredOccurrenceNumber(number, maxOccurrence) .. "'''</center>" .. nl |
||
+ | |||
+ | i = i + 1 |
||
end |
end |
||
− | number = SoSPerkCountTable[perk.id] |
||
− | if number == maxOccurrence then number = frame:expandTemplate{title = "clr", args = {3, SoSPerkCountTable[perk.id]}} |
||
− | elseif number == 0 then number = frame:expandTemplate{title = "clr", args = {8, SoSPerkCountTable[perk.id]}} |
||
− | elseif number == 1 then number = frame:expandTemplate{title = "clr", args = {2, SoSPerkCountTable[perk.id]}} |
||
− | end |
||
− | |||
− | result = result .. "! [[File:Teachable " .. utils.FirstLetterLower(utils.resolveFileName(perk.name)) .. ".png|64px|center]]" .. nl |
||
− | result = result .. "! [[" .. perk.name .. "]]" .. nl |
||
− | result = result .. "| <center>'''" .. number .. "'''</center>" .. nl |
||
end |
end |
||
result = result .. "|}" |
result = result .. "|}" |
||
--mw.log(mw.dumpObject(result)) |
--mw.log(mw.dumpObject(result)) |
||
− | mw.log(maxOccurrence) |
||
return result |
return result |
||
end |
end |
||
+ | |||
+ | function GetColoredOccurrenceNumber(number, maxOccurrence) |
||
+ | if number == maxOccurrence then return frame:expandTemplate{title = "clr", args = {3, number}} |
||
+ | elseif number == 0 then return frame:expandTemplate{title = "clr", args = {8, number}} |
||
+ | elseif number == 1 then return frame:expandTemplate{title = "clr", args = {2, number}} |
||
+ | elseif number == nil then return strings.unknown |
||
+ | end |
||
+ | return number |
||
+ | end |
||
+ | |||
+ | --Old ID is the ID that occurs in old Perk table in Datatable (not in Datatable/Perks) |
||
+ | function GetWeeksAgoOfLastOccurrenceById(id) |
||
+ | local offset = 0 |
||
+ | |||
+ | for i, sosWeek in ipairs(sos) do -- i = weeks ago (to current day) |
||
+ | --mw.log(mw.dumpObject(sosWeek)) |
||
+ | for j, perk in ipairs(sosWeek) do |
||
+ | if j <= 4 then |
||
+ | if perk == id then |
||
+ | mw.log("Last Occ: " .. GetDateFromSoSIndex(i + offset) .. ", perk: " .. mPerks.GetPerkById(id).name) |
||
+ | return i - 1 + offset |
||
+ | end |
||
+ | else |
||
+ | if perk.offset ~= nil then |
||
+ | offset = offset + perk.offset |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | return 0 |
||
+ | end |
||
+ | |||
+ | function GetLastPerkOccurrenceById(id) |
||
+ | return GetDateFromSoSIndex(GetWeeksAgoOfLastOccurrenceById(id)) |
||
+ | end |
||
+ | |||
+ | --sosIndex should be a number of how many weeks ago the perk occurred |
||
+ | function GetDateFromSoSIndex(sosIndex) |
||
+ | local result = os.time() - sosIndex * _week |
||
+ | local weekDay = tonumber(os.date("%w", result)) |
||
+ | local offset |
||
+ | |||
+ | if weekDay < 3 then offset = (-weekDay - 4) * _day -- current day is Sunday, Monday, or Tuesday (WeekDay = 0 - 2) |
||
+ | elseif weekDay > 3 then offset = (-weekDay + 3) * _day --current day is Thursday, Friday, or Saturday (WeekDay = 4 - 6) |
||
+ | else offset = 0 end -- current day is Wednesday |
||
+ | |||
+ | return os.date("%d.%m.%Y", result + offset) --offset is in negative |
||
+ | --2 = -6 |
||
+ | --1 = -5 |
||
+ | --0 = -4 |
||
+ | --6 = -3 |
||
+ | --5 = -2 |
||
+ | --4 = -1 |
||
+ | --3 = 0 |
||
+ | end |
||
+ | |||
+ | function GetTextWeeksAgoOfLastOccurrenceById(id) --there will be probably needed to make a copy of a replacing string |
||
+ | result = GetWeeksAgoOfLastOccurrenceById(id) |
||
+ | if result > 1 then |
||
+ | strings.weekAgoString = strings.weekAgoString:gsub("#weekString", "#weeks") |
||
+ | elseif result == 1 then |
||
+ | strings.weekAgoString = strings.weekAgoString:gsub("#weekString", "#week") |
||
+ | else |
||
+ | return strings.currentlyInSoS |
||
+ | end |
||
+ | |||
+ | return utils.regularReplace(strings.weekAgoString:gsub("#result", result), regexTable) |
||
+ | end |
||
+ | |||
function GetIndexesOfPeriod(year) |
function GetIndexesOfPeriod(year) |
||
local currentWeekDate = os.time(inception) |
local currentWeekDate = os.time(inception) |
||
Line 137: | Line 351: | ||
index = #sos - i -- INDEX SHIFT |
index = #sos - i -- INDEX SHIFT |
||
if sos[index] ~= nil and sos[index][5] ~= nil and sos[index][5].offset ~= nil then --need to reorder logic instructions |
if sos[index] ~= nil and sos[index][5] ~= nil and sos[index][5].offset ~= nil then --need to reorder logic instructions |
||
− | currentWeekDate = currentWeekDate + ( |
+ | currentWeekDate = currentWeekDate + (_week * (sos[index][5].offset + 1)) |
else |
else |
||
− | currentWeekDate = currentWeekDate + |
+ | currentWeekDate = currentWeekDate + _week |
end |
end |
||
end |
end |
||
Line 283: | Line 497: | ||
local numberOfWeeksInYear = pStart - pEnd + 1 + globalOffset |
local numberOfWeeksInYear = pStart - pEnd + 1 + globalOffset |
||
− | if |
+ | if perkInception == -1 then return strings.wrongCharType end |
result = result .. "<div id=\"inceptionPerks" .. year .."\" class=\"inceptionSwitch\"></div>" .. nl --Show/Hide Switch |
result = result .. "<div id=\"inceptionPerks" .. year .."\" class=\"inceptionSwitch\"></div>" .. nl --Show/Hide Switch |
||
result = result .. "{| class=\"wikitable unsortable\"" .. nl |
result = result .. "{| class=\"wikitable unsortable\"" .. nl |
||
− | result = result .. "! |
+ | result = result .. "! " .. strings.icon .." !! " .. strings.name .. " !! colspan = " .. numberOfWeeksInYear .. "| " .. strings.weeksOf .. " " .. year .. "!! " .. strings.shrineCount .. nl |
result = result .. ntl .. nl |
result = result .. ntl .. nl |
||
result = result .. "! colspan = 2" .. "| " .. nl |
result = result .. "! colspan = 2" .. "| " .. nl |
||
Line 311: | Line 525: | ||
mw.log(43) |
mw.log(43) |
||
for i, perk in ipairs(perks) do |
for i, perk in ipairs(perks) do |
||
− | if perkList[perk.id] ~= 0 then |
+ | if perk.character ~= nil and perkList[perk.id] ~= 0 then |
for j, perkOcc in ipairs(perkList[perk.id]) do |
for j, perkOcc in ipairs(perkList[perk.id]) do |
||
hideable = false |
hideable = false |
||
Line 323: | Line 537: | ||
result = result .. " class=\"inception-row" .. year .. "\" style=\"display: none;\" " |
result = result .. " class=\"inception-row" .. year .. "\" style=\"display: none;\" " |
||
end |
end |
||
− | result = result .. nl .. "! [[ |
+ | result = result .. nl .. "! [[" .. strings.file .. ":" .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName(perk.name)) .. ".png|32px]] !! " .. perk.name .. nl .. "|" |
for j = startWeekDate, lastWeekNumber do --going through week in year |
for j = startWeekDate, lastWeekNumber do --going through week in year |
||
Line 332: | Line 546: | ||
local color = frame:expandTemplate{title = "clr", args = {perkOcc.color or "white"}} |
local color = frame:expandTemplate{title = "clr", args = {perkOcc.color or "white"}} |
||
− | result = result .. "style=\"background-color: #" .. color .. ";\" title = \" |
+ | result = result .. "style=\"background-color: #" .. color .. ";\" title = \"" ..strings.week .. " " .. perkOcc.week .. "\" | " --[[File:nothing.png]] |
weekFound = true |
weekFound = true |
||
break |
break |
||
Line 346: | Line 560: | ||
result = result .. "|}" |
result = result .. "|}" |
||
+ | |||
+ | mw.log(result) |
||
+ | return result |
||
+ | end |
||
+ | |||
+ | function p.AssembleSoSYearPage(year) |
||
+ | year = ResolveYearParam(year) |
||
+ | local pStart, pEnd = unpack(GetIndexesOfPeriod(year)) |
||
+ | local result = "" |
||
+ | local currentWeekDate = 1 |
||
+ | local startWeekDate = 1 |
||
+ | local sosIndex = 0 |
||
+ | local header |
||
+ | if year == 2016 then |
||
+ | currentWeekDate = tonumber(os.date("%W", os.time(inception))) --43 |
||
+ | startWeekDate = tonumber(os.date("%W", os.time(inception))) --52 |
||
+ | end |
||
+ | local currentOffset = 0 |
||
+ | local lastWeekNumber = currentWeekDate + (pStart - pEnd) |
||
+ | |||
+ | if perkInception == -1 then return strings.wrongCharType end |
||
+ | |||
+ | utils.sortItemsByName(perks) |
||
+ | mw.log("pStart: " .. pStart) |
||
+ | mw.log("pEnd: " .. pEnd) |
||
+ | mw.log("lastWeekNumber: " .. lastWeekNumber) |
||
+ | mw.log("lastWeekNumber CALC: " .. lastWeekNumber - (pStart - pEnd)) |
||
+ | mw.log("startWeekDate: " .. startWeekDate) |
||
+ | for i = startWeekDate, lastWeekNumber do --going through week in year |
||
+ | sosIndex = pStart + startWeekDate - i |
||
+ | if sos[sosIndex][5] ~= nil then --If there's a table after 4 perks then retrieve data |
||
+ | if sos[sosIndex][5].header ~= nil then |
||
+ | header = sos[sosIndex][5].header |
||
+ | elseif sos[sosIndex][5].offset ~= nil then |
||
+ | currentOffset = currentOffset - 1 |
||
+ | header = strings.week .. " " .. (i + currentOffset) |
||
+ | if sos[sosIndex][5].hideVersion ~= true then |
||
+ | header = header .. " v." .. (1 - sos[sosIndex][5].offset) |
||
+ | end |
||
+ | else |
||
+ | header = strings.week .. " " .. i + currentOffset |
||
+ | end |
||
+ | text = sos[sosIndex][5].text or "" |
||
+ | else |
||
+ | header = strings.week .. " " .. i + currentOffset |
||
+ | text = "" |
||
+ | end |
||
+ | --result = sos[sosIndex][1] .. ", " .. sos[sosIndex][2] .. ", " .. sos[sosIndex][3] .. ", " .. sos[sosIndex][4] .. nl .. nl .. result |
||
+ | --result = ("i: " .. i .. "| Index: " .. sosIndex .. "| lastWeekNumber - currentOffset: " .. lastWeekNumber - currentOffset) .. nl .. result |
||
+ | result = SoS(sosIndex) .. nl .. nl .. result |
||
+ | result = text .. nl .. result |
||
+ | result = "== " .. header .. " ==" ..nl .. result |
||
+ | |||
+ | end |
||
mw.log(result) |
mw.log(result) |
Revision as of 12:02, 25 November 2020
local p = {}
local data = require("Module:Datatable")
local sosData = require("Module:Datatable/SoS")
local utils = require("Module:Utils")
local mPerks = require("Module:Perks")
local frame = mw.getCurrentFrame()
local nl = "\n"
local ntl = "|-" -- new table line
local inception = {year = 2016, month = 10, day = 26}
local _day = 24 * 60 * 60 --hours * minutes * seconds
local _week = 7 * _day
local _soSCountTableColumns = 6
local inceptionColor = "3bg" --clr template value
local CountOfPerksWithHigherPrice = 12
local strings = {
file = "File", --[[File:...]]
teachable = "Teachable", --[[File:Teachable ...]]
foreignLang = false, --not used
wrongCharType = "Error: There's an invalid CharType in [[Module:DataTable]] - table perks",
icon = "Icon",
name = "Name",
weeksOf = "Weeks of",
shrineCount = "Shrine Count",
week = "Week",
weeks = "weeks",
weeksAgo = "ago",
weekAgoString = "#result #weekString #weeksAgo",
--weekAgoString = "#weeksAgo #result #weekString", --example for foreign language with different wording order
currentlyInSoS = "Currently in Shrine of Secrets!",
lastOcc = "Last occ",
cost = "Cost",
tPerk = "Teachable Perk",
uPerkOf = "Unique Perk of",
refreshes = "refreshes in",
hours = "hours",
hour = "hour",
days = "days",
--day = "day", --not used
unknownPerk = "Uknown Perk",
unknown = "Unknown",
}
regexTable = {
["#weeksAgo"] = strings.weeksAgo,
["#week"] = strings.week:lower(),
["#weeks"] = strings.weeks
}
price = {
normal = 2000,
high = 2700
}
function p.convertSoSIds() -- this is ust helping function generating a SoS list increased by 32 common and unused perks (it's not uused in any other function)
local modulePerks = require("Module:Perks")
local result = {}
for _, week in ipairs(sos) do
local newWeek = {}
for i = 1, 4, 1 do
table.insert(newWeek, week[i] + modulePerks._nonUniquePerksCount)
end
table.insert(result, newWeek)
end
for _, week in ipairs(result) do
mw.log("{" .. week[1] .. ", " .. week[2] .. ", " .. week[3] .. ", " .. week[4] .. "},")
end
end
-- Assembling SoS Table --
function p.AssembleSoSTable(sosPerks)
local result = ""
result = result .. '{| class = "wikitable"' ..nl .. ntl .. nl
result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.tPerk .. nl
result = result .. '! class = "sosHeader" width = "64px" | ' .. strings.cost .. nl
result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.uPerkOf .. nl
for i, perk in ipairs(sosPerks) do
if type(perk) == "table" and perk.character ~= nil and perk.charType ~= nil then
result = result .. ntl .. ' style="text-align:center"' .. nl
result = result .. '! [[' .. strings.file .. ':' .. GetSoSPerkImageByPerk(perk) .. '|64px|frameless|center]]' .. nl
result = result .. '| [[' .. perk.name .. ']]' .. nl
result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div>' .. GetPerkCostByPerk(perk) .. '</div><div>[[' ..strings.file .. ':' .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl
result = result .. '| [[' .. mPerks.getPerksOwnerNameByPerk(perk) .. ']]' .. nl
result = result .. '! [[' .. strings.file .. ':' .. mPerks.getPortraitOfPerkOwnerByPerk(perk) .. '|64px|frameless|center]]' .. nl
else
result = result .. ntl .. ' style="text-align:center"' .. nl
result = result .. '! [[' .. strings.file .. ':Dbd-perks-teachable.png|64px|frameless|center]]' .. nl
result = result .. '| ' .. strings.unknownPerk .. nl
result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div> - </div><div>[[' ..strings.file .. ':' .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl
result = result .. '| - ' .. nl
result = result .. '! - ' .. nl
end
end
result = result .. ntl .. nl
result = result .. '! class = "sosHeader" colspan= 5 | ' .. strings.refreshes .. ' '.. utils.clr(p.GetSoSRemaningTime(), 4) .. nl
result = result .. '|}'
mw.log(result)
return result
end
function p.GetSoSRemaningTime()
local currentWeekDay = tonumber(os.date("%w"))
local result = ""
mw.log(os.date("Current weekday: %w"))
if currentWeekDay == 2 then
local remainingHours = 24 - os.date("%H")
return remainingHours .. " " .. remainingHours == 1 and strings.hours or strings.hour
elseif currentWeekDay > 2 then
result = 10 - currentWeekDay .. " " .. strings.days
--3 4 5 6 --weekday
--7 6 5 4 --days remaining
else
result = 3 - currentWeekDay .. " " .. strings.days --day/days
--0 1 --weekday
--3 2 --days remaining
end
mw.log(result)
return result
end
function GetPerkCostByPerk(perk)
if perk == 0 then return "-" end
if perk.id <= mPerks._allPerksCount - CountOfPerksWithHigherPrice then return price.normal
else return price.high end
end
function GetSoSPerkImageByPerk(perk)
if perk == 0 then return "Dbd-perks-template.png" end
local name = utils.FirstLetterLower(utils.resolveFileName(perk.name, false))
return strings.teachable .. "_" .. name .. ".png"
end
function GetSoSPerks(sos)
result = {}
for i = 1, 4, 1 do
table.insert(result, GetPerkById(sos[i]))
end
mw.log(mw.dumpObject(result))
return result
end
function GetPerkById(id)
local dataPerks = require("Module:Datatable/Perks")
local modulePerks = require("Module:Perks")
--mw.log(mw.dumpObject(modulePerks))
--mw.log('Type: ' .. type(perks))
for _, perk in ipairs(perks) do
if perk.id == id then return perk end --TODO: Remove the tomporary variable. Before that the IDs in Module:Datatable/SoS must by raised by this constant!! (32)
end
return 0
end
-- #END# Assembling SoS Table #END# --
function sos.last()
return sos[#sos]
end
function p.SoS(index)
return p.AssembleSoSTable(GetSoSPerks(sos[#sos - tonumber(index.args[1])]))
end
function SoS(index)
return p.AssembleSoSTable(GetSoSPerks(sos[index]))
end
function p.CurrentSoS()
return p.AssembleSoSTable(GetSoSPerks(sos[1]))
end
function p.ManualSoS(args) --Unused?
args = args.args
p.AssembleSoSTable(GetSoSPerks(args))
end
--ISO: https://en.wikipedia.org/wiki/ISO_week_date
--If 1 January is on a Monday, Tuesday, Wednesday or Thursday, it is in W01. If it is on a Friday, it is part of W53 of the previous year.
--If it is on a Saturday, it is part of the last week of the previous year which is numbered W52 in a common year and W53 in a leap year.
--If it is on a Sunday, it is part of W52 of the previous year.
function GetWeekNumber(dateStamp) --in milliseconds, os.time()
firstWeekDayOfYear = tonumber(os.date("%w", os.time({year = os.date("%Y", dateStamp), month = 1, day = 1})))
firstWeekOfYear = tonumber(os.date("%W", os.time({year = os.date("%Y", dateStamp), month = 1, day = 1})))
-- ATTENTION as per description above some years have first week 01
-- because all first weeks of year that starts with Sunday, Saturday, Friday or Thursday must be shifted
if firstWeekDayOfYear > 0 and firstWeekDayOfYear < 4 and firstWeekOfYear == 0 then
return tonumber(os.date("%W", dateStamp)) + 1
else
return tonumber(os.date("%W", dateStamp))
end
end
function p.GetCurrentWeekNumber()
return GetWeekNumber(os.time())
end
function GetEmptyPerkTable()
local result = {}
if not emptyTable then for i = 1, #perks do result[i] = 0 end --make empty table with 0 values for every perk in sos table
else for i = 1, #perks do result[i] = {} end end
return result
end
function GetCountOfPerks()
local perkList = GetEmptyPerkTable()
for i, sosWeek in ipairs(sos) do
for j, sosPerk in ipairs(sosWeek) do
if type(sosPerk) ~= "table" then
mw.logObject("sosPerk: " .. sosPerk)
if perkList[sosPerk] == nil then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable())
perkList[sosPerk] = 1 --DEV TODO check if possible to remove it
else
perkList[sosPerk] = perkList[sosPerk] + 1
end
end
end
end
return perkList
end
function p.AssembleSoSPerkCountTable()
local SoSPerkCountTable = GetCountOfPerks()
local maxOccurrence = math.max(unpack(SoSPerkCountTable))
local result = ""
local number
utils.sortItemsByName(perks)
result = result .. "{| class=\"wikitable unsortable\"" .. nl
local i = 1
for _, perk in ipairs(perks) do
if perk.character ~= nil then
if (i - 1) % _soSCountTableColumns == 0 then
result = result .. ntl .. nl
end
number = SoSPerkCountTable[perk.id]
result = result .. "! [[" .. strings.file .. ":" .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName(perk.name)) .. ".png|64px|center]]" .. nl
result = result .. "! [[" .. perk.name .. "]]" .. nl
if number ~= 0 then
result = result .. "<div class='noticeText' title='" .. GetTextWeeksAgoOfLastOccurrenceById(perk.id) .. "'>" .. strings.lastOcc .. ": " .. GetLastPerkOccurrenceById(perk.id) .. "</div>" .. nl
end
result = result .. "| <center>'''" .. GetColoredOccurrenceNumber(number, maxOccurrence) .. "'''</center>" .. nl
i = i + 1
end
end
result = result .. "|}"
--mw.log(mw.dumpObject(result))
return result
end
function GetColoredOccurrenceNumber(number, maxOccurrence)
if number == maxOccurrence then return frame:expandTemplate{title = "clr", args = {3, number}}
elseif number == 0 then return frame:expandTemplate{title = "clr", args = {8, number}}
elseif number == 1 then return frame:expandTemplate{title = "clr", args = {2, number}}
elseif number == nil then return strings.unknown
end
return number
end
--Old ID is the ID that occurs in old Perk table in Datatable (not in Datatable/Perks)
function GetWeeksAgoOfLastOccurrenceById(id)
local offset = 0
for i, sosWeek in ipairs(sos) do -- i = weeks ago (to current day)
--mw.log(mw.dumpObject(sosWeek))
for j, perk in ipairs(sosWeek) do
if j <= 4 then
if perk == id then
mw.log("Last Occ: " .. GetDateFromSoSIndex(i + offset) .. ", perk: " .. mPerks.GetPerkById(id).name)
return i - 1 + offset
end
else
if perk.offset ~= nil then
offset = offset + perk.offset
end
end
end
end
return 0
end
function GetLastPerkOccurrenceById(id)
return GetDateFromSoSIndex(GetWeeksAgoOfLastOccurrenceById(id))
end
--sosIndex should be a number of how many weeks ago the perk occurred
function GetDateFromSoSIndex(sosIndex)
local result = os.time() - sosIndex * _week
local weekDay = tonumber(os.date("%w", result))
local offset
if weekDay < 3 then offset = (-weekDay - 4) * _day -- current day is Sunday, Monday, or Tuesday (WeekDay = 0 - 2)
elseif weekDay > 3 then offset = (-weekDay + 3) * _day --current day is Thursday, Friday, or Saturday (WeekDay = 4 - 6)
else offset = 0 end -- current day is Wednesday
return os.date("%d.%m.%Y", result + offset) --offset is in negative
--2 = -6
--1 = -5
--0 = -4
--6 = -3
--5 = -2
--4 = -1
--3 = 0
end
function GetTextWeeksAgoOfLastOccurrenceById(id) --there will be probably needed to make a copy of a replacing string
result = GetWeeksAgoOfLastOccurrenceById(id)
if result > 1 then
strings.weekAgoString = strings.weekAgoString:gsub("#weekString", "#weeks")
elseif result == 1 then
strings.weekAgoString = strings.weekAgoString:gsub("#weekString", "#week")
else
return strings.currentlyInSoS
end
return utils.regularReplace(strings.weekAgoString:gsub("#result", result), regexTable)
end
function GetIndexesOfPeriod(year)
local currentWeekDate = os.time(inception)
local currentYear
local index = #sos
local perkList = GetEmptyPerkTable()
local result = {}
for i, sosWeek in ipairs(sos) do
currentYear = tonumber(os.date("%Y", currentWeekDate))
if year == nil or year == currentYear then
if result[1] == nil then
result[1] = index
end
--mw.log("[" .. index .. "] Week " ..GetWeekNumber(currentWeekDate) .. ", Year: " .. os.date("%Y", currentWeekDate) .. ": {" .. sos[index][1] .. ", " .. sos[index][2] .. ", " .. sos[index][3] .. ", " .. sos[index][4] .. "} (" .. os.date("%d. %m. %Y",currentWeekDate) .. ")")
result[2] = index
end
-------------------------------
index = #sos - i -- INDEX SHIFT
if sos[index] ~= nil and sos[index][5] ~= nil and sos[index][5].offset ~= nil then --need to reorder logic instructions
currentWeekDate = currentWeekDate + (_week * (sos[index][5].offset + 1))
else
currentWeekDate = currentWeekDate + _week
end
end
--mw.log(mw.dumpObject(result))
return result
end
function ResolveYearParam(year)
if type(year) == "table" and year.args[1] ~= nil then
return tonumber(year.args[1])
elseif type(year) == "number" then
return year
else
return os.date("%Y")
end
end
function SoSArchiveCalendar(year)
local currentWeekDate = os.time(inception)
local perkList = GetEmptyPerkTable()
local pStart, pEnd = unpack(GetIndexesOfPeriod(year)) --Period Start and Period End
local offset = 0
local offset2016 = 0
local notices = {}
local week
local color
local index
if year == 2016 then
offset2016 = tonumber(os.date("%W", os.time(inception))) - 1 --setting offset by 43 weeks
end
for i = pStart, pEnd, -1 do
week = (pStart - i + 1 + offset2016)
if sos[i][5] ~= nil and type(sos[i][5]) == "table" then
offset = offset + (sos[i][5].offset or 0) --offset must be global because we need to shift the rest of all weeks as well
color = sos[i][5].color
notices[week] = sos[i][5].notice
else
color = nil
end
for j, sosPerk in ipairs(sos[i]) do --sosPerk = individual perk in sos Week row, goes 4x - 5x
if type(sosPerk) ~= "table" then
if sosPerk ~= 0 then
if perkList[sosPerk] == 0 then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable())
perkList[sosPerk] = {{week = week + offset}}
if color ~= nil then
perkList[sosPerk][1].color = color
end
else
perkList[sosPerk][#perkList[sosPerk] + 1] = {week = week + offset, color = color}
end
end
end
end
end
return {perkList, notices} -- sorting: perkList[perks.id] gives you weeks of appropriate perk
end
function GetGlobalOffsetInYear(pStart, pEnd)
local offset = 0
for i = pStart, pEnd, -1 do
if sos[i][5] ~= nil and type(sos[i][5]) == "table" then
offset = offset + (sos[i][5].offset or 0)
end
end
mw.log("Week Offset: " .. offset)
return tonumber(offset)
end
function GetPerksInception(year)
local charTable
local dlcDate
local weekOffset
local result = GetEmptyPerkTable()
for i, perk in ipairs(perks) do
if perk.character ~= nil then --if Perk has associated character that means it's a unique perk
if perk.charType == 'S' then charTable = survivors
elseif perk.charType == 'K' then charTable = killers
else return -1
end
if charTable[perk.character].dlc ~= nil then
dlcDate = utils.GetDatetime(dlcs[charTable[perk.character].dlc].rDate)
if tonumber(year) == tonumber(dlcDate.year) then
weekOffset = tonumber(os.date("%W", os.time({year = dlcDate.year, month = 1, day = 1}))) --check if the year starts with W0 or W1 - see #48 (documentation of GetWeekNumber())
releaseWeek = tonumber(os.date("%W", os.time(dlcDate))) - weekOffset + 1 -- +1 because week indexing start at 0
result[perk.id] = {week = releaseWeek, color = inceptionColor, inception = true}
mw.log("Perk " .. perk.name .. " was released at week " .. releaseWeek .. "(+" .. weekOffset .. ")")
end
end
end
end
return result
end
function mergePerkListWithInceptionList(perkList, perkInception)
local merged = GetEmptyPerkTable()
for i = 1, #perkList do --perkList as I would to keep dependency on the logic that's used when creating perkList variable due to potential later changes
if perkInception[i] ~= 0 then
if perkList[i] == 0 then
perkList[i] = {perkInception[i]}
else
perkList[i][#perkList[i] + 1] = perkInception[i]
end
end
end
--mw.log(mw.dumpObject(perkList))
return perkList
end
function ResolvePerkOccurence(perkOccurenceList)
local result = 0
for _, perkOcc in ipairs(perkOccurenceList) do
if perkOcc.inception == true then
else
result = result + 1
end
end
return result
end
function p.AssembleSoSCalendarTable(year)
year = ResolveYearParam(year)
local pStart, pEnd = unpack(GetIndexesOfPeriod(year))
local perkList, weekNames = unpack(SoSArchiveCalendar(year))
local perkInception = GetPerksInception(year)
perkList = mergePerkListWithInceptionList(perkList, perkInception)
local result = ""
local currentWeekDate = 1
local startWeekDate = 1
local weekFound
local hideable
if year == 2016 then
currentWeekDate = tonumber(os.date("%W", os.time(inception)))
startWeekDate = tonumber(os.date("%W", os.time(inception)))
end
local globalOffset = GetGlobalOffsetInYear(pStart, pEnd)
local lastWeekNumber = currentWeekDate + (pStart - pEnd + globalOffset)
local numberOfWeeksInYear = pStart - pEnd + 1 + globalOffset
if perkInception == -1 then return strings.wrongCharType end
result = result .. "<div id=\"inceptionPerks" .. year .."\" class=\"inceptionSwitch\"></div>" .. nl --Show/Hide Switch
result = result .. "{| class=\"wikitable unsortable\"" .. nl
result = result .. "! " .. strings.icon .." !! " .. strings.name .. " !! colspan = " .. numberOfWeeksInYear .. "| " .. strings.weeksOf .. " " .. year .. "!! " .. strings.shrineCount .. nl
result = result .. ntl .. nl
result = result .. "! colspan = 2" .. "| " .. nl
mw.log(mw.dumpObject(weekNames))
for i = 1, numberOfWeeksInYear do -- Weeks Header
if i ~= 1 then
result = result .. " || class = \"week-cell\" | "
else
result = result .. "| class = \"week-cell\" | "
end
result = result .. (weekNames[currentWeekDate] or currentWeekDate)
currentWeekDate = currentWeekDate + 1
end
result = result .. nl .. "!" .. nl
utils.sortItemsByName(perks)
mw.log("pStart: " .. pStart)
mw.log("pEnd: " .. pEnd)
mw.log(numberOfWeeksInYear)
mw.log(lastWeekNumber)
mw.log(lastWeekNumber - (pStart - pEnd))
mw.log(43)
for i, perk in ipairs(perks) do
if perk.character ~= nil and perkList[perk.id] ~= 0 then
for j, perkOcc in ipairs(perkList[perk.id]) do
hideable = false
if perkOcc.inception == true and (j == 1 and #perkList[perk.id] == 1) then
hideable = true
break
end
end
result = result .. ntl
if hideable then
result = result .. " class=\"inception-row" .. year .. "\" style=\"display: none;\" "
end
result = result .. nl .. "! [[" .. strings.file .. ":" .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName(perk.name)) .. ".png|32px]] !! " .. perk.name .. nl .. "|"
for j = startWeekDate, lastWeekNumber do --going through week in year
weekFound = false
for k, perkOcc in ipairs(perkList[perk.id]) do --perkOcc = Perk Occurrence
if perk.id == 30 then mw.log("Perk " .. perk.name .. ": " .. perk.id .. ", weekOcc:" .. perkOcc.week .. ", j: " .. j) end
if perkOcc.week == j then
local color = frame:expandTemplate{title = "clr", args = {perkOcc.color or "white"}}
result = result .. "style=\"background-color: #" .. color .. ";\" title = \"" ..strings.week .. " " .. perkOcc.week .. "\" | " --[[File:nothing.png]]
weekFound = true
break
end
end
if j ~= lastWeekNumber then --if it's not occurence in last week then add delimeters
result = result .. " ||"
end
end
result = result .. nl .. "! " .. ResolvePerkOccurence(perkList[perks[i].id]) .. nl
end
end
result = result .. "|}"
mw.log(result)
return result
end
function p.AssembleSoSYearPage(year)
year = ResolveYearParam(year)
local pStart, pEnd = unpack(GetIndexesOfPeriod(year))
local result = ""
local currentWeekDate = 1
local startWeekDate = 1
local sosIndex = 0
local header
if year == 2016 then
currentWeekDate = tonumber(os.date("%W", os.time(inception))) --43
startWeekDate = tonumber(os.date("%W", os.time(inception))) --52
end
local currentOffset = 0
local lastWeekNumber = currentWeekDate + (pStart - pEnd)
if perkInception == -1 then return strings.wrongCharType end
utils.sortItemsByName(perks)
mw.log("pStart: " .. pStart)
mw.log("pEnd: " .. pEnd)
mw.log("lastWeekNumber: " .. lastWeekNumber)
mw.log("lastWeekNumber CALC: " .. lastWeekNumber - (pStart - pEnd))
mw.log("startWeekDate: " .. startWeekDate)
for i = startWeekDate, lastWeekNumber do --going through week in year
sosIndex = pStart + startWeekDate - i
if sos[sosIndex][5] ~= nil then --If there's a table after 4 perks then retrieve data
if sos[sosIndex][5].header ~= nil then
header = sos[sosIndex][5].header
elseif sos[sosIndex][5].offset ~= nil then
currentOffset = currentOffset - 1
header = strings.week .. " " .. (i + currentOffset)
if sos[sosIndex][5].hideVersion ~= true then
header = header .. " v." .. (1 - sos[sosIndex][5].offset)
end
else
header = strings.week .. " " .. i + currentOffset
end
text = sos[sosIndex][5].text or ""
else
header = strings.week .. " " .. i + currentOffset
text = ""
end
--result = sos[sosIndex][1] .. ", " .. sos[sosIndex][2] .. ", " .. sos[sosIndex][3] .. ", " .. sos[sosIndex][4] .. nl .. nl .. result
--result = ("i: " .. i .. "| Index: " .. sosIndex .. "| lastWeekNumber - currentOffset: " .. lastWeekNumber - currentOffset) .. nl .. result
result = SoS(sosIndex) .. nl .. nl .. result
result = text .. nl .. result
result = "== " .. header .. " ==" ..nl .. result
end
mw.log(result)
return result
end
return p