Mô đun:Authority control

require('strict')
local p = {}
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')
--======================================================================**
--                            Category functions                            
--======================================================================**
function p.getCatForId( id )
	local catName = 
	if namespace == 0 then
		catName = 'Bài viết chứa nhận dạng '..id..
	elseif namespace == 2 and not title.isSubpage then
		catName = 'Trang thành viên chứa nhận dạng '..id..
	else
		catName = 'Trang khác chứa nhận dạng '..id..
	end
	return ..p.redCatLink(catName)
end
function p.redCatLink( catName ) --catName == 'Blah' (not 'Category:Blah', not )
	if catName and catName ~=  and
	   testcases == false and
	   mw.title.new(catName, 14).exists == false
	then
		return 'Thể loại:Trang có thể loại kiểm soát tính nhất quán được liên kết đỏ'
	end
	return 
end
function p.createRow( id, label, rawValue, link, withUid, specialCat )
	if link then
		if withUid then
			return '*'..label..' '..link..'\n'
		end
		return '*'..label..' '..link..'\n'
	end
	local catName = 'Bài viết Wikipedia chứa nhận dạng '..(specialCat or id)..' sai'
	return '* '..id..' id '..rawValue..' không hợp lệ.'..p.redCatLink(catName)..'\n'
end
--======================================================================**
--                      Property formatting functions                       
--======================================================================**
-- If a link has a suitable entry in the global inter-wiki prefix table at :m:Interwiki_map, please consider routing through this prefix rather than as external link URL. This will ease future maintenance as necessary updates to the link can be centrally carried out there rather than by updating this module. The "external link" icon would disappear for such entries.
function p.aagLink( id )
	--P3372's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'AAG' )
end
function p.acmLink( id )
	--P864's format regex: \d{11} (e.g. 12345678901)
	if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'ACM-DL' )
end
function p.adbLink( id )
	--P1907's format regex: a-z-a-z+-(1-2\d|1-9)\d{0,3} (e.g. barton-sir-edmund-toby-71)
	if not id:match( '^a-z-a-z+-1-2%d%d?%d?%d?$' ) and
	   not id:match( '^a-z-a-z+-1-9%d?%d?%d?$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'ADB' )
end
function p.agsaLink( id )
	--P6804's format regex: 1-9\d* (e.g. 3625)
	if not id:match( '^1-9%d*$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'AGSA' )
end
function p.autoresuyLink( id )
	--P2558's format regex: 1-9\d{0,4} (e.g. 12345)
	if not id:match( '^1-9%d?%d?%d?%d?$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'autores.uy' )
end
function p.awrLink( id )
	--P4186's format regex: ((A-Z{3}\d{4})|(A-Z{2}\d{5}))a-z (e.g. PR00768b)
	if not id:match( '^A-ZA-ZA-Z%d%d%d%da-z$' ) and
	   not id:match( '^A-ZA-Z%d%d%d%d%da-z$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'AWR' )
end
function p.balatLink( id )
	--P3293's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'BALaT' ) --no https as of 9/2019
end
function p.bibsysLink( id )
	--P1015's format regex: 1-9\d* or 1-9(\d{0,8}|\d{12}) (e.g. 1234567890123)
	--TODO: follow up @ d:Property talk:P1015#Discrepancy between the 2 regex constraints or escalate/investigate
	if not id:match( '^1-9%d?%d?%d?%d?%d?%d?%d?%d?$' ) and
	   not id:match( '^1-9%d%d%d%d%d%d%d%d%d%d%d%d$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'BIBSYS' )
end
function p.bildLink( id )
	--P2092's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'Bildindex' )
end
function p.bncLink( id )
	--P1890's format regex: \d{9} (e.g. 123456789)
	if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'BNC' )
end
function p.bneLink( id )
	--P950's format regex: (XX|FF|a)\d{4,7}|(bima|bimo|bica|biseo|bivi|Mise|Mimo|Mima)\d{10} (e.g. XX1234567)
	if not id:match( '^XFXF%d%d%d%d%d?%d?%d?$' ) and
	   not id:match( '^a%d%d%d%d%d?%d?%d?$' ) and
	   not id:match( '^bimcsvaoei%d%d%d%d%d%d%d%d%d%d$' ) and
	   not id:match( '^Mismeoa%d%d%d%d%d%d%d%d%d%d$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'BNE' ) --no https as of 9/2019
end
function p.bnfLink( id )
	--P268's format regex: \d{8}0-9bcdfghjkmnpqrstvwxz (e.g. 123456789)
	if not id:match( '^c?b?%d%d%d%d%d%d%d%d0-9bcdfghjkmnpqrstvwxz$' ) then
		return false
	end
	--Add cb prefix if it has been removed
	if not id:match( '^cb.+$' ) then
		id = 'cb'..id
	end
	return ' '..id..'  (data)'..p.getCatForId( 'BNF' )
end
function p.botanistLink( id )
	--P428's format regex: ('t )?(d')?(de )?(la )?(van (der )?)?(Ma?c)?(De)?(Di)?\p{Lu}?C?'\p{Ll}*(-'. *(van )?(y )?(daenr?- )?(Ma?c)?\p{Lu}bht?C?'\p{Ll}*)*\.? ?f?\.? (e.g. L.)
	--not easily/meaningfully implementable in Lua's regex since "(this)?" is not allowed...
	if not mw.ustring.match( id, "^%u%l%d%. '-+$" ) then --better than nothing
		return false
	end
	local id2 = id:gsub(' +', '%%20')
	return ' '..id....p.getCatForId( 'Botanist' )
end
function p.bpnLink( id )
	--P651's format regex: \d{6,8} (e.g. 00123456)
	if not id:match( '^%d%d%d%d%d%d%d%d$' ) and --original format regex, changed 8/2019 to
	   not id:match( '^0?%d%d%d%d%d%d%d$' ) and --allow 1-2 leading 0s, allowed by the website
	   not id:match( '^0?0?%d%d%d%d%d%d$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'BPN' ) --no https as of 9/2019
end
function p.canticLink( id )
	--P1273's format regex: a\d{7}0-9x (e.g. a10640745)
	if not id:match( '^a%d%d%d%d%d%d%d%dx$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'CANTIC' ) --no https as of 10/2019
end
function p.ciniiLink( id )
	--P271's format regex: DA\d{7}\dX (e.g. DA12345678)
	if not id:match( '^DA%d%d%d%d%d%d%d%dX$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'CINII' )
end
function p.cwgcLink( id )
	--P1908's format regex: 1-9\d* (e.g. 75228351)
	if not id:match( '^1-9%d*$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'CWGC' )
end
function p.daaoLink( id )
	--P1707's format regex: a-z\-+\d* (e.g. rolf-harris)
	if not id:match( '^a-z%-+%d*$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'DAAO' )
end
function p.dblpLink( id )
	--P2456's format regex: \d{2,3} /\d+(-\d+)?|a-z /a-zA-Z0-9A-Za-z*(-\d+)? (e.g. 123/123)
	if not id:match( '^%d%d%d?/%d+$' ) and
	   not id:match( '^%d%d%d?/%d+%-%d+$' ) and
	   not id:match( '^a-z/a-zA-Z0-9A-Za-z*$' ) and
	   not id:match( '^a-z/a-zA-Z0-9A-Za-z*%-%d+$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'DBLP' )
end
function p.dsiLink( id )
	--P2349's format regex: 1-9\d* (e.g. 1538)
	if not id:match( '^1-9%d*$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'DSI' )
end
function p.fnzaLink( id )
	--P6792's format regex: 1-9\d* (e.g. 9785)
	if not id:match( '^1-9%d*$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'FNZA' )
end
function p.gndLink( id )
	--P227's format regex: 1012?\d{7}0-9X|47\d{6}-\d|1-9\d{0,7}-0-9X|3\d{7}0-9X (e.g. 4079154-3)
	if not id:match( '^1012?%d%d%d%d%d%d%d0-9X$' ) and
	   not id:match( '^47%d%d%d%d%d%d%-%d$' ) and
	   not id:match( '^1-9%d?%d?%d?%d?%d?%d?%d?%-0-9X$' ) and
	   not id:match( '^3%d%d%d%d%d%d%d0-9X$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'GND' )
end
function p.hdsLink( id )
	--P902's format regex: \d{6} (e.g. 050123)
	if not id:match( '^%d%d%d%d%d%d$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'HDS' )
end
function p.iaafLink( id )
	--P1146's format regex: 0-90-9* (e.g. 012)
	if not id:match( '^%d+$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'IAAF' )
end
function p.iciaLink( id )
	--P1736's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'ICIA' )
end
function p.isniLink( id )
	id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
	if not id then
		return false
	end
	return ' '..id:sub( 1, 4 )..' '..id:sub( 5, 8 )..' '..id:sub( 9, 12 )..' '..id:sub( 13, 16 )....p.getCatForId( 'ISNI' ) --no https as of 9/2019
end
function p.jocondeLink( id )
	--P347's format regex: \-0-9A-Za-z{11} (e.g. 12345678901)
	local regex = '^'..string.rep('%-0-9A-Za-z', 11)..'$'
	if not id:match( regex ) then
		return false
	end
	return ' '..id....p.getCatForId( 'Joconde' )
end
function p.kulturnavLink( id )
	--P1248's format regex: 0-9a-f{8}\-0-9a-f{4}\-0-9a-f{4}\-0-9a-f{4}\-0-9a-f{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
	if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'KULTURNAV' ) --no https as of 9/2019
end
function p.lccnLink( id )
	local parts = p.splitLccn( id ) --e.g. n78039510
	if not parts then
		return false
	end
	local lccnType = parts1 ~= 'sh' and 'names' or 'subjects'
	id = parts1 .. parts2 .. p.append( parts3, '0', 6 )
	return ' '..id....p.getCatForId( 'LCCN' )
end
function p.lirLink( id )
	--P886's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'LIR' ) --no https as of 9/2019
end
function p.lnbLink( id )
	--P1368's format regex: \d{9} (e.g. 123456789)
	if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
		return false
	end
	return ' '..id....p.getCatForId( 'LNB' )
end
function p.leonoreLink( id )
	--P640's format regex: LH/\d{1,4}/\d{1,3}|19800035/\d{1,4}/\d{1,5}(Bis)?|C/0/\d{1,2} (e.g. LH/2064/18)
	if not id:match( '^LH/%d%d?%d?%d?/%d%d?%d?$' ) and             --IDs from       LH/1/1 to         LH/2794/54 (legionaries)
	   not id:match( '^19800035/%d%d?%d?%d?/%d%d?%d?%d?%d?$' ) and --IDs from 19800035/1/1 to 19800035/385/51670 (legionnaires who died 1954-1977 & some who died value before adding it
local reqs = {}
-- Parameter format: { 'parameter name', 'label', propertyId # in Wikidata, formatting/validation function }
p.conf = {
	{ 'AAG', 'AAG', 3372, p.aagLink },
	{ 'ACM-DL', 'ACM DL', 864, p.acmLink },
	{ 'ADB', 'ADB', 1907, p.adbLink },
	{ 'AGSA', 'AGSA', 6804, p.agsaLink },
	{ 'autores.uy', 'autores.uy', 2558, p.autoresuyLink },
	{ 'AWR', 'AWR', 4186, p.awrLink },
	{ 'BALaT', 'BALaT', 3293, p.balatLink },
	{ 'BIBSYS', 'BIBSYS', 1015, p.bibsysLink },
	{ 'Bildindex', 'Bildindex', 2092, p.bildLink },
	{ 'BNC', 'BNC', 1890, p.bncLink },
	{ 'BNE', 'BNE', 950, p.bneLink },
	{ 'BNF', 'BNF', 268, p.bnfLink },
	{ 'Botanist', 'Botanist', 428, p.botanistLink },
	{ 'BPN', 'BPN', 651, p.bpnLink },
	{ 'CANTIC', 'CANTIC', 1273, p.canticLink },
	{ 'CINII', 'CiNii', 271, p.ciniiLink },
	{ 'CWGC', 'CWGC', 1908, p.cwgcLink },
	{ 'DAAO', 'DAAO', 1707, p.daaoLink },
	{ 'DBLP', 'DBLP', 2456, p.dblpLink },
	{ 'DSI', 'DSI', 2349, p.dsiLink },
	{ 'FNZA', 'FNZA', 6792, p.fnzaLink },
	{ 'GND', 'GND', 227, p.gndLink },
	{ 'HDS', 'HDS', 902, p.hdsLink },
	{ 'IAAF', 'IAAF', 1146, p.iaafLink },
	{ 'ICCU', 'ICCU', 396, p.iccuLink }, --formerly SBN
	{ 'ICIA', 'ICIA', 1736, p.iciaLink },
	{ 'ISNI', 'ISNI', 213, p.isniLink },
	{ 'Joconde', 'Joconde' , 347, p.jocondeLink },
	{ 'KULTURNAV', 'KulturNav', 1248, p.kulturnavLink },
	{ 'LCCN', 'LCCN', 244, p.lccnLink },
	{ 'LIR', 'LIR', 886, p.lirLink },
	{ 'LNB', 'LNB', 1368, p.lnbLink },
	{ 'Léonore', 'Léonore', 640, p.leonoreLink },
	{ 'MBA', 'MBA', 434, p.mbaLink, category = 'MusicBrainz' }, --special category name
	{ 'MBAREA', 'MBAREA', 982, p.mbareaLink, category = 'MusicBrainz area' }, --special category name
	{ 'MBI', 'MBI', 1330, p.mbiLink, category = 'MusicBrainz instrument' }, --special category name
	{ 'MBL', 'MBL', 966, p.mblLink, category = 'MusicBrainz label' }, --special category name
	{ 'MBP', 'MBP', 1004, p.mbpLink, category = 'MusicBrainz place' }, --special category name
	{ 'MBRG', 'MBRG', 436, p.mbrgLink, category = 'MusicBrainz release group' }, --special category name
	{ 'MBS', 'MBS', 1407, p.mbsLink, category = 'MusicBrainz series' }, --special category name
	{ 'MBW', 'MBW work', 435, p.mbwLink, category = 'MusicBrainz work' }, --special category name
	{ 'MGP', 'MGP', 549, p.mgpLink },
	{ 'NARA', 'NARA', 1225, p.naraLink },
	{ 'NCL', 'NBL', 1048, p.nclLink },
	{ 'NDL', 'NDL', 349, p.ndlLink },
	{ 'NGV', 'NGV', 2041, p.ngvLink },
	{ 'NKC', 'NKC', 691, p.nkcLink },
	{ 'NLA', 'NLA', 409, p.nlaLink },
	{ 'NLG', 'NLG', 3348, p.nlgLink },
	{ 'NLI', 'NLI', 949, p.nliLink },
	{ 'NLK', 'NLK', 5034, p.nlkLink },
	{ 'NLP', 'NLP', 1695, p.nlpLink },
	{ 'NLR', 'NLR', 1003, p.nlrLink },
	{ 'NSK', 'NSK', 1375, p.nskLink },
	{ 'NTA', 'NTA', 1006, p.ntaLink },
	{ 'ORCID', 'ORCID', 496, p.orcidLink },
	{ 'PIC', 'PIC', 2750, p.picLink },
	{ 'PLWABN', 'PLWABN', 7293, p.plwabnLink },
	{ 'RID', 'ResearcherID', 1053, p.ridLink },
	{ 'RERO', 'RERO', 3065, p.reroLink },
	{ 'RKDartists', 'RKD', 650, p.rkdartistsLink },
	{ 'RKDID', 'RKDimages ID', 350, p.rkdidLink },
	{ 'RSL', 'RSL', 947, p.rslLink },
	{ 'SELIBR', 'SELIBR', 906, p.selibrLink },
	{ 'SIKART', 'SIKART', 781, p.sikartLink },
	{ 'SNAC-ID', 'SNAC', 3430, p.snacLink },
	{ 'SUDOC', 'SUDOC', 269, p.sudocLink },
	{ 'S2AuthorId', 'S2AuthorId', 4012, p.s2authoridLink, category = 'Semantic Scholar author' }, --special category name
	{ 'TA98', 'TA98', 1323, p.ta98Link },
	{ 'TDVİA', 'TDVİA', 7314, p.tdviaLink },
	{ 'TE', 'TE', 1693, p.teLink },
	{ 'TePapa', 'TePapa', 3544, p.tepapaLink },
	{ 'TH', 'TH', 1694, p.thLink },
	{ 'TLS', 'TLS', 1362, p.tlsLink },
	{ 'Trove', 'Trove', 1315, p.troveLink }, --formerly NLA-person
	{ 'UKPARL', 'UKPARL', 6213, p.ukparlLink },
	{ 'ULAN', 'ULAN', 245, p.ulanLink },
	{ 'USCongress', 'US Congress', 1157, p.uscongressLink },
	{ 'VcBA', 'VcBA', 8034, p.vcbaLink },
	{ 'VIAF', 'VIAF', 214, p.viafLink },
	{ 'WORLDCATID', 'WorldCat Identities', 7859, nil },
}
-- Legitimate aliases to p.conf, for convenience
-- Format: { 'alias', 'parameter name in p.conf' }
p.aliases = {
	{ 'Leonore', 'Léonore' }, --alias name without diacritics
	{ 'leonore', 'Léonore' }, --lowercase variant without diacritics
	{ 'MusicBrainz', 'MBA' },
	{ 'MusicBrainz artist', 'MBA' },
	{ 'MusicBrainz label', 'MBL' },
	{ 'MusicBrainz release group', 'MBRG' },
	{ 'MusicBrainz work', 'MBW' },
	{ 'SBN', 'ICCU' }, --SBN alias to be deprecated at a later stage
	{ 'TDVIA', 'TDVİA' }, --alias name without diacritics
	{ 'tdvia', 'TDVİA' }, --lowercase variant without diacritics
}
-- Deprecated aliases to p.conf; tracked in 
-- Format: { 'deprecated parameter name', 'replacement parameter name in p.conf' }
p.deprecated = {
	{ 'GKD', 'GND' },
	{ 'PND', 'GND' },
	{ 'RLS', 'RSL' },	
	{ 'SWD', 'GND' },
	{ 'NARA-organization', 'NARA' },
	{ 'NARA-person', 'NARA' },
}
--======================================================================**
--                                   Main                                   
--======================================================================**
function p.authorityControl( frame )
	local resolveEntity = require( "Module:ResolveEntityId" )
	local parentArgs = frame:getParent().args
	local elements = {} --create/insert rows later
	local worldcatCat = 
	local suppressedIdCat = 
	local deprecatedIdCat = 
	
	--Redirect aliases to proper parameter names
	for _, a in pairs( p.aliases ) do
		local alias, param = a1, a2
		if (parentArgsparam == nil or parentArgsparam == ) and parentArgsalias then
			parentArgsparam = parentArgsalias
		end
	end
	
	--Redirect deprecated parameters to proper parameter names, and assign tracking cat
	for _, d in pairs( p.deprecated ) do
		local dep, param = d1, d2
		if (parentArgsparam == nil or parentArgsparam == ) and parentArgsdep then
			parentArgsparam = parentArgsdep
			if namespace == 0 then
				deprecatedIdCat = ..dep..
			end
		end
	end
	
	--Use QID= parameter for testing/example purposes only
	local itemId = nil
	if namespace ~= 0 then
		local qid = parentArgs'qid' or parentArgs'QID'
		if qid then
			itemId = 'Q'..mw.ustring.gsub(qid, '^Qq', )
			itemId = resolveEntity._id(itemId) --nil if unresolvable
		end
	else
		itemId = mw.wikibase.getEntityIdForCurrentPage()
	end
	
	--Wikidata fallback if requested
	if itemId then
		for _, params in ipairs( p.conf ) do
			if params3 > 0 then
				local val = parentArgsmw.ustring.lower(params1) or parentArgsparams1
				if val == nil or val ==  then
					local canUseWikidata = nil
					if reqsparams1 then
						canUseWikidata = p.matchesWikidataRequirements( itemId, reqsparams1 )
					else
						canUseWikidata = true
					end
					if canUseWikidata then
						local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params3 )
						if wikidataIds1 then
							if val ==  and (namespace == 0 or testcases) then
								suppressedIdCat = 'Thể loại:Bài viết Wikipedia chứa nhận dạng kiểm soát tính nhất quán bị chặn|'..params1..
							else
								parentArgsparams1 = wikidataIds1
	end	end	end	end	end	end	end
	
	--Configured rows
	local rct = 0
	for _, params in ipairs( p.conf ) do
		local val = parentArgsmw.ustring.lower(params1) or parentArgsparams1
		if val and val ~=  and type(params4) == 'function' then
			table.insert( elements, p.createRow( params1, params2..':', val, params4( val ), true, params.category ) )
			rct = rct + 1
		end
	end
	
	--WorldCat
	local worldcatId = parentArgs'worldcatid' or parentArgs'WORLDCATID'
	if worldcatId and worldcatId ~=  then --if WORLDCATID present & unsuppressed
		table.insert( elements, p.createRow( 'WORLDCATID', , worldcatId, 'WorldCat Identities:  'PATH')..' '..worldcatId.., false ) ) --Validation?
		worldcatCat = p.getCatForId( 'WORLDCATID' )
	elseif worldcatId == nil then --if WORLDCATID absent but unsuppressed
		local viafId = parentArgs'viaf' or parentArgs'VIAF'
		local lccnId = parentArgs'lccn' or parentArgs'LCCN'
		if viafId and viafId ~=  and p.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validated
			table.insert( elements, p.createRow( 'VIAF', , viafId, 'WorldCat Identities (via VIAF):  '..viafId.., false ) )
			if namespace == 0 then 
				worldcatCat = 
			end
		elseif lccnId and lccnId ~=  and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
			local lccnParts = p.splitLccn( lccnId )
			if lccnParts and lccnParts1 ~= 'sh' then
				local lccnIdFmtd = lccnParts1..lccnParts2..'-'..lccnParts3
				table.insert( elements, p.createRow( 'LCCN', , lccnId, 'WorldCat Identities (via LCCN):  '..lccnIdFmtd.., false ) )
				if namespace == 0 then
					worldcatCat = 'Thể loại:Bài viết chứa nhận dạng WorldCat-LCCN'
				end
			end
		end
	elseif worldcatId ==  then --if WORLDCATID suppressed
		suppressedIdCat = 'WORLDCATID'
	end
	
	local Navbox = require('Module:Navbox')
	local elementsCat = 
	if rct == 0 or rct >= 25 then
		local eCat = 'Kiểm soát tính nhất quán với '..rct..' yếu tố'
		elementsCat  = ..p.redCatLink(eCat)
	end
	
	local outString = 
	if #elements > 0 then
		local args = { pid = 'identifiers' } -- #target the list of identifiers
		if testcases and itemId then args = { pid = 'identifiers', qid = itemId } end --expensive
		local pencil = frame:expandTemplate{ title = 'EditAtWikidata', args = args}
		outString = Navbox._navbox( {
			name  = 'Authority control',
			navboxclass = 'authority-control',
			bodyclass = 'hlist',
			group1 = 'Tiêu đề chuẩn'..pencil,
			list1 = table.concat( elements )
			} )
	end
	local auxCats = worldcatCat .. elementsCat .. suppressedIdCat .. deprecatedIdCat
	if testcases then
		auxCats = mw.ustring.gsub(auxCats, '(%%)(Category)', '%1:%2') --for easier checking
	end
	outString = outString .. auxCats
	if namespace ~= 0 then
		outString = mw.ustring.gsub(outString, '(%%)(Thể loại:Bài viết)', '%1:%2') --by definition
	end
	
	return outString
end
return p