<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://micras.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ABassaridiaOutbreaks</id>
	<title>Module:BassaridiaOutbreaks - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://micras.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ABassaridiaOutbreaks"/>
	<link rel="alternate" type="text/html" href="https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;action=history"/>
	<updated>2026-11-03T04:20:25Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.3</generator>
	<entry>
		<id>https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;diff=403342&amp;oldid=prev</id>
		<title>NewZimiaGov at 04:02, 24 May 2026</title>
		<link rel="alternate" type="text/html" href="https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;diff=403342&amp;oldid=prev"/>
		<updated>2026-05-24T04:02:11Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;amp;diff=403342&amp;amp;oldid=378288&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>NewZimiaGov</name></author>
	</entry>
	<entry>
		<id>https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;diff=378288&amp;oldid=prev</id>
		<title>NewZimiaGov at 17:56, 21 October 2025</title>
		<link rel="alternate" type="text/html" href="https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;diff=378288&amp;oldid=prev"/>
		<updated>2025-10-21T17:56:30Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;amp;diff=378288&amp;amp;oldid=376962&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>NewZimiaGov</name></author>
	</entry>
	<entry>
		<id>https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;diff=376962&amp;oldid=prev</id>
		<title>NewZimiaGov at 19:10, 28 September 2025</title>
		<link rel="alternate" type="text/html" href="https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;diff=376962&amp;oldid=prev"/>
		<updated>2025-09-28T19:10:16Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;amp;diff=376962&amp;amp;oldid=376961&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>NewZimiaGov</name></author>
	</entry>
	<entry>
		<id>https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;diff=376961&amp;oldid=prev</id>
		<title>NewZimiaGov: Created page with &quot;--------------------------------------------------------- -- Module: BassaridiaOutbreaks -- Daily outbreak tracker for Bassaridia Vaeringheim. -- Public functions: --   1) outbreaksAll(frame)      -&gt; single big table for ALL cities --   2) outbreaksForCity(frame)  -&gt; single table for a city --   3) diseaseGlossary(frame)   -&gt; legend of disease names &amp; controls -- -- Deterministic per-day values via math.randomseed(year*1000 + yday). -- City rows are further stabilized by...&quot;</title>
		<link rel="alternate" type="text/html" href="https://micras.org/wiki/index.php?title=Module:BassaridiaOutbreaks&amp;diff=376961&amp;oldid=prev"/>
		<updated>2025-09-28T19:05:56Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;--------------------------------------------------------- -- Module: BassaridiaOutbreaks -- Daily outbreak tracker for Bassaridia Vaeringheim. -- Public functions: --   1) outbreaksAll(frame)      -&amp;gt; single big table for ALL cities --   2) outbreaksForCity(frame)  -&amp;gt; single table for a city --   3) diseaseGlossary(frame)   -&amp;gt; legend of disease names &amp;amp; controls -- -- Deterministic per-day values via math.randomseed(year*1000 + yday). -- City rows are further stabilized by...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;---------------------------------------------------------&lt;br /&gt;
-- Module: BassaridiaOutbreaks&lt;br /&gt;
-- Daily outbreak tracker for Bassaridia Vaeringheim.&lt;br /&gt;
-- Public functions:&lt;br /&gt;
--   1) outbreaksAll(frame)      -&amp;gt; single big table for ALL cities&lt;br /&gt;
--   2) outbreaksForCity(frame)  -&amp;gt; single table for a city&lt;br /&gt;
--   3) diseaseGlossary(frame)   -&amp;gt; legend of disease names &amp;amp; controls&lt;br /&gt;
--&lt;br /&gt;
-- Deterministic per-day values via math.randomseed(year*1000 + yday).&lt;br /&gt;
-- City rows are further stabilized by seeding (dailySeed + cityIndex).&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 0. Date helpers (PSSC-compatible) &amp;amp; seeding&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
local function getCurrentDateInfo()&lt;br /&gt;
    local startDate   = os.time({year=1999, month=8, day=6})&lt;br /&gt;
    local secondsInDay= 86400&lt;br /&gt;
    local daysPerYear = 183&lt;br /&gt;
&lt;br /&gt;
    local now         = os.time()&lt;br /&gt;
    local totalDays   = math.floor((now - startDate) / secondsInDay)&lt;br /&gt;
    local fraction    = totalDays / daysPerYear&lt;br /&gt;
    local psscYear    = math.floor(fraction)&lt;br /&gt;
    local dayOfYear   = math.floor((fraction - psscYear) * daysPerYear) + 1&lt;br /&gt;
&lt;br /&gt;
    return { psscYear = psscYear, dayOfYear = dayOfYear }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getDailySeed()&lt;br /&gt;
    local d = os.date(&amp;quot;*t&amp;quot;)&lt;br /&gt;
    return (d.year * 1000) + d.yday&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 1. Canon diseases (names &amp;amp; quick controls)&lt;br /&gt;
--    Names mirror national public-health page terms.&lt;br /&gt;
--    You can tweak weights/controls without touching code logic.&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
local diseases = {&lt;br /&gt;
  -- name                  short     weight  baseR  desc / controls&lt;br /&gt;
  {name=&amp;quot;Thalassan Rot&amp;quot;,          code=&amp;quot;TR&amp;quot;,  w=10, r=1.20, controls=&amp;quot;canal flush, rat-proofing, food-handler checks&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Festival Blush&amp;quot;,         code=&amp;quot;FB&amp;quot;,  w=8,  r=1.25, controls=&amp;quot;ring vaccination, crowd-spacing, dorm rotation&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Pilgrim’s Flux&amp;quot;,         code=&amp;quot;PF&amp;quot;,  w=9,  r=1.15, controls=&amp;quot;boil notices, cistern audit, ORS distribution&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Stygian Dust&amp;quot;,           code=&amp;quot;SD&amp;quot;,  w=5,  r=1.05, controls=&amp;quot;respirators, mist carts, guide clinic checks&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Haifan Salt-Sickness&amp;quot;,   code=&amp;quot;HS&amp;quot;,  w=6,  r=1.10, controls=&amp;quot;indoor rotations, antifungal clinics, dehumidify&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Norsolyrian Drain&amp;quot;,      code=&amp;quot;ND&amp;quot;,  w=6,  r=1.18, controls=&amp;quot;lined ditches, praziquantel, snail abatement&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Somniumpolis Lung&amp;quot;,      code=&amp;quot;SL&amp;quot;,  w=5,  r=1.07, controls=&amp;quot;dust suppression, respirator fit-checks&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Haifan Crimson Fever&amp;quot;,   code=&amp;quot;HCF&amp;quot;, w=3,  r=1.30, controls=&amp;quot;larval control, dusk patrols, vector abatement&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Strip Yellowing&amp;quot;,        code=&amp;quot;SY&amp;quot;,  w=10, r=1.10, controls=&amp;quot;single-use ladles, vendor relicensing, recall&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Eye of Styx&amp;quot;,            code=&amp;quot;ES&amp;quot;,  w=4,  r=1.00, controls=&amp;quot;eye-wash stations, visor compliance&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Cato’s Curse&amp;quot;,           code=&amp;quot;CC&amp;quot;,  w=4,  r=1.05, controls=&amp;quot;PPE audits, solvent exposure controls&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;White Pestilence&amp;quot;,       code=&amp;quot;WP&amp;quot;,  w=2,  r=1.40, controls=&amp;quot;tiered quarantine, convoy assays, cordons&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Breath of Nephele&amp;quot;,      code=&amp;quot;BN&amp;quot;,  w=9,  r=1.12, controls=&amp;quot;ventilation drills, mask catechism, spacing&amp;quot;},&lt;br /&gt;
  {name=&amp;quot;Agnian Lockjaw&amp;quot;,         code=&amp;quot;AL&amp;quot;,  w=3,  r=0.95, controls=&amp;quot;tetanus boosters, injury clinics&amp;quot;},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Weighted picker&lt;br /&gt;
local function pickNDiseases(n, rnd)&lt;br /&gt;
    -- build cumulative weights&lt;br /&gt;
    local total = 0&lt;br /&gt;
    for _,d in ipairs(diseases) do total = total + d.w end&lt;br /&gt;
    local chosen, used = {}, {}&lt;br /&gt;
    local tries = 0&lt;br /&gt;
    while #chosen &amp;lt; n and tries &amp;lt; 50 do&lt;br /&gt;
        tries = tries + 1&lt;br /&gt;
        local roll = rnd() * total&lt;br /&gt;
        local acc = 0&lt;br /&gt;
        for i,d in ipairs(diseases) do&lt;br /&gt;
            acc = acc + d.w&lt;br /&gt;
            if roll &amp;lt;= acc then&lt;br /&gt;
                if not used[i] then&lt;br /&gt;
                    table.insert(chosen, d)&lt;br /&gt;
                    used[i] = true&lt;br /&gt;
                end&lt;br /&gt;
                break&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return chosen&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 2. City roster (same links as your weather module)&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
local cityData = {&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Vaeringheim Vaeringheim]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Luminaria Luminaria]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Serena Serena]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Pyralis Pyralis]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Symphonara Symphonara]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Aurelia Aurelia]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Somniumpolis Somniumpolis]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Nexa Nexa]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Lunalis_Sancta Lunalis Sancta]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Sylvapolis Sylvapolis]&amp;quot;},&lt;br /&gt;
&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Saluria Saluria]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Aetherium Aetherium]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Ferrum_Citadel Ferrum Citadel]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Acheron Acheron]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Erythros Erythros]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Catonis_Atrium Catonis Atrium]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Delphica Delphica]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Koinonía Koinonía]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Aureum Aureum]&amp;quot;},&lt;br /&gt;
&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Skýrophos Skýrophos]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Bjornopolis Bjornopolis]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Aegirheim Aegirheim]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Norsolyra Norsolyra]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Thorsalon Thorsalon]&amp;quot;},&lt;br /&gt;
&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Pelagia Pelagia]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Myrene Myrene]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Thyrea Thyrea]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Ephyra Ephyra]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Halicarn Halicarn]&amp;quot;},&lt;br /&gt;
&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Keybir-Aviv Keybir-Aviv]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Tel-Amin Tel-Amin]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Diamandis Diamandis]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Jogi Jogi]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Lewisburg Lewisburg]&amp;quot;},&lt;br /&gt;
&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Thermosalem Thermosalem]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Akróstadium Akróstadium]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Sufriya Sufriya]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Lykopolis Lykopolis]&amp;quot;},&lt;br /&gt;
&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Ardclach Ardclach]&amp;quot;},&lt;br /&gt;
    {city=&amp;quot;[https://micras.org/mwiki/List_of_cities_in_Bassaridia_Vaeringheim#Riddersborg Riddersborg]&amp;quot;},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Plain city name extractor for single-city lookups&lt;br /&gt;
local function plainName(link)&lt;br /&gt;
    return (link:match(&amp;quot;%s+([^%]]+)%]$&amp;quot;)) or link&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 3. Severity, colors, and tiny helpers&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
local function severityFor(casesPer100k)&lt;br /&gt;
    if casesPer100k &amp;gt;= 60 then return &amp;quot;CRITICAL&amp;quot;&lt;br /&gt;
    elseif casesPer100k &amp;gt;= 25 then return &amp;quot;HIGH&amp;quot;&lt;br /&gt;
    elseif casesPer100k &amp;gt;= 10 then return &amp;quot;MEDIUM&amp;quot;&lt;br /&gt;
    elseif casesPer100k &amp;gt;= 1 then return &amp;quot;LOW&amp;quot;&lt;br /&gt;
    else return &amp;quot;NONE&amp;quot; end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local severityColors = {&lt;br /&gt;
    CRITICAL=&amp;quot;#ffcccc&amp;quot;, HIGH=&amp;quot;#ffe0b2&amp;quot;, MEDIUM=&amp;quot;#fff9c4&amp;quot;, LOW=&amp;quot;#e0f2f1&amp;quot;, NONE=&amp;quot;#f2f2f2&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function arrow(trend)&lt;br /&gt;
    if trend &amp;gt; 0.1 then return &amp;quot;▲&amp;quot;&lt;br /&gt;
    elseif trend &amp;lt; -0.1 then return &amp;quot;▼&amp;quot;&lt;br /&gt;
    else return &amp;quot;▬&amp;quot; end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 4. City outbreak synthesis (deterministic daily)&lt;br /&gt;
--    For each city, 0–3 active diseases are picked.&lt;br /&gt;
--    We synthesize 24h cases, 7-day trend, Rt, positivity, advisory.&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
local function synthCityRow(rnd, cityLink)&lt;br /&gt;
    -- how many diseases today?&lt;br /&gt;
    local nActive = 0&lt;br /&gt;
    local r = rnd()&lt;br /&gt;
    if     r &amp;lt; 0.12 then nActive = 0&lt;br /&gt;
    elseif r &amp;lt; 0.55 then nActive = 1&lt;br /&gt;
    elseif r &amp;lt; 0.88 then nActive = 2&lt;br /&gt;
    else nActive = 3 end&lt;br /&gt;
&lt;br /&gt;
    local picked = pickNDiseases(nActive, rnd)&lt;br /&gt;
&lt;br /&gt;
    -- Combine signals into overall metrics&lt;br /&gt;
    local names, short = {}, {}&lt;br /&gt;
    local totalCases = 0&lt;br /&gt;
    local totalPopBase = 0&lt;br /&gt;
    local maxSeverity = &amp;quot;NONE&amp;quot;&lt;br /&gt;
    local maxColor    = severityColors.NONE&lt;br /&gt;
    local advices     = {}&lt;br /&gt;
&lt;br /&gt;
    for _,d in ipairs(picked) do&lt;br /&gt;
        -- Pseudopop base lets us derive cases per 100k without real populations&lt;br /&gt;
        local popBase = 100000 -- nominal per disease&lt;br /&gt;
        local base    = (d.r * 10) -- crude baseline&lt;br /&gt;
        local jitter  = math.floor(rnd()*base*3 + 0.5)&lt;br /&gt;
        local cases   = math.max(0, math.floor(base + jitter))&lt;br /&gt;
&lt;br /&gt;
        totalCases    = totalCases + cases&lt;br /&gt;
        totalPopBase  = totalPopBase + popBase&lt;br /&gt;
&lt;br /&gt;
        local per100k = (cases / popBase) * 100000&lt;br /&gt;
        local sev     = severityFor(per100k)&lt;br /&gt;
        if sev == &amp;quot;CRITICAL&amp;quot; or (sev==&amp;quot;HIGH&amp;quot; and maxSeverity~=&amp;quot;CRITICAL&amp;quot;)&lt;br /&gt;
            or (sev==&amp;quot;MEDIUM&amp;quot; and (maxSeverity==&amp;quot;LOW&amp;quot; or maxSeverity==&amp;quot;NONE&amp;quot;))&lt;br /&gt;
            or (sev==&amp;quot;LOW&amp;quot; and maxSeverity==&amp;quot;NONE&amp;quot;) then&lt;br /&gt;
            maxSeverity = sev&lt;br /&gt;
            maxColor    = severityColors[sev]&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        table.insert(names, d.name)&lt;br /&gt;
        table.insert(short, d.code)&lt;br /&gt;
        table.insert(advices, string.format(&amp;quot;%s: %s&amp;quot;, d.code, d.controls))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Aggregate stats&lt;br /&gt;
    local per100k = (totalPopBase&amp;gt;0) and (totalCases / totalPopBase) * 100000 or 0&lt;br /&gt;
    local Rt      = (#picked&amp;gt;0) and (1.0 + rnd()*0.8) or 0.85 + rnd()*0.1  -- rises with activity&lt;br /&gt;
    local trend   = (rnd()*0.6 - 0.3)  -- -0.3..+0.3 (neg=improving)&lt;br /&gt;
    local posRate = (#picked&amp;gt;0) and (15 + math.floor(rnd()*25)) or (5 + math.floor(rnd()*5))&lt;br /&gt;
&lt;br /&gt;
    local diseasesCell = (#picked&amp;gt;0) and table.concat(names, &amp;quot;, &amp;quot;) or &amp;quot;—&amp;quot;&lt;br /&gt;
    local codesCell    = (#picked&amp;gt;0) and table.concat(short, &amp;quot;/&amp;quot;)  or &amp;quot;—&amp;quot;&lt;br /&gt;
    local advisory     = (#picked&amp;gt;0) and table.concat(advices, &amp;quot; • &amp;quot;) or &amp;quot;No active advisories&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        cityLink      = cityLink,&lt;br /&gt;
        diseases      = diseasesCell,&lt;br /&gt;
        codes         = codesCell,&lt;br /&gt;
        cases24       = totalCases,&lt;br /&gt;
        per100k       = math.floor(per100k + 0.5),&lt;br /&gt;
        Rt            = tonumber(string.format(&amp;quot;%.2f&amp;quot;, Rt)),&lt;br /&gt;
        trend         = trend,&lt;br /&gt;
        trendIcon     = arrow(trend),&lt;br /&gt;
        positivity    = posRate,&lt;br /&gt;
        severity      = maxSeverity,&lt;br /&gt;
        color         = maxColor,&lt;br /&gt;
        advisory      = advisory&lt;br /&gt;
    }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 5. Render helpers&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
local function renderHeaderAll(pssc)&lt;br /&gt;
    local out = {}&lt;br /&gt;
    table.insert(out, &amp;quot;== Daily Outbreak Report ==\n&amp;quot;)&lt;br /&gt;
    table.insert(out, string.format(&amp;quot;&amp;#039;&amp;#039;(Day %d of Year %d PSSC)&amp;#039;&amp;#039;\n\n&amp;quot;, pssc.dayOfYear, pssc.psscYear))&lt;br /&gt;
    table.insert(out, &amp;#039;{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%; text-align:left;&amp;quot;\n&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;quot;! City !! Active Diseases !! Codes !! 24h Cases !! /100k !! R&amp;lt;sub&amp;gt;t&amp;lt;/sub&amp;gt; !! 7d Trend !! Positivity (%) !! Severity !! Advisory\n&amp;quot;)&lt;br /&gt;
    return out&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderRowAll(row)&lt;br /&gt;
    return string.format(&lt;br /&gt;
        &amp;quot;|-\n| %s || %s || %s || %d || %d || %.2f || %s %.0f%% || %d || style=\&amp;quot;background:%s\&amp;quot; | %s || %s\n&amp;quot;,&lt;br /&gt;
        row.cityLink, row.diseases, row.codes, row.cases24, row.per100k, row.Rt,&lt;br /&gt;
        row.trendIcon, math.abs(row.trend*100), row.positivity, row.color, row.severity, row.advisory&lt;br /&gt;
    )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderFooter()&lt;br /&gt;
    return &amp;quot;|}\n&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 6A. ALL CITIES&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
function p.outbreaksAll(frame)&lt;br /&gt;
    local seed = getDailySeed()&lt;br /&gt;
    math.randomseed(seed)&lt;br /&gt;
&lt;br /&gt;
    local d = getCurrentDateInfo()&lt;br /&gt;
    local out = renderHeaderAll(d)&lt;br /&gt;
&lt;br /&gt;
    for i,entry in ipairs(cityData) do&lt;br /&gt;
        -- stabilize row randomness per city&lt;br /&gt;
        math.randomseed(seed + i*97)&lt;br /&gt;
        local function rnd() return math.random() end&lt;br /&gt;
        local row = synthCityRow(rnd, entry.city)&lt;br /&gt;
        table.insert(out, renderRowAll(row))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    table.insert(out, renderFooter())&lt;br /&gt;
    return table.concat(out)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 6B. SINGLE CITY&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
function p.outbreaksForCity(frame)&lt;br /&gt;
    local q = frame.args.city&lt;br /&gt;
    if not q or q == &amp;quot;&amp;quot; then&lt;br /&gt;
        return &amp;quot;Error: Please specify a city. E.g. {{#invoke:BassaridiaOutbreaks|outbreaksForCity|city=Vaeringheim}}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local seed = getDailySeed()&lt;br /&gt;
    math.randomseed(seed)&lt;br /&gt;
&lt;br /&gt;
    local idx, link&lt;br /&gt;
    for i,entry in ipairs(cityData) do&lt;br /&gt;
        local plain = plainName(entry.city)&lt;br /&gt;
        if entry.city == q or plain == q then&lt;br /&gt;
            idx = i; link = entry.city; break&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if not idx then return &amp;quot;Error: City &amp;#039;&amp;quot;..q..&amp;quot;&amp;#039; not found.&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
    math.randomseed(seed + idx*97)&lt;br /&gt;
    local function rnd() return math.random() end&lt;br /&gt;
    local row = synthCityRow(rnd, link)&lt;br /&gt;
&lt;br /&gt;
    local out = {}&lt;br /&gt;
    table.insert(out, &amp;#039;{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%; text-align:left;&amp;quot;\n&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;quot;! City !! Active Diseases !! Codes !! 24h Cases !! /100k !! R&amp;lt;sub&amp;gt;t&amp;lt;/sub&amp;gt; !! 7d Trend !! Positivity (%) !! Severity !! Advisory\n&amp;quot;)&lt;br /&gt;
    table.insert(out, renderRowAll(row))&lt;br /&gt;
    table.insert(out, renderFooter())&lt;br /&gt;
    return table.concat(out)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
-- 6C. GLOSSARY&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
function p.diseaseGlossary(frame)&lt;br /&gt;
    local out = {}&lt;br /&gt;
    table.insert(out, &amp;quot;=== Disease Glossary &amp;amp; Standard Controls ===\n&amp;quot;)&lt;br /&gt;
    table.insert(out, &amp;#039;{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%; text-align:left;&amp;quot;\n&amp;#039;)&lt;br /&gt;
    table.insert(out, &amp;quot;! Code !! Disease !! Typical Controls\n&amp;quot;)&lt;br /&gt;
    for _,d in ipairs(diseases) do&lt;br /&gt;
        table.insert(out, string.format(&amp;quot;|-\n| %s || %s || %s\n&amp;quot;, d.code, d.name, d.controls))&lt;br /&gt;
    end&lt;br /&gt;
    table.insert(out, &amp;quot;|}\n&amp;quot;)&lt;br /&gt;
    return table.concat(out)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>NewZimiaGov</name></author>
	</entry>
</feed>