모듈:Authority control

위키백과, 우리 모두의 백과사전.
모듈 설명문서[보기] [편집] [역사] [새로 고침]

이 모듈은 {{전거 통제}} 틀의 루아 코드를 담고 있습니다. 해당 틀의 설명문서를 참고하세요.

변수, 위키데이터 속성, 추적용 분류

변수 문단 표시 위키데이터 속성 추적용 분류와 문서 수
문서 사용자 문서 기타 문서 잘못된 ID
AAG 미술관 오클랜드 Auckland Art Gallery artist ID (P3372) 161 0 0 0
ACM-DL 학술 데이터베이스 ACM ACM 전자도서관 저자 식별자 (P864) 135 0 0 0
ADB 인명 사전 오스트레일리아 Australian Dictionary of Biography ID (P1907) 86 0 0 1
AGSA 미술관 사우스오스트레일리아주 Art Gallery of South Australia creator ID (P6804) 158 0 0 0
autores.uy 인명 사전 우루과이 autores.uy ID (P2558) 19 0 0 0
AWR 인명 사전 Australian Women's Register Australian Women's Register ID (P4186) 54 0 0 0
BIBSYS 국립도서관 노르웨이 BIBSYS ID (P1015) 11,114 0 0 0
Bildindex 미술 연구소 Bildindex (독일) Bildindex der Kunst und Architektur ID (P2092) 1 0 0 0
BNC 국립도서관 칠레 CCAB ID (P1890) 655 0 0 0
BNE 국립도서관 스페인 스페인 국립도서관 ID (P950) 20,577 0 0 0
BNF 국립도서관 프랑스 (데이터) 프랑스 국립도서관 ID (P268) 41,232 1 0 0
Botanist 학술 데이터베이스 국제 식물명 색인 식물학자 약자 (P428) 136 0 0 0
BPN 인명 사전 네덜란드 Biografisch Portaal van Nederland ID (P651) 455 0 0 0
CANTIC 국립도서관 카탈루냐 카탈루냐 국립도서관 ID (P1273) 7,298 0 0 0
CINII 학술 데이터베이스 CiNii (일본) CiNii 저자 식별자 (P271) 7,054 0 0 0
CWGC 기타 연합군인묘지위원회 CWGC 인물 ID (P1908) 20 0 0 0
DAAO 미술 연구소 Australian Artists DAAO ID (P1707) 21 0 0 1
DBLP 학술 데이터베이스 DBLP (컴퓨터 과학) DBLP ID (P2456) 406 0 0 0
DIB 인명 사전 아일랜드 Dictionary of Irish Biography ID (P6829) 229 0 0 0
DSI 미술 연구소 Scientific illustrators Stuttgart Database of Scientific Illustrators ID (P2349) 154 0 0 0
FAST 기타 Faceted Application of Subject Terminology FAST ID (P2163) 27,790 0 0 0
FNZA 미술 연구소 뉴질랜드 아티스트 Find NZ Artists ID (P6792) 13 0 0 0
GND 일반 게마인자메 노름다타이 (독일) GND 식별자 (P227) 57,870 1 6 0
HDS 기타 스위스 역사 사전 HDS ID (P902) 1,418 0 0 0
IAAF 기타 월드 애슬레틱스 국제육상경기연맹 ID (P1146) 788 0 0 0
ICCU 국립도서관 이탈리아 이탈리아 국가도서관서비스 ID (P396) 3,288 0 0 0
ICIA 미술 연구소 ICIA (이스라엘) Information Center for Israeli Art artist ID (P1736) 6 0 0 0
IEU 기타 우크라이나 인터넷 백과사전 Internet Encyclopedia of Ukraine ID (P9070) 217 0 0 0
ISNI 일반 ISNI ISNI (P213) 49,825 1 0 0
Joconde 미술 연구소 Joconde (프랑스) Joconde (P347) 5 0 0 0
KULTURNAV 미술 연구소 KulturNav (노르웨이) KulturNav-ID (P1248) 447 0 0 0
LCCN 국립도서관 미국 미국 의회도서관 전거 ID (P244) 71,806 1 6 0
LIR 기타 Lexicon Istoric Retic (스위스) LIR (P886) 23 0 0 0
LNB 국립도서관 라트비아 라트비아 국립도서관 ID (P1368) 4,850 0 0 0
Léonore 기타 Léonore (프랑스) Léonore ID (P640) 401 0 0 2
MA 기타 마이크로소프트 아카데믹 마이크로소프트 학술 ID (P6366) 9,087 0 0 1
MBA 기타 뮤직브레인즈 아티스트 뮤직브레인즈 아티스트 ID (P434) 17,705 0 0 0
MBAREA 기타 뮤직브레인즈 지역 뮤직브레인즈 지역 ID (P982) 8,224 0 0 0
MBI 기타 뮤직브레인즈 악기 뮤직브레인즈 악기 ID (P1330) 99 0 0 0
MBL 기타 뮤직브레인즈 레이블 뮤직브레인즈 레이블 ID (P966) 177 0 0 0
MBP 기타 뮤직브레인즈 장소 뮤직브레인즈 장소 ID (P1004) 361 0 0 0
MBRG 기타 뮤직브레인즈 릴리스 그룹 뮤직브레인즈 음반 목록 ID (P436) 3,514 0 0 0
MBS 기타 뮤직브레인즈 시리즈 뮤직브레인즈 주제별 목록 ID (P1407) 40 0 0 0
MBW 기타 뮤직브레인즈 작품 뮤직브레인즈 작품 ID (P435) 824 0 0 0
MGP 학술 데이터베이스 수학 계보 프로젝트 수학 계보 프로젝트 ID (P549) 1,372 0 0 0
NARA 기타 국립문서기록관리청 (미국) 미 국립문서기록관리청 식별자 (P1225) 7,861 0 0 0
NCL 국립도서관 타이완 NCL 식별자 (P1048) 125 0 0 1
NDL 국립도서관 일본 일본 국립국회도서관 ID (P349) 24,646 0 0 0
NGV 미술관 빅토리아 빅토리아 국립미술관 예술가 ID (P2041) 326 0 0 0
NKC 국립도서관 체코 체코 국립도서관 ID (P691) 27,419 0 0 0
NLA 국립도서관 오스트레일리아 오스트레일리아 국립도서관 ID (P409) 8,050 0 0 0
NLG 국립도서관 그리스 그리스 국립도서관 ID (P3348) 4,131 0 0 0
NLI 국립도서관 이스라엘 이스라엘 국립도서관 ID (P949) 9,061 0 0 0
NLK 국립도서관 한국 대한민국 국립중앙도서관 ID (P5034) 13,978 0 0 0
NLP 국립도서관 폴란드 폴란드 국립도서관 식별자 (P1695) 136 0 0 0
NLR 국립도서관 루마니아 루마니아 국립도서관 식별자 (P1003) 114 0 0 0
NSK 국립도서관 크로아티아 자그레브 국립대학도서관 식별자 (P1375) 3,095 0 0 0
NTA 국립도서관 네덜란드 네덜란드 국립도서관 저자 ID (P1006) 22,606 0 0 0
ORCID 일반 ORCID ORCID iD (P496) 232 1 0 0
PIC 미술 연구소 Photographers' Identities 사진가의 식별자 카탈로그 ID (P2750) 509 0 0 0
PLWABN 국립도서관 폴란드 PLWABN ID (P7293) 18,539 0 0 0
Publons 학술 데이터베이스 Publons (researchers) Publons author ID (P3829) 30 0 0 0
RID 학술 데이터베이스 ResearcherID ResearcherID (P1053) 38 0 0 0
RISM 기타 RISM (프랑스) RISM ID (P5504) 1,627 0 0 0
RERO 기타 RERO (스위스) RERO ID (P3065) 4,509 0 0 1
RKDartists 미술 연구소 RKD Artists (네덜란드) RKDartists ID (P650) 1,692 0 0 0
RKDID 미술 연구소 RKD ID (네덜란드) RKDimages (P350) 4 0 0 0
RSL 국립도서관 러시아 러시아 국립도서관 인물 ID (P947) 370 0 0 0
SELIBR 국립도서관 스웨덴 스웨덴 도서관정보시스템 ID (P906) 7,820 0 0 0
SIKART 미술 연구소 SIKART (스위스) SIKART ID (P781) 49 0 0 0
SNAC-ID 기타 Social Networks and Archival Context SNAC ARK ID (P3430) 15,308 0 0 0
SUDOC 기타 SUDOC (프랑스) SUDOC 전거 식별자 (P269) 29,414 0 0 0
S2AuthorId 학술 데이터베이스 시맨틱 스콜라 Semantic Scholar author ID (P4012) 102 0 0 0
TA98 학술 데이터베이스 Terminologia Anatomica Terminologia Anatomica 98 ID (P1323) 179 0 0 0
TDVİA 기타 이슬람 백과사전 TDV İslam Ansiklopedisi ID (P7314) 587 0 0 0
TePapa 미술관 Te Papa (뉴질랜드) Te Papa agent ID (P3544) 468 0 0 0
TLS 기타 Theaterlexikon (스위스) Theaterlexikon der Schweiz ID (P1362) 82 0 0 0
Trove 기타 Trove (오스트레일리아) NLA Trove ID (P1315) 9,698 0 0 0
UKPARL 기타 영국 의회 UK Parliament identifier (P6213) 70 0 0 0
ULAN 미술 연구소 Artist Names (Getty) ULAN ID (P245) 3,255 0 0 0
USCongress 기타 미국 의회 US Congress Bio ID (P1157) 367 0 0 0
VcBA 국립도서관 바티칸 Vatican Library VcBA ID (P8034) 5,167 0 0 0
VIAF 일반 VIAF VIAF 식별자 (P214) 85,652 1 3 2
WORLDCATID 일반 월드캣 WorldCat Identities ID (P7859) 76,034 0 0 0
일반 월드캣 (미국 의회도서관을 통해) 176
일반 월드캣 (VIAF를 통해) 9,662

require('Module:No globals')

local p = {}
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local testcases = (string.sub(title.subpageText,1,3) == '시험장')

--[[==========================================================================]]
--[[                            Category functions                            ]]
--[[==========================================================================]]

function p.getCatForId( id )
	local catName = ''
	if namespace == 0 then
		catName = id..' 식별자를 포함한 위키백과 문서'
	elseif namespace == 2 and not title.isSubpage then
		catName = id..' 식별자를 포함한 사용자 문서'
	else
		catName = id..' 식별자를 포함한 기타 문서'
	end
	return '[[분류:'..catName..']]'..p.redCatLink(catName)
end

function p.redCatLink( catName ) --catName == 'Blah' (not 'Category:Blah', not '[[Category:Blah]]')
	if catName and catName ~= '' and
	   testcases == false and
	   mw.title.new(catName, 14).exists == false
	then
		return '[[분류:깨진 전거 통제 분류를 포함한 문서]]'
	end
	return ''
end

function p.createRow( id, rawValues, link, links, withUid, specialCat, prefix)
	local catName = '잘못된 '..(specialCat or id)..' 식별자를 포함한 위키백과 문서'
	if links then -- all links[] use withUid = false; no check needed
		local row = ''
		if prefix then 
			row = row .. '*' .. prefix
		end
		for i, l in ipairs( links ) do
			if i == 1 and not prefix then row = row..'*'
			else           row = row..'\n**' end
			if l then
				row = row..'<span class="uid">'..l..'</span>'
			else
				row = row..'<span class="error">'..id..' id '..rawValues[i]..' 값은 유효하지 않습니다.</span>[[분류:'..catName..']]'..p.redCatLink(catName)
			end
		end
		return row..'\n'
	elseif link then -- All IDs that have a prefix support multiple identifiers, so prefix is not needed
		if withUid then
			return '*<span class="nowrap"><span class="uid">'..link..'</span></span>\n'
		end
		return '*<span class="nowrap">'..link..'</span>\n'
	end
	
	return '* <span class="error">The '..id..' id '..rawValues..' is not valid.</span>[[분류:'..catName..']]'..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, label)
	--P3372's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[https://www.aucklandartgallery.com/explore-art-and-ideas/artist/'..id..'/ '..(label or '오클랜드')..']'..p.getCatForId( 'AAG' )
end

function p.acmLink( id, label )
	--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 '[https://dl.acm.org/profile/'..id..' '..(label or 'ACM')..']'..p.getCatForId( 'ACM-DL' )
end

function p.adbLink( id, label )
	--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 '[http://adb.anu.edu.au/biography/'..id..' '..(label or '오스트레일리아')..']'..p.getCatForId( 'ADB' )
end

function p.agsaLink( id, label )
	--P6804's format regex: [1-9]\d* (e.g. 3625)
	if not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[https://www.agsa.sa.gov.au/collection-publications/collection/creators/_/'..id..'/ '..(label or '사우스오스트레일리아주')..']'..p.getCatForId( 'AGSA' )
end

function p.autoresuyLink( id, label )
	--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 '[https://autores.uy/autor/'..id..' '..(label or '우루과이')..']'..p.getCatForId( 'autores.uy' )
end

function p.awrLink( id, label )
	--P4186's format regex: (([A-Z]{3}\d{4})|([A-Z]{2}\d{5}))[a-z] (e.g. PR00768b)
	if not id:match( '^[A-Z][A-Z][A-Z]%d%d%d%d[a-z]$' ) and
	   not id:match( '^[A-Z][A-Z]%d%d%d%d%d[a-z]$' ) then
		return false
	end
	return '[http://www.womenaustralia.info/biogs/'..id..'.htm '..(label or 'Australian Women\'s Register')..']'..p.getCatForId( 'AWR' )
end

function p.bibsysLink( id, label )
	--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 '[https://authority.bibsys.no/authority/rest/authorities/html/'..id..' '..(label or '노르웨이')..']'..p.getCatForId( 'BIBSYS' )
end

function p.bildLink( id, label )
	--P2092's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[https://www.bildindex.de/document/obj'..id..' '..(label or 'Bildindex (독일)')..']'..p.getCatForId( 'Bildindex' )
end

function p.bncLink( id, label )
	--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 '[http://www.bncatalogo.cl/F?func=direct&local_base=red10&doc_number='..id..' '..(label or '칠레')..']'..p.getCatForId( 'BNC' )
end

function p.bneLink( id, label )
	--P950's format regex: (XX|FF|a)\d{4,7}|(bima|bimo|bica|bis[eo]|bivi|Mise|Mimo|Mima)\d{10} (e.g. XX1234567)
	if not id:match( '^[XF][XF]%d%d%d%d%d?%d?%d?$' ) and
	   not id:match( '^a%d%d%d%d%d?%d?%d?$' ) and
	   not id:match( '^bi[mcsv][aoei]%d%d%d%d%d%d%d%d%d%d$' ) and
	   not id:match( '^Mi[sm][eoa]%d%d%d%d%d%d%d%d%d%d$' ) then
		return false
	end
	return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id='..id..' '..(label or '스페인')..']'..p.getCatForId( 'BNE' ) --no https as of 9/2019
end

function p.bnfLink( id, label )
	--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789)
	if not id:match( '^c?b?%d%d%d%d%d%d%d%d[0-9bcdfghjkmnpqrstvwxz]$' ) then
		return false
	end
	--Add cb prefix if it has been removed
	if not id:match( '^cb.+$' ) then
		id = 'cb'..id
	end
	return '[https://catalogue.bnf.fr/ark:/12148/'..id..' ' .. (label or '프랑스')..'] [https://data.bnf.fr/ark:/12148/'..id..' (데이터)]'..p.getCatForId( 'BNF' )
end

function p.botanistLink( id, label )
	--P428's format regex: ('t )?(d')?(de )?(la )?(van (der )?)?(Ma?c)?(De)?(Di)?\p{Lu}?C?['\p{Ll}]*([-'. ]*(van )?(y )?(d[ae][nr]?[- ])?(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
	id = id:gsub(' +', '%%20')
	return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id..' '..(label or '국제 식물명 색인')..']'..p.getCatForId( 'Botanist' )
end

function p.bpnLink( id, label )
	--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 '[http://www.biografischportaal.nl/en/persoon/'..id..' '..(label or '네덜란드')..']'..p.getCatForId( 'BPN' ) --no https as of 9/2019
end

function p.canticLink( id, label )
	--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 '[http://cantic.bnc.cat/registres/CUCId/'..id..' '..(label or '카탈루냐')..']'..p.getCatForId( 'CANTIC' ) --no https as of 10/2019
end

function p.ciniiLink( id, label )
	--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 '[https://ci.nii.ac.jp/author/'..id..'?l=en '..(label or 'CiNii (일본)')..']'..p.getCatForId( 'CINII' )
end

function p.cwgcLink( id, label )
	--P1908's format regex: [1-9]\d* (e.g. 75228351)
	if not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[https://www.cwgc.org/find-war-dead/casualty/'..id..'/ '..(label or '연합군인묘지위원회')..']'..p.getCatForId( 'CWGC' )
end

function p.daaoLink( id, label )
	--P1707's format regex: [a-z\-]+\d* (e.g. rolf-harris)
	if not id:match( '^[a-z%-]+%d*$' ) then
		return false
	end
	return '[https://www.daao.org.au/bio/'..id..' '..(label or 'Australian Artists')..']'..p.getCatForId( 'DAAO' )
end

function p.dblpLink( id, label )
	--P2456's format regex: \d{2,3} /\d+(-\d+)?|[a-z] /[a-zA-Z][0-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-Z][0-9A-Za-z]*$' ) and
	   not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*%-%d+$' ) then
		return false
	end
	return '[https://dblp.org/pid/'..id..' '..(label or 'DBLP (컴퓨터 과학)')..']'..p.getCatForId( 'DBLP' )
end

function p.dibLink( id, label )
	--P6829's format regex: a\d{4}\d?(-[A-D])? (e.g. a1953)
	if not id:match( '^a%d%d%d%d%d?%-?[A-D]?$' ) then
		return false
	end
	return '[https://dib.cambridge.org/viewReadPage.do?articleId='..id..' '..(label or '아일랜드')..']'..p.getCatForId( 'DIB' )
end

function p.dsiLink( id, label )
	--P2349's format regex: [1-9]\d* (e.g. 1538)
	if not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[http://www.uni-stuttgart.de/hi/gnt/dsi2/index.php?table_name=dsi&function=details&where_field=id&where_value='..id..' '..(label or 'Scientific illustrators')..']'..p.getCatForId( 'DSI' )
end

function p.fastLink( id, label )
	--P2163's format regex: [1-9]\d{0,7} (e.g. 1916996)
	if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[http://id.worldcat.org/fast/'..id..'/ '..(label or 'Faceted Application of Subject Terminology')..']'..p.getCatForId( 'FAST' )
end


function p.fnzaLink( id, label )
	--P6792's format regex: [1-9]\d* (e.g. 9785)
	if not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[https://findnzartists.org.nz/artist/'..id..'/ '..(label or '뉴질랜드 아티스트')..']'..p.getCatForId( 'FNZA' )
end

function p.gndLink( id, label )
	--P227's format regex: 1[012]?\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( '^1[012]?%d%d%d%d%d%d%d[0-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%d[0-9X]$' ) then
		return false
	end
	return '[https://d-nb.info/gnd/'..id..' '..(label or '게마인자메 노름다타이 (독일)')..']'..p.getCatForId( 'GND' )
end

function p.hdsLink( id, label )
	--P902's format regex: \d{6} (e.g. 050123)
	if not id:match( '^%d%d%d%d%d%d$' ) then
		return false
	end
	return '[https://hls-dhs-dss.ch/fr/articles/'..id..' '..(label or '스위스 역사 사전')..']'..p.getCatForId( 'HDS' )
end

function p.iaafLink( id, label )
	--P1146's format regex: [0-9][0-9]* (e.g. 012)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[https://www.iaaf.org/athletes/_/'..id..' '..(label or '월드 애슬레틱스')..']'..p.getCatForId( 'IAAF' )
end


function p.iccuLink( id, label )
	--P396's format regex: IT\\ICCU\\(\d{10}|\D\D[\D\d]\D\\\d{6}) (e.g. IT\ICCU\CFIV\000163)
	if not id:match( '^IT\\ICCU\\%d%d%d%d%d%d%d%d%d%d$' ) and
	   not id:match( '^IT\\ICCU\\%u%u[%u%d]%u\\%d%d%d%d%d%d$' ) then --legacy: %u used here instead of %D (but the faulty ID cat is empty, out of ~12k uses)
		return false
	end
	return '[https://opac.sbn.it/opacsbn/opac/iccu/scheda_authority.jsp?bid='..id..' '..(label or '이탈리아')..']'..p.getCatForId( 'ICCU' )
end
function p.iciaLink( id, label )
	--P1736's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[https://www.imj.org.il/artcenter/newsite/en/?artist='..id..' '..(label or 'ICIA (이스라엘)')..']'..p.getCatForId( 'ICIA' )
end

function p.ieuLink( id, label )
	--P9070's format regex: [A-Z]\\[A-Z]\\[A-Za-z0-9]+ (e.g. K\Y\Kyiv)
	if not id:match( '^[A-Z]\\[A-Z]\\%w+$' ) then
		return false
	end
	return '[http://www.encyclopediaofukraine.com/display.asp?linkpath=pages\\'..id..' '..(label or '우크라이나 인터넷 백과사전')..']'..p.getCatForId( 'IEU' )
end

function p.isniLink( id, label )
	id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
	if not id then
		return false
	end
	return '[https://isni.org/isni/'..id..' '..(label or 'ISNI')..']'..p.getCatForId( 'ISNI' )
end

function p.jocondeLink( id, label )
	--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 '[https://www.pop.culture.gouv.fr/notice/joconde/'..id..' '..(label or 'Joconde (프랑스)')..']'..p.getCatForId( 'Joconde' )
end

function p.kulturnavLink( id, label )
	--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 '[http://kulturnav.org/'..id..' '..(label or 'KulturNav (노르웨이)')..']'..p.getCatForId( 'KULTURNAV' ) --no https as of 9/2019
end

function p.lccnLink( id, label )
	local parts = p.splitLccn( id ) --e.g. n78039510
	if not parts then
		return false
	end
	local lccnType = parts[1] ~= 'sh' and 'names' or 'subjects'
	id = parts[1] .. parts[2] .. p.append( parts[3], '0', 6 )
	return '[https://id.loc.gov/authorities/'..lccnType..'/'..id..' '..(label or '미국')..']'..p.getCatForId( 'LCCN' )
end

function p.lirLink( id, label )
	--P886's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..(label or 'Lexicon Istoric Retic (스위스)')..']'..p.getCatForId( 'LIR' ) --no https as of 9/2019
end

function p.lnbLink( id, label )
	--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 '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..(label or '라트비아')..']'..p.getCatForId( 'LNB' )
end

function p.leonoreLink( id, label )
	--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 < 1954)
	   not id:match( '^C/0/%d%d?$' ) then                          --IDs from        C/0/1 to             C/0/84 (84 famous legionaries)
		return false
	end
	return '[http://www.culture.gouv.fr/public/mistral/leonore_fr?ACTION=CHERCHER&FIELD_1=COTE&VALUE_1='..id..' '..(label or 'Léonore (프랑스)')..']'..p.getCatForId( 'Léonore' ) --no https as of 9/2019
end

function p.maLink( id, label )
	--P6366's format regex: [1-9]\d{4,9} (e.g. 1498221862)
	if not id:match( '^[1-9]%d%d%d%d%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[https://academic.microsoft.com/v2/detail/'..id..' '..(label or '마이크로소프트 아카데믹')..']'..p.getCatForId( 'MA' )
end

function p.mbaLink( id, label )
	--P434'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
	local url = 'https://musicbrainz.org/artist/'..id
	local cat = p.getCatForId( 'MusicBrainz' )--special cat name
	if label then
		return '['..url..' '..label..']'..cat	
	else
		return '[[MBA (식별자)|뮤직브레인즈]] [' .. url .. ' 아티스트]' .. cat
	end
end

function p.mbareaLink( id, label )
	--P982'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
	local url = 'https://musicbrainz.org/area/'..id
	local cat = p.getCatForId( 'MusicBrainz area' )--special cat name
	if label then
		return '['..url..' '..label..']'..cat	
	else
		return '[[MBAREA (식별자)|뮤직브레인즈]] [' .. url .. ' 지역]' .. cat
	end
end

function p.mbiLink( id, label )
	--P1330'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
	local url = 'https://musicbrainz.org/instrument/'..id
	local cat = p.getCatForId( 'MusicBrainz instrument' )--special cat name
	if label then
		return '['..url..' '..label..']'..cat	
	else
		return '[[MBI (식별자)|뮤직브레인즈]] [' .. url .. ' 악기]' .. cat
	end
end

function p.mblLink( id, label )
	--P966'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
	local url = 'https://musicbrainz.org/label/'..id
	local cat = p.getCatForId( 'MusicBrainz label' )--special cat name
	if label then
		return '['..url..' '..label..']'..cat	
	else
		return '[[MBL (식별자)|뮤직브레인즈]] [' .. url .. ' 레이블]' .. cat
	end
end

function p.mbpLink( id, label )
	--P1004'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
	local url = 'https://musicbrainz.org/place/'..id
	local cat = p.getCatForId( 'MusicBrainz place' )--special cat name
	if label then
		return '['..url..' '..label..']'..cat	
	else
		return '[[MBP (식별자)|뮤직브레인즈]] [' .. url .. ' 장소]' .. cat
	end
end

function p.mbrgLink( id, label )
	--P436'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
	local url = 'https://musicbrainz.org/release-group/'..id
	local cat = p.getCatForId( 'MusicBrainz release group' )--special cat name
	if label then
		return '['..url..' '..label..']'..cat	
	else
		return '[[MBRG (식별자)|뮤직브레인즈]] [' .. url .. ' 릴리스 그룹]' .. cat
	end
end

function p.mbsLink( id, label )
	--P1407'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
	local url = 'https://musicbrainz.org/series/'..id
	local cat = p.getCatForId( 'MusicBrainz series' )--special cat name
	if label then
		return '['..url..' '..label..']'..cat	
	else
		return '[[MBS (식별자)|뮤직브레인즈]] [' .. url .. ' 시리즈]' .. cat
	end
end

function p.mbwLink( id, label )
	--P435'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
	
	local url = 'https://musicbrainz.org/work/'..id
	local cat = p.getCatForId( 'MusicBrainz work' )--special cat name
	if label then
		return '['..url..' '..label..']'..cat	
	else
		return '[[MBW (식별자)|뮤직브레인즈]] [' .. url .. ' 작품]' .. cat
	end
end

function p.mgpLink( id, label )
	--P549's format regex: \d{1,6} (e.g. 123456)
	if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[https://genealogy.math.ndsu.nodak.edu/id.php?id='..id..' '..(label or '수학 계보 프로젝트')..']'..p.getCatForId( 'MGP' )
end

function p.naraLink( id, label )
	--P1225's format regex: ^([1-9]\d{0,8})$ (e.g. 123456789)
	if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[https://catalog.archives.gov/id/'..id..' '..(label or '국립문서기록관리청 (미국)')..']'..p.getCatForId( 'NARA' )
end

function p.nclLink( id, label )
	--P1048's format regex: \d+ (e.g. 1081436)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence='..id..'&CON_LNG=ENG '..(label or '타이완')..']'..p.getCatForId( 'NCL' ) --no https as of 9/2019
end

function p.ndlLink( id, label )
	--P349's format regex: 0?\d{8} (e.g. 012345678)
	if not id:match( '^0?%d%d%d%d%d%d%d%d$' ) then
		return false
	end
	return '[https://id.ndl.go.jp/auth/ndlna/'..id..' '..(label or '일본')..']'..p.getCatForId( 'NDL' )
end

function p.ngvLink( id, label )
	--P2041's format regex: \d+ (e.g. 12354)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[https://www.ngv.vic.gov.au/explore/collection/artist/'..id..'/ '..(label or '빅토리아')..']'..p.getCatForId( 'NGV' )
end

function p.nkcLink( id, label )
	--P691's format regex: [a-z]{2,4}[0-9]{2,14} (e.g. abcd12345678901234)
	if not id:match( '^[a-z][a-z][a-z]?[a-z]?%d%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica='..id..'&CON_LNG=ENG '..(label or '체코')..']'..p.getCatForId( 'NKC' )
end

function p.nlaLink( id, label )
	--P409's format regex: [1-9][0-9]{0,11} (e.g. 123456789012)
	if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[https://nla.gov.au/anbd.aut-an'..id..' '..(label or '오스트레일리아')..']'..p.getCatForId( 'NLA' )
end

function p.nlgLink( id, label )
	--P3348's format regex: [1-9]\d* (e.g. 1)
	if not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[https://data.nlg.gr/resource/authority/record'..id..' '..(label or '그리스')..']'..p.getCatForId( 'NLG' )
end

function p.nliLink( id, label )
	--P949'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 '[http://uli.nli.org.il/F/?func=direct&doc_number='..id..'&local_base=nlx10'..' '..(label or '이스라엘')..']'..p.getCatForId( 'NLI' )
end

function p.nlkLink( id, label )
	--P5034's format regex: KA.(19|20).{7} (e.g. KAC201501465)
	if not id:match( '^KA.19.......$' ) and
	   not id:match( '^KA.20.......$' ) then
		return false
	end
	return '[https://nl.go.kr/authorities/resource/'..id..' '..(label or '한국')..']'..p.getCatForId( 'NLK' )
end

function p.nlpLink( id, label )
	--P1695's format regex: 9810[0-9]\d* or A[0-9]{7}[0-9X] (e.g. 9810123456789012345 or A10414836)
	if not id:match( '^9810%d+$' ) and
	   not id:match( '^A%d%d%d%d%d%d%d[%dX]$' ) then
		return false
	end
	return '[https://tools.wmflabs.org/wikidata-externalid-url?p=1695&id='..id..' '..(label or '폴란드')..']'..p.getCatForId( 'NLP' )
end

function p.nlrLink( id, label )
	--P1003'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 '[http://aleph.bibnat.ro:8991/F/?func=direct&local_base=NLR10&doc_number='..id..' '..(label or '루마니아')..']'..p.getCatForId( 'NLR' )
end

function p.nskLink( id, label )
	--P1375'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 '[http://katalog.nsk.hr/F/?func=direct&doc_number='..id..'&local_base=nsk10 '..(label or '크로아티아')..']'..p.getCatForId( 'NSK' ) --no https as of 9/2019
end

function p.ntaLink( id, label )
	--P1006's format regex: \d{8}[\dX] (e.g. 12345678X)
	if not id:match( '^%d%d%d%d%d%d%d%d[%dX]$' ) then
		return false
	end
	return '[http://data.bibliotheken.nl/id/thes/p'..id..' '..(label or '네덜란드')..']'..p.getCatForId( 'NTA' )
end

function p.orcidLink( id, label )
	id = p.validateIsni( id ) --e.g. 0000-0002-7398-5483
	if not id then
		return false
	end
	id = id:sub( 1, 4 )..'-'..id:sub( 5, 8 )..'-'..id:sub( 9, 12 )..'-'..id:sub( 13, 16 )
	return '[https://orcid.org/'..id..' '..(label or 'ORCID')..']'..p.getCatForId( 'ORCID' )
end

function p.picLink( id, label )
	--P2750's format regex: [1-9]\d* (e.g. 1)
	if not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[https://pic.nypl.org/constituents/'..id..' '..(label or 'Photographers\' Identities')..']'..p.getCatForId( 'PIC' )
end

function p.plwabnLink( id, label )
	--P7293's format regex: 981[0-9]{8}05606 (e.g. 9810696457305606)
	if not id:match( '^981%d%d%d%d%d%d%d%d05606*$' ) then
		return false
	end
	return '[http://mak.bn.org.pl/cgi-bin/KHW/makwww.exe?BM=1&NU=1&IM=4&WI='..id..' '..(label or '폴란드')..']'..p.getCatForId( 'PLWABN' )
end

function p.publonsLink( id, label )
	--P3829's format regex: \d+ (e.g. 654601)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[https://publons.com/author/'..id..'/ '..(label or 'Publons (researchers)')..']'..p.getCatForId( 'Publons' )
end

function p.ridLink( id, label )
	--P1053's format regex: [A-Z]{1,3}-\d{4}-(19|20)\d\d (e.g. AAS-5150-2020)
	if not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-19%d%d$' ) and
	   not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-20%d%d$' ) then
		return false
	end
	return '[https://www.researcherid.com/rid/'..id..' '..(label or 'ResearcherID')..']'..p.getCatForId( 'RID' )
end

function p.rismLink( id, label )
	--P5504's format regex: (pe|ks)?\[1-9]d* (e.g. pe30006410)
	if not id:match( '^pe[1-9]%d*$' ) and --99% start with 'pe'
	   not id:match( '^ks[1-9]%d*$' ) and
	   not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[https://opac.rism.info/search?id='..id..' '..(label or 'RISM (프랑스)')..']'..p.getCatForId( 'RISM' )
end

function p.reroLink( id, label )
	--P3065's format regex: 0[1-2]-[A-Z0-9]{1,10} (e.g. 02-A012345678)
	if not id:match( '^0[1-2]%-[A-Z%d][A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?$' ) then
		return false
	end
	return '[http://data.rero.ch/'..id..' '..(label or 'RERO (스위스)')..']'..p.getCatForId( 'RERO' )
end

function p.rkdartistsLink( id, label )
	--P650's format regex: [1-9]\d{0,5} (e.g. 123456)
	if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[https://rkd.nl/en/explore/artists/'..id..' '..(label or 'RKD Artists (네덜란드)')..']'..p.getCatForId( 'RKDartists' )
end

function p.rkdidLink( id, label )
	--P350's format regex: [1-9]\d{0,5} (e.g. 123456)
	if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[https://rkd.nl/nl/explore/images/'..id..' '..(label or 'RKD ID (네덜란드)')..']'..p.getCatForId( 'RKDID' )
end

function p.rslLink( id, label )
	--P947's format regex: \d{1,9} (e.g. 123456789)
	if not id:match( '^%d%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
		return false
	end
	return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request='..id..'&CON_LNG=ENG '..(label or '러시아')..']'..p.getCatForId( 'RSL' ) --no https as of 9/2019
end

function p.selibrLink( id, label )
	--P906's format regex: [1-9]\d{4,5} (e.g. 123456)
	if not id:match( '^[1-9]%d%d%d%d%d?$' ) then
		return false
	end
	return '[https://libris.kb.se/auth/'..id..' '..(label or '스웨덴')..']'..p.getCatForId( 'SELIBR' )
end

function p.sikartLink( id, label )
	--P781's format regex: \d{7,9} (e.g. 123456789)
	if not id:match( '^%d%d%d%d%d%d%d%d?%d?$' ) then
		return false
	end
	return '[http://www.sikart.ch/KuenstlerInnen.aspx?id='..id..'&lng=en '..(label or 'SIKART (스위스)')..']'..p.getCatForId( 'SIKART' ) --no https as of 9/2019
end

function p.snacLink( id, label )
	--P3430's format regex: \d*[A-Za-z][0-9A-Za-z]* (e.g. A)
	if not id:match( '^%d*[A-Za-z][0-9A-Za-z]*$' ) then
		return false
	end
	return '[https://snaccooperative.org/ark:/99166/'..id..' '..(label or 'Social Networks and Archival Context')..']'..p.getCatForId( 'SNAC-ID' )
end

function p.sudocLink( id, label )
	--P269's format regex: (\d{8}[\dX]|) (e.g. 026927608)
	if not id:match( '^%d%d%d%d%d%d%d%d[%dxX]$' ) then --legacy: allow lowercase 'x'
		return false
	end
	return '[https://www.idref.fr/'..id..' '..(label or 'SUDOC (프랑스)')..']'..p.getCatForId( 'SUDOC' )
end

function p.s2authoridLink( id, label )
	--P4012's format regex: [1-9]\d* (e.g. 1796130)
	if not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[https://www.semanticscholar.org/author/'..id..' '..(label or '시맨틱 스콜라')..']'..p.getCatForId( 'Semantic Scholar author' ) --special cat name
end

function p.ta98Link( id, label )
	--P1323's format regex: A\d{2}\.\d\.\d{2}\.\d{3}[FM]? (e.g. A12.3.45.678)
	if not id:match( '^A%d%d%.%d%.%d%d%.%d%d%d[FM]?$' ) then
		return false
	end
	return '[http://tools.wmflabs.org/wikidata-externalid-url/?p=1323&url_prefix=https:%2F%2Fwww.unifr.ch%2Fifaa%2FPublic%2FEntryPage%2FTA98%20Tree%2FEntity%20TA98%20EN%2F&url_suffix=%20Entity%20TA98%20EN.htm&id='..id..' '..(label or 'Terminologia Anatomica')..']'..p.getCatForId( 'TA98' )
end

function p.tdviaLink( id, label )
	--P7314's format regex: [a-z/-]+] (e.g. barkan-omer-lutfi)
	if not id:match( '^[a-z/-]+$' ) then
		return false
	end
	return '[https://islamansiklopedisi.org.tr/'..id..' '..(label or '이슬람 백과사전')..']'..p.getCatForId( 'TDVİA' )
end

function p.tepapaLink( id, label )
	--P3544's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[https://collections.tepapa.govt.nz/agent/'..id..' '..(label or 'Te Papa (뉴질랜드)')..']'..p.getCatForId( 'TePapa' )
end

function p.tlsLink( id, label )
	id = id:gsub(' +', '_')
	--P1362's format regex: \p{Lu}[\p{L}\d_',\.\-\(\)\*/–]{3,59} (e.g. Abcd)
	local class = "[%a%d_',%.%-%(%)%*/–]"
	local regex = "^%u"..string.rep(class, 3)..string.rep(class.."?", 56).."$"
	if not mw.ustring.match( id, regex ) then
		return false
	end
	return '[http://tls.theaterwissenschaft.ch/wiki/'..id..' '..(label or 'Theaterlexikon (스위스)')..']'..p.getCatForId( 'TLS' ) --no https as of 9/2019
end

function p.troveLink( id, label )
	--P1315's format regex: [1-9]\d{5,7} (e.g. 12345678)
	if not id:match( '^[1-9]%d%d%d%d%d%d?%d?$' ) then
		return false
	end
	return '[https://trove.nla.gov.au/people/'..id..' '..(label or 'Trove (오스트레일리아)')..']'..p.getCatForId( 'Trove' )
end

function p.ukparlLink( id, label )
	--P6213's format regex: [a-zA-Z\d]{8} (e.g. AQUupyiR)
	if not id:match( '^[a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d]$' ) then
		return false
	end
	return '[https://id.parliament.uk/'..id..' '..(label or '영국 의회')..']'..p.getCatForId( 'UKPARL' )
end

function p.ulanLink( id, label )
	--P245's format regex: 500\d{6} (e.g. 500123456)
	if not id:match( '^500%d%d%d%d%d%d$' ) then
		return false
	end
	return '[https://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid='..id..' '..(label or 'Artist Names (Getty)')..']'..p.getCatForId( 'ULAN' )
end

function p.uscongressLink( id, label )
	--P1157's format regex: [A-Z]00[01]\d{3} (e.g. A000123)
	if not id:match( '^[A-Z]00[01]%d%d%d$' ) then
		return false
	end
	return '[http://bioguide.congress.gov/scripts/biodisplay.pl?index='..id..' '..(label or '미국 의회')..']'..p.getCatForId( 'USCongress' ) --no https as of 9/2019
end

function p.vcbaLink( id, label )
	--P8034's format regex: \d{3}\/[1-9]\d{0,5} (e.g. 494/9793)
	if not id:match( '^%d%d%d\/[1-9]%d?%d?%d?%d?%d?$' ) then
		return false
	end
	id = id:gsub('\/', '_')
	return '[https://opac.vatlib.it/auth/detail/'..id..' '..(label or '바티칸')..']'..p.getCatForId( 'VcBA' )
end

function p.viafLink( id, label )
	--P214's format regex: [1-9]\d(\d{0,7}|\d{17,20}) (e.g. 123456789, 1234567890123456789012)
	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%d%d%d%d%d%d%d?%d?%d?$' ) then
		return false
	end
	-- If the "VIAF" entry at [[:m:Interwiki map]] would resolve to "https://viaf.org/viaf/$1" (rather than "http://viaf.org/viaf/$1", as it currently still does), the code below could change from '[https://viaf.org/viaf/'..id..' '..id..']' to '[[:VIAF:'..id..'|'..id..']]'.
	return '[https://viaf.org/viaf/'..id..' '..(label or 'VIAF')..']'..p.getCatForId( 'VIAF' )
end

--[[=========================== Helper functions =============================]]

function p.append(str, c, length)
	while str:len() < length do
		str = c .. str
	end
	return str
end

--Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145
function p.getIsniCheckDigit( isni )
	local total = 0
	for i = 1, 15 do
		local digit = isni:byte( i ) - 48 --Get integer value
		total = (total + digit) * 2
	end
	local remainder = total % 11
	local result = (12 - remainder) % 11
	if result == 10 then
		return "X"
	end
	return tostring( result )
end

--Validate ISNI (and ORCID) and retuns it as a 16 characters string or returns false if it's invalid
--See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
function p.validateIsni( id )
	--P213 (ISNI) format regex: [0-9]{4} [0-9]{4} [0-9]{4} [0-9]{3}[0-9X] (e.g. 0000-0000-6653-4145)
	--P496 (ORCID) format regex: 0000-000(1-[5-9]|2-[0-9]|3-[0-4])\d{3}-\d{3}[\dX] (e.g. 0000-0002-7398-5483)
	id = id:gsub( '[ %-]', '' ):upper()
	if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) then
		return false
	end
	if p.getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
		return false
	end
	return id
end

function p.splitLccn( id )
	--P244's format regex: (n|nb|nr|no|ns|sh)([4-9][0-9]|00|20[0-1][0-9])[0-9]{6} (e.g. n78039510)
	if id:match( '^%l%l?%l?%d%d%d%d%d%d%d%d%d?%d?$' ) then
		id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )
	end
	if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then
		return mw.text.split( id, '/' )
	end
	return false
end

--[[==========================================================================]]
--[[                    Wikidata & documentation functions                    ]]
--[[==========================================================================]]

function p.getIdsFromWikidata( itemId, property )
	local ids = {}
	local statements = mw.wikibase.getBestStatements( itemId, property )
	if statements then
		for _, statement in ipairs( statements ) do
			if statement.mainsnak.datavalue then
				table.insert( ids, statement.mainsnak.datavalue.value )
			end
		end
	end
	return ids
end

-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation
function p.docConfTable( frame )
	local wikiTable = '{| class="wikitable sortable"\n'..
					  '! rowspan=2 | 변수\n'..
					  '! rowspan=2 | 문단\n'..
					  '! rowspan=2 | 표시\n'..
					  '! rowspan=2; data-sort-type=number | 위키데이터 속성\n'..
					  '! colspan=4 | 추적용 분류와 문서 수\n'..
					  '|-\n'..
					  '! [[:분류:전거 통제 정보를 포함한 위키백과 문서|'..       '문서]]\n'..
					  '! [[:분류:전거 통제 정보를 포함한 사용자 문서|'..               '사용자 문서]]\n'..
					  '! [[:분류:전거 통제 정보를 포함한 기타 문서|'..      '기타 문서]]\n'..
					  '! [[:분류:잘못된 전거 통제 정보를 포함한 위키백과 문서|'..'잘못된 ID]]\n'..
					  '|-\n'
	local lang = mw.getContentLanguage()
	for _, conf in pairs( p.conf ) do
		local param, pid, section = conf[1], conf[2], conf[4]
		local appearsAs
		if param == "WORLDCATID" then
			-- WorldCat is special
			appearsAs = "[https://www.worldcat.org/identities/lccn-n78039510 월드캣]"
		elseif conf.prefix then
			appearsAs = conf.prefix
		else
			appearsAs = conf[3](conf[5])
		end
		local link = conf.link or param .. ' (식별자)'
		local category = conf.category or param
		local args = { id = 'f', pid }
		local wpl = frame:expandTemplate{ title = '위키데이터 속성 링크', args = args }
		--cats
		local articleCat = category..' 식별자를 포함한 위키백과 문서'
		local userCat =    category..' 식별자를 포함한 사용자 문서'
		local miscCat =    category..' 식별자를 포함한 기타 문서'
		local faultyCat =  '잘못된 '..category..' 식별자를 포함한 위키백과 문서'
		--counts
		local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
		local userCount =    lang:formatNum( mw.site.stats.pagesInCategory(userCat, 'pages') )
		local miscCount =    lang:formatNum( mw.site.stats.pagesInCategory(miscCat, 'pages') )
		local faultyCount =  lang:formatNum( mw.site.stats.pagesInCategory(faultyCat, 'pages') )
		
		--concat
		wikiTable = wikiTable..'\n'..
					'|-\n'..
					'||[['..link..'|'..param..']]'..
					'||'..section..
					'||'..appearsAs..
					'||data-sort-value='..pid..'|'..wpl..
					'||style="text-align: right;"|[[:분류:'..articleCat..'|'..articleCount..']]'..
					'||style="text-align: right;"|[[:분류:'..   userCat..'|'..   userCount..']]'..
					'||style="text-align: right;"|[[:분류:'..   miscCat..'|'..   miscCount..']]'..
					'||style="text-align: right;"|[[:분류:'.. faultyCat..'|'.. faultyCount..']]'
	end
	
	--append derivative WorldCat cats
	local wcd = { 'WorldCat-LCCN', 'WorldCat-VIAF' }
	for _, w in pairs(wcd) do
		local articleCat = w.. ' 식별자를 포함한 위키백과 문서'
		local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
		local appearsAs 
		if w == "WorldCat-LCCN" then
			appearsAs = "[https://www.worldcat.org/identities/lccn-n79-113947 월드캣 (미국 의회도서관을 통해)]"
		else
			appearsAs = "[https://www.worldcat.org/identities/containsVIAFID/12345789 월드캣 (VIAF를 통해)]"
		end
		wikiTable = wikiTable..'\n'..
					'|-\n'..
					'||'..'—'..
					'||일반'..
					'||'..appearsAs..
					'||data-sort-value='..w..'|'..'—'..
					'||style="text-align: right;"|[[:분류:'..articleCat..'|'..articleCount..']]'..
					'||style="text-align: right;"|—'..
					'||style="text-align: right;"|—'..
					'||style="text-align: right;"|—'
	end
	
	return require("Module:Suppress categories").main(wikiTable)..'\n|}'
end

--[[==========================================================================]]
--[[                              Configuration                               ]]
--[[==========================================================================]]

-- If a specific "(identifier) redirect" exists for an identifier, please route through this particular redirect rather than linking directly to the target page. This reduces clutter in "What links here" and improves reverse lookup of articles where a manifestation of this particular identifier is used.


-- Parameter format: { 'parameter name', propertyId # in Wikidata, formatting/validation function, section, example ID for documentation }
-- Optional named parameters: `link` to override the link in the documentation (defaults to parameter + (identifer)),
-- category to override the ID in category names (defaults to parameter),
-- prefix to include a prefix (usually a wikilink explaining what the identifier is) before the external link itself
p.conf = {
	{ 'AAG', 3372, p.aagLink, "미술관", "1"},
	{ 'ACM-DL', 864, p.acmLink, "학술 데이터베이스", "12345678901", link="ACM DL (식별자)"},
	{ 'ADB', 1907, p.adbLink,"인명 사전", "barton-sir-edmund-toby-71"},
	{ 'AGSA', 6804, p.agsaLink, "미술관", "3625"},
	{ 'autores.uy', 2558, p.autoresuyLink, "인명 사전", "12345"},
	{ 'AWR', 4186, p.awrLink, "인명 사전", "PR00768b"},
	{ 'BIBSYS', 1015, p.bibsysLink, "국립도서관", "1234567890123"},
	{ 'Bildindex', 2092, p.bildLink, "미술 연구소", "1"},
	{ 'BNC', 1890, p.bncLink, "국립도서관", "123456789"},
	{ 'BNE', 950, p.bneLink, "국립도서관", "XX1234567"},
	{ 'BNF', 268, p.bnfLink, "국립도서관", "123456789"},
	{ 'Botanist', 428, p.botanistLink , "학술 데이터베이스", "L."},
	{ 'BPN', 651, p.bpnLink , "인명 사전", "12345678"},
	{ 'CANTIC', 1273, p.canticLink, "국립도서관", "a12345678"},
	{ 'CINII', 271, p.ciniiLink, "학술 데이터베이스", "DA12345678", link = "CiNii (식별자)"},
	{ 'CWGC', 1908, p.cwgcLink, "기타", "1234567"},
	{ 'DAAO', 1707, p.daaoLink, "미술 연구소", "rolf-harris"},
	{ 'DBLP', 2456, p.dblpLink, "학술 데이터베이스", "123/123"},
	{ 'DIB',  6829, p.dibLink, "인명 사전", "a1234"},
	{ 'DSI', 2349, p.dsiLink, "미술 연구소", "1538"},
	{ 'FAST', 2163, p.fastLink, "기타", "1"},
	{ 'FNZA', 6792, p.fnzaLink, "미술 연구소", "12"},
	{ 'GND', 227, p.gndLink, "일반", "4079154-3"},
	{ 'HDS', 902, p.hdsLink, "기타", "050123"},
	{ 'IAAF', 1146, p.iaafLink, "기타", "123"},
	{ 'ICCU', 396, p.iccuLink, "국립도서관", "IT\\ICCU\\CFIV\\000163"}, --formerly SBN
	{ 'ICIA', 1736, p.iciaLink, "미술 연구소", "1"},
	{ 'IEU', 9070, p.ieuLink, "기타", "N\\A\\NationalAcademyofArtandArchitecture"},
	{ 'ISNI', 213, p.isniLink, "일반", "0000-0000-6653-4145", prefix = '[[ISNI (식별자)|ISNI]]'},
	{ 'Joconde', 347, p.jocondeLink, "미술 연구소", "12345678901"},
	{ 'KULTURNAV', 1248, p.kulturnavLink, "미술 연구소", "12345678-1234-1234-1234-1234567890AB", link="KulturNav (식별자)"},
	{ 'LCCN', 244, p.lccnLink, "국립도서관", "n78039510"},
	{ 'LIR', 886, p.lirLink, "기타", "1"},
	{ 'LNB', 1368, p.lnbLink, "국립도서관", "123456789"},
	{ 'Léonore', 640, p.leonoreLink, "기타", "LH/1/1", prefix = "[[Léonore (식별자)|Léonore (프랑스)]]"},
	{ 'MA', 6366, p.maLink, "기타", "123456789"},
	{ 'MBA', 434, p.mbaLink, "기타", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz'}, --special cat name
	{ 'MBAREA', 982, p.mbareaLink, "기타", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz area' }, --special cat name
	{ 'MBI', 1330, p.mbiLink, "기타", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz instrument' }, --special cat name
	{ 'MBL', 966, p.mblLink, "기타", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz label' }, --special cat name
	{ 'MBP', 1004, p.mbpLink, "기타", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz place' }, --special cat name
	{ 'MBRG', 436, p.mbrgLink, "기타", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz release group' }, --special cat name
	{ 'MBS', 1407, p.mbsLink, "기타", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz series' }, --special cat name
	{ 'MBW',  435, p.mbwLink, "기타", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz work' }, --special cat name
	{ 'MGP', 549, p.mgpLink, "학술 데이터베이스", "123456"},
	{ 'NARA', 1225, p.naraLink, "기타", "12345678"},
	{ 'NCL', 1048, p.nclLink, "국립도서관", "1081436"},
	{ 'NDL', 349, p.ndlLink, "국립도서관", "012345678"},
	{ 'NGV', 2041, p.ngvLink, "미술관", "12354"},
	{ 'NKC', 691, p.nkcLink, "국립도서관", "abcd12345678901234"},
	{ 'NLA', 409, p.nlaLink, "국립도서관", "123456789012"},
	{ 'NLG', 3348, p.nlgLink, "국립도서관", "12345678"},
	{ 'NLI', 949, p.nliLink, "국립도서관", "123456789"},
	{ 'NLK', 5034, p.nlkLink, "국립도서관", "KAB197000000"},
	{ 'NLP', 1695, p.nlpLink, "국립도서관", "9810123456789012345"},
	{ 'NLR', 1003, p.nlrLink, "국립도서관", "123456789"},
	{ 'NSK', 1375, p.nskLink, "국립도서관", "123456789"},
	{ 'NTA', 1006, p.ntaLink, "국립도서관", "12345678X"},
	{ 'ORCID', 496, p.orcidLink, "일반", "0000-0002-7398-5483", prefix = '[[ORCID (식별자)|ORCID]]'},
	{ 'PIC', 2750, p.picLink, "미술 연구소", "1"},
	{ 'PLWABN',  7293, p.plwabnLink, "국립도서관", "9812345678905606"},
	{ 'Publons', 3829, p.publonsLink, "학술 데이터베이스", "2776255"},
	{ 'RID', 1053, p.ridLink, "학술 데이터베이스", "A-1234-1934"},
	{ 'RISM', 5504, p.rismLink, "기타", "pe1",  prefix = '[[RISM (식별자)|RISM (프랑스)]]'},
	{ 'RERO', 3065, p.reroLink, "기타", "02-A012345678", prefix = '[[RERO (식별자)|RERO (스위스)]]'},
	{ 'RKDartists', 650, p.rkdartistsLink, "미술 연구소", "123456"},
	{ 'RKDID', 350, p.rkdidLink, "미술 연구소", "123456"},
	{ 'RSL', 947, p.rslLink, "국립도서관", "123456789"},
	{ 'SELIBR', 906, p.selibrLink, "국립도서관", "123456"},
	{ 'SIKART', 781, p.sikartLink, "미술 연구소", '123456789'},
	{ 'SNAC-ID', 3430, p.snacLink, "기타", "A"},
	{ 'SUDOC', 269, p.sudocLink, "기타", "026927608", prefix = '[[SUDOC (식별자)|SUDOC (프랑스)]]'},
	{ 'S2AuthorId', 4012, p.s2authoridLink, "학술 데이터베이스", "1796130", category = 'Semantic Scholar author' }, --special cat name
	{ 'TA98', 1323, p.ta98Link, "학술 데이터베이스", "A12.3.45.678"},
	{ 'TDVİA', 7314, p.tdviaLink, "기타", "asim-b-behdele"},
	{ 'TePapa', 3544, p.tepapaLink, "미술관", "1"},
	{ 'TLS',  1362, p.tlsLink, "기타", "Abcd"},
	{ 'Trove', 1315, p.troveLink, "기타", "12345678", prefix = '[[Trove (식별자)|Trove (오스트레일리아)]]'}, --formerly NLA-person
	{ 'UKPARL', 6213, p.ukparlLink, "기타", "AQUupyiR"},
	{ 'ULAN', 245, p.ulanLink, "미술 연구소", "500123456"},
	{ 'USCongress', 1157, p.uscongressLink, "기타", "A000123", link = "US Congress (식별자)"},
	{ 'VcBA', 8034, p.vcbaLink, "국립도서관", "494/9793"},
	{ 'VIAF', 214, p.viafLink, "일반", "123456789", prefix = "[[VIAF (식별자)|VIAF]]"},
	{ 'WORLDCATID', 7859, nil, "일반", nil, link = "WorldCat Identities (식별자)"},
}

-- Legitimate aliases to p.conf, for convenience
-- Format: { 'alias', 'parameter name in p.conf' }
p.aliases = {
	{ 'DNB', 'GND' }, --Deutsche Nationalbibliothek -> Gemeinsame Normdatei
	{ '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 [[Category:Wikipedia articles with deprecated authority control identifiers]]
-- 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 --WD IDs added here later
	local iParentArgs = 0 --count original/manual parent args only later
	local worldcatCat = ''
	local multipleIdCat = ''
	local suppressedIdCat = ''
	local deprecatedIdCat = ''
	local differentOnWDCat = ''
	local sameOnWDCat = ''
	
	--Redirect aliases to proper parameter names
	for _, a in pairs( p.aliases ) do
		local alias, param = a[1], a[2]
		if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then
			parentArgs[param] = parentArgs[alias]
		end
	end
	
	--Redirect deprecated parameters to proper parameter names, and assign tracking cat
	for _, d in pairs( p.deprecated ) do
		local dep, param = d[1], d[2]
		if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then
			parentArgs[param] = parentArgs[dep]
			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 available
	if itemId then
		local iMatches = 0
		for _, params in ipairs( p.conf ) do
			if params[2] > 0 then
				local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
				if val == nil or val == '' then
					local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
					if wikidataIds[1] then
						if val == '' and (namespace == 0 or testcases) then
							suppressedIdCat = '[[분류:전거 통제 식별자가 생략된 위키백과 문서|'..params[1]..']]'
						else
							parentArgs[params[1]] = wikidataIds[1] --add ID from WD
						end
					end
				else
					iParentArgs = iParentArgs + 1
					local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
					if wikidataIds[1] and differentOnWDCat == '' then
						local bMatch = false
						for _, wd in pairs( wikidataIds ) do
							if val == wd then
								iMatches = iMatches + 1
								bMatch = true
							end
						end
						if bMatch == false then
							differentOnWDCat = '[[분류:위키데이터와 다른 변수를 포함한 전거 통제를 사용하는 문서|'..params[1]..']]'
		end	end	end	end	end
		if iMatches > 0 and iMatches == iParentArgs then
			sameOnWDCat = '[[분류:위키데이터와 모두 일치하는 변수를 포함한 전거 통제를 사용하는 문서]]'
		end
	end
	--Configured rows
	local rct = 0
	local sectionOrder = {"일반","국립도서관","미술관",
						  "미술 연구소","인명 사전","학술 데이터베이스",
						  "기타"}
	local sections = {
		["일반"] = {},
		["국립도서관"] = {},
		["미술관"] = {},
		["미술 연구소"] = {},
		["인명 사전"] = {},
		["학술 데이터베이스"] = {},
		["기타"] = {}
	}
	-- Don't show NLP is PLWABN is present, since they both go to the National Library of Poland
	-- and the library has deprecated NLP IDs in favor of PLWABN IDs
	if parentArgs.PLWABN or parentArgs.plwabn then
		parentArgs.NLP = ''
		parentArgs.nlp = ''
	end
	for _, params in ipairs( p.conf ) do
		local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
		local tval, tlinks = {}, {} --init tables
		if val and val ~= '' and type(params[3]) == 'function' then
			table.insert( tval, val )
			if params.prefix then 
				table.insert( tlinks, params[3]( val, "1" ) )
			else
				table.insert( tlinks, params[3]( val ) )
			end
		end
		--collect other unique vals (IDs) from WD, if present
		if itemId and tval[1] then
			local nextIdVal = 2
			local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
			for _, v in pairs( wikidataIds ) do
				local bnew = true
				for _, w in pairs( tval ) do
					if v == w then bnew = false end
				end
				if bnew then
					table.insert( tval, v )
					table.insert( tlinks, params[3]( v, tostring(nextIdVal) ) )
					nextIdVal = nextIdVal + 1
				end
			end
		end
		--assemble
		if tval[1] then
			table.insert( sections[params[4]], p.createRow( params[1], tval, nil, tlinks, true, params.category, params.prefix) )
			rct = rct + 1
			if tval[2] then
				multipleIdCat = p.getCatForId( '여러' )
			end
		end

	end
	
	--WorldCat
	local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
	if worldcatId and worldcatId ~= '' then --if WORLDCATID present & unsuppressed
		table.insert( sections["일반"], p.createRow( 'WORLDCATID', worldcatId, '[https://www.worldcat.org/identities/'..mw.uri.encode(worldcatId, 'PATH')..' 월드캣]', nil, false ) ) --Validation?
		worldcatCat = p.getCatForId( 'WORLDCATID' )
		rct = rct + 1
	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( sections["일반"], p.createRow( 'VIAF', viafId, '[https://www.worldcat.org/identities/containsVIAFID/'..viafId..' 월드캣 (VIAF를 통해)]', nil, false ) )
			if namespace == 0 then 
				worldcatCat = '[[분류:WorldCat-VIAF 식별자를 포함한 위키백과 문서]]'
			end
			rct = rct + 1
		elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
			local lccnParts = p.splitLccn( lccnId )
			if lccnParts and lccnParts[1] ~= 'sh' then
				local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]
				table.insert( sections["일반"], p.createRow( 'LCCN', lccnId, '[https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' 월드캣 (미국 의회도서관을 통해)]', nil, false ) )
				if namespace == 0 then
					worldcatCat = '[[분류:WorldCat-LCCN 식별자를 포함한 위키백과 문서]]'
				end
			end
			rct = rct + 1
		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 = rct..'개의 요소가 포함된 전거 통제'
		elementsCat  = '[[분류:'..eCat..']]'..p.redCatLink(eCat)
	end
	
	local outString = ''
	if rct > 0 then
		local sectionID = 1
		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}
		local navboxArgs = {
			name  = 'Authority control',
			navboxclass = 'authority-control',
			bodyclass = 'hlist',
			state = parentArgs.state or 'autocollapse',
			navbar = 'off'
		}
		for _, sectName in ipairs(sectionOrder) do
			if #sections[sectName] ~= 0 then
				navboxArgs["group" .. sectionID] = sectName
				navboxArgs["list" .. sectionID] = table.concat(sections[sectName])
				sectionID = sectionID + 1
			end
		end
		if navboxArgs.group2 then
			navboxArgs.title = "[[위키백과:전거 통제|전거 통제]]" .. pencil
		else
			local sect = navboxArgs.group1
			if sect == "일반" or sect == "기타" then
				-- Just say "Authority control" with no label if only general or only other IDs are present
				-- since "general" is redundant and "other" is silly when there's nothing to contrast it with
				navboxArgs.group1 = "[[위키백과:전거 통제|전거 통제]]" .. pencil
			else 
				navboxArgs.group1 = "[[위키백과:전거 통제|전거 통제: " .. sect .. "]] " .. pencil
			end
		end
		outString = Navbox._navbox(navboxArgs)
	end
	
	local auxCats = worldcatCat .. elementsCat .. multipleIdCat .. suppressedIdCat .. 
					deprecatedIdCat .. differentOnWDCat .. sameOnWDCat
	if testcases then
		auxCats = mw.ustring.gsub(auxCats, '(%[%[)(분류)', '%1:%2') --for easier checking
	end
	outString = outString .. auxCats
	if namespace ~= 0 then
		outString = mw.ustring.gsub(outString, '(%[%[)(분류:위키백과 문서)', '%1:%2') --by definition
	end
	
	return outString
end

return p