Mô đun:Thông tin khu dân cư

local p = {}
local lang = mw.getContentLanguage()
local leader_fmt = {
	=
	 - %s
	%s %s
**,
}
local event_fmt = {
	=
	%s
	%s %s
**,
}
local pop_fmt = {
	=
	Dân số %s
	%s %s
**,
	"%s %s %s",
}
local coord_fmt = {
	=
	Tọa độ: %s %s
**,
}
local map_fmt = {
	=

%s

**,
"%s",
}
local date_fmts_by_precision = {
	6 = function (os_time)
		local year = os.date("*t", os_time).year
		local century
		if year > 0 then
			century = math.floor((year - 1) / 1000 + 1)
		else
			century = math.ceil((year + 1) / 1000 - 1)
		end
		return mw.ustring.format("Thiên niên kỷ %i", century)
	end,
	7 = function (os_time)
		local year = os.date("*t", os_time).year
		local century
		if year > 0 then
			century = year / 100 + 1
		else
			century = year / 100 - 1
		end
		return mw.ustring.format("Thế kỷ %i", century)
	end,
	8 = '"Thập niên" Y',
	9 = "Y",
	10 = '"Tháng" n "năm" Y',
	11 = 'j "tháng" n "năm" Y',
	12 = 'j "tháng" n "năm" Y "lúc" G "giờ"',
	13 = 'j "tháng" n "năm" Y "lúc" G:i',
	14 = 'j "tháng" n "năm" Y "lúc" G:i:s',
}
function map(domain, func)
	local range = {}
	for i, item in ipairs(domain) do
		table.insert(func(item))
	end
	return range
end
function all_pass(items, test)
	for i, item in ipairs(items) do
		if not test(item) then return false end
	end
	return true
end
function any_pass(items, test)
	for i, item in ipairs(items) do
		if test(item) then return true end
	end
	return false
end
function has(items, item)
	for i, it in ipairs(items) do
		if it == item then return true end
	end
	return false
end
---Returns the maximum item in the given list, as defined by a function that
-- returns true if and only if the first parameter is less than the second.
function max(items, comp)
	local item = items1
	if #items > 1 then
		for i = 2, #items do
			if comp(item, itemsi) then
				item = itemsi
			end
		end
	end
	return item
end
---Creates a time object compatible with os.time() given an ISO 8601 date
-- string. See mw:Wikibase/DataModel#Dates and times.
function create_time(iso_time)
	local t = {}
	t.year = string.sub(iso_time, 1, 12)
	t.month = string.sub(iso_time, 14, 15)
	t.day = string.sub(iso_time, 17, 18)
	t.hour = string.sub(iso_time, 20, 21)
	t.min = string.sub(iso_time, 23, 24)
	t.sec = string.sub(iso_time, 26, 27)
	return os.time(t)
end
--p.create_time = create_time														-- debug
---Returns whether the given qualifier is in the past.
function is_past(qualifier)
	local iso_time = qualifier and qualifier.datavalue
		and qualifier.datavalue.value and qualifier.datavalue.value.time
	return os.difftime(os.time(), create_time(iso_time)) > 0
end
---Returns whether the given qualifier is in the future.
function is_future(qualifier)
	local iso_time = qualifier and qualifier.datavalue
		and qualifier.datavalue.value and qualifier.datavalue.value.time
	return os.difftime(create_time(iso_time), os.time()) > 0
end
---Returns claims that are currently in effect or are not time-qualified.
function claim_is_current(claim)
	local start_dates = claim.qualifiers and claim.qualifiers.P580
	local end_dates = claim.qualifiers and claim.qualifiers.P582
	return (not start_dates or #start_dates  1 then return frame.args.override end
	
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil end
	
	local leaders = entity.claims.P6
	if not leaders then return nil end
	
	local version = tonumber(frame.args.version) or #leader_fmt
	local edit_button = frame:expandTemplate{
		title = "EditAtWikidata",
		args = {
			pid = 6,
		},
	}
	
	local rows = {}
	for i, leader in ipairs(leaders) do
		local leader_id = leader.mainsnak.datavalue.value"numeric-id"
		if leader_id and claim_is_current(leader) then
			local leader_name = entity_link(leader_id)
			local leader_title_ids = qualifier_entities(leader, 39)
			if leader_title_ids and #leader_title_ids > 0 then
				for i, leader_title_id in ipairs(leader_title_ids) do
					local row = mw.ustring.format(leader_fmtversion,
						entity_link(leader_title_id, true), leader_name,
						edit_button)
					table.insert(rows, row)
				end
			else
				local row = mw.ustring.format(leader_fmtversion,
					"Viên chức", leader_name, edit_button)
				table.insert(rows, row)
			end
		end
	end
	return table.concat(rows, "\n")
end
---Returns the os.time() compatible object represented by the given claim.
function time_from_claim(claim)
	local iso_time = claim and claim.mainsnak.datavalue
		and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.time
	return create_time(iso_time)
end
function time_str_from_claim(claim)
	local os_time = time_from_claim(claim)
	local precision = claim and claim.mainsnak.datavalue
		and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.precision
	if not os_time and precision then return end
	
	local fmt = date_fmts_by_precisionprecision
	if not fmt then return end
	if type(fmt) == "function" then return fmt(os_time) end
	
	local fmt_date = lang:formatDate(fmt, claim.mainsnak.datavalue.value.time:sub(9))
	if os.date("*t", os_time).year  1 then return frame.args.override end
	
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil end
	
	local events = entity.claims.P571
	if not events then return nil end
	table.sort(events, function (a, b)
		return os.difftime(time_from_claim(b), time_from_claim(a)) > 0
	end)
	
	local version = tonumber(frame.args.version) or #event_fmt
	local edit_button = frame:expandTemplate{
		title = "EditAtWikidata",
		args = {
			pid = 571,
		},
	}
	
	local rows = {}
	for i, event in ipairs(events) do
		local event_str = time_str_from_claim(event)
		if event_str then
			local event_title_ids = qualifier_entities(event, 132)
			if event_title_ids and #event_title_ids > 0 then
				for i, event_title_id in ipairs(event_title_ids) do
					local row = mw.ustring.format(event_fmtversion,
						entity_link(event_title_id, true), event_str,
						edit_button)
					table.insert(rows, row)
				end
			else
				local row = mw.ustring.format(event_fmtversion,
					"Thành lập", event_str, edit_button)
				table.insert(rows, row)
			end
		end
	end
	return table.concat(rows, "\n")
end
---Returns an os.time() compatible object representing the time by which the
-- given claim is qualified.
function time_of_claim(claim)
	local qualifiers = claim.qualifiers and claim.qualifiers.P585
	local iso_time = qualifiers and qualifiers1 and qualifiers1.datavalue
		and qualifiers1.datavalue.value and qualifiers1.datavalue.value.time
	return (iso_time and create_time(iso_time)) or os.time()
end
function latest_population_claim()
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil end
	
	local pops = entity.claims.P1082
	if not pops then return nil end
	local latest_pop = max(pops, function (a, b)
		return os.difftime(time_of_claim(b), time_of_claim(a)) > 0
	end)
	return latest_pop
end
function number_from_claim(claim)
	return claim and claim.mainsnak.datavalue.value
		and tonumber(claim.mainsnak.datavalue.value.amount)
end
function claim_is_estimate(claim)
	local method_ids = qualifier_entities(claim, 459)
	return method_ids and has(method_ids, 791801)
end
function p.population(frame)
	if frame.args.override and #frame.args.override > 1 then return frame.args.override end
	
	local latest_pop = latest_population_claim()
	if not latest_pop then return end
	
	local pop = number_from_claim(latest_pop)
	if not pop or frame.args.plain then return pop end
	
	local version = tonumber(frame.args.version) or #pop_fmt
	local edit_button = frame:expandTemplate{
		title = "EditAtWikidata",
		args = {
			pid = 1082,
		},
	}
	
	local os_time = time_of_claim(latest_pop)
	local is_estimate = claim_is_estimate(latest_pop)
	local fmt_date
	if os_time then
		local year = os.date("*t", os_time).year
		fmt_date = string.format("%i", year)
		if year  1 then return frame.args.override end
	
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil end
	
	local coords = entity.claims.P625
	if not coords or #coords  0 then
			table.insert(params, param .. ":" .. frame.argsparam)
		end
	end
	
	local coord_str = frame:expandTemplate{
		title = "Tọa độ",
		args = {
			coord.latitude,
			coord.longitude,
			table.concat(params, "_"),
			display = (frame.args.display and "inline,title") or "inline",
			format = (frame.args.format and #frame.args.format > 0 and frame.args.format) or "dms",
			name = frame.args.name,
			notes = frame.args.notes,
		},
	}
	
	return mw.ustring.format(coord_fmtversion, coord_str, edit_button)
end
function p.rawCoordinates(frame)
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil end
	
	local coords = entity.claims.P625
	if not coords or #coords  1 then return frame.args.override end
	
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil end
	
	local coords = entity.claims.P625
	if not coords or #coords %s", frame.args.caption)),
			border = frame.args.border or "none",
			position = frame.args.position or "right",
			width = frame.args.width or 250,
		},
	}
	
	return mw.ustring.format(map_fmtversion, map_str)
end
local math_module = require( "Module:Math" )
local precision = math_module._precision
local infobox_module = require('Module:Infobox')
local image_module = require('Module:InfoboxImage')
local locationmap_module = require('Module:Location map')
local function isnotempty(s)
	return s and s:match( '^%s*(.-)%s*$' ) ~= 
end
local function firstnonempty(s)
	for i=1,#s do
		if (si and si:match( '^%s*(.-)%s*$' ) ~= ) then
			return si
		end
	end
	return 
end
local function yesno(s, yes, no, ukn, blank)
	-- this function implements yesno
	local vals = {'yes' = 1, 'y' = 1, '1' = 1, 'no' = 0, 'n' = 0, '0' = 0}
	if( s and s:match( '^%s*(.-)%s*$' ) ~= ) then
		local outval = vals(s:lower())
		if( outval == nil ) then
			return ukn
		else
			return (outval == 1) and yes or no
		end
	else
		return blank
	end
end
local function rnd(num, digits)
	-- This function implements 
	return math_module._precision_format(tostring(num), tostring(digits))
end
local function order_of_magnitude(num)
	-- This function partially implements 
if( num ) then
		num = math.abs(num)
		if( num == 0 ) then
			return 0
		else
			return math.floor( math.log10(num) )
		end
	else
		return 0
	end
end
local function page_exists( title )
-- This function implements #ifexist
local noError, titleObject = pcall(mw.title.new, title)
if not noError then
return false
else
if titleObject then
return titleObject.exists
else
return false
end
end
end
local function link(pagelink, linktext, name)
-- This function implements 
pagelink = pagelink or 
linktext = linktext or 
name     = name or 

if( pagelink ~=  ) then
-- use "linktext"
return string.format('%s', pagelink, linktext)
else
-- try "linktext"
pagelink = string.format('%s of %s',linktext, mw.title.getCurrentTitle().text)
if( page_exists( pagelink ) ) then
return string.format('%s', pagelink, linktext)
elseif( name ~=  ) then
-- try "linktext"
pagelink = string.format('%s of %s', linktext, name)
if( page_exists(pagelink) ) then
return string.format('%s', pagelink, linktext)
end
end
end
return linktext
end
local function columns(cell1, cell2, cell3, cell4)
--- This function implements  with no cell0
local function makecell( c1 )
if isnotempty(c1) then
			local root = mw.html.create('td')
			root:attr('align', 'center')
				:css('vertical-align', 'middle')
				:wikitext(c1)
return tostring(root)
end
return 
end

local function makerow( c1, c2 )
local root = mw.html.create()
if isnotempty(c1) then
if isnotempty(c2) then
	root:tag('td')
					:attr('align', 'center')
					:css('vertical-align', 'middle')
					:wikitext(c1)
				root:tag('td')
					:attr('align', 'center')
					:css('vertical-align', 'middle')
					:wikitext(c2)
else
	root:tag('td')
					:attr('colspan', '2')
					:attr('align', 'center')
					:css('vertical-align', 'middle')
					:wikitext(c1)
end
elseif isnotempty(c2) then
			root:tag('td')
				:attr('colspan', '2')
				:attr('align', 'center')
				:css('vertical-align', 'middle')
				:wikitext(c2)
end
return tostring(root)
end

local count = 0
count = count + (isnotempty(cell1) and 1 or 0)
count = count + (isnotempty(cell2) and 1 or 0)
count = count + (isnotempty(cell3) and 1 or 0)
count = count + (isnotempty(cell4) and 1 or 0)
if(count > 0) then
		local root = mw.html.create('table')
		root:css('width', '100%')
			:css('background', 'transparent')
		if(count > 2) then
			root:tag('tr')
					:wikitext(makerow(cell1, cell2))
			root:tag('tr')
					:wikitext(makerow(cell3, cell4))
		else
			root:tag('tr')
				:wikitext(makecell(cell1))
				:wikitext(makecell(cell2))
				:wikitext(makecell(cell3))
				:wikitext(makecell(cell4))
		end
		return tostring(root)
	else
		return 
	end
end
local function columns2(cell0, cell1, cell2, cell3, cell4, cell5)
-- This function implements  with cell0
local function makerow( c1 )
		if isnotempty(c1) then
			local root = mw.html.create('tr')
			root:tag('td')
				:attr('align', 'center')
				:css('style', 'vertical-align:middle')
				:wikitext(c1)
			return tostring(root)
		else
			return 
		end
	end

	local count = 0
	count = count + (isnotempty(cell1) and 1 or 0)
	count = count + (isnotempty(cell2) and 1 or 0)
	count = count + (isnotempty(cell3) and 1 or 0)
	count = count + (isnotempty(cell4) and 1 or 0)
	count = count + (isnotempty(cell5) and 1 or 0)
	if(count > 0) then
		local root = mw.html.create('table')
		root:css('width', '100%')
			:css('background', 'transparent')
		local row = root:tag('tr')
		row
			:tag('td')
				:tag('table')
					:css('width', '100%')
					:css('background', 'transparent')
					:wikitext(makerow(cell1))
					:wikitext(makerow(cell2))
					:wikitext(makerow(cell3))
					:wikitext(makerow(cell4))
					:wikitext(makerow(cell5))
if isnotempty(cell0) then
			row
				:tag('td')
					:attr('align', 'center')
					:css('vertical-align', 'top')
					:wikitext(cell0)
		end
		return tostring(root)
	else
		return cell0
	end
end
local function translitlangbox(transtype, transinfo)
	local args = {}
	args'child' = 'yes'
	local count = 0
	for i=0,6 do
		if(isnotempty(transinfoi) and isnotempty(transtypei)) then
			args'rowclass' .. tostring(i+1) = isnotempty(transtypei+1) and 'mergedrow' or 'mergedbottomrow'
			args'label' .. tostring(i+1) = ' • ' .. transtypei
			args'data' .. tostring(i+1) = transinfoi
			count = count + 1
		end
	end
	return ( count > 0 ) and args or nil
end
local function unitpref(pref, region, unit_type)
-- This function implements 
local pref_impus = { 'imperial' = 1, 'english' = 1, 'uk' = 1, 'us' = 1, 
'u.s.' = 1, 'standard' = 1, 'us customary' = 1, 'u.s. customary' = 1}
local pr = (pref and pref:lower()) or 
local r = region or 
local u = unit_type or 
pr = mw.ustring.gsub(pr, '^%s*(a-z.*a-z\.)%s*$','%1')
if( pref_impuspr ) then
return 'impus'
end
if( mw.ustring.match( r, 'United States' ) ) then
return 'impus'
end
if( mw.ustring.match( r, 'United Kingdom' ) ) then
return 'impus'
end
if( (u .. '_' .. pr ) == 'area_dunam' ) then
return 'dunam'
end

return 'metric'
end
local function areadisp(frame, pref, name, mag, ha, km2, sqmi, acre, dunam, percent, link)
-- This function implements 
local function formatnum(num)
return frame:callParserFunction{ name = 'formatnum', args = num }
end

local metv, metu = , 
local impv, impu = , 
local dunv, dunu = , 
local lstr1, lstr2 = , 
local rndv = 0

pref = pref or 
name = name or 
mag = mag or 
ha = ha or 
km2 = km2 or 
sqmi = sqmi or 
acre = acre or 
dunam = dunam or 
percent = percent or 
link = link or 

if ( ha ~=  ) then
metv = formatnum( ha )
metu = 'ha'
elseif ( km2 ~=  ) then
metv = formatnum( km2 )
metu = 'km2'
elseif ( dunam ~=  ) then
if (tonumber(dunam) 2'
rndv = precision(dunam)+3
metv = rnd(metv,rndv)
end
elseif( acre ~=  ) then 
-- convert acres to hectares
metv = acre*0.4046856422
metu = 'ha'
rndv = math.max(precision(acre),-1*order_of_magnitude(metv))
metv = rnd(metv,rndv)
elseif( sqmi ~=  ) then
-- convert sqmi to km2
metv = sqmi*2.589988110336
metu = 'km2'
rndv = math.max(precision(sqmi)-1,-1*order_of_magnitude(metv))
metv = rnd(metv,rndv)
end
if ( acre ~=  ) then
impv = formatnum( acre )
impu = 'acre'
elseif ( sqmi ~=  ) then
impv = formatnum( sqmi )
impu = 'sq mi'
elseif (ha ~=  ) then
-- convert hectares to acres
impv = ha/0.4046856422
impu = 'acre'
rndv = precision(ha)
impv = rnd(impv,rndv)
elseif (km2 ~=  ) then
-- convert square kilometres to square miles
impv = km2/2.589988110336
impu = 'sq mi'
rndv = math.max(precision(km2),-1*order_of_magnitude(impv))
impv = rnd(impv,rndv)
elseif (dunam ~=  ) then
if (tonumber(dunam) 2'
local impv, impu = , 'sq mi'
local rndv = 0
local perkm2num = tonumber(formatnumR(perkm2 or ))
local persqminum = tonumber(formatnumR(persqmi or ))
local popnum = tonumber(formatnumR(pop or ))
pref = pref or 
name = name or 
perkm2 = perkm2 or 
persqmi = persqmi or 
pop = pop or 
ha = numorzero(ha)
km2 = numorzero(km2)
acre = numorzero(acre)
sqmi = numorzero(sqmi)
dunam = numorzero(dunam)

if( (perkm2num == nil) and (persqminum == nil) ) then
if( mw.ustring.match(perkm2:lower(), '^%s*auto%s*$') or mw.ustring.match(persqmi:lower(), '^%s*auto%s*$') ) then
if( popnum ~= nil ) then
if( km2 > 0 ) then
metv = popnum/km2
rndv = 1 - order_of_magnitude(metv)
metv = rnd(metv,rndv)
elseif( ha > 0 ) then
metv = 100*popnum/ha
rndv = 1 - order_of_magnitude(metv)
metv = rnd(metv,rndv)
elseif( dunam > 0 ) then
metv = 1000*popnum/dunam
rndv = 1 - order_of_magnitude(metv)
metv = rnd(metv,rndv)
elseif( acre > 0 ) then
metv = (popnum/acre)/0.004046856422
rndv = 1 - order_of_magnitude(metv)
metv = rnd(metv,rndv)
elseif( sqmi > 0 ) then
metv = (popnum/sqmi)/2.589988110336
rndv = 1 - order_of_magnitude(metv)
metv = rnd(metv,rndv)
end
if( sqmi > 0 ) then
impv = popnum/sqmi
rndv = 1 - order_of_magnitude(impv)
impv = rnd(impv,rndv)
elseif( acre > 0 ) then
impv = 640*popnum/acre
rndv = 1 - order_of_magnitude(impv)
impv = rnd(impv,rndv)
elseif( km2 > 0 ) then
impv = 2.589988110336*popnum/km2
rndv = 1 - order_of_magnitude(impv)
impv = rnd(impv,rndv)
elseif( ha > 0 ) then
impv = 258.9988110336*popnum/ha
rndv = 1 - order_of_magnitude(impv)
impv = rnd(impv,rndv)
elseif( dunam > 0 ) then
impv = 2589.988110336*popnum/dunam
rndv = 1 - order_of_magnitude(impv)
impv = rnd(impv,rndv)
end
end
end
elseif( perkm2num ~= nil ) then
if( persqminum ~= nil ) then
metv = formatnum( perkm2 )
impv = formatnum( persqmi )
else
metv = formatnum( perkm2 )
impv = perkm2num*2.589988110336
rndv = math.max(precision(perkm2num)-1,-1*order_of_magnitude(impv)) 
impv = rnd(impv,rndv)
end
elseif( persqminum ~= nil ) then
metv = persqminum/2.589988110336
rndv = math.max(precision(persqminum),-1*order_of_magnitude(metv))
metv = rnd(metv,rndv)
impv = formatnum( persqmi )
end
if( metv ~=  and impv ~= ) then
pref = unitpref(pref, name, 'area')
if( pref == 'impus' ) then
return string.format('%s/%s (%s/%s)', impv, impu, metv, metu)
else
return string.format('%s/%s (%s/%s)', metv, metu, impv, impu)
end
else
return 
end  
end
local function lengthdisp(frame, pref, name, km, m, mi, ft)
-- This function implements 
local function formatnum(num)
return frame:callParserFunction{ name = 'formatnum', args = num }
end

local metv, metu = , 
local impv, impu = , 
pref = pref or 
name = name or 
m = m or 
km = km or 
ft = ft or 
mi = mi or 

if ( km ~=  ) then
metv = formatnum( km )
metu = 'km'
elseif ( m ~=  ) then
metv = formatnum( m )
metu = 'm'
elseif ( mi ~=  ) then
metv = mi*1.609344
metu = 'km'
rndv = precision(mi)
metv = rnd(metv,rndv)
elseif ( ft ~=  ) then
metv = ft*0.3048
metu = 'm'
rndv = math.max(precision(ft),-1*order_of_magnitude(metv))
metv = rnd(metv,rndv)
end

if ( mi ~=  ) then
impv = formatnum( mi )
impu = 'mi'
elseif ( ft ~=  ) then
impv = formatnum( ft )
impu = 'ft'
elseif ( km ~=  ) then
impv = km/1.609344
impu = 'mi'
rndv = math.max(precision(km),-1*order_of_magnitude(impv))
impv = rnd(impv,rndv)
elseif ( m ~=  ) then
impv = m/0.3048
impu = 'ft'
rndv = precision(m)
impv = rnd(impv,rndv)
end

if( impv ~=  and metv ~=  ) then
pref = unitpref(pref, name, 'length')
if( pref == 'impus' ) then
return string.format('%s %s (%s %s)', impv, impu, metv, metu)
else
return string.format('%s %s (%s %s)', metv, metu, impv, impu)
end
else
return 
end    
end
function p.areadisp(frame)
local args = frame.args
return areadisp(frame, args'pref', args'name', args'mag', 
args'ha', args'km2', args'sqmi', args'acre', args'dunam', args'percent', args'link')
end
function p.densdisp(frame)
local args = frame.args
return densdisp(frame, args'pref', args'name', 
args'/km2', args'/sqmi', args'pop', args'ha', args'km2', args'sqmi', args'acre', args'dunam')
end
function p.lengthdisp(frame)
local args = frame.args
return lengthdisp(frame, args'pref', args'name', args'km', args'm', args'mi', args'ft')
end
function p.link(frame)
local args = frame.args
return link(args'link', args'type', args'name')
end
function p.columns(frame)
local args = frame.args
if( args0 and args0 ~=  ) then
return columns2(args0, args1, args2, args3, args4, args5)
else
return columns(args1, args2, args3, args4)
end
end
function p.infobox(frame)
local args = {}
local oargs = frame:getParent().args
local pname = firstnonempty({oargs'name', oargs'official_name', mw.title.text})
local narrowmap = isnotempty(oargs'pushpin_map_narrow') and isnotempty(oargs'pushpin_map')
args'bodyclass' = 'geography vcard'
args'bodystyle' = 'width:23em'
args'headerstyle' = 'text-align:left'
args'abovestyle' = 'font-size:1.25em; white-space:nowrap'
-- build the names, type, and transliterations subbox
local sargs = {}
local scount = 0
sargs'child' = 'yes'
if( (isnotempty(oargs'name') or isnotempty(oargs'official_name') ) and
	(isnotempty(oargs'settlement_type') or isnotempty(oargs'type') ) ) then
	    sargs'subheaderstyle' = 'background-color:#cddeff; font-weight:bold;'
	sargs'subheader' = 
		.. firstnonempty(oargs'settlement_type', oargs'type') .. 
	scount = scount + 1
end
if( isnotempty(oargs'name') and isnotempty(oargs'official_name') ) then
	sargs'rowclass1' = 'mergedtoprow'
	sargs'header1' = oargs'official_name'
	scount = scount + 1
end
if( isnotempty(oargs'translit_lang1') ) then
	local targs = translitlangbox(
		{oargs'translit_lang1_type',
		 oargs'translit_lang1_type1',
		 oargs'translit_lang1_type2',
		 oargs'translit_lang1_type3',
		 oargs'translit_lang1_type4',
		 oargs'translit_lang1_type5',
		 oargs'translit_lang1_type6'},
		{oargs'translit_lang1_info',
		 oargs'translit_lang1_info1',
		 oargs'translit_lang1_info2',
		 oargs'translit_lang1_info3',
		 oargs'translit_lang1_info4',
		 oargs'translit_lang1_info5',
		 oargs'translit_lang1_info6'})
	if( targs ) then
		sargs'rowclass2' = 'mergedtoprow'
		sargs'header2' = oargs'translit_lang1' .. ' transcription(s)' .. infobox_module._infobox(targs)
	    	scount = scount + 1
	end
end
if( isnotempty(oargs'translit_lang2') ) then
	local targs = translitlangbox(
		{oargs'translit_lang2_type',
		 oargs'translit_lang2_type1',
		 oargs'translit_lang2_type2',
		 oargs'translit_lang2_type3',
		 oargs'translit_lang2_type4',
		 oargs'translit_lang2_type5',
		 oargs'translit_lang2_type6'},
		{oargs'translit_lang2_info',
		 oargs'translit_lang2_info1',
		 oargs'translit_lang2_info2',
		 oargs'translit_lang2_info3',
		 oargs'translit_lang2_info4',
		 oargs'translit_lang2_info5',
		 oargs'translit_lang2_info6'})
	if( targs ) then
		sargs'rowclass3' = 'mergedtoprow'
		sargs'header3' = oargs'translit_lang2' .. ' transcription(s)' .. infobox_module._infobox(targs)
	    	scount = scount + 1
	end
	end
-- End of names, type, and transliterations
args'above' =   .. pname .. 
if(isnotempty(oargs'native_name')) then
	args'above' = args'above' .. 
		.. oargs'native_name' .. 
end
if(isnotempty(oargs'other_name')) then
	args'above' = args'above' .. 
		.. oargs'other_name' .. 
end
	if( scount > 0 ) then
	    args'above' = args'above' .. infobox_module._infobox(sargs)
	end
	-- Skyline image
	if( isnotempty(oargs'image_skyline') ) then
		args'imagestyle' = 'padding:0.7em 0.8em'
		args'image' = image_module._InfoboxImage(
			{'image' = oargs'image_skyline', 
			 'size' = oargs'imagesize', 
			 'sizedefault' = '250px', 
			 'alt' = oargs'image_alt',
			 'title' = oargs'image_caption' or ('Hình nền trời của ' .. pname)
			 })
		if( isnotempty(oargs'image_caption') ) then
			args'image' = args'image' ..  .. oargs'image_caption' .. 
		end
	end
	-- Other image
	if( isnotempty(oargs'image') ) then
		args'image2' = oargs'image'
	end
	-- Primary map
	local image_map = nil
	if( isnotempty(oargs'image_map') ) then
		local msize = narrowmap and '100px' or '250px'
		
		image_map = image_module._InfoboxImage({
			'image' = oargs'image_map',
			'size' = oargs'mapsize',
			'sizedefault' = msize,
			'alt' = oargs'map_alt',
			'title' = oargs'map_caption' or 'Vị trí của ' .. pname,
			})
		if( isnotempty(oargs'map_caption')) then
			image_map = image_map ..  .. oargs'map_caption' .. 
		end
	end
	-- Primary pushpin map
	local pushpin_map = nil
	if( isnotempty(oargs'pushpin_map') and isnotempty(oargs'latd') and isnotempty(oargs'longd')) then
		local plabel
		if(oargs'pushpin_label_position' and oargs'pushpin_label_position':lower() == 'none') then
			plabel = 
		else if( isnotempty(oargs'pushpin_label') ) then
			plabel = oargs'pushpin_label'
		else
			plabel = pname
		end
		local pwidth = 
		if(narrowmap) then
			pwidth = firstnonempty(oargs'pushpin_mapsize', '150')
		end
		local lat, lat_deg, lat_min, lat_sec
		if(isnotempty(oargs'latm') or isnotempty(oargs'latNS')) then
			lat = 
			lat_deg = oargs'latd' or 
			lat_min = oargs'latm' or 
			lat_sec = oargs'lats' or 
		else
			lat = oargs'latd' or 
		end
		local long, lon_deg, lon_min, lon_sec
		if(isnotempty(oargs'longm') or isnotempty(oargs'longEW')) then
			long = 
			lon_deg = oargs'longd' or 
			lon_min = oargs'longm' or 
			lon_sec = oargs'longs' or 
		else
			long = oargs'longd' or 
		end
		local caption = firstnonempty({oargs'pushpin_map_caption', oargs'map_caption'})
		pushpin_map =  .. locationmap_module._main({
			'1' = oargs'pushpin_map',
			'border' = 'none',
			'alt' = oargs'pushpin_map_alt',
			'caption' = ,
			'float' = 'none',
			'width' = pwidth,
			'default_width' = '250',
			'relief' = oargs'pushpin_relief',
			'AlternativeMap' = oargs'pushpin_image',
			'label' = plabel,
			'lat' = lat, 'long' = long,
			'lat_deg' = lat_deg, 'lat_min' = lat_min, 'lat_sec' = lat_sec,
			'lat_dir' = oargs'latNS' or ,
			'lon_deg' = lon_deg, 'lon_min' = lon_min, 'lon_sec' = lon_sec,
			'lon_dir' = oargs'lonEW' or ,
			'marksize' = '6',
			'position' = oargs'pushpin_label_position' or 
			})
		if( caption ) then
			pushpin_map = pushpin_map ..  .. caption .. 
		end
			pushpin_map = pushpin_map .. 
		end
	end
	-- Flag, Seal, Shield and Coat of arms
	if( isnotempty(oargs'image_flag') or isnotempty(oargs'image_seal') 
		or isnotempty(oargs'image_shield') or isnotempty(oargs'image_blank_emblem')
		or narrowmap) then
		args'rowclass1' = 'mergedtoprow'
		args'class1' = 'maptable'
		local isize = (isnotempty(oargs'pushpin_map_narrow') and isnotempty(oargs'pushpin_map')) and '85px' or '100px'
		local targs = {}
		if( isnotempty(oargs'image_flag') ) then
			local iborder = yesno(oargs'flag_border', 'yes', , 'yes', 'yes')
			targs1 = image_module._InfoboxImage({
				'image' = oargs'image_flag',
				'size' = oargs'flag_size',
				'sizedefault' = isize,
				'border' = iborder,
				'alt' = oargs'flag_alt',
				'title' = 'Hiệu kỳ của ' .. pname,
				}) .. '\'\'\ .. link(oargs'flag_link', 'Flag', oargs'official_name') .. '\'\'\
		end
		if( isnotempty(oargs'image_seal') ) then
			targs2 = image_module._InfoboxImage({
				'image' = oargs'image_seal',
				'size' = oargs'seal_size',
				'sizedefault' = isize,
				'alt' = oargs'seal_alt',
				'title' = 'Con dấu chính thức của ' .. pname,
				}) .. '\'\'\ .. link(oargs'seal_link', firstnonempty(oargs'seal_type', 'Seal'), oargs'official_name') .. '\'\'\
		end
		if( isnotempty(oargs'image_shield') ) then
			targs3 = image_module._InfoboxImage({
				'image' = oargs'image_shield',
				'size' = oargs'shield_size',
				'sizedefault' = isize,
				'alt' = oargs'shield_alt',
				'title' = 'Huy hiệu của ' .. pname,
				}) .. '\'\'\ .. link(oargs'shield_link', 'Coat of arms', oargs'official_name') .. '\'\'\
		end
		if( isnotempty(oargs'image_blank_emblem') ) then
			targs4 = image_module._InfoboxImage({
				'image' = oargs'image_blank_emblem',
				'size' = oargs'blank_emblem_size',
				'sizedefault' = isize,
				'alt' = oargs'blank_emblem_alt',
				'title' = 'Biểu trưng chính thức của ' .. pname,
				}) .. '\'\'\ .. link(oargs'blank_emblem_link', firstnonempty(oargs'blank_emblem_type', 'Logo'), oargs'official_name') .. '\'\'\
		end
		targs5 = image_map
		if( narrowmap and pushpin_map) then
			args'data1' = columns2(pushpin_map, targs1, targs2, targs3, targs4, targs5)
		else
			args'data1' = columns(targs1, targs2, targs3, targs4)
		end
	end
	-- Nickname
	if( isnotempty(oargs'nickname') ) then
		args'rowclass2' = 'mergedrow'
		args'data2' = 'Tên hiệu: ' .. oargs'nickname' .. 
	end
	-- Motto
	if( isnotempty(oargs'motto') ) then
		args'rowclass3' = 'mergedrow'
		args'data3' = 'Khẩu hiệu: ' .. oargs'motto'
	end
	-- Anthem
	if( isnotempty(oargs'anthem') ) then
		args'rowclass4' = 'mergedrow'
		args'data4' = 'Nhạc hiệu: ' .. oargs'anthem'
	end
	-- Map
	if( narrowmap  and image_map ) then
		args'rowclass5' = mergedrow
		args'data5' = image_map
	end
	if( isnotempty(oargs'image_map1') ) then
		args'rowclass6' = mergedrow
		args'data6' = image_module._InfoboxImage({
			'image' = oargs'image_map1',
			'size' = oargs'mapsize1',
			'sizedefault' = '250px',
			'alt' = oargs'map_alt1',
			'title' = oargs'map_caption1' or 'Vị trí của ' .. pname,
			})
		if( isnotempty(oargs'map_caption1')) then
			image_map = image_map ..  .. oargs'map_caption1' .. 
		end
	end
	-- Dot map
	if( isnotempty(oargs'image_dot_map') ) then
		args'rowclass7' = 'mergedrow'
		args'data7' = 'Bản đồ vị trí không hỗ trợ!'
	end
	
-- Pushpin map
	if( narrowmap == nil and pushpin_map) then
		args'rowclass8' = 'mergedtoprow'
		args'data8' = pushpin_map
	end
return infobox_module._infobox(args)

end
local function _superdivisions(entity, divisions, i)
	if not divisionsi then divisionsi = {} end
	if divisionsientity.id:sub(2) then return end
	divisionsientity.id:sub(2) = true
	local claims = entity.claims.P131
	for j, claim in ipairs(claims or {}) do
		local superentity = mw.wikibase.getEntity("Q" .. claim.mainsnak.datavalue.value"numeric-id")
		_superdivisions(superentity, divisions, i + 1)
	end
end
function p.subdivisions(frame)
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil end
	
	local edit_button = frame:expandTemplate{
		title = "EditAtWikidata",
		args = {
			pid = 131,
		},
	}
	
	local divisions = {}
	_superdivisions(entity, divisions, 1)
	local rows = {}
	for i = #divisions, 2, -1 do
		local row = {}
		for id, _ in pairs(divisionsi) do
			table.insert(row, entity_link(id))
		end
		table.insert(rows, "* " .. table.concat(row, ", "))
	end
	
	return frame:expandTemplate{
		title = "Liệt kê",
		args = {
			table.concat(rows, "\n"),
		},
	} .. " " .. edit_button
end

return p