Mô đun:Xếp hạng số lần sửa đổi của thành viên

Tài liệu mô đun[xem] [sửa] [lịch sử] [làm mới]

Cách bản mẫu này được cập nhật sửa

Dữ liệu cập nhật được trích xuất những danh sách tự động sau đây:

Trong trường hợp bạn không có tên trong danh sách, định dạng sysop, patroller sẽ trả về lỗi. Với user, sẽ trả về các số liệu -1.

Cách sử dụng sửa

Hãy thử bản mẫu tại trang thử bản mẫu với tên người dùng của bạn để có trải nghiệm tốt nhất.

Thành viên đóng góp sửa

|kiểu=user

Hiển thị hộp thông tin người dùng với vị trí trên danh sách thành viên sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên}}

Sẽ cho ra kết quả:

1Thành viên xếp hạng 1 với 250.652 sửa đổi trên Danh sách thành viên Wikipedia theo số lần sửa trang

Hiển thị số sửa đổi (văn bản thô) sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|c}}

Sẽ cho ra kết quả là tổng số sửa đổi của bạn ở dạng văn bản thô, ví dụ: -1

Có thể sử dụng kết hợp với bản mẫu {{Tổng số lần sửa đổi}}: {{Tổng số lần sửa đổi|{{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|c}}}} hoặc tùy biến theo sở thích.

250.652+Thành viên này đã có hơn 250.652 sửa đổi trên Wikipedia.

Hiển thị vị trí (văn bản thô) sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|n}}

Sẽ cho ra kết quả là vị trí của bạn trên danh sách thành viên ở dạng văn bản thô, ví dụ: 1


Kiểm tra sửa đổi cuối có phải trong vòng 1 giờ đồng hồ trở lại (văn bản thô) sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|s}}

Sẽ cho ra kết quả kiểm tra xem lần thay đổi cuối của người dùng có phải trong vòng 1 giờ đồng hồ trở lại không, ví dụ: false

Có thể viết một bản mẫu đơn giản như sau để hiển thị trạng thái Online/Offline: {{#ifeq:{{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|s}}|true|<span style="color:green;">Online (sửa đổi cuối trong vòng 1 giờ trước)</span>|<span style="color:red;">Offline (sửa đổi cuối vào hơn 1 giờ trước)</span>}}

Offline (sửa đổi cuối vào hơn 1 giờ trước)

Sử dụng userbox-2 sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|new=1}}

Chuyển qua sử dụng bản mẫu {{userbox-2}} với một cột bên phải thể hiện biến động vị trí của bạn trên danh sách thành viên so với lần cập nhật tự động cuối, ví dụ:

1Thành viên xếp hạng 1 với 250.652 sửa đổi trên Danh sách thành viên Wikipedia theo số lần sửa trang0

Tuần tra viên sửa

|kiểu=patroller

Hiển thị bảng thống kê tác vụ sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|kiểu=patroller}}

Trả về bảng thống kê tác vụ của tuần tra viên, ví dụ:

Thống kê tuần tra
Tác vụ Thực hiện
Lùi sửa 6881
Tuần tra 2609


Hiển thị bảng thống kê tác vụ với chi tiết tổng và tên thành viên sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|kiểu=patroller|show_name=1|show_title=1}}

Trả về bảng thống kê tác vụ của tuần tra viên cùng tên với tham số show_name và hiện thêm 1 dòng tính tổng với tham số show_total, ví dụ:

Thống kê tuần tra của Biheo2812
Tác vụ Thực hiện
Lùi sửa 6881
Tuần tra 2609
Tổng 9490


Lấy văn bản thô của bất kỳ thông số nào sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|kiểu=patroller|<thông_số>=1}}

Hiện <thông_số> hợp lệ dành cho tuần tra viên là: rollback, patrol, last, total

Trong đó:

<thông_số> mô tả
rollback Số tác vụ lùi sửa
patrol Số tác vụ tuần tra
last Thời gian thực hiện tác vụ cuối, có thể tùy biến định dạng thời gian bằng tham số timeFormat với các tùy chọn như dmy, mdy, ymd
total Tổng số tác vụ tuần tra đã thực hiện

Ví dụ thông số là patrol: 2609



Thành viên có công cụ bảo quản sửa

|kiểu=sysop

Hiển thị bảng thống kê tác vụ sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|kiểu=sysop}}

Trả về bảng thống kê tác vụ của thành viên giữ công cụ bảo quản viên, ví dụ:

Thống kê tác vụ bảo quản
Tác vụ Thực hiện
Xóa trang 6502
Phục hồi trang 471
Ẩn lịch sử 2844
Khóa trang 2412
Mở khóa trang 22
Sửa đổi khóa trang 1436
Cấm thành viên 0
Bỏ cấm thành viên 0
Cấu hình lệnh cấm thành viên 0
Đổi tên thành viên 0
Đổi quyền thành viên 0


Hiển thị bảng thống kê tác vụ với chi tiết tổng và tên thành viên sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|kiểu=sysop|show_name=1|show_title=1}}

Trả về bảng thống kê tác vụ của thành viên giữ công cụ bảo quản viên cùng tên với tham số show_name và hiện thêm 1 dòng tính tổng với tham số show_total, ví dụ:

Thống kê tác vụ bảo quản của NguoiDungKhongDinhDanh
Tác vụ Thực hiện
Xóa trang 6502
Phục hồi trang 471
Ẩn lịch sử 2844
Khóa trang 2412
Mở khóa trang 22
Sửa đổi khóa trang 1436
Cấm thành viên 0
Bỏ cấm thành viên 0
Cấu hình lệnh cấm thành viên 0
Đổi tên thành viên 0
Đổi quyền thành viên 0
Tổng 13687


Lấy văn bản thô của bất kỳ thông số nào sửa

Cú pháp: {{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|kiểu=sysop|<thông_số>=1}}

Hiện <thông_số> hợp lệ dành cho thành viên giữ công cụ bảo quản là: delete, restore, revdel, protect, unprotect, modifyprotect, block, unblock, reblock, rename, rights, last, total

Trong đó:

<thông_số> mô tả
delete Số tác vụ xóa trang
restore Số tác vụ khôi phục trang
revdel Số tác vụ ẩn lịch sử
protect Số tác vụ khóa trang
unprotect Số tác vụ mở khóa trang
modifyprotect Số tác vụ đổi khóa trang
block Số tác vụ chặn
unblock Số tác vụ mở chặn
reblock Số tác vụ cấu hình chặn
rename Số tác vụ đổi tên
rights Số tác vụ đổi quyền
last Thời gian thực hiện tác vụ cuối, có thể tùy biến định dạng thời gian bằng tham số timeFormat với các tùy chọn như dmy, mdy, ymd
total Tổng số tác vụ tuần tra đã thực hiện

Ví dụ <thông_số> là delete: 6502


Lưu ý sửa

Trường hợp tên thành viên không tồn tại hoặc không có trong danh sách thành viên, bản mẫu sẽ trả về -1 cho số, rỗng cho chuỗi và false cho giá trị boolean như các ví dụ trên.

TemplateData sửa

Đây là tài liệu Dữ liệu bản mẫu cho bản mẫu này được sử dụng bởi Trình soạn thảo trực quan và các công cụ khác; xem báo cáo sử dụng tham số hàng tháng cho bản mẫu này.

Dữ liệu bản mẫu cho Xếp hạng số lần sửa đổi của thành viên

Trích xuất dữ liệu từ danh sách thành viên hoạt động trong vòng 2 tháng gần nhất có trên 300 sửa đổi hoặc thống kê dữ liệu tuần tra viên, thành viên có công cụ bảo quản.

Tham số bản mẫu[Quản lý Dữ liệu bản mẫu]

Nên dùng bản mẫu này với các tham số đặt thành khối.

Tham sốMiêu tảKiểuTrạng thái
Tên tài khoản1 tên thành viên

Tên thành viên trên danh sách

Ví dụ
{{Xếp hạng số lần sửa đổi của thành viên|tên_tài_khoản}}
Chuỗi dàibắt buộc
Định dạng hiển thị2 định dạng

Định dạng hiển thị, thông tin hiển thị

Giá trị đề nghị
t n c s
Mặc định
t
Ví dụ
{{Xếp hạng số lần sửa đổi của thành viên|tên_tài_khoản|n}}
Chuỗi ngắnkhuyên dùng
Kiểu thông tin3 kiểu

Kiểu thông tin cần lấy

Giá trị đề nghị
user patroller sysop
Mặc định
user
Chuỗi ngắntùy chọn
Bản mẫu userbox-2new

Chuyển qua sử dụng bản mẫu userbox-2 với một cột bên phải thể hiện biến động vị trí của bạn trên danh sách thành viên so với lần cập nhật tự động cuối

Giá trị đề nghị
1
Ví dụ
{{Xếp hạng số lần sửa đổi của thành viên|Tên thành viên|new=1}}
Sốtùy chọn
Định dạng ngày thángtimeFormat

Tùy biến định dạng ngày tháng trả về

Giá trị đề nghị
dmy mdy ymd
Mặc định
dmy
Chuỗi ngắntùy chọn
Văn bản thô của thời gian sửa cuốilast

Lấy văn bản thô của thời gian sửa đổi cuối

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Hiển thị tên của người dùng trong bản thống kêshow_name

Hiển thị tên của người dùng trong bản thống kê hay không

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Hiển thị thêm dòng tổng trong bản thống kêshow_total

Hiển thị thêm dòng tổng trong bản thống kê

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của số tác vụ lùi sửarollback

Lấy văn bản thô của số tác vụ lùi sửa

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của số tác vụ tuần trapatrol

Lấy văn bản thô của số tác vụ đánh dấu tuần tra

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tổng số tác vụtotal

Lấy văn bản thô của tổng số tác vụ

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ xóa trangdelete

Lấy văn bản thô của tác vụ xóa trang

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ khôi phục trangrestore

Lấy văn bản thô của tác vụ khôi phục trang

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ ẩn lịch sử trangrevdel

Lấy văn bản thô của tác vụ ẩn lịch sử trang

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ khóa trangprotect

Lấy văn bản thô của tác vụ bảo vệ trang

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ mở khóa trangunprotect

Lấy văn bản thô của tác vụ mở khóa trang

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ thay đổi khóa trangmodifyprotect

Lấy văn bản thô của tác vụ thay đổi khóa trang

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ chặn thành viênblock

Lấy văn bản thô của tác vụ chặn thành viên

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ mở chặn thành viênunblock

Lấy văn bản thô của tác vụ mở chặn thành viên

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ cấu hình chặn thành viênreblock

Lấy văn bản thô của tác vụ cấu hình chặn thành viên

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ thay đổi tên thành viênrename

Lấy văn bản thô của tác vụ thay đổi tên thành viên

Giá trị đề nghị
1
Chuỗi ngắntùy chọn
Lấy văn bản thô của tác vụ thay đổi quyền thành viênrights

Lấy văn bản thô của tác vụ thay đổi quyền thành viên

Giá trị đề nghị
1
Chuỗi ngắntùy chọn

local getArgs = require('Mô đun:Arguments').getArgs
local userBox = require('Mô đun:Userbox')

local p = {}
_p_prf = "Thành viên:Lê Song Vĩ/"
_c_tp = {
    ["user"] = "us",
    ["patroller"] = "pt",
    ["sysop"] = "ss"
}
t_dir = {
    [_c_tp["user"]] = _p_prf .. "Danh sách thành viên Wikipedia theo số lần sửa trang",
    [_c_tp["patroller"]] = _p_prf .. "Danh sách thành viên tuần tra thay đổi gần đây theo số tác vụ",
    [_c_tp["sysop"]] = _p_prf .. "Danh sách thành viên có công cụ bảo quản theo số tác vụ"
}
hb_dir = {
    [_c_tp["user"]] = "#Danh sách thành viên",
    [_c_tp["patroller"]] = "",
    [_c_tp["sysop"]] = ""
}
_p_dir = {
    [_c_tp["user"]] = {
        ["user_r_p_1"] = "|%s*(%d+)%s*||%s*%[%[Thành viên:([^|]*)|[^|]*||%s*%[%[[^|]*|(%d+[%.%d]+)[^%]]*%]%][^S]*Sửa đổi cuối:%s*([^,]*),[^{]*{{([^}]*)}}%s(%d+),%s*([^s]*)sửa đổi mới",
    },
    [_c_tp["patroller"]] = {
        ["ptr_r_p_1"] = "||%s*(%d+)%s*||%s*%[%[Thành viên:([^|]*)|[^|]*||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s*||%s*(%d+[%.%d]*)%s*",
        ["ptr_r_p_2"] = "||%s*(%d+)%s*||%s*%[%[Thành viên:([^|]*)|[^|]*||%s*((%d+)-(%d+)-(%d+)%s*(%d+):(%d+):(%d+))",
    },
    [_c_tp["sysop"]] = {
        ["ss_r_p_1"] = "||%s*(%d+)%s*||%s*%[%[Thành viên:([^|]*)|[^|]*||%s*(%d+[%.%d]+)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s||%s*(%d+[%.%d]*)%s",
        ["ptr_r_p_2"] = "||%s*(%d+)%s*||%s*%[%[Thành viên:([^|]*)|[^|]*||%s*((%d+)-(%d+)-(%d+)%s*(%d+):(%d+):(%d+))",
    },
    ["f_num_1"] = {
        ["format"] = "^(-?)(%d+)(%.?%d*)$",
        ["g_3"] = "(%d%d%d)"
    }
}
_c_dir = {
    ">=100#808080",
    ">89&&<100#DDDDDD",
    ">79&&<90#FFFFFF",
    ">69&&<80#FFFF99",
    ">59&&<70#FFFF00",
    ">49&&<60#FF6600",
    ">39&&<50#FF0000",
    ">29&&<40#3366FF",
    ">19&&<30#333399",
    ">9&&<20#CC99FF",
    ">3&&<10#16A83D",
    "=3#CD7F32",
    "=2#C0C0C0",
    "=1#D4AF37",
    "<=0#808080",
}
_n_c_dir = {
    ">=735#808080",
    "<735&&>=510#1b00a1:_fn_g_r_1",
    "<510&&>=255#008fa1:_fn_g_r_1",
    "<255&&>=1#a1d100:_fn_g_r_1",
    "<=0#808080",
}
rankColorDir = {
    "<0#808080",
    "=0#c10202",
    ">0&&<=5#34CB00",
    ">5#EE0000",
}
_c_c_dir = {
    "<0#808080",
    "=0#c10202",
    ">0&&<=255#34CB00:_fn_g_r_1",
}
_t_dir = {
    ["n_us"] = "Thành viên này không (hoặc chưa) có tên trong [[%s|Danh sách thành viên Wikipedia theo số lần sửa trang]]",
    ["us_"] = "Thành viên xếp hạng '''%s''' với '''%s''' sửa đổi trên [[%s|Danh sách thành viên Wikipedia theo số lần sửa trang]]"
}

function formatTimeByFormat (time, format)
    local _format = format or "dmy"
    local _time = time or os.date("%d-%m-%Y")
    local _d, _m, _y = _time:match("(%d+)%-(%d+)%-(%d+)")
    local _d_f, _m_f, _y_f = _d, _m, _y

    if _format == "dmy" then
        _d_f, _m_f, _y_f = _d, _m, _y
    elseif _format == "mdy" then
        _d_f, _m_f, _y_f = _m, _d, _y
    elseif _format == "ymd" then
        _d_f, _m_f, _y_f = _y, _m, _d
    end

    return _d_f .. "-" .. _m_f .. "-" .. _y_f
end

function hexToNumber (h)
    return tonumber(h, 16)
end

function numberToHex (number)
    if number == 0 then
        return '0'
    end
    local neg = false
    if number < 0 then
        neg = true
        number = number * -1
    end
    local hexstr = "0123456789ABCDEF"
    local result = ""
    while number > 0 do
        local n = math.mod(number, 16)
        result = string.sub(hexstr, n + 1, n + 1) .. result
        number = math.floor(number / 16)
    end
    if neg then
        result = '-' .. result
    end

    return result
end

function _fn_g_r_1 (cl, _a, _m)
    return cl:gsub("..", function (color)
        return ('0' .. numberToHex(math.min(255, math.max(0, hexToNumber(color) + _m - _a)))):sub(-2)
    end)
end

function formatNumber(n)
	if not n then
		return ''
	end
	local _, _, m_ns, i, _ = tostring(n):find(_p_dir["f_num_1"]["format"])
	i = i:reverse():gsub(_p_dir["f_num_1"]["g_3"], "%1.")
	i = i:reverse():gsub("^%.", "")
	i = m_ns .. i
	return i
end

function numberFormat (n)
    if not n then
        return ''
    end
    n = string.gsub(n, "%.", "")
    n = string.gsub(n, ",", "")
    return tonumber(n)
end

function operatorMapping (op, n, cl)
    local dcs = nil

    if op == "<" then
        dcs = function (x) return x < n end
    elseif op == ">" then
        dcs = function (x) return x > n end
    elseif op == "=" then
        dcs = function (x) return x == n end
    elseif op == "<=" then
        dcs = function (x) return x <= n end
    elseif op == ">=" then
        dcs = function (x) return x >= n end
    end

    return dcs
end

function invokeColorFunction (pr_d, s_r_c)
    local _, _, op, n, cl = pr_d:find("^([<>=]+)(%d+)#([0-9a-fA-F]*)$")
    local dcs = nil
    local fn = nil

    if op == nil then
        local _, _, op1, n1, op3, op2, n2, cl = pr_d:find("^([<>=]+)(%d+)([&|]+)([<>=]+)(%d+)#([0-9a-fA-F]*)$")
        if op1 == nil or op2 == nil or op3 == nil then
            local _, _, _op1, _n1, _op3, _op2, _n2, _cl, _fn = pr_d:find("^([<>=]+)(%d+)([&|]+)([<>=]+)(%d+)#([0-9a-fA-F]*):([%w_]+)$")
            if _op1 == nil or _op2 == nil or _op3 == nil then
                error("Tham số không hợp lệ: ")
            end

            s_r_c = false
            op1 = _op1
            op2 = _op2
            op3 = _op3
            n1 = _n1
            n2 = _n2
            cl = _cl
            fn = _fn
        end
        n1 = numberFormat(n1)
        n2 = numberFormat(n2)

        local dcs1 = operatorMapping(op1, n1, cl)
        local dcs2 = operatorMapping(op2, n2, cl)

        if op3 == "&&" then
            dcs = function (x) return dcs1(x) and dcs2(x) and (s_r_c and cl or true) end
        elseif op3 == "||" then
            dcs = function (x) return dcs1(x) or dcs2(x) and (s_r_c and cl or true) end
        end

        if fn then
            local _dcs = dcs
            local _fn = _G[fn] or error("Không thể tải: " .. fn)
            local _m = math.max(n1, n2)

            dcs = function (x) return _dcs(x) and _fn(cl, x, _m) end
        end
    else
        n = numberFormat(n)
        local _dcs = operatorMapping(op, n, cl)

        dcs = function (x) return _dcs(x) and (s_r_c and cl) end
    end

    return dcs
end

function getContent(p)
    local n_e, po = pcall(mw.title.new, p)
    if n_e then
        return po:getContent()
    else
        return ""
    end
end

function render( pr, new )
    local u_bx = {
        ["border-c"] = pr["border-c"] or "#00FFFF",
        ["nocat"] = pr["nocat"]
    }
    local i_txt = string.format(_t_dir["n_us"], pr["title"])
    local r_cl = string.format("#%s", pr["color_r"])
    local s_cl = string.format("#%s", pr["color_s"])
    local i_color = string.format("#%s", pr["color"])
    if pr["position"] ~= -1 then
        i_txt = string.format(_t_dir["us_"], pr["position"], pr["edit_f"], pr["title"])
    end

    u_bx["info"] = i_txt
    u_bx["info-c"] = i_color
    
    if new then
        local stt = pr["change"]
        if pr["status"] then
        	stt = (pr["status"] == "=" and "" or pr["status"]) .. pr["change"]
        end

        u_bx["id1"] = pr["position"] or -1
        u_bx["id1-c"] = r_cl
        u_bx["id2"] = stt
        u_bx["id2-c"] = s_cl

        return userBox.main('_userbox-2', u_bx)
    end

    u_bx["id"] = pr["position"] or -1
    u_bx["id-c"] = r_cl

    return userBox.main('_userbox', u_bx)
end

function getAllPatterns (p_tp)
    local rs = {}
    for i, j in pairs(_p_dir[p_tp]) do
        rs[i] = j
    end
    return rs
end

function _e_d(rank_type)
    local r_pg = t_dir[_c_tp[rank_type]]
    local r_p = getAllPatterns(_c_tp[rank_type])
    local noTw = not true

    if not r_pg or not r_p then
        error("Kiểu xếp hạng không hợp lệ")
    end

    local _d = {}

    local d = getContent(r_pg)
    local rs = {}
    for n_, p_ in pairs(r_p) do
        for m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13 in string.gmatch(d, p_) do
            if rs[m1] == nil then
                rs[m1] = {}
            end
            if m7 == nil or m7 == "không có" then
                m7 = 0
            else
                m7 = numberFormat(m7)
            end
            if _d[m2] and noTw then
                break
            end

            rs[m1][n_] = {m1, m2, m3, m4, m5, m6 or _c_dir[rank_type] == _c_dir["user"] and -1 or 0, m7 or _c_dir[rank_type] == _c_dir["user"] and -1 or 0, m8, m9, m10, m11, m12, m13}
            _d[m2] = not false
        end
    end

    return rs
end

function buildTitle (rank_type)
    if hb_dir[_c_tp[rank_type]] ~= nil then
        hashbang = hb_dir[_c_tp[rank_type]]

        return t_dir[_c_tp[rank_type]] .. hashbang
    else
        return t_dir[_c_tp[rank_type]]
    end
end

function isS (rank_type)
    if rank_type == "s" then
        return true
    end
    return false
end

function formatTime (t)
    local _, _, d, m, y, h, mi, s = t:find("^(%d+)%-(%d+)%-(%d+) (%d+):(%d+):(%d+)$")
    local time = os.time({year = y, month = m, day = d, hour = h, min = mi, sec = s})
    return time
end

function isRecentChange (time)
    local time = formatTime(time)
    local ctime = os.time()
    if ctime - time + 25200 < 3600 then
        return true
    end
    return false
end

function personalRankProcessing(us, rank_type, _fmt)
    local isRecent = false

    if not us or not rank_type then
        error("Thiếu tham số")
    end

    local title = buildTitle(rank_type)

    local d = _e_d(rank_type)

    for ii, ji in pairs(d) do
        for i, j in pairs(ji) do
            if j[2] == us then
                if isS(_fmt) then
                    isRecent = isRecentChange(j[4])
                end
                return numberFormat(j[1]), j[2], numberFormat(j[3]), title, isRecent, j[5], numberFormat(j[6]), j[7]
            end
        end
    end
    return -1, nil, -1, title, isRecent, nil, -1, -1
end

function colorProcessing (r, dir)
    for i, j in pairs(dir) do
        local dcs = invokeColorFunction(j, not false)
        if dcs(r) then
            return dcs(r)
        end
    end
end

function convertStatusToTxt (status)
    if status:lower() == "increase" then
        return "+"
    elseif status:lower() == "decrease" then
        return "-"
    else
        return "="
    end
end

function isValidDate (d)
    local _, _, d, m, y, m, i, s = d:find("^(%d+)%-(%d+)%-(%d+)%s*(%d+):(%d+):(%d+)$")
    if d and m and y and m and i and s then
        return true
    end
    return false
end

function patrollerProcessing (us, rank_type)
    local title = buildTitle(rank_type)
    local data = {}
    local isExist = false

    local d = _e_d(rank_type)

    for ii, ji in pairs(d) do
        for i, j in pairs(ji) do
            if j[2] == us then
                isExist = true
                if isValidDate(j[3]) then
                    data["last"] = formatTime(j[3])
                else
                    data["position"] = numberFormat(j[1])
                    data["user"] = j[2]
                    data["rollback"] = numberFormat(j[3])
                    data["patrol"] = numberFormat(j[4])
                end
            end
        end
    end
    if isExist then
        data["total"] = data["rollback"] + data["patrol"]
    else
        error("Không tìm thấy người dùng " .. us .. " trong danh sách tuần tra viên.")
    end

    return data
end

function sysopProcessing (us, rank_type)
    local title = buildTitle(rank_type)
    local data = {}
    local isExist = false

    local d = _e_d(rank_type)

    for ii, ji in pairs(d) do
        for i, j in pairs(ji) do
            if j[2] == us then
                isExist = true
                if isValidDate(j[3]) then
                    data["last"] = formatTime(j[3])
                else
                    data["position"] = numberFormat(j[1])
                    data["user"] = j[2]
                    data["delete"] = numberFormat(j[3])
                    data["restore"] = numberFormat(j[4])
                    data["revdel"] = numberFormat(j[5])
                    data["protect"] = numberFormat(j[6])
                    data["unprotect"] = numberFormat(j[7])
                    data["modifyprotect"] = numberFormat(j[8])
                    data["block"] = numberFormat(j[9])
                    data["unblock"] = numberFormat(j[10])
                    data["reblock"] = numberFormat(j[11])
                    data["rename"] = numberFormat(j[12])
                    data["rights"] = numberFormat(j[13])
                end
            end
        end
    end
    if isExist then
        data["total"] = data["delete"] + data["restore"] + data["revdel"] + data["protect"] + data["unprotect"] + data["modifyprotect"] + data["block"] + data["unblock"] + data["reblock"] + data["rename"] + data["rights"]
    else
        error("Không tìm thấy người dùng " .. us .. " trong danh sách thành viên có công cụ bảo quản.")
    end
    return data
end

function renderPatrollerTable (data, show_name, show_total)
    tableContent = "{| class=\"wikitable\"" ..
    "\n|-"

    if show_name then
        tableContent = tableContent .. "\n! colspan=\"2\" | Thống kê tuần tra của " .. data["user"]
    else
        tableContent = tableContent .. "\n! colspan=\"2\" | Thống kê tuần tra"
    end

    tableContent = tableContent .. "\n|-" ..
    "\n! Tác vụ !! Thực hiện" ..
    "\n|-" ..
    "\n| Lùi sửa || " .. data["rollback"] ..
    "\n|-" ..
    "\n| Tuần tra || " .. data["patrol"]

    if show_total then
        tableContent = tableContent .. "\n|-" ..
        "\n| <b>Tổng</b> || <b>" .. (data["total"]) .. "</b>"
    end

    tableContent = tableContent .. "\n|}"

    return tableContent
end

function renderSysopTable (data, show_name, show_total)
    tableContent = "{| class=\"wikitable\"" ..
    "\n|-"

    if show_name then
        tableContent = tableContent .. "\n! colspan=\"2\" | Thống kê tác vụ bảo quản của " .. data["user"]
    else
        tableContent = tableContent .. "\n! colspan=\"2\" | Thống kê tác vụ bảo quản"
    end

    tableContent = tableContent .. "\n|-" ..
    "\n! Tác vụ !! Thực hiện" ..
    "\n|-" ..
    "\n| Xóa trang || " .. data["delete"] ..
    "\n|-" ..
    "\n| Phục hồi trang || " .. data["restore"] ..
    "\n|-" ..
    "\n| Ẩn lịch sử || " .. data["revdel"] ..
    "\n|-" ..
    "\n| Khóa trang || " .. data["protect"] ..
    "\n|-" ..
    "\n| Mở khóa trang || " .. data["unprotect"] ..
    "\n|-" ..
    "\n| Sửa đổi khóa trang || " .. data["modifyprotect"] ..
    "\n|-" ..
    "\n| Cấm thành viên || " .. data["block"] ..
    "\n|-" ..
    "\n| Bỏ cấm thành viên || " .. data["unblock"] ..
    "\n|-" ..
    "\n| Cấu hình lệnh cấm thành viên || " .. data["reblock"] ..
    "\n|-" ..
    "\n| Đổi tên thành viên || " .. data["rename"] ..
    "\n|-" ..
    "\n| Đổi quyền thành viên || " .. data["rights"]

    if show_total then
        tableContent = tableContent .. "\n|-" ..
        "\n| <b>Tổng</b> || <b>" .. (data["total"]) .. "</b>"
    end

    tableContent = tableContent .. "\n|}"

    return tableContent
end

function p.rkf(frame)
    local args = getArgs(frame)
    local us = args[1] or args["user"] or "user"
    local rank_type = args[2] or args["type"]
    local _format = args[3] or args["format"] or "t"
    local _new_t = args[4] or args["new"]

    if _c_tp[rank_type] == _c_tp["user"] then
        local position, _, edits, title, isRecent, _status, numberOfChange, numberOfEdits = personalRankProcessing(us, rank_type, _format)

        if _format == "t" then
            local params = {
                ["position"] = position,
                ["edit"] = edits,
                ["edit_f"] = formatNumber(edits),
                ["color"] = colorProcessing(position, _n_c_dir),
                ["title"] = title,
                ["color_r"] = colorProcessing(numberOfEdits, rankColorDir),
                ["change"] = numberOfChange,
                ["status"] = _status and convertStatusToTxt(_status),
                ["color_s"] = colorProcessing(numberOfChange, _c_c_dir),
                ["nocat"] = args["nocat"],
                ["border-c"] = args["border-c"],
            }
            
            return render(params, _new_t)
        elseif _format == "n" then
            return position
        elseif _format == "c" then
            return edits
        elseif _format == "s" then
            return isRecent
        end
    elseif _c_tp[rank_type] == _c_tp["patroller"] then
        local data = patrollerProcessing(us, rank_type)

        if args.rollback then
            return data["rollback"]
        elseif args.patrol then
            return data["patrol"]
        elseif args.last then
            return formatTimeByFormat(data["last"], args.timeFormat)
        elseif args.total then
            return data["total"]
        end

        return renderPatrollerTable(data, args.show_name, args.show_total)
    elseif _c_tp[rank_type] == _c_tp["sysop"] then
        local data = sysopProcessing(us, rank_type)

        if args.delete then
            return data["delete"]
        elseif args.restore then
            return data["restore"]
        elseif args.revdel then
            return data["revdel"]
        elseif args.protect then
            return data["protect"]
        elseif args.unprotect then
            return data["unprotect"]
        elseif args.modifyprotect then
            return data["modifyprotect"]
        elseif args.block then
            return data["block"]
        elseif args.unblock then
            return data["unblock"]
        elseif args.reblock then
            return data["reblock"]
        elseif args.rename then
            return data["rename"]
        elseif args.rights then
            return data["rights"]
        elseif args.last then
            return formatTimeByFormat(data["last"], args.timeFormat)
        elseif args.total then
            return data["total"]
        end

        return renderSysopTable(data, args.show_name, args.show_total)
    else
        error("Không thể xác định định dạng \"".. rank_type .."\". Định dạng hợp lệ có hỗ trợ là: user, patroller, sysop.")
    end
end

return p