Przejdź do zawartości

Moduł:Rekordy sezon

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Rekordy sezon/opis

local p = {}

-- =========================================================
-- Moduł:Rekordy_sezon
--
-- Wspólny moduł rekordów sezonu.
--
-- Wywołanie:
--
-- {{#invoke:Rekordy_sezon|main
--  |sezon=2026/2027
--  |druzyna=Lech Poznań
--  |dyscyplina=piłka nożna
-- }}
--
-- Obsługiwane dyscypliny:
--   - koszykówka
--   - piłka nożna
--
-- =========================================================


-- =========================================================
-- FUNKCJE WSPÓLNE
-- =========================================================

local function escapeSQL(value)

    value = value or ""

    return mw.ustring.gsub(
        tostring(value),
        "'",
        "''"
    )

end


local function liczba(value)

    if value == nil or value == "" then
        return 0
    end

    value = tostring(value)

    value = mw.ustring.gsub(
        value,
        "%s+",
        ""
    )

    return tonumber(value) or 0

end


-- =========================================================
-- WYNIK MECZU
--
-- WAŻNE:
-- funkcja jest lokalna i dostępna dla całego modułu.
-- =========================================================

local function wynikMeczu(row)

    local g1 = tonumber(
        row.gole1 or ""
    )

    local g2 = tonumber(
        row.gole2 or ""
    )

    if g1 and g2 then
        return g1, g2
    end


    local wynik =
        row.wynik or ""


    local a, b =
        wynik:match(
            "(%d+)%s*:%s*(%d+)"
        )


    if a and b then

        return
            tonumber(a),
            tonumber(b)

    end


    return nil, nil

end


-- =========================================================
-- MIEJSCE MECZU
-- =========================================================

local function miejsceMeczu(
    row,
    druzyna
)

    local d1 =
        row.druzyna1 or ""

    local d2 =
        row.druzyna2 or ""


    if d1 == druzyna then
        return "dom"
    end


    if d2 == druzyna then
        return "wyjazd"
    end


    return nil

end


-- =========================================================
-- NAZWA MECZU
-- =========================================================

local function nazwaMeczu(row)

    local d1 =
        row.druzyna1 or ""

    local d2 =
        row.druzyna2 or ""

    local tekst =
        d1 .. " – " .. d2


    local strona =
        row.strona_meczu or ""


    if strona ~= "" then

        return "[[" ..
            strona ..
            "|" ..
            tekst ..
            "]]"

    end


    return tekst

end


-- =========================================================
-- PARSOWANIE MINUTY GOLA
--
-- Obsługujemy:
--
-- 14
-- 45
-- 45+2
-- 90+4
-- 105
-- 120+1
--
-- Zwracamy:
--   minuta podstawowa
--   doliczony czas
-- =========================================================

local function parsujMinute(value)

    if value == nil or value == "" then
        return nil, 0
    end


    value =
        tostring(value)


    value =
        mw.ustring.gsub(
            value,
            "%s+",
            ""
        )


    local minuta,
          doliczona =
        value:match(
            "^(%d+)%+(%d+)$"
        )


    if minuta then

        return
            tonumber(minuta),
            tonumber(doliczona)

    end


    minuta =
        value:match(
            "^(%d+)"
        )


    if minuta then

        return
            tonumber(minuta),
            0

    end


    return nil, 0

end


-- =========================================================
-- PRZEDZIAŁ CZASOWY GOLA
-- =========================================================

local function przedzialGola(value)

    local minuta,
          doliczona =
        parsujMinute(value)


    if not minuta then
        return nil
    end


    -- 45+ oraz 90+ itd.
    if minuta == 45 and doliczona > 0 then
        return "45+"
    end


    if minuta == 90 and doliczona > 0 then
        return "90+"
    end


    if minuta == 105 and doliczona > 0 then
        return "105+"
    end


    if minuta == 120 and doliczona > 0 then
        return "120+"
    end


    if minuta >= 1 and minuta <= 15 then
        return "0–15"
    end


    if minuta >= 16 and minuta <= 30 then
        return "16–30"
    end


    if minuta >= 31 and minuta <= 45 then
        return "31–45"
    end


    if minuta >= 46 and minuta <= 60 then
        return "46–60"
    end


    if minuta >= 61 and minuta <= 75 then
        return "61–75"
    end


    if minuta >= 76 and minuta <= 90 then
        return "76–90"
    end


    if minuta >= 91 and minuta <= 105 then
        return "91–105"
    end


    if minuta >= 106 and minuta <= 120 then
        return "106–120"
    end


    if minuta > 120 then
        return "120+"
    end


    return nil

end


-- =========================================================
-- DODANIE REKORDU DO LISTY
-- =========================================================

local function dodajRekord(
    tabela,
    miejsce,
    wartosc,
    item
)

    local lista =
        tabela[miejsce]


    if not lista then

        tabela[miejsce] = {}

        lista =
            tabela[miejsce]

    end


    if #lista == 0 then

        table.insert(
            lista,
            item
        )

        return

    end


    local obecna =
        lista[1].wartosc


    if wartosc > obecna then

        tabela[miejsce] = {
            item
        }

    elseif wartosc == obecna then

        table.insert(
            lista,
            item
        )

    end

end


-- =========================================================
-- FORMAT LISTY
-- =========================================================

local function formatMecze(lista)

    if not lista or #lista == 0 then
        return "—"
    end


    local wynik = {}


    for _, item in ipairs(lista) do

        table.insert(
            wynik,
            item.tekst ..
            " (" ..
            item.wynik ..
            ")"
        )

    end


    return table.concat(
        wynik,
        "<br>"
    )

end


-- =========================================================
-- FORMAT ZAWODNIKÓW
-- =========================================================

local function formatZawodnicy(lista)

    if not lista or #lista == 0 then
        return "—"
    end


    local wynik = {}


    for _, item in ipairs(lista) do

        local zawodnik =
            "[[" ..
            item.zawodnik ..
            "]]"


        table.insert(
            wynik,
            zawodnik ..
            " — " ..
            tostring(item.wartosc) ..
            "<br>" ..
            item.tekst ..
            " (" ..
            item.wynik ..
            ")"
        )

    end


    return table.concat(
        wynik,
        "<br>"
    )

end


-- =========================================================
-- REKORDY PIŁKARSKIE
-- =========================================================

local function pilkaNozna(
    sezon,
    druzyna
)

    local sezonSQL =
        escapeSQL(sezon)

    local druzynaSQL =
        escapeSQL(druzyna)


    -- =====================================================
    -- MECZE
    -- =====================================================

    local fieldsMecze =
        table.concat({

            "Mecze.id=mecz",
            "Mecze.data=data",
            "Mecze.sezon=sezon",
            "Mecze.rozgrywki=rozgrywki",
            "Mecze.druzyna1=druzyna1",
            "Mecze.druzyna2=druzyna2",
            "Mecze.gole1=gole1",
            "Mecze.gole2=gole2",
            "Mecze.wynik=wynik",
            "Mecze.strona_meczu=strona_meczu"

        }, ",")


    local mecze =
        mw.ext.cargo.query(
            "Mecze",
            fieldsMecze,
            {
                where =
                    "(Mecze.druzyna1='" ..
                    druzynaSQL ..
                    "' OR Mecze.druzyna2='" ..
                    druzynaSQL ..
                    "')" ..
                    " AND Mecze.sezon='" ..
                    sezonSQL ..
                    "'",

                orderBy =
                    "Mecze.data ASC",

                limit = 5000
            }
        )


    if not mecze or #mecze == 0 then

        return
            "''Brak wprowadzonych meczów dla tej drużyny w podanym sezonie.''"

    end


    -- =====================================================
    -- REKORDY MECZOWE
    -- =====================================================

    local najwyzszeZwyciestwo = {
        dom = {},
        wyjazd = {}
    }


    local najwyzszaPorazka = {
        dom = {},
        wyjazd = {}
    }


    -- =====================================================
    -- SERIE
    -- =====================================================

    local serie = {

        wszystkie = {
            wygrane = 0,
            remisy = 0,
            porazki = 0,
            bezporazki = 0,
            bezwygranej = 0
        },

        dom = {
            wygrane = 0,
            remisy = 0,
            porazki = 0,
            bezporazki = 0,
            bezwygranej = 0
        },

        wyjazd = {
            wygrane = 0,
            remisy = 0,
            porazki = 0,
            bezporazki = 0,
            bezwygranej = 0
        }

    }


    local aktualna = {

        wszystkie = {
            W = 0,
            R = 0,
            P = 0
        },

        dom = {
            W = 0,
            R = 0,
            P = 0
        },

        wyjazd = {
            W = 0,
            R = 0,
            P = 0
        }

    }


    -- =====================================================
    -- WYNIKI
    -- =====================================================

    local czestotliwoscWynikow = {}


    -- =====================================================
    -- BILANS ROZGRYWEK
    -- =====================================================

    local rozgrywki = {}


    -- =====================================================
    -- PRZETWARZANIE MECZÓW
    -- =====================================================

    for _, row in ipairs(mecze) do

        local g1, g2 =
            wynikMeczu(row)


        local miejsce =
            miejsceMeczu(
                row,
                druzyna
            )


        if g1 and g2 and miejsce then

            local zdobyte
            local stracone


            if miejsce == "dom" then

                zdobyte = g1
                stracone = g2

            else

                zdobyte = g2
                stracone = g1

            end


            local roznica =
                zdobyte - stracone


            local wynik


            if roznica > 0 then
                wynik = "W"
            elseif roznica < 0 then
                wynik = "P"
            else
                wynik = "R"
            end


            local tekst =
                nazwaMeczu(row)


            local item = {

                tekst = tekst,

                wynik =
                    tostring(g1) ..
                    ":" ..
                    tostring(g2),

                roznica =
                    roznica,

                rozgrywki =
                    row.rozgrywki or "",

                miejsce =
                    miejsce

            }


            -- =============================================
            -- NAJWYŻSZE ZWYCIĘSTWO
            -- =============================================

            if wynik == "W" then

                dodajRekord(
                    najwyzszeZwyciestwo,
                    miejsce,
                    roznica,
                    item
                )

            end


            -- =============================================
            -- NAJWYŻSZA PORAŻKA
            -- =============================================

            if wynik == "P" then

                local porazka =
                    -roznica


                item.wartosc =
                    porazka


                dodajRekord(
                    najwyzszaPorazka,
                    miejsce,
                    porazka,
                    item
                )

            end


            -- =============================================
            -- CZĘSTOTLIWOŚĆ WYNIKÓW
            -- =============================================

            local klucz =
                tostring(g1) ..
                ":" ..
                tostring(g2)


            if not czestotliwoscWynikow[klucz] then

                czestotliwoscWynikow[klucz] = {

                    liczba = 0,
                    dom = 0,
                    wyjazd = 0

                }

            end


            czestotliwoscWynikow[klucz].liczba =
                czestotliwoscWynikow[klucz].liczba + 1


            czestotliwoscWynikow[klucz][miejsce] =
                czestotliwoscWynikow[klucz][miejsce] + 1


            -- =============================================
            -- ROZGRYWKI
            -- =============================================

            local nazwaRozgrywek =
                row.rozgrywki or ""


            if nazwaRozgrywek == "" then
                nazwaRozgrywek = "Pozostałe"
            end


            if not rozgrywki[nazwaRozgrywek] then

                rozgrywki[nazwaRozgrywek] = {

                    wszystkie = {
                        W = 0,
                        R = 0,
                        P = 0
                    },

                    dom = {
                        W = 0,
                        R = 0,
                        P = 0
                    },

                    wyjazd = {
                        W = 0,
                        R = 0,
                        P = 0
                    }

                }

            end


            local r =
                rozgrywki[nazwaRozgrywek]


            r[miejsce][wynik] =
                r[miejsce][wynik] + 1


            r.wszystkie[wynik] =
                r.wszystkie[wynik] + 1


            -- =============================================
            -- SERIE OGÓŁEM
            -- =============================================

            if wynik == "W" then

                serie.wszystkie.wygrane =
                    serie.wszystkie.wygrane + 1

                serie.wszystkie.bezwygranej = 0

                aktualna.wszystkie.W =
                    aktualna.wszystkie.W + 1

                aktualna.wszystkie.R = 0
                aktualna.wszystkie.P = 0

            elseif wynik == "R" then

                serie.wszystkie.remisy =
                    serie.wszystkie.remisy + 1

                aktualna.wszystkie.R =
                    aktualna.wszystkie.R + 1

                aktualna.wszystkie.W = 0
                aktualna.wszystkie.P = 0

            else

                serie.wszystkie.porazki =
                    serie.wszystkie.porazki + 1

                aktualna.wszystkie.P =
                    aktualna.wszystkie.P + 1

                aktualna.wszystkie.W = 0
                aktualna.wszystkie.R = 0

            end


            -- seria bez porażki
            if wynik ~= "P" then

                aktualna.wszystkie.bezporazki =
                    (aktualna.wszystkie.bezporazki or 0) + 1

            else

                aktualna.wszystkie.bezporazki = 0

            end


            -- seria bez wygranej
            if wynik ~= "W" then

                aktualna.wszystkie.bezwygranej =
                    (aktualna.wszystkie.bezwygranej or 0) + 1

            else

                aktualna.wszystkie.bezwygranej = 0

            end


            if aktualna.wszystkie.bezporazki >
                serie.wszystkie.bezporazki then

                serie.wszystkie.bezporazki =
                    aktualna.wszystkie.bezporazki

            end


            if aktualna.wszystkie.bezwygranej >
                serie.wszystkie.bezwygranej then

                serie.wszystkie.bezwygranej =
                    aktualna.wszystkie.bezwygranej

            end


            -- =============================================
            -- SERIE DOM / WYJAZD
            -- =============================================

            local s =
                aktualna[miejsce]

            local sr =
                serie[miejsce]


            if wynik == "W" then

                sr.wygrane =
                    sr.wygrane + 1

                s.W =
                    s.W + 1

                s.R = 0
                s.P = 0

            elseif wynik == "R" then

                sr.remisy =
                    sr.remisy + 1

                s.R =
                    s.R + 1

                s.W = 0
                s.P = 0

            else

                sr.porazki =
                    sr.porazki + 1

                s.P =
                    s.P + 1

                s.W = 0
                s.R = 0

            end


            s.bezporazki =
                s.bezporazki or 0

            s.bezwygranej =
                s.bezwygranej or 0


            if wynik ~= "P" then

                s.bezporazki =
                    s.bezporazki + 1

            else

                s.bezporazki = 0

            end


            if wynik ~= "W" then

                s.bezwygranej =
                    s.bezwygranej + 1

            else

                s.bezwygranej = 0

            end


            if s.bezporazki >
                sr.bezporazki then

                sr.bezporazki =
                    s.bezporazki

            end


            if s.bezwygranej >
                sr.bezwygranej then

                sr.bezwygranej =
                    s.bezwygranej

            end

        end

    end


    -- =====================================================
    -- STRZELCY I ASYSTY
    --
    -- Dane z:
    -- StrzelecBramki
    --
    -- Pola:
    -- mecz
    -- zawodnik
    -- druzyna
    -- minuta
    -- =====================================================

    local fieldsStrzelcy =
        table.concat({

            "StrzelecBramki.mecz=mecz",
            "StrzelecBramki.zawodnik=zawodnik",
            "StrzelecBramki.druzyna=druzyna_strzelca",
            "StrzelecBramki.minuta=minuta"

        }, ",")


    local strzelcy =
        mw.ext.cargo.query(
            "StrzelecBramki",
            fieldsStrzelcy,
            {
                where =
                    "StrzelecBramki.mecz IN " ..
                    "(SELECT Mecze.id FROM Mecze WHERE " ..
                    "(Mecze.druzyna1='" ..
                    druzynaSQL ..
                    "' OR Mecze.druzyna2='" ..
                    druzynaSQL ..
                    "') AND Mecze.sezon='" ..
                    sezonSQL ..
                    "')",

                limit = 10000
            }
        )


    -- =====================================================
    -- GOLE W JEDNYM MECZU
    -- =====================================================

    local goleWmeczu = {

        dom = {},
        wyjazd = {}

    }


    -- =====================================================
    -- PRZEDZIAŁY CZASOWE
    -- =====================================================

    local goleCzas = {

        ["0–15"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["16–30"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["31–45"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["45+"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["46–60"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["61–75"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["76–90"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["90+"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["91–105"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["105+"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["106–120"] = {
            zdobyte = 0,
            stracone = 0
        },

        ["120+"] = {
            zdobyte = 0,
            stracone = 0
        }

    }


    -- =====================================================
    -- PRZETWARZANIE GOLI
    -- =====================================================

    if strzelcy then

        for _, row in ipairs(strzelcy) do

            local mecz =
                row.mecz or ""


            local minuta =
                row.minuta or ""


            local dru =
                row.druzyna_strzelca or ""


            -- Pobieramy informacje o meczu
            local meczInfo =
                mw.ext.cargo.query(
                    "Mecze",
                    table.concat({

                        "Mecze.druzyna1=druzyna1",
                        "Mecze.druzyna2=druzyna2"

                    }, ","),
                    {
                        where =
                            "Mecze.id='" ..
                            escapeSQL(mecz) ..
                            "'",

                        limit = 1
                    }
                )


            if meczInfo and
                #meczInfo > 0 then

                local info =
                    meczInfo[1]


                local miejsce =
                    miejsceMeczu(
                        info,
                        druzyna
                    )


                if miejsce then

                    -- =====================================
                    -- GOL W JEDNYM SPOTKANIU
                    -- =====================================

                    if not goleWmeczu[miejsce][mecz] then

                        goleWmeczu[miejsce][mecz] = {

                            zawodnik = {},
                            gole = 0

                        }

                    end


                    local gm =
                        goleWmeczu[miejsce][mecz]


                    if dru == druzyna then

                        gm.gole =
                            gm.gole + 1


                        table.insert(
                            gm.zawodnik,
                            row.zawodnik or ""
                        )


                    end


                    -- =====================================
                    -- PRZEDZIAŁ CZASOWY
                    -- =====================================

                    local przedzial =
                        przedzialGola(
                            minuta
                        )


                    if przedzial and
                        goleCzas[przedzial] then

                        if dru == druzyna then

                            goleCzas[przedzial].zdobyte =
                                goleCzas[przedzial].zdobyte + 1

                        else

                            goleCzas[przedzial].stracone =
                                goleCzas[przedzial].stracone + 1

                        end

                    end

                end

            end

        end

    end


    -- =====================================================
    -- NAJWIĘCEJ GOLI W JEDNYM MECZU
    -- =====================================================

    local najlepszyStrzelec = {

        dom = {},
        wyjazd = {}

    }


    for miejsce, meczeGolowe
        in pairs(goleWmeczu) do

        for mecz, dane
            in pairs(meczeGolowe) do

            if dane.gole > 0 then

                for _, zawodnik
                    in ipairs(dane.zawodnik) do

                    local item = {

                        zawodnik =
                            zawodnik,

                        wartosc =
                            dane.gole,

                        tekst =
                            mecz

                    }


                    dodajRekord(
                        najlepszyStrzelec,
                        miejsce,
                        dane.gole,
                        item
                    )

                end

            end

        end

    end


    -- =====================================================
    -- GENEROWANIE WYNIKU
    -- =====================================================

    local wynik = {}


    table.insert(
        wynik,
        "=== Rekordy sezonu ==="
    )


    table.insert(
        wynik,
        ""
    )


    -- =====================================================
    -- REKORDY MECZOWE
    -- =====================================================

    table.insert(
        wynik,
        "==== Rekordy meczowe ===="
    )


    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )


    table.insert(
        wynik,
        "! Rekord !! 🏠 Dom !! ✈️ Wyjazd"
    )


    table.insert(
        wynik,
        "|-"
    )


    table.insert(
        wynik,
        "! 🏆 Najwyższe zwycięstwo"
    )


    table.insert(
        wynik,
        "| " ..
        formatMecze(
            najwyzszeZwyciestwo.dom
        )
    )


    table.insert(
        wynik,
        "| " ..
        formatMecze(
            najwyzszeZwyciestwo.wyjazd
        )
    )


    table.insert(
        wynik,
        "|-"
    )


    table.insert(
        wynik,
        "! ❌ Najwyższa porażka"
    )


    table.insert(
        wynik,
        "| " ..
        formatMecze(
            najwyzszaPorazka.dom
        )
    )


    table.insert(
        wynik,
        "| " ..
        formatMecze(
            najwyzszaPorazka.wyjazd
        )
    )


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- SERIE I BILANS
    -- =====================================================

    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        "==== Serie i bilans ===="
    )


    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )


    table.insert(
        wynik,
        "! Rekord !! Wszystkie !! 🏠 Dom !! ✈️ Wyjazd"
    )


    local function wierszSerii(
        nazwa,
        pole
    )

        table.insert(
            wynik,
            "|-"
        )


        table.insert(
            wynik,
            "! " .. nazwa
        )


        table.insert(
            wynik,
            "| " ..
            tostring(
                serie.wszystkie[pole]
            )
        )


        table.insert(
            wynik,
            "| " ..
            tostring(
                serie.dom[pole]
            )
        )


        table.insert(
            wynik,
            "| " ..
            tostring(
                serie.wyjazd[pole]
            )
        )

    end


    wierszSerii(
        "🏆 Wygrane",
        "wygrane"
    )


    wierszSerii(
        "🤝 Remisy",
        "remisy"
    )


    wierszSerii(
        "❌ Porażki",
        "porazki"
    )


    wierszSerii(
        "🛡️ Najdłuższa seria bez porażki",
        "bezporazki"
    )


    wierszSerii(
        "📉 Najdłuższa seria bez wygranej",
        "bezwygranej"
    )


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- STRZELCY
    -- =====================================================

    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        "==== Najwięcej goli w jednym meczu ===="
    )


    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )


    table.insert(
        wynik,
        "! Rekord !! 🏠 Dom !! ✈️ Wyjazd"
    )


    table.insert(
        wynik,
        "|-"
    )


    table.insert(
        wynik,
        "! ⚽ Najwięcej goli zawodnika w jednym meczu"
    )


    table.insert(
        wynik,
        "| " ..
        formatZawodnicy(
            najlepszyStrzelec.dom
        )
    )


    table.insert(
        wynik,
        "| " ..
        formatZawodnicy(
            najlepszyStrzelec.wyjazd
        )
    )


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- NAJCZĘSTSZE WYNIKI
    -- =====================================================

    local wynikiSort = {}


    for rezultat, dane
        in pairs(czestotliwoscWynikow) do

        table.insert(
            wynikiSort,
            {
                wynik = rezultat,
                liczba = dane.liczba,
                dom = dane.dom,
                wyjazd = dane.wyjazd
            }
        )

    end


    table.sort(
        wynikiSort,
        function(a, b)

            if a.liczba ~= b.liczba then
                return a.liczba > b.liczba
            end

            return a.wynik < b.wynik

        end
    )


    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        "==== Najczęstsze wyniki ===="
    )


    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )


    table.insert(
        wynik,
        "! Wynik !! Wszystkie !! 🏠 Dom !! ✈️ Wyjazd"
    )


    for _, dane
        in ipairs(wynikiSort) do

        table.insert(
            wynik,
            "|-"
        )


        table.insert(
            wynik,
            "| " ..
            dane.wynik
        )


        table.insert(
            wynik,
            "| " ..
            tostring(dane.liczba)
        )


        table.insert(
            wynik,
            "| " ..
            tostring(dane.dom)
        )


        table.insert(
            wynik,
            "| " ..
            tostring(dane.wyjazd)
        )

    end


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- ROZGRYWKI
    -- =====================================================

    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        "==== Bilans według rozgrywek ===="
    )


    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )


    table.insert(
        wynik,
        "! Rozgrywki !! Miejsce !! W !! R !! P"
    )


    local nazwyRozgrywek = {}


    for nazwa in pairs(rozgrywki) do

        table.insert(
            nazwyRozgrywek,
            nazwa
        )

    end


    table.sort(
        nazwyRozgrywek
    )


    for _, nazwa
        in ipairs(nazwyRozgrywek) do

        local r =
            rozgrywki[nazwa]


        for _, miejsce
            in ipairs({
                "wszystkie",
                "dom",
                "wyjazd"
            }) do

            local nazwaMiejsca =
                miejsce


            if miejsce == "wszystkie" then
                nazwaMiejsca = "Wszystkie"
            elseif miejsce == "dom" then
                nazwaMiejsca = "Dom"
            else
                nazwaMiejsca = "Wyjazd"
            end


            table.insert(
                wynik,
                "|-"
            )


            table.insert(
                wynik,
                "| " ..
                nazwa
            )


            table.insert(
                wynik,
                "| " ..
                nazwaMiejsca
            )


            table.insert(
                wynik,
                "| " ..
                tostring(
                    r[miejsce].W
                )
            )


            table.insert(
                wynik,
                "| " ..
                tostring(
                    r[miejsce].R
                )
            )


            table.insert(
                wynik,
                "| " ..
                tostring(
                    r[miejsce].P
                )
            )

        end

    end


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- GOLE W PRZEDZIAŁACH CZASOWYCH
    -- =====================================================

    local kolejnoscCzasu = {

        "0–15",
        "16–30",
        "31–45",
        "45+",
        "46–60",
        "61–75",
        "76–90",
        "90+",
        "91–105",
        "105+",
        "106–120",
        "120+"

    }


    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        "==== Gole według przedziałów czasowych ===="
    )


    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )


    table.insert(
        wynik,
        "! Przedział !! ⚽ Zdobyte !! 🥅 Stracone !! Bilans"
    )


    for _, przedzial
        in ipairs(kolejnoscCzasu) do

        local dane =
            goleCzas[przedzial]


        local bilans =
            dane.zdobyte -
            dane.stracone


        local bilansTekst =
            tostring(bilans)


        if bilans > 0 then

            bilansTekst =
                "+" ..
                bilansTekst

        end


        table.insert(
            wynik,
            "|-"
        )


        table.insert(
            wynik,
            "| " ..
            przedzial
        )


        table.insert(
            wynik,
            "| " ..
            tostring(
                dane.zdobyte
            )
        )


        table.insert(
            wynik,
            "| " ..
            tostring(
                dane.stracone
            )
        )


        table.insert(
            wynik,
            "| " ..
            bilansTekst
        )

    end


    table.insert(
        wynik,
        "|}"
    )


    return table.concat(
        wynik,
        "\n"
    )

end


-- =========================================================
-- KOSZYKÓWKA
--
-- Tu zostawiamy dotychczasową wersję logiki.
-- =========================================================

local function koszykowka(
    sezon,
    druzyna
)

    -- Pobieramy mecze

    local sezonSQL =
        escapeSQL(sezon)

    local druzynaSQL =
        escapeSQL(druzyna)


    local fields =
        table.concat({

            "Mecze.id=mecz",
            "Mecze.data=data",
            "Mecze.sezon=sezon",
            "Mecze.druzyna1=druzyna1",
            "Mecze.druzyna2=druzyna2",
            "Mecze.gole1=gole1",
            "Mecze.gole2=gole2",
            "Mecze.wynik=wynik",
            "Mecze.strona_meczu=strona_meczu"

        }, ",")


    local mecze =
        mw.ext.cargo.query(
            "Mecze",
            fields,
            {
                where =
                    "(Mecze.druzyna1='" ..
                    druzynaSQL ..
                    "' OR Mecze.druzyna2='" ..
                    druzynaSQL ..
                    "')" ..
                    " AND Mecze.sezon='" ..
                    sezonSQL ..
                    "'",

                orderBy =
                    "Mecze.data ASC",

                limit = 5000
            }
        )


    if not mecze or #mecze == 0 then

        return
            "''Brak wprowadzonych meczów dla tej drużyny w podanym sezonie.''"

    end


    local zwyciestwa = {
        dom = {},
        wyjazd = {}
    }


    local porazki = {
        dom = {},
        wyjazd = {}
    }


    for _, row in ipairs(mecze) do

        local g1, g2 =
            wynikMeczu(row)


        local miejsce =
            miejsceMeczu(
                row,
                druzyna
            )


        if g1 and g2 and miejsce then

            local zdobyte
            local stracone


            if miejsce == "dom" then

                zdobyte = g1
                stracone = g2

            else

                zdobyte = g2
                stracone = g1

            end


            local roznica =
                zdobyte - stracone


            local item = {

                tekst =
                    nazwaMeczu(row),

                wynik =
                    tostring(g1) ..
                    ":" ..
                    tostring(g2),

                roznica =
                    roznica,

                miejsce =
                    miejsce

            }


            if roznica > 0 then

                dodajRekord(
                    zwyciestwa,
                    miejsce,
                    roznica,
                    item
                )

            elseif roznica < 0 then

                item.wartosc =
                    -roznica


                dodajRekord(
                    porazki,
                    miejsce,
                    -roznica,
                    item
                )

            end

        end

    end


    -- =============================================
    -- STATYSTYKI ZAWODNIKÓW
    -- =============================================

    local fieldsZ =
        table.concat({

            "UdzialZawodnika.zawodnik=zawodnik",
            "UdzialZawodnika.druzyna=druzyna_zawodnika",
            "UdzialZawodnika.gol=gol",
            "UdzialZawodnika.minuty=minuty",
            "UdzialZawodnika.minuty_format=minuty_format",
            "UdzialZawodnika.asysta=asysta",
            "UdzialZawodnika.zbiorka=zbiorka",
            "UdzialZawodnika.eval=eval",
            "UdzialZawodnika.plusminus=plusminus",

            "Mecze.id=mecz",
            "Mecze.data=data",
            "Mecze.druzyna1=druzyna1",
            "Mecze.druzyna2=druzyna2",
            "Mecze.gole1=gole1",
            "Mecze.gole2=gole2",
            "Mecze.wynik=wynik",
            "Mecze.strona_meczu=strona_meczu"

        }, ",")


    local zawodnicy =
        mw.ext.cargo.query(
            "UdzialZawodnika,Mecze",
            fieldsZ,
            {
                join =
                    "UdzialZawodnika.mecz=Mecze.id",

                where =
                    "UdzialZawodnika.druzyna='" ..
                    druzynaSQL ..
                    "'" ..
                    " AND Mecze.sezon='" ..
                    sezonSQL ..
                    "'" ..
                    " AND UdzialZawodnika.minuty > 0",

                orderBy =
                    "Mecze.data ASC",

                limit = 10000
            }
        )


    local rekordy = {

        punkty = {
            dom = {},
            wyjazd = {}
        },

        minuty = {
            dom = {},
            wyjazd = {}
        },

        asysty = {
            dom = {},
            wyjazd = {}
        },

        zbiorki = {
            dom = {},
            wyjazd = {}
        },

        eval = {
            dom = {},
            wyjazd = {}
        },

        plusminus = {
            dom = {},
            wyjazd = {}
        }

    }


    if zawodnicy then

        for _, row in ipairs(zawodnicy) do

            local miejsce =
                miejsceMeczu(
                    row,
                    druzyna
                )


            if miejsce then

                local item = {

                    zawodnik =
                        row.zawodnik or "",

                    tekst =
                        nazwaMeczu(row),

                    wynik =
                        row.wynik or "",

                    punkty =
                        liczba(row.gol),

                    minuty =
                        liczba(row.minuty),

                    minuty_format =
                        row.minuty_format or "",

                    asysty =
                        liczba(row.asysta),

                    zbiorki =
                        liczba(row.zbiorka),

                    eval =
                        liczba(row.eval),

                    plusminus =
                        liczba(row.plusminus)

                }


                local rekordyLista = {

                    {
                        tabela = rekordy.punkty,
                        wartosc = item.punkty
                    },

                    {
                        tabela = rekordy.minuty,
                        wartosc = item.minuty
                    },

                    {
                        tabela = rekordy.asysty,
                        wartosc = item.asysty
                    },

                    {
                        tabela = rekordy.zbiorki,
                        wartosc = item.zbiorki
                    },

                    {
                        tabela = rekordy.eval,
                        wartosc = item.eval
                    },

                    {
                        tabela = rekordy.plusminus,
                        wartosc = item.plusminus
                    }

                }


                for _, r
                    in ipairs(rekordyLista) do

                    dodajRekord(
                        r.tabela,
                        miejsce,
                        r.wartosc,
                        {
                            zawodnik =
                                item.zawodnik,

                            wartosc =
                                r.wartosc,

                            tekst =
                                item.tekst,

                            wynik =
                                item.wynik,

                            punkty =
                                item.punkty,

                            minuty =
                                item.minuty,

                            minuty_format =
                                item.minuty_format,

                            asysty =
                                item.asysty,

                            zbiorki =
                                item.zbiorki,

                            eval =
                                item.eval,

                            plusminus =
                                item.plusminus
                        }
                    )

                end

            end

        end

    end


    -- =============================================
    -- SERIE KOSZYKÓWKI
    -- =============================================

    local serie = {

        wszystkie = {
            W = 0,
            P = 0
        },

        dom = {
            W = 0,
            P = 0
        },

        wyjazd = {
            W = 0,
            P = 0
        }

    }


    local aktualna = {

        wszystkie = {
            W = 0,
            P = 0
        },

        dom = {
            W = 0,
            P = 0
        },

        wyjazd = {
            W = 0,
            P = 0
        }

    }


    for _, row in ipairs(mecze) do

        local g1, g2 =
            wynikMeczu(row)


        local miejsce =
            miejsceMeczu(
                row,
                druzyna
            )


        if g1 and g2 and miejsce then

            local wygrana


            if miejsce == "dom" then
                wygrana = g1 > g2
            else
                wygrana = g2 > g1
            end


            local s =
                aktualna.wszystkie


            if wygrana then

                s.W = s.W + 1
                s.P = 0

                if s.W >
                    serie.wszystkie.W then

                    serie.wszystkie.W =
                        s.W

                end

            else

                s.P = s.P + 1
                s.W = 0

                if s.P >
                    serie.wszystkie.P then

                    serie.wszystkie.P =
                        s.P

                end

            end


            s =
                aktualna[miejsce]


            if wygrana then

                s.W = s.W + 1
                s.P = 0

                if s.W >
                    serie[miejsce].W then

                    serie[miejsce].W =
                        s.W

                end

            else

                s.P = s.P + 1
                s.W = 0

                if s.P >
                    serie[miejsce].P then

                    serie[miejsce].P =
                        s.P

                end

            end

        end

    end


    -- =============================================
    -- WYNIK
    -- =============================================

    local out = {}


    table.insert(
        out,
        "=== Rekordy sezonu ==="
    )


    table.insert(
        out,
        ""
    )


    table.insert(
        out,
        "==== Rekordy meczowe ===="
    )


    table.insert(
        out,
        ""
    )


    table.insert(
        out,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )


    table.insert(
        out,
        "! Rekord !! 🏠 Dom !! ✈️ Wyjazd"
    )


    table.insert(
        out,
        "|-"
    )


    table.insert(
        out,
        "! 🏆 Najwyższe zwycięstwo"
    )


    table.insert(
        out,
        "| " ..
        formatMecze(
            zwyciestwa.dom
        )
    )


    table.insert(
        out,
        "| " ..
        formatMecze(
            zwyciestwa.wyjazd
        )
    )


    table.insert(
        out,
        "|-"
    )


    table.insert(
        out,
        "! ❌ Najwyższa porażka"
    )


    table.insert(
        out,
        "| " ..
        formatMecze(
            porazki.dom
        )
    )


    table.insert(
        out,
        "| " ..
        formatMecze(
            porazki.wyjazd
        )
    )


    table.insert(
        out,
        "|}"
    )


    table.insert(
        out,
        ""
    )


    table.insert(
        out,
        "==== Rekordy indywidualne ===="
    )


    table.insert(
        out,
        ""
    )


    table.insert(
        out,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )


    table.insert(
        out,
        "! Rekord !! 🏠 Dom !! ✈️ Wyjazd"
    )


    local rekordyKosz = {

        {
            nazwa = "🏀 Najwięcej punktów",
            tabela = rekordy.punkty
        },

        {
            nazwa = "⏱️ Najwięcej minut",
            tabela = rekordy.minuty
        },

        {
            nazwa = "🎯 Najwięcej asyst",
            tabela = rekordy.asysty
        },

        {
            nazwa = "🏀 Najwięcej zbiórek",
            tabela = rekordy.zbiorki
        },

        {
            nazwa = "⭐ Najwyższy EVAL",
            tabela = rekordy.eval
        },

        {
            nazwa = "➕ Najwyższy +/-",
            tabela = rekordy.plusminus
        }

    }


    for _, r
        in ipairs(rekordyKosz) do

        table.insert(
            out,
            "|-"
        )


        table.insert(
            out,
            "! " .. r.nazwa
        )


        table.insert(
            out,
            "| " ..
            formatZawodnicy(
                r.tabela.dom
            )
        )


        table.insert(
            out,
            "| " ..
            formatZawodnicy(
                r.tabela.wyjazd
            )
        )

    end


    table.insert(
        out,
        "|}"
    )


    return table.concat(
        out,
        "\n"
    )

end


-- =========================================================
-- MAIN
-- =========================================================

function p.main(frame)

    local sezon =
        frame.args.sezon or ""


    local druzyna =
        frame.args.druzyna or ""


    local dyscyplina =
        frame.args.dyscyplina or ""


    sezon =
        mw.text.trim(
            sezon
        )


    druzyna =
        mw.text.trim(
            druzyna
        )


    dyscyplina =
        mw.text.trim(
            dyscyplina
        )


    if sezon == "" then

        return
            "'''Błąd:''' nie podano sezonu."

    end


    if druzyna == "" then

        return
            "'''Błąd:''' nie podano drużyny."

    end


    if dyscyplina == "" then

        return
            "'''Błąd:''' nie podano dyscypliny."

    end


    -- =====================================================
    -- KOSZYKÓWKA
    -- =====================================================

    if mw.ustring.lower(
        dyscyplina
    ) == "koszykówka" then

        return koszykowka(
            sezon,
            druzyna
        )

    end


    -- =====================================================
    -- PIŁKA NOŻNA
    -- =====================================================

    if mw.ustring.lower(
        dyscyplina
    ) == "piłka nożna" then

        return pilkaNozna(
            sezon,
            druzyna
        )

    end


    return
        "'''Błąd:''' nieobsługiwana dyscyplina: " ..
        dyscyplina

end


return p