Przejdź do zawartości

Moduł:H2H

Z Encyklopedia Poznanskiego Sportu

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

local p = {}

-- =========================================================
-- Module:H2H
--
-- Historia bezpośrednich spotkań dwóch drużyn.
--
-- Drużyny są rozpoznawane po:
--   Mecze.nazwa_statystyki1
--   Mecze.nazwa_statystyki2
--
-- Dzięki temu zmiana sponsora / nazwy drużyny nie rozbija H2H.
--
-- Funkcje:
--   1. bilans spotkań
--   2. suma punktów
--   3. wszystkie mecze
--   4. najlepsi strzelcy
--   5. trenerzy
--   6. rekordy meczowe
--   7. rekordy indywidualne
--   8. serie zwycięstw / porażek
--   9. kwartowe porównanie wyników
--
-- =========================================================


function p.main(frame)

    -- =====================================================
    -- PARAMETRY
    -- =====================================================

    local team1 =
        mw.text.trim(frame.args.team1 or "")

    local team2 =
        mw.text.trim(frame.args.team2 or "")


    if team1 == "" or team2 == "" then

        return "'''Błąd:''' należy podać obie drużyny."

    end


    -- =====================================================
    -- BEZPIECZEŃSTWO SQL
    -- =====================================================

    local function sql(value)

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

    end


    local t1 = sql(team1)
    local t2 = sql(team2)


    -- =====================================================
    -- WARUNEK H2H DLA TABELI Mecze
    --
    -- WAŻNE:
    -- tutaj używamy nazwa_statystyki.
    -- Dzięki temu zmiana nazwy sponsorskiej nie rozbija H2H.
    -- =====================================================

    local whereMecze =
        "(" ..
        "M.nazwa_statystyki1='" .. t1 ..
        "' AND M.nazwa_statystyki2='" .. t2 ..
        "')" ..
        " OR " ..
        "(" ..
        "M.nazwa_statystyki1='" .. t2 ..
        "' AND M.nazwa_statystyki2='" .. t1 ..
        "')"


    -- =====================================================
    -- FUNKCJE POMOCNICZE
    -- =====================================================

    local function number(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


    local function parseScore(value)

        if not value then
            return nil
        end

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

        if a and b then
            return tonumber(a), tonumber(b)
        end

        return nil, nil

    end


    local function matchScore(row)

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

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

        if g1 and g2 then
            return g1, g2
        end

        return parseScore(row.wynik)

    end


    local function location(row)

        local d1 =
            row.nazwa_statystyki1 or ""

        local d2 =
            row.nazwa_statystyki2 or ""


        if d1 == team1 then
            return "dom"
        end

        if d2 == team1 then
            return "wyjazd"
        end

        return nil

    end


    local function teamScore(row)

        local g1, g2 =
            matchScore(row)

        if not g1 or not g2 then
            return nil, nil
        end


        if location(row) == "dom" then
            return g1, g2
        end

        return g2, g1

    end


    local function result(row)

        local zdobyte, stracone =
            teamScore(row)

        if not zdobyte or not stracone then
            return nil
        end

        if zdobyte > stracone then
            return "W"
        end

        if zdobyte < stracone then
            return "P"
        end

        return "R"

    end


    local function matchName(row)

        local d1 =
            row.druzyna1 or ""

        local d2 =
            row.druzyna2 or ""

        local page =
            row.strona_meczu or ""


        local text =
            d1 ..
            " – " ..
            d2


        if page ~= "" then

            return
                "[[" ..
                page ..
                "|" ..
                text ..
                "]]"

        end

        return text

    end


    local function formatPlusMinus(value)

        value =
            number(value)

        if value > 0 then
            return "+" .. tostring(value)
        end

        return tostring(value)

    end


    -- =====================================================
    -- POBRANIE MECZÓW
    -- =====================================================

    local fieldsMecze =
        table.concat({

            "M.id=mecz",
            "M.data=data",
            "M.sezon=sezon",

            "M.druzyna1=druzyna1",
            "M.druzyna2=druzyna2",

            "M.nazwa_statystyki1=ns1",
            "M.nazwa_statystyki2=ns2",

            "M.gole1=gole1",
            "M.gole2=gole2",

            "M.wynik=wynik",

            "M.kwart1=kwarta1",
            "M.kwart2=kwarta2",
            "M.kwart3=kwarta3",
            "M.kwart4=kwarta4",

            "M.dogrywka1=dogrywka1",
            "M.dogrywka2=dogrywka2",

            "M.hala=hala",
            "M.widzowie=widzowie",
            "M.sedziowie=sedziowie",

            "M.strona_meczu=strona_meczu"

        }, ",")


    local mecze =
        mw.ext.cargo.query(
            "Mecze=M",
            fieldsMecze,
            {
                where = whereMecze,
                orderBy = "M.data ASC",
                limit = 20000
            }
        )


    if not mecze or #mecze == 0 then

        return
            "'''Brak wyników.'''"

    end


    -- =====================================================
    -- BILANS
    -- =====================================================

    local liczbaMeczow = 0

    local wygrane1 = 0
    local wygrane2 = 0

    local remisy = 0

    local punkty1 = 0
    local punkty2 = 0


    for _, row in ipairs(mecze) do

        local g1, g2 =
            matchScore(row)

        if g1 and g2 then

            liczbaMeczow =
                liczbaMeczow + 1


            local d1 =
                row.nazwa_statystyki1 or ""

            local d2 =
                row.nazwa_statystyki2 or ""


            if d1 == team1 then

                punkty1 =
                    punkty1 + g1

                punkty2 =
                    punkty2 + g2


                if g1 > g2 then
                    wygrane1 =
                        wygrane1 + 1

                elseif g2 > g1 then
                    wygrane2 =
                        wygrane2 + 1

                else
                    remisy =
                        remisy + 1
                end


            elseif d1 == team2 then

                punkty1 =
                    punkty1 + g2

                punkty2 =
                    punkty2 + g1


                if g2 > g1 then
                    wygrane1 =
                        wygrane1 + 1

                elseif g1 > g2 then
                    wygrane2 =
                        wygrane2 + 1

                else
                    remisy =
                        remisy + 1
                end

            end

        end

    end


    -- =====================================================
    -- WYNIK PODSUMOWANIA
    -- =====================================================

    local output = {}


    table.insert(
        output,
        "== Bilans bezpośrednich spotkań =="
    )

    table.insert(
        output,
        ""
    )


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

    table.insert(
        output,
        "! Drużyna !! Mecze !! Wygrane !! Remisy !! Porażki !! Punkty"
    )


    table.insert(
        output,
        "|-"
    )

    table.insert(
        output,
        "| '''" ..
        team1 ..
        "''' || " ..
        liczbaMeczow ..
        " || " ..
        wygrane1 ..
        " || " ..
        remisy ..
        " || " ..
        wygrane2 ..
        " || " ..
        punkty1
    )


    table.insert(
        output,
        "|-"
    )

    table.insert(
        output,
        "| '''" ..
        team2 ..
        "''' || " ..
        liczbaMeczow ..
        " || " ..
        wygrane2 ..
        " || " ..
        remisy ..
        " || " ..
        wygrane1 ..
        " || " ..
        punkty2
    )


    table.insert(
        output,
        "|}"
    )


    -- =====================================================
    -- HISTORIA SPOTKAŃ
    -- =====================================================

    table.insert(
        output,
        ""
    )

    table.insert(
        output,
        "== Historia spotkań =="
    )

    table.insert(
        output,
        ""
    )


    table.insert(
        output,
        '{| class="wikitable sortable" style="width:100%;"'
    )

    table.insert(
        output,
        "! Lp. !! Data !! Sezon !! Gospodarz !! Wynik !! Gość !! Hala"
    )


    local lp = 0


    for i = #mecze, 1, -1 do

        local row =
            mecze[i]

        local g1, g2 =
            matchScore(row)

        if g1 and g2 then

            lp =
                lp + 1


            table.insert(
                output,
                "|-"
            )

            table.insert(
                output,
                "| " ..
                lp ..
                " || " ..
                (row.data or "") ..
                " || " ..
                (row.sezon or "") ..
                " || " ..
                (row.druzyna1 or "") ..
                " || '''" ..
                g1 ..
                ":" ..
                g2 ..
                "''' || " ..
                (row.druzyna2 or "") ..
                " || " ..
                (row.hala or "")
            )

        end

    end


    table.insert(
        output,
        "|}"
    )


    -- =====================================================
    -- NAJLEPSI STRZELCY
    -- =====================================================

    local fieldsStrzelcy =
        table.concat({

            "U.zawodnik=zawodnik",
            "U.druzyna=druzyna",
            "SUM(U.gol)=punkty"

        }, ",")


    local strzelcy1 =
        mw.ext.cargo.query(
            "UdzialZawodnika=U,Mecze=M",
            fieldsStrzelcy,
            {
                join =
                    "U.mecz=M.id",

                where =
                    "(" ..
                    whereMecze ..
                    ")" ..
                    " AND " ..
                    "(" ..
                    "(M.nazwa_statystyki1='" ..
                    t1 ..
                    "' AND U.druzyna=M.druzyna1)" ..
                    " OR " ..
                    "(M.nazwa_statystyki2='" ..
                    t1 ..
                    "' AND U.druzyna=M.druzyna2)" ..
                    ")",

                groupBy =
                    "U.zawodnik,U.druzyna",

                orderBy =
                    "punkty DESC",

                limit = 1000
            }
        )


    local strzelcy2 =
        mw.ext.cargo.query(
            "UdzialZawodnika=U,Mecze=M",
            fieldsStrzelcy,
            {
                join =
                    "U.mecz=M.id",

                where =
                    "(" ..
                    whereMecze ..
                    ")" ..
                    " AND " ..
                    "(" ..
                    "(M.nazwa_statystyki1='" ..
                    t2 ..
                    "' AND U.druzyna=M.druzyna1)" ..
                    " OR " ..
                    "(M.nazwa_statystyki2='" ..
                    t2 ..
                    "' AND U.druzyna=M.druzyna2)" ..
                    ")",

                groupBy =
                    "U.zawodnik,U.druzyna",

                orderBy =
                    "punkty DESC",

                limit = 1000
            }
        )


    table.insert(
        output,
        ""
    )

    table.insert(
        output,
        "== Najlepsi strzelcy rywalizacji =="
    )

    table.insert(
        output,
        ""
    )


    table.insert(
        output,
        '{| class="wikitable" style="width:100%;"'
    )

    table.insert(
        output,
        "! " ..
        team1 ..
        " !! Punkty !! " ..
        team2 ..
        " !! Punkty"
    )


    local maxStrzelcy =
        math.max(
            strzelcy1 and #strzelcy1 or 0,
            strzelcy2 and #strzelcy2 or 0
        )


    for i = 1, maxStrzelcy do

        local s1 =
            strzelcy1 and strzelcy1[i]

        local s2 =
            strzelcy2 and strzelcy2[i]


        table.insert(
            output,
            "|-"
        )


        table.insert(
            output,
            "| " ..
            (
                s1
                and
                "[[" ..
                s1.zawodnik ..
                "]]"
                or
                ""
            ) ..
            " || " ..
            (
                s1
                and
                tostring(
                    number(s1.punkty)
                )
                or
                ""
            ) ..
            " || " ..
            (
                s2
                and
                "[[" ..
                s2.zawodnik ..
                "]]"
                or
                ""
            ) ..
            " || " ..
            (
                s2
                and
                tostring(
                    number(s2.punkty)
                )
                or
                ""
            )
        )

    end


    table.insert(
        output,
        "|}"
    )


    -- =====================================================
    -- TRENERZY
    -- =====================================================

    local fieldsTrenerzy =
        table.concat({

            "S.osoba=osoba",
            "S.druzyna=druzyna",
            "S.rola=rola"

        }, ",")


    local trenerzy =
        mw.ext.cargo.query(
            "SztabMeczu=S,Mecze=M",
            fieldsTrenerzy,
            {
                join =
                    "S.mecz=M.id",

                where =
                    "(" ..
                    whereMecze ..
                    ")" ..
                    " AND " ..
                    "S.rola IN ('Trener','II trener')",

                groupBy =
                    "S.osoba,S.druzyna,S.rola",

                orderBy =
                    "S.osoba ASC",

                limit = 5000
            }
        )


    table.insert(
        output,
        ""
    )

    table.insert(
        output,
        "== Trenerzy w historii rywalizacji =="
    )

    table.insert(
        output,
        ""
    )


    table.insert(
        output,
        '{| class="wikitable sortable" style="width:100%;"'
    )

    table.insert(
        output,
        "! Trener !! Drużyna !! Rola"
    )


    if trenerzy then

        for _, row in ipairs(trenerzy) do

            table.insert(
                output,
                "|-"
            )

            table.insert(
                output,
                "| [[" ..
                (row.osoba or "") ..
                "]] || " ..
                (row.druzyna or "") ..
                " || " ..
                (row.rola or "")
            )

        end

    end


    table.insert(
        output,
        "|}"
    )


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

    local rekordMecz =
        {
            zwyciestwo =
            {
                dom = {},
                wyjazd = {}
            },

            porazka =
            {
                dom = {},
                wyjazd = {}
            }
        }


    local function addMatchRecord(
        list,
        item,
        value,
        field
    )

        if #list == 0 then

            item[field] =
                value

            table.insert(
                list,
                item
            )

            return

        end


        local current =
            list[1][field]


        if value > current then

            item[field] =
                value

            list[1] =
                item

        elseif value == current then

            item[field] =
                value

            table.insert(
                list,
                item
            )

        end

    end


    for _, row in ipairs(mecze) do

        local zdobyte, stracone =
            teamScore(row)

        local miejsce =
            location(row)


        if zdobyte and stracone and miejsce then

            local roznica =
                zdobyte - stracone


            local item =
            {
                tekst =
                    matchName(row),

                wynik =
                    tostring(
                        row.gole1 or zdobyte
                    ) ..
                    ":" ..
                    tostring(
                        row.gole2 or stracone
                    ),

                roznica =
                    roznica
            }


            if roznica > 0 then

                addMatchRecord(
                    rekordMecz.zwyciestwo[miejsce],
                    item,
                    roznica,
                    "wartosc"
                )

            elseif roznica < 0 then

                addMatchRecord(
                    rekordMecz.porazka[miejsce],
                    item,
                    math.abs(roznica),
                    "wartosc"
                )

            end

        end

    end


    local function formatMatchRecord(list)

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


        local out = {}


        for _, item in ipairs(list) do

            table.insert(
                out,
                item.tekst ..
                " (" ..
                item.wynik ..
                ", +" ..
                tostring(
                    item.wartosc
                ) ..
                ")"
            )

        end


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

    end


    table.insert(
        output,
        ""
    )

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

    table.insert(
        output,
        ""
    )


    table.insert(
        output,
        '{| class="wikitable" style="width:100%;"'
    )

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


    table.insert(
        output,
        "|-"
    )

    table.insert(
        output,
        "! 🏆 Najwyższe zwycięstwo || " ..
        formatMatchRecord(
            rekordMecz.zwyciestwo.dom
        ) ..
        " || " ..
        formatMatchRecord(
            rekordMecz.zwyciestwo.wyjazd
        )
    )


    table.insert(
        output,
        "|-"
    )

    table.insert(
        output,
        "! ❌ Najwyższa porażka || " ..
        formatMatchRecord(
            rekordMecz.porazka.dom
        ) ..
        " || " ..
        formatMatchRecord(
            rekordMecz.porazka.wyjazd
        )
    )


    table.insert(
        output,
        "|}"
    )


    -- =====================================================
    -- REKORDY INDYWIDUALNE
    -- =====================================================

    local fieldsZaw =
        table.concat({

            "U.zawodnik=zawodnik",
            "U.druzyna=druzyna_zawodnika",

            "U.gol=gol",
            "U.minuty=minuty",
            "U.minuty_format=minuty_format",

            "U.asysta=asysta",
            "U.zbiorka=zbiorka",

            "U.eval=eval",
            "U.plusminus=plusminus",

            "M.id=mecz",
            "M.data=data",

            "M.druzyna1=druzyna1",
            "M.druzyna2=druzyna2",

            "M.gole1=gole1",
            "M.gole2=gole2",

            "M.wynik=wynik",

            "M.nazwa_statystyki1=ns1",
            "M.nazwa_statystyki2=ns2",

            "M.strona_meczu=strona_meczu"

        }, ",")


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

                where =
                    "(" ..
                    whereMecze ..
                    ")" ..
                    " AND U.minuty > 0",

                orderBy =
                    "M.data ASC",

                limit = 20000
            }
        )


    local rekordy =
    {
        punkty =
        {
            dom = {},
            wyjazd = {}
        },

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

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

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

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

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


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

        local list =
            tabela[miejsce]


        if #list == 0 then

            item.wartosc =
                wartosc

            table.insert(
                list,
                item
            )

            return

        end


        local current =
            list[1].wartosc


        if wartosc > current then

            item.wartosc =
                wartosc

            tabela[miejsce] =
            {
                item
            }

        elseif wartosc == current then

            item.wartosc =
                wartosc

            table.insert(
                list,
                item
            )

        end

    end


    if zawodnicy then

        for _, row in ipairs(zawodnicy) do

            local miejsce =
                location(row)


            if miejsce then

                local item =
                {
                    zawodnik =
                        row.zawodnik or "",

                    mecz =
                        row.mecz or "",

                    tekst =
                        matchName(row),

                    wynik =
                        row.wynik or "",

                    punkty =
                        number(row.gol),

                    minuty =
                        number(row.minuty),

                    minuty_format =
                        row.minuty_format or "",

                    asysty =
                        number(row.asysta),

                    zbiorki =
                        number(row.zbiorka),

                    eval =
                        number(row.eval),

                    plusminus =
                        number(row.plusminus)
                }


                addPlayerRecord(
                    rekordy.punkty,
                    miejsce,
                    item.punkty,
                    item
                )


                addPlayerRecord(
                    rekordy.minuty,
                    miejsce,
                    item.minuty,
                    item
                )


                addPlayerRecord(
                    rekordy.asysty,
                    miejsce,
                    item.asysty,
                    item
                )


                addPlayerRecord(
                    rekordy.zbiorki,
                    miejsce,
                    item.zbiorki,
                    item
                )


                addPlayerRecord(
                    rekordy.eval,
                    miejsce,
                    item.eval,
                    item
                )


                addPlayerRecord(
                    rekordy.plusminus,
                    miejsce,
                    item.plusminus,
                    item
                )

            end

        end

    end


    local function formatPlayerRecord(
        list,
        typ
    )

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


        local out = {}


        for _, item in ipairs(list) do

            local value = ""


            if typ == "punkty" then

                value =
                    tostring(item.punkty) ..
                    " pkt"

            elseif typ == "minuty" then

                value =
                    item.minuty_format

                if value == "" then

                    value =
                        tostring(item.minuty)

                end

                value =
                    value ..
                    " min"

            elseif typ == "asysty" then

                value =
                    tostring(item.asysty) ..
                    " as."

            elseif typ == "zbiorki" then

                value =
                    tostring(item.zbiorki) ..
                    " zb."

            elseif typ == "eval" then

                value =
                    tostring(item.eval) ..
                    " EVAL"

            elseif typ == "plusminus" then

                value =
                    formatPlusMinus(
                        item.plusminus
                    ) ..
                    " +/-"

            end


            table.insert(
                out,
                "[[" ..
                item.zawodnik ..
                "]] — " ..
                value ..
                "<br>" ..
                item.tekst ..
                " (" ..
                item.wynik ..
                ")"
            )

        end


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

    end


    table.insert(
        output,
        ""
    )

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

    table.insert(
        output,
        ""
    )


    table.insert(
        output,
        '{| class="wikitable" style="width:100%;"'
    )

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


    local rekordyLista =
    {
        {
            nazwa =
                "🏀 Najwięcej punktów",

            tabela =
                rekordy.punkty,

            typ =
                "punkty"
        },

        {
            nazwa =
                "⏱️ Najwięcej minut",

            tabela =
                rekordy.minuty,

            typ =
                "minuty"
        },

        {
            nazwa =
                "🎯 Najwięcej asyst",

            tabela =
                rekordy.asysty,

            typ =
                "asysty"
        },

        {
            nazwa =
                "🏀 Najwięcej zbiórek",

            tabela =
                rekordy.zbiorki,

            typ =
                "zbiorki"
        },

        {
            nazwa =
                "⭐ Najwyższy EVAL",

            tabela =
                rekordy.eval,

            typ =
                "eval"
        },

        {
            nazwa =
                "➕ Najwyższy +/-",

            tabela =
                rekordy.plusminus,

            typ =
                "plusminus"
        }
    }


    for _, rekord in ipairs(rekordyLista) do

        table.insert(
            output,
            "|-"
        )

        table.insert(
            output,
            "! " ..
            rekord.nazwa ..
            " || " ..
            formatPlayerRecord(
                rekord.tabela.dom,
                rekord.typ
            ) ..
            " || " ..
            formatPlayerRecord(
                rekord.tabela.wyjazd,
                rekord.typ
            )
        )

    end


    table.insert(
        output,
        "|}"
    )


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

    local serie =
    {
        wszystkie =
        {
            W = 0,
            P = 0,
            maxW = 0,
            maxP = 0
        },

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

        wyjazd =
        {
            W = 0,
            P = 0,
            maxW = 0,
            maxP = 0
        }
    }


    local function updateSerie(
        obj,
        wynik
    )

        if wynik == "W" then

            obj.W =
                obj.W + 1

            obj.P =
                0

            if obj.W > obj.maxW then

                obj.maxW =
                    obj.W

            end


        elseif wynik == "P" then

            obj.P =
                obj.P + 1

            obj.W =
                0

            if obj.P > obj.maxP then

                obj.maxP =
                    obj.P

            end

        else

            obj.W =
                0

            obj.P =
                0

        end

    end


    for _, row in ipairs(mecze) do

        local wynik =
            result(row)

        local miejsce =
            location(row)


        if wynik then

            updateSerie(
                serie.wszystkie,
                wynik
            )


            if miejsce == "dom" then

                updateSerie(
                    serie.dom,
                    wynik
                )

            elseif miejsce == "wyjazd" then

                updateSerie(
                    serie.wyjazd,
                    wynik
                )

            end

        end

    end


    table.insert(
        output,
        ""
    )

    table.insert(
        output,
        "== Serie zwycięstw i porażek =="
    )

    table.insert(
        output,
        ""
    )


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

    table.insert(
        output,
        "! Seria !! Wszystkie mecze !! 🏠 Dom !! ✈️ Wyjazd"
    )


    table.insert(
        output,
        "|-"
    )

    table.insert(
        output,
        "! 🔥 Najdłuższa seria zwycięstw || " ..
        serie.wszystkie.maxW ..
        " || " ..
        serie.dom.maxW ..
        " || " ..
        serie.wyjazd.maxW
    )


    table.insert(
        output,
        "|-"
    )

    table.insert(
        output,
        "! 📉 Najdłuższa seria porażek || " ..
        serie.wszystkie.maxP ..
        " || " ..
        serie.dom.maxP ..
        " || " ..
        serie.wyjazd.maxP
    )


    table.insert(
        output,
        "|}"
    )


    -- =====================================================
    -- KWARTY A KOŃCOWY WYNIK
    --
    -- Nie korzystamy z dogrywka3.
    -- Dzięki temu mecz z trzema dogrywkami nie powoduje
    -- błędu "No field named dogrywka3".
    --
    -- Analizujemy wyłącznie kwarty 1-4.
    -- =====================================================

    local kwartowe =
    {
        [1] =
        {
            wygrana = 0,
            porazka = 0,
            remis = 0,
            wszystkie = 0
        },

        [2] =
        {
            wygrana = 0,
            porazka = 0,
            remis = 0,
            wszystkie = 0
        },

        [3] =
        {
            wygrana = 0,
            porazka = 0,
            remis = 0,
            wszystkie = 0
        },

        [4] =
        {
            wygrana = 0,
            porazka = 0,
            remis = 0,
            wszystkie = 0
        }
    }


    local function quarterScore(value)

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

        return parseScore(value)

    end


    for _, row in ipairs(mecze) do

        local final =
            result(row)


        if final == "W" or final == "P" then

            for q = 1, 4 do

                local value =
                    row["kwarta" .. q]


                local a, b =
                    quarterScore(value)


                if a and b then

                    local teamPoints
                    local opponentPoints


                    if location(row) == "dom" then

                        teamPoints = a
                        opponentPoints = b

                    elseif location(row) == "wyjazd" then

                        teamPoints = b
                        opponentPoints = a

                    end


                    if teamPoints and opponentPoints then

                        kwartowe[q].wszystkie =
                            kwartowe[q].wszystkie + 1


                        if final == "W" then

                            if teamPoints > opponentPoints then

                                kwartowe[q].wygrana =
                                    kwartowe[q].wygrana + 1

                            elseif teamPoints < opponentPoints then

                                kwartowe[q].porazka =
                                    kwartowe[q].porazka + 1

                            else

                                kwartowe[q].remis =
                                    kwartowe[q].remis + 1

                            end


                        elseif final == "P" then

                            if teamPoints < opponentPoints then

                                kwartowe[q].wygrana =
                                    kwartowe[q].wygrana + 1

                            elseif teamPoints > opponentPoints then

                                kwartowe[q].porazka =
                                    kwartowe[q].porazka + 1

                            else

                                kwartowe[q].remis =
                                    kwartowe[q].remis + 1

                            end

                        end

                    end

                end

            end

        end

    end


    table.insert(
        output,
        ""
    )

    table.insert(
        output,
        "== Wynik kwarty a końcowy wynik meczu =="
    )

    table.insert(
        output,
        ""
    )


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

    table.insert(
        output,
        "! Kwarta !! Mecz zakończony wygraną !! Mecz zakończony porażką !! Remis w kwarcie !! Wszystkie analizowane mecze"
    )


    for q = 1, 4 do

        local data =
            kwartowe[q]


        table.insert(
            output,
            "|-"
        )

        table.insert(
            output,
            "! " ..
            q ..
            ". kwarta || " ..
            data.wygrana ..
            " || " ..
            data.porazka ..
            " || " ..
            data.remis ..
            " || " ..
            data.wszystkie
        )

    end


    table.insert(
        output,
        "|}"
    )


    -- =====================================================
    -- KONIEC
    -- =====================================================

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

end


return p