Модуль:Песочница/Игорь Темиров/Модуль:CRC

Документация
--
-- CRC32.lua
--
-- A pure Lua implementation of a CRC32 hashing algorithm. Slower than using a C implemtation,
-- but useful having no other dependancies.
--
--
-- Synopsis
--
-- require('CRC32')
--
-- crchash = CRC32.Hash('a string')
--
-- Methods:
--
-- hashval = CRC32.Hash(val)
--    Calculates and returns (as an integer) the CRC32 hash of the parameter 'val'. 

local p = {}

local ABCmain = mw.loadData("Модуль:Statistical/ABC0")

local max = 2^32 -1

local CRC32 = {
    0,79764919,159529838,222504665,319059676,
    398814059,445009330,507990021,638119352,
    583659535,797628118,726387553,890018660,
    835552979,1015980042,944750013,1276238704,
    1221641927,1167319070,1095957929,1595256236,
    1540665371,1452775106,1381403509,1780037320,
    1859660671,1671105958,1733955601,2031960084,
    2111593891,1889500026,1952343757,2552477408,
    2632100695,2443283854,2506133561,2334638140,
    2414271883,2191915858,2254759653,3190512472,
    3135915759,3081330742,3009969537,2905550212,
    2850959411,2762807018,2691435357,3560074640,
    3505614887,3719321342,3648080713,3342211916,
    3287746299,3467911202,3396681109,4063920168,
    4143685023,4223187782,4286162673,3779000052,
    3858754371,3904687514,3967668269,881225847,
    809987520,1023691545,969234094,662832811,
    591600412,771767749,717299826,311336399,
    374308984,453813921,533576470,25881363,
    88864420,134795389,214552010,2023205639,
    2086057648,1897238633,1976864222,1804852699,
    1867694188,1645340341,1724971778,1587496639,
    1516133128,1461550545,1406951526,1302016099,
    1230646740,1142491917,1087903418,2896545431,
    2825181984,2770861561,2716262478,3215044683,
    3143675388,3055782693,3001194130,2326604591,
    2389456536,2200899649,2280525302,2578013683,
    2640855108,2418763421,2498394922,3769900519,
    3832873040,3912640137,3992402750,4088425275,
    4151408268,4197601365,4277358050,3334271071,
    3263032808,3476998961,3422541446,3585640067,
    3514407732,3694837229,3640369242,1762451694,
    1842216281,1619975040,1682949687,2047383090,
    2127137669,1938468188,2001449195,1325665622,
    1271206113,1183200824,1111960463,1543535498,
    1489069629,1434599652,1363369299,622672798,
    568075817,748617968,677256519,907627842,
    853037301,1067152940,995781531,51762726,
    131386257,177728840,240578815,269590778,
    349224269,429104020,491947555,4046411278,
    4126034873,4172115296,4234965207,3794477266,
    3874110821,3953728444,4016571915,3609705398,
    3555108353,3735388376,3664026991,3290680682,
    3236090077,3449943556,3378572211,3174993278,
    3120533705,3032266256,2961025959,2923101090,
    2868635157,2813903052,2742672763,2604032198,
    2683796849,2461293480,2524268063,2284983834,
    2364738477,2175806836,2238787779,1569362073,
    1498123566,1409854455,1355396672,1317987909,
    1246755826,1192025387,1137557660,2072149281,
    2135122070,1912620623,1992383480,1753615357,
    1816598090,1627664531,1707420964,295390185,
    358241886,404320391,483945776,43990325,
    106832002,186451547,266083308,932423249,
    861060070,1041341759,986742920,613929101,
    542559546,756411363,701822548,3316196985,
    3244833742,3425377559,3370778784,3601682597,
    3530312978,3744426955,3689838204,3819031489,
    3881883254,3928223919,4007849240,4037393693,
    4100235434,4180117107,4259748804,2310601993,
    2373574846,2151335527,2231098320,2596047829,
    2659030626,2470359227,2550115596,2947551409,
    2876312838,2788305887,2733848168,3165939309,
    3094707162,3040238851,2985771188,
}

local function xor(a, b)
    local calc = 0    

    for i = 32, 0, -1 do
	local val = 2 ^ i
	local aa = false
	local bb = false

	if a == 0 then
	    calc = calc + b
	    break
	end

	if b == 0 then
	    calc = calc + a
	    break
	end

	if a >= val then
	    aa = true
	    a = a - val
	end

	if b >= val then
	    bb = true
	    b = b - val
	end

	if not (aa and bb) and (aa or bb) then
	    calc = calc + val
	end
    end

    return calc
end

local function lshift(num, left)
    local res = num * (2 ^ left)
    return res % (2 ^ 32)
end

local function rshift(num, right)
    local res = num / (2 ^ right)
    return math.floor(res)
end

local function Hash(str)
    local count = string.len(tostring(str))
    local crc = max
    
    local i = 1
    while count > 0 do
	local byte = string.byte(str, i)

	crc = xor(lshift(crc, 8), CRC32[xor(rshift(crc, 24), byte) + 1])

	i = i + 1
	count = count - 1
    end

    return crc
end

bit32 = require( 'bit32' )

 local bit_band, bit_bxor, bit_rshift, str_byte, str_len = bit32.band, bit32.bxor, bit32.rshift, string.byte, string.len
 local consts = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }
 
function CRC32(s)
  local crc, l, i = 0xFFFFFFFF, str_len(s)
  --do return crc ,"   ", str_byte(s, 1) ,"   ", bit_bxor(crc, str_byte(s, 1)) end
--  	do return bit_band(bit_bxor(crc, str_byte(s, 1)), 0xFF)+1, "    ", consts[bit_band(bit_bxor(crc, str_byte(s, 1)), 0xFF) + 1] end
  	do return bit_bxor(bit_rshift(crc, 8), consts[bit_band(bit_bxor(crc, str_byte(s, 1)), 0xFF) + 1]) end
  for i = 1, l, 1 do
   crc = bit_bxor(bit_rshift(crc, 8), consts[bit_band(bit_bxor(crc, str_byte(s, i)), 0xFF) + 1])
  end
end

local function First_less_Second(a, b)  
    local LenA = mw.ustring.len(a)
    local LenB = mw.ustring.len(b)
    for i = 1, (LenA < LenB) and LenA or LenB do
        if mw.ustring.codepoint(a, i, i) ~= mw.ustring.codepoint(b, i, i) then
            return mw.ustring.codepoint(a, i, i) < mw.ustring.codepoint(b, i, i) 
        end
    end
    return LenA < LenB
end  

local function internalFormatNumber(a_number, a_decimalMark, a_groupMark, a_groupMinLength, a_groupOnlyIntegerPart)
    -- find the decimal point
    local decimalPosition = mw.ustring.find(a_number, ".", 1, true);
    local needsGrouping = false;
    local DIGIT_GROUPING_SIZE = 3
    if (not decimalPosition) then
        -- no decimal point - integer number
		decimalPosition = mw.ustring.len(a_number) + 1;
		if (decimalPosition > a_groupMinLength) then
			needsGrouping = true;
		end
	else
		-- decimal point present
		if ((decimalPosition > a_groupMinLength) or (((mw.ustring.len(a_number) - decimalPosition) > DIGIT_GROUPING_SIZE) and (not a_groupOnlyIntegerPart))) then
			needsGrouping = true;
		end
		-- replace the decimal point
		a_number = mw.ustring.sub(a_number, 1, decimalPosition - 1) .. a_decimalMark .. mw.ustring.sub(a_number, decimalPosition + 1);
	end
	if (needsGrouping and (decimalPosition > DIGIT_GROUPING_SIZE + 1)) then
		-- grouping of integer part necessary
		local i = decimalPosition - DIGIT_GROUPING_SIZE;
		while (i > 1) do
			-- group the integer part
			a_number = mw.ustring.sub(a_number, 1, i - 1) .. a_groupMark .. mw.ustring.sub(a_number, i);
			decimalPosition = decimalPosition + mw.ustring.len(a_groupMark);
			i = i - DIGIT_GROUPING_SIZE;
		end
	end
	-- skip to the end of the new decimal mark (in case it is more than one char)
	decimalPosition = decimalPosition + mw.ustring.len(a_decimalMark) - 1;
	if (a_groupOnlyIntegerPart) then
		needsGrouping = false;
	end
	if (needsGrouping and ((mw.ustring.len(a_number) - decimalPosition) > DIGIT_GROUPING_SIZE)) then
		-- grouping of fractional part necessary
		-- using negative numbers (index from the end of the string)
		local i = decimalPosition - mw.ustring.len(a_number) + DIGIT_GROUPING_SIZE;
		while (i <= -1) do
			-- group the fractional part
			a_number = mw.ustring.sub(a_number, 1, i - 1) .. a_groupMark .. mw.ustring.sub(a_number, i);
			i = i + DIGIT_GROUPING_SIZE;
		end
	end
	return a_number;
end

-- from de:Modul:FormatNum
function formatNum(number)    
	if (number) then
        number = tostring(number)
		format = {decimalMark = ",", groupMark = " ", groupMinLength = 5, groupOnlyIntegerPart = true}
		-- lua can parse the number (first check passed) and format entry found
		local sign = mw.ustring.sub(number, 1, 1);
		if ((sign == "+") or (sign == "-")) then
			-- remove sign from number, add it later again
			number = mw.ustring.sub(number, 2);
		else
			-- was not a sign
			sign = "";
		end
		if (mw.ustring.sub(number, 1, 1) == ".") then
			-- number begins with "." -> add a 0 to the beginning
			number = "0" .. number;
		else
			if (mw.ustring.sub(number, -1) == ".") then
				-- number ends with "." -> remove it
				number = mw.ustring.sub(number, 1, -2);
			end
		end
		if ((number == mw.ustring.match(number, "^%d+$")) or (number == mw.ustring.match(number, "^%d+%.%d+$"))) then
			-- number has valid format (only digits or digits.digits) -> format it and add sign (if any) again
			number = sign .. internalFormatNumber(number, format.decimalMark, format.groupMark, format.groupMinLength, format.groupOnlyIntegerPart);
		else
			-- number has no valid format -> undo all modifications
			number = a_frame.args["number"];
		end
	end	   
	return number;
end

function p.GetStat(frame)

    local args = frame:getParent().args
    
    if args == nil then return "Введите название объекта АТД" end
    local PlaceName = args[1]

    if PlaceName == nil then return "Введите название объекта АТД" end
    PlaceName = mw.text.trim(PlaceName)
    local check = args['check'] or '';
    if check == '' or check == '0' or check == 'false' then
    	check = false;
    else
    	check = true;
    end
    
    local NumABC = nil
    -- ё = е , так как по соглашению их не различают при сортировке
    local PlaceEEE = mw.ustring.gsub (PlaceName, "ё", "е")
	PlaceEEE = mw.ustring.gsub (PlaceEEE, "Ё", "Е")
	PlaceEEE = mw.ustring.gsub (PlaceEEE, "-", "")
	
--	do return  First_less_Second("Сельское поселение «Село Ильинское» (Малоярославецкий район)", "Сельское поселение Званновский сельсовет"), "Сельское поселение «Село Ильинское» (Малоярославецкий район)"< "Сельское поселение Званновский сельсовет" end
--	do return  First_less_Second("Сельское поселение ", "Сельское посе-ление"), "Сельское поселение "< "Сельское посе-ление" end
--	do return  First_less_Second("Сельское поселение ", "Сёльс"), "Сельское поселение "< "Сёльс" end
		
    for k, v in pairs(ABCmain) do 
    	-- mw.ustring.lower для регистроНЕзависимого сравнения
        if First_less_Second(mw.ustring.lower(PlaceEEE), mw.ustring.lower(v)) then break else NumABC = k end
    end    
    
    if NumABC == nil then 
    	if check then
    		return 0;
    	else
    		return "#Н/Д"..frame:callParserFunction{name = '#tag:ref', args = {PlaceName .." > Данные не обнаружены. Возможно страница переименовывалась. Проверьте справочник[[Категория:Википедия:Статьи с неправильными параметрами шаблона Население]]"}} 
    	end
    end

	local ABCPage = mw.loadData("Модуль:Statistical/ABC"..NumABC)

    if ABCPage[PlaceName] == nil then 
    	if check then
    		return 0;
    	else
    		return "#Н/Д"..frame:callParserFunction{name = '#tag:ref', args = {PlaceName .." > Данные не обнаружены. Возможно страница переименовывалась. Проверьте справочник[[Категория:Википедия:Статьи с неправильными параметрами шаблона Население]]"}} 
    	end
    end
    local RegionData = mw.loadData("Модуль:Statistical/"..ABCPage[PlaceName][1])
    local PlaceData = RegionData[ABCPage[PlaceName][2]]
    if PlaceData == nil then 
    	if check then
    		return 0;
    	else
    		return "#Н/Д"..frame:callParserFunction{name = '#tag:ref', args = {PlaceName .." > Данные не обнаружены. Возможно страница переименовывалась. Проверьте справочник[[Категория:Википедия:Статьи с неправильными параметрами шаблона Население]]"}} 
    	end
	end
	if check then
		return 1;
	end

    local Format = mw.text.trim ( (args[2] or "Таблица"))
    
    local LastRecord = 0
    for k in pairs(PlaceData) do LastRecord = LastRecord + 1 end
    local NumRecord = LastRecord
    
	local function FormatY()    
	    return PlaceData[NumRecord][1]
	end

	local function FormatN()    
	    return PlaceData[NumRecord][2]
	end

	local function FormatS(SourceType)  
	    if PlaceData[NumRecord][3] == "" then
	        return ""
	    else
	        local Source1
	        local Source2 
	        if string.find(PlaceData[NumRecord][3],"%d+[A-Z]+")==1 then
	            Source1 = RegionData['Источники'][PlaceData[NumRecord][3]][1]
	            Source2 = PlaceData[NumRecord][3]
	        else
	            Source1 = PlaceData[NumRecord][3]
	            Source2 = ""
	        end
	        if string.find(Source1, "http://")==1 then
	            Source1 = '['..Source1..']'
	        end
			if SourceType == "и" then
				return Source1
			end
	        if Source2 == "" then
	            return frame:callParserFunction{name = '#tag:ref', args = {Source1}}
	        else
	            return frame:callParserFunction{name = '#tag:ref', args = {Source1, name = Source2}}
	        end
	    end
	end        

	local function FormatF()    
	    return formatNum(PlaceData[NumRecord][2])    
	end

	local function FormatT()    
	    if NumRecord > 1 then
	        if PlaceData[NumRecord][2] > PlaceData[NumRecord - 1][2] then
	            return "<span style='color: #0c0; font-weight:bold; font-size: larger;'>↗</span>" 
	        elseif PlaceData[NumRecord][2] < PlaceData[NumRecord - 1][2] then
	            return "<span style='color: red; font-weight:bold; font-size: larger;'>↘</span>"  
	        else
	            return "<span style='color:#0AF;'>→</span>"  
	        end
	    else
	        return ""
	    end            
	end

    if Format == 'Год' or Format == 'г' then
        return FormatY()    
    elseif Format == 'Безформат' or Format == 'Число' or Format == 'ч'  then
        return FormatN()    
    elseif Format == 'Ссылка' or Format == 'с'  then
        return FormatS("с")    
    elseif Format == 'Источник' or Format == 'и'  then
        return FormatS("и")    
    elseif Format == 'Формат' or Format == 'ф'  then
        return FormatF()    
    elseif Format == 'Формат' or Format == 'фг'  then
        return FormatF().." ("..FormatY()..")"    
    elseif Format == 'Формат' or Format == 'фс'  then
        return FormatF()..FormatS()    
    elseif Format == 'ФорматСсылкаГод' or Format == 'фсг'  then
        return FormatF()..FormatS().." ("..FormatY()..")"
    elseif Format == 'Тренд' or Format == 'т'  then
        return FormatT()..FormatF()    
    elseif Format == 'Значение' or Format == 'ТрендСсылка' or Format == 'тс'  then
        return FormatT()..FormatF()..FormatS()
    elseif Format == 'ТрендСсылкаГод' or Format == 'тсг'  then
        return FormatT()..FormatF()..FormatS().." ("..FormatY()..")"
    elseif Format == 'Хеш' or Format == 'х'  then
--        return Hash(PlaceName) 
        return CRC32(PlaceName) 
	elseif Format == 'Диаграмма' or Format == 'д'  then
		local tempHeight = 370
		local tempWidth = 800
		local tempMod = math.fmod (LastRecord, 5)
		if LastRecord < 40 then 
			tempHeight = 200  + 170 * (LastRecord - 1) / 40
			tempWidth = 200 + 600 * (LastRecord - 1) / 40
		end
		local tempGroup = ""
		local tempTooltip = ""
		local tempLegend = ""
		for k in pairs(PlaceData) do 
			NumRecord = k
			tempGroup = tempGroup .. FormatN() .. ":"
			tempTooltip = tempTooltip .. FormatF() .. " (" .. FormatY() .. "):"
			if LastRecord < 5 or math.fmod (k, 5) == tempMod  then tempLegend = tempLegend .. FormatY() end
			tempLegend = tempLegend .. ":"
		end
		tempGroup = string.sub (tempGroup, 1, string.len (tempGroup)-1)
		tempTooltip = string.sub (tempTooltip, 1, string.len (tempTooltip)-1)
		tempLegend = string.sub (tempLegend, 1, string.len (tempLegend)-1)
    	local barChart = require('Модуль:Chart')['bar chart'];
		local Diagram = {
			['height'] = tempHeight,
			['width'] = tempWidth,
			['group 1'] = tempGroup,
			['tooltip 1'] = tempTooltip,
			['x legends'] = tempLegend,
			['group names'] = 'Численность населения',
			['default color'] = '#00CCFF'
			}    	
		local cframe = mw.getCurrentFrame();
		return barChart(cframe:newChild{ title=cframe.title, args = Diagram})
    else
        -- Формироание HTML-таблицы
        local HtmlBuilder = require('Модуль:HtmlBuilder')    
        local HTML = HtmlBuilder.create('table')
    
        local MaxData
        if args['Столбцов'] then
            Column = tonumber(args['Столбцов'])
        else
            MaxData = (PlaceData[1][2] > PlaceData[LastRecord][2]) and PlaceData[1][2] or PlaceData[LastRecord][2]
            if MaxData < PlaceData[math.floor((LastRecord + 1) / 2)][2] then MaxData = PlaceData[math.floor((LastRecord + 1) / 2)][2] end
            if MaxData < 10 then Column = 15 
            elseif MaxData < 100 then Column = 12 
            elseif MaxData < 1000 then Column = 12
            elseif MaxData < 10000 then Column = 12
            elseif MaxData < 100000 then Column = 10
            elseif MaxData < 1000000 then Column = 10
            elseif MaxData < 10000000 then Column = 8
            elseif MaxData < 100000000 then Column = 8
            else Column = 7 end
            if Column > LastRecord then Column = LastRecord end
        end

        if args['Оформление'] ~= nil then
            HTML.attr('class', args['Оформление'])
        else
            if Column > 7 then HTML.attr('class', 'wide') else HTML.attr('class', 'standard') end
        end

        local TempRow
        local NumRow = 0
        TempRow = HTML.tag('th').attr('colspan', Column).wikitext(args['Заголовок'] or 'Численность населения')
        for i = 1, math.ceil(LastRecord / Column) do
            TempRow = HTML.tag('tr').addClass("bright")
            for j = 1, Column do
				NumRecord = (i - 1) * Column + j
                if PlaceData[NumRecord] == nil then
                    TempRow.tag('th').wikitext("")
                else
                    TempRow.tag('th').wikitext(FormatY()..FormatS("с"))
                end
            end
        
            TempRow = HTML.tag('tr').attr('align', 'center')
            for j = 1, Column do
				NumRecord = (i - 1) * Column + j
                if PlaceData[NumRecord] == nil then
                    TempRow.tag('td').wikitext("")
                else
                    TempRow.tag('td').wikitext(FormatT()..FormatF())
                end
            end
        end            
        return tostring(HTML)
    end
    return 1, Format
end

return p