Module:Infobox/Fonctions/Personne/Bac à sable

 Documentation[voir] [modifier] [historique] [purger]

Cette page définit un module d'infobox.


--[[ 
Avant de mettre en production une nouvelle version avez-vous :
- mis en place des tests dans au moins une des pages de test d'un des modèles utilisant la fonction ?
- testé avec la version bac à sable ?
- modifié la documentation ?
]]

-- Functions utilisées par les infobox personnes
local p = {}
local localdata = require 'Module:Infobox/Localdata'
local item = localdata.item
local wikidata = require 'Module:Wikidata'
local general = require 'Module:Infobox/Fonctions'
local datemodule = require 'Module:Date'
local complexdate = require 'Module:Date complexe'
local linguistic = require 'Module:Linguistique'
local languagedata = mw.loadData 'Module:Langue/Data'
local militaryranks = require 'Module:Dictionnaire Wikidata/Grades militaires'
local ppath = require 'Module:Wikidata/Chemin'
local noble = require 'Module:Noble'

-- == Accord en genre
local gender = wikidata.getgender(item) -- genre de la personne dont c'est l'infobox

-- Version locale de wikidata.genderedlabel où si le genre n'est pas indiqué, c'est celui de la personne dont c'est l'infobox
local function genderedlabel(id, labelgender)
	if not labelgender then labelgender = gender end
	return wikidata.genderedlabel(id, labelgender)
end

-- === Gestion des dates

-- Liens thématiques vers les dates
local datelinks = { -- lien vers le domaine d'activité approprié
	Q483501 = 'en arts plastiques', -- artiste
	Q1028181 = 'en arts plastiques', -- peintre
	Q1281618 = 'en arts plastiques', -- sculpteur
	Q2309784 = 'en cyclisme', -- cycliste
	Q16947657 = 'en arts plastiques', -- lithographe
	Q11569986 = 'en arts plastiques', -- graveur
	Q13365770 = 'en arts plastiques', -- graveur sur cuivre
	Q21925567 = 'en arts plastiques', -- sérigraphe
	Q10862983 = 'en arts plastiques', -- aquafortiste
	Q36180 = 'en littérature', -- écrivain
}

local function getdatetopic() -- obtient le lien le plus approprié pour une date en fonction de la profession
	local claims = wikidata.stringTable{entity = item, property = 'P106', excludespecial = true, displayformat = 'raw'}
	if not claims then
		return nil
	end
	for i, j in pairs(claims) do
		if datelinks[j] then
			return datelinks[j]
		end
	end
end

local linktopic = getdatetopic()


local unknowndatelabel = 'date inconnue'

local birthdate = localdata['naissance'] or
	localdata['date de naissance'] or
	wikidata.formatAndCat{
		entity = item,
		property = 'P569',
		unknownlabel = unknowndatelabel,
		conjtype = 'or',
		sorttype = 'chronological',
		removedupesdate = 'cat',
		minprecision = 8, --précision minimale pour être affichée : décennie
	}

local dead = wikidata.getClaims{entity = item, property = 'P570'} --utilisé comme booléen qui dit si une personne est morte pour modifier certaines élément d'affichage
local stillvalid
if dead then
		stillvalid = "?" -- permet de remplacer des "depuis" par des "à partir de"
end

local deathdate = localdata['décès'] or localdata['date de décès']
local wddeathdate = wikidata.formatAndCat{
	entity = item,
	property = 'P570',
	unknownlabel = unknowndatelabel,
	conjtype = 'or',
	sorttype = 'chronological',
	removedupesdate = 'cat',
	minprecision = 8,
}

local disappeardate = localdata['disparition']
local wddisappeardate = wikidata.formatAndCat{
	entity = item,
	property = 'P746',
	unknownlabel = unknowndatelabel,
	conjtype = 'or',
	sorttype = 'chronological',
	removedupesdate = 'cat',
	showqualifiers = 'P276',
	minprecision = 8,
}

local function format1(event, period, predecessor, together, successor, displayformat)
	local mainstr = event
	if predecessor then
		local s = 'précédé par ' .. predecessor
		if gender == 'f' then
			s = 'précédée par ' .. predecessor
		end
		mainstr = mainstr .. '<small><br />&nbsp;' .. s .. '</small>'
	end
	if together then
		local s = 'avec ' .. together
		mainstr = mainstr .. '<small><br />&nbsp;' .. s .. '</small>'
	end
	if successor then
		local s = 'suivi par ' .. successor
		if gender == 'f' then
			s = 'suivie par ' .. successor
		end
		mainstr = mainstr .. '<small><br />&nbsp;' .. s .. '</small>'
	end
	return {type = 'row', label = period or '', value = function() return mainstr end}
end

-----------------

local function format2(event, period, predecessor, together, successor, displayformat)
	if (not event) then
		return nil
	end
	
	local rows = {}

	local eventrow = {type = 'row1col', color = 'secondcolor', value = event }
	table.insert(rows, eventrow)

	if period then
		period = '<span style="font-weight:normal">' .. period .. '</span>'
		local periodrow = {type = 'row1col', color = '#F9F9F9', value = period }
		table.insert(rows, periodrow)
	end

	if predecessor then
		local prederow = {type = 'row', label = 'Prédécesseur', value = function() return predecessor end}
		table.insert(rows, prederow)
	end

	if together then
		local succrow = {type = 'row', label = 'Avec', value = function() return together end}
		table.insert(rows, succrow)
	end

	if successor then
		local succrow = {type = 'row', label = 'Successeur', value = function() return successor end}
		table.insert(rows, succrow)
	end
	return {type = 'multi', rows = rows}
end


local function format3(event, period, predecessor, together, successor, displayformat, details)
	if details then
		details = '<span style="font-weight:normal">' .. details .. '</span>'
		event = linguistic.conj({event, details}, 'new line')
	end
	local mainrow =  {type = 'row1col', color = 'secondcolor', value = event }
	if period then
		period = '<span style="font-weight:normal">' .. period .. '</span>'
	end
	local periodrow = {type = 'row1col', color = '#F9F9F9', value = period }
	local successionrow = {
		style = {['background-color'] = '#F9F9F9', ['padding-bottom'] = '2%'},
		type = 'navigator',
		inner = true,
		previousval = function() return predecessor end,
		nextval = function() return successor end,
	}

	return {type = 'multi', rows = {mainrow, periodrow, successionrow}}
end


local function timeline(localparam, wdconf, timelineformat, title, singtitle, details) -- affiche date : événement (suppose les événements déjà triés)
	local rows = {}
	local function returnTable()
		return {
			type = 'table',
			title = title,
			rows = rows
	}
	end
	
	-- avec données locales
	local val = localdata[localparam]
	if val == '-' then
		return nil
	elseif val then
		table.insert(rows, {type = 'row1col', color = 'secondcolor', value = val})
		return returnTable()
	end
	-- avec données wikidata
	if not wdconf then
		return nil
	end
	
	wdconf.entity = wdconf.entity or item
	wdconf.sorttype = wdconf.sorttype or 'chronological'
	wdconf.labelformat = wdconf.labelformat  or genderedlabel
	wdconf.linktopic = wdconf.linktopic or '-'

	local statements = wikidata.getClaims(wdconf)
	if not statements then
		return nil
	end
	if #statements == 1 then
		title = singtitle
	end
	local displayformats = {
		A = format1,
		B = format2,
		C = format3,
	}
	local applyformat = displayformats[timelineformat] or displayformats['A']
	
	rows = {}
	for i, statement in pairs(statements) do
		local event =  linguistic.ucfirst(wikidata.formatStatement(statement, wdconf))
		local predecessor = wikidata.getFormattedQualifiers(statement, {'P155', 'P1365'}, {labelformat2 = noble.labelInfobox})
		local together = wikidata.getFormattedQualifiers(statement, {'P1706', ''}, {labelformat2 = noble.labelInfobox})
		local successor = wikidata.getFormattedQualifiers(statement, {'P156', 'P1366'}, {labelformat2 = noble.labelInfobox})
		local period = wikidata.getFormattedDate(statement, {linktopic = wdconf.linktopic, stilltrue = stillvalid } ) -- dont pass all wdconf or else qualifiers will show up
		local detailstr		
		if type(details) == 'function' then
			detailstr = details(statement)
		end
		local row = applyformat(event, period, predecessor, together, successor, wdconf, detailstr)
		if row then
			table.insert(rows, row)
		end
	end
	table.insert(rows, {type = 'external text', value = function() return wikidata.addTrackingCat(wdconf.property) end})
	return returnTable()
end


local function dateandplace(thedate, theplace)
	if thedate and theplace and mw.ustring.find(thedate, 'inconnu') and mw.ustring.find(theplace, 'inconnu') then
		theplace = nil
		thedate =  mw.ustring.gsub(thedate, linguistic.ucfirst(unknowndatelabel), 'Date et lieu inconnus')	
	end
	return linguistic.conj({thedate, theplace}, 'new line')
end


--Titre
function p.title(icon, style)
	local title = general.title(icon, style)
	title.value = function() 
		return localdata['nom'] or localdata['association_nom'] or localdata['nom_think'] or localdata['acronymelaboratoire'] or localdata['titre']
			or wikidata.getLabel(localdata.item) and noble.labelInfobox( mw.language.getContentLanguage():ucfirst( wikidata.getLabel(localdata.item) ) )
			or noble.labelInfobox( mw.title.getCurrentTitle().text )
	end
	return title
end

--Image
function p.mainimage(cat)
	
	 -- demande d'illustration que si la personne est née ou morte après 1900, sinon c'est souvent impossible à trouver
	local defaultimage = 'Defaut 2.svg'
	local age = wikidata.stringTable{property = 'P569,P570', entity = item, displayformat = 'raw', excludespecial = true}

	if age and age[1] then
		local pattern = '(%W)(%d+)%-(%d+)%-(%d+)'
		local era, year = age[1]:match(pattern)
		if (era == '-') or (tonumber(year)) < 1900 then
			defaultimage = nil
		end
	end
	return  general.mainimage({cat = cat or 'Article à illustrer Biographie', altparameter = 'alt'}, defaultimage)
end

-- Noms

function p.nativenames()  -- projet d'affichage intelligent des "noms dans la langue maternelle"
	if not localdata.item then
		return nil
	end
	-- récupération des valeurs
	local claims = wikidata.getClaims({ entity = item, property = 'P1559'})
	if not claims then
		return nil
	end

	-- création des lignes
	local rows = {}
	
	for i, j in pairs(claims) do
		local rowlabel, nativenamelang, nativename
		if j.mainsnak.snaktype == 'value' and j.mainsnak.datavalue.type == 'monolingualtext' then
			nativenamelang = j.mainsnak.datavalue.value.language
		end
		if nativenamelang then
			rowlabel = "Nom en " .. languagedata[nativenamelang].nom
		else
			rowlabel = "Nom dans la langue maternelle"
		end
		
		nativename = wikidata.formatStatement(j)
		
		local islangnew = true --si il y a déjà un nom pour cette langue on l'ajoute à la ligne existante
		for k,r in pairs(rows) do
			if r.label == rowlabel then
				table.insert(r.namestable, nativename)
				islangnew = false
			end
		end
		if islangnew then --sinon nouvelle ligne
			table.insert(rows, {type = "row", label = rowlabel, namestable = {nativename} } )
		end
	end
	for i,r in pairs(rows) do --deuxième passage por concaténer et mettre un linkback
		local rowvalue = linguistic.conj(r.namestable,'or')
		rowvalue = wikidata.addLinkBack(rowvalue, item, 'P1559')
		r.value = function() return rowvalue end
		table.remove(r,3)
	end
	
	return {type = "multi", rows = rows or {}}
end


function p.othernames()

	local names = {
		{'P1477', 'Nom de naissance', 'Noms de naissance', 'nom de naissance'},
		{'P1448', 'Nom officiel', 'Noms officiels', 'nom officiel'},
		{'P1449', 'Surnom', 'Surnoms', 'surnom'},
		{'P2001', 'Romanisation révisée', 'Romanisation révisée', 'romanisation révisée'},
		{'P1942', 'McCune-Reischauer', 'McCune-Reischauer', 'McCune-Reischauer'},
		{'P742', 'Pseudonyme', 'Pseudonymes', 'pseudonyme'},
		{'P1782', 'Prénom social', 'Prénoms sociaux', 'prénom social'},
		{'P1786', 'Nom posthume', 'Noms posthumes', 'nom posthume'},
		{'P1785', 'Nom de temple', 'Noms de temple', 'nom de temple'},
		{'P1787', 'Nom de pinceau', 'Noms de pinceau', 'nom de pinceau'},
		{'P1813', 'Nom court', 'Noms courts', 'nom court'},
		{nil, 'Autres noms', 'Autres noms', 'autres noms'},
	}

	local nativelangnamerow = { -- un peu particulier, donc à part
		type = 'row',
		wikidata  = function()
			local s = wikidata.formatAndCat{entity = item, property = 'P1559', showqualifiers = 'P1721', conjtype = 'or'}
			if (not s) then
				return nil
			end
			-- regarde si le nom de la valeur ressemble au libellé (en tenant compte de la pollution des marqueurs de langue)
			local label = mw.ustring.lower(wikidata.getLabel(item) or '')
			local useless
			if mw.ustring.find(mw.ustring.lower(s), mw.ustring.lower(label), 1, true) then
				useless = true
			end
			if localdata['nom de naissance'] then useless = true end
			if not useless then   --inutile si duplique le "nom de naissance"
				local birthname = localdata['nom de naissance'] or wikidata.formatStatements{entity = item, property = 'P1477', displayformat='raw'}
				if wikidata.formatStatements{entity = item, property = 'P1559'} == birthname then useless = true end
			end
			if useless then
				return nil
			end
			return s		
			end,
		label = 'Nom dans la langue maternelle',
		plurallabel = 'Noms dans la langue maternelle',
		value = 'nom dans la langue maternelle',
	}
	
	local rows = {type = 'multi', rows = {nativelangnamerow}}
	for i, j in pairs(names) do
		local query
		if j[1] and not localdata['autres noms'] then -- lorsqu'il y a un paramètre "autres noms", Wikidata est désactivée pour éviter risques de doublon
			query = {property = j[1], showqualifiers = {'P1721'}, conjtype = 'comma'}
		end
		table.insert(rows.rows, {type = 'row', value = j[4], wikidata = query, label = j[2], plurallabel = j[3]})
	end
	return rows
end

-- NAISSANCE ET MORT
function p.birth() -- date de naissance en première ligne, lieu de naissance en deuxième
	return {
		type = 'row',
		label = 'Naissance',
		value =
			function()
			local thedate = datemodule.dateInfobox{args = {[1] = 'naissance', [2] = birthdate or '', [3] = deathdate or wddeathdate or disappeardate or wddisappeardate or '', qualificatif = linktopic}}
			local theplace = localdata['lieu de naissance'] or 
			                 wikidata.formatAndCat({entity =item, -- affichage du nom du lieu de naissance en vigueur à la date de naissance 
			                                        property= 'P19', 
			                                        rank = 'best',
			                                        labelformat = function(val) return wikidata.getLabel(val) end, 
			                                        conjtype= ' ou ',
													defaultlinkquery =  {property = {'P361'}}, -- liens par défaut :  "partie de",
			                                        unknownlabel = "lieu inconnu",
			                                        showqualifiers = {'P131', 'P17'},
			                                        qualifconjtype = 'comma'
			                                        }
			                                       )
			return dateandplace(thedate, theplace)
			end
	}
end

function p.death() -- même fonctionnement que la fonction p.birth
	
	-- date de disparition
	local ldisappeardate = disappeardate
	if (not ldisappeardate ) and (not deathdate) then -- récupérée de Wikidata seulement si la date de décès n'est pas fournie en locale
		ldisappeardate = wddisappeardate
	end
	if ldisappeardate and birthdate then
		ldisappeardate  = datemodule.dateInfobox{args = {[1] = 'événement', [2] = birthdate  or '', [3] = ldisappeardate or '', qualificatif = linktopic, unknownlabel = 'date inconnue'}}
	end

	-- date de décès
	local ddate = deathdate --déclarée pour l'ensemble du module

	if (not ddate) and (not ldisappeardate) then
		deathdate = wddeathdate -- récupérée de Wikidata seulement si la date de disparition n'est pas fournie en locale
	end
	local thedate = datemodule.dateInfobox{args = {[1] = 'mort', [2] = birthdate or '', [3] = deathdate or '', qualificatif = linktopic, unknownlabel = 'date inconnue'}}
	local theplace = localdata['lieu de décès'] or 
	                 wikidata.formatAndCat{entity =item, 
			                                 property= 'P20', 
			                                 rank = 'best',
			                                 -- affichage du nom du lieu de décès en vigueur à la date de décès
			                                 labelformat = function(val) return wikidata.getLabel(val) end,
				                             conjtype= ' ou ',
											 defaultlinkquery =  {property = {'P361'}}, -- liens par défaut :  "partie de", 
				                             unknownlabel = "lieu inconnu",
			                                 showqualifiers = {'P131', 'P17'},
			                                 qualifconjtype = 'comma'
			                                 }

	local val = dateandplace(thedate, theplace)

	return
	{type = 'multi', rows = {
		{ -- disparition
		type = 'row',
		label = 'Disparition',
		value = function() return ldisappeardate end
		},
		{ -- décès
		type = 'row',
		label = 'Décès',
		value = function() return val end,
		}
	}}
end

function p.floruit()
	return {
		type = 'row',
		label = "Période d'activité",
		value = "période d'activité",
		wikidata = function() 
			local startDate = wikidata.formatAndCat{entity = item, property = 'P2031', conjtype = 'or', sorttype = 'chronological', linkback = '-'}
			local endDate =  wikidata.formatAndCat{entity = item, property = 'P2032', conjtype = 'or', sorttype = 'chronological'}
			if not (startDate or endDate) then
				return wikidata.formatAndCat{entity = item, property = 'P1317', conjtype = 'or', sorttype = 'chronological'}
			end
			if startDate and not endDate then
				startDate = wikidata.formatAndCat{entity = item, property = 'P2031', conjtype = 'or', sorttype = 'chronological'}
			end
			return complexdate.daterange(startDate, endDate, {precision = 11, stilltrue = stillvalid})
			end
	}
end

function p.placeofburial()
	return
		{type = 'row', label = 'Sépulture', value = 'sépulture', wikidata = {property = "P119", showdate = true, novaluelabel = 'aucune'}}
end


function table.slice(tbl, first, last, step)
  local sliced = {}

  for i = first or 1, last or #tbl, step or 1 do
    sliced[#sliced+1] = tbl[i]
  end

  return sliced
end

-- function that creates a filter function
-- if the main country "base_country_item" is (replaced by)+ 
-- the subsequent statement main value that the function will receive as a parameter
-- then the created function will return true for this statement to be filtered out

local function filter_replaces_builder(base_country_item)
	-- P1365 = remplace
	-- P1366 = remplacé par
	local replaced_query = {property = 'P1365'}
	return function(may_be_replacing_stmt)
		local may_be_replacing_item = wikidata.getMainId(may_be_replacing_stmt)
		local replaces = wikidata.inTransitiveVals(may_be_replacing_item, base_country_item, replaced_query)
		return not(wikidata.inTransitiveVals(may_be_replacing_item, base_country_item, replaced_query))
	end
end

-- filter parameterized by each of the values of the claims, in the order
-- « filter_function_builder » will be called by all the values (remaining after filtering) in « claims »
-- to filter the rest of the claims, starting from the first one in the list.
local function iterated_filter(claims, filter_function_builder)
	-- the first country in the list, if any of the following value replaces this one
	-- we remove them. So we split the list
	local first_country_claim = claims[1]
	local to_test = table.slice(claims, 2, #claims)
	
	if #to_test > 0 then
		-- building the filter function with the first country as base value
		-- (a closure)
		local condition = filter_function_builder(wikidata.getMainId(first_country_claim))
		-- keeping the number of values before the filter
		local nb_before = #to_test
		to_test = wikidata.filterClaims(to_test, {condition = condition}) or {}
		local nb_after = #to_test
		-- if some country was filtered out, we remove the dates of the main statement to avoid showing incomplete dates
		if (nb_before ~= nb_after and first_country_claim.qualifiers) then
			first_country_claim.qualifiers["P580"] = nil
			first_country_claim.qualifiers["P582"] = nil
		end
		-- if there still exists candidate countries, filter them recursively
		if #to_test > 0 then
			to_test = iterated_filter(to_test, filter_function_builder)
		end
		
		-- reconstruct the list of statement by readding our first country to the filtered list
		to_test = to_test or {}
		table.insert(to_test, 1, first_country_claim)
		return to_test
	end
	-- if there were nothing to filter, just return the first statement
	return {first_country_claim}
end

function p.nationality() 
	
	local cmp = wikidata.compare
	-- à améliorer étant donnée les mœurs Wikidata comme nationalité : Empire allemand (1901-1918)  République de Weimar (1918-1933)
	local function wdDate()
		local nation = require 'Module:Country data'.nationality
		
		-- désactivation si date de naissance avant l'Ère contemporaine : trop d'imprécisions et d'anachronismes
		local mindate = '1789'
		
		local birthdate = wikidata.formatStatements{entity = item, property = 'P569', displayformat = 'raw', numval = 1}
        local deathdate = wikidata.formatStatements{entity = item, property = 'P570', displayformat = 'raw', numval = 1}
		
		if ((not birthdate) or complexdate.before(mindate, birthdate)) and ((not deathdate) or complexdate.before(mindate, deathdate)) then
			return nil
		end
		
		
		-- preprocessing the "P27" statements
		--  if there is statements about a country that changed its regime, like France before and after the french Revolution
		--    then we just want to show "France" and not "France and France" because there is two statement (or worse)
		--    so we take advantage of the fact that the French Kingdom was "replaced by" French Republic (P1366)
		--    to detect and filter out such «redundant» values
		--    (we also remove the begin/end dates of statements in such cases to avoid wrong dating)
		local statements = wikidata.getClaims{entity = item, property = 'P27', rank='best', excludespecial=true} or {}
		
		-- sort nationality statements by statement dates or regime creation date if statement is not dated
		local sort_by_statement_or_regime = wikidata.chrono_key_sort{
			sort_key="RegimeKey",                                               -- use another key than « chronosort »
			snak_key_get_function = ppath.snak_key_by_paths{">P580","P571"},    --[[ either by « begin date » qualifier or « inception » of the nationality
			                                                                         if the statement is not dated ]]
			key_compare_function = cmp.rev(function(v1, v2) return v1 < v2 end) -- sort in reverse chronological order to remove all values the first nationalities replaces
		}
		
		-- ordering statement by dates so that we can test only "A replaces B" and not "B replaces A" because A is an older regime than B
		statements = sort_by_statement_or_regime(statements)
		-- actual statement filtering
		statements = iterated_filter(statements, filter_replaces_builder)
		-- re-sorting in chronological ordering
		statements = wikidata.sortClaims(statements, cmp.chronoCompare)
		
		return {
			property = 'P27',
			claims = statements, -- our filtered statement as claims instead of the regular query
			showdate = true,
			entity = item,
			conjtype = 'new line',
			removedupes = true,
			linktopic = '-',
			sorttype = 'chronological',
			ucfirst = '-',
			stilltrue = not dead,
			displayformat = 
				function(snak)
					-- local g = gender -- genre de la personne, pour affichage du gentilé
					-- if g == '?' then -- si inconnu, au masculin
					--  	g = 'm'
					-- end
					local val, success = nation(wikidata.getId(snak), 'f') -- au féminin pour accorder au mot nationalité
					if not success then
						val = wikidata.formatSnak(snak)
					end
					return val
				end
			}
	end
		
	return {
		type = 'row',
		label = 'Nationalité',
		plurallabel = 'Nationalités',
		value = 'nationalité',
		wikidata = wdDate() -- wdDate() retourne une table
	}

end
function p.nativelanguage()
	return
	{type = 'row', label = 'Langue maternelle', value = 'langue maternelle', property = 'P103'}
end

function p.writinglanguage()
	return
	{type = 'row', label = "Langue d\'écriture", value = 'langue d\'écriture', plurallabel = "Langues d\'écriture" , wikidata = {property = 'P6886' , expl = true}}
end

-- Domiciles
function p.places()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Dème',
		plurallabel = 'Dèmes',
		value = 'dème',
		wikidata = {property = 'P2462', showdate = true, sorttype= 'chronological', stilltrue = not dead, precision = 'year'},
},
{
		type = 'row',
		label = 'Domicile',
		plurallabel = 'Domiciles',
		value = 'domicile',
		wikidata = {property = 'P551', showdate = true, sorttype= 'chronological', stilltrue = not dead, precision = 'year'},
},
	}}
end

-- parcours professionel
function p.education()
	local query = {sorttype= 'chronological', property = 'P69', showdate = true, stilltrue = '?', showqualifiers = 'P512', conjtype = 'new line', linktopic = '-'}
	return {
		type = 'row',
		value = {'éducation', 'formation'},
		wikidata = query,
		label = 'Formation',
	}
end

function p.occupation()

	local speciallabels = {
		f = {
		['Q33999'] = '[[Acteur|actrice]]',
		['Q10798782'] = '[[Acteur|actrice]]',
		['Q10800557'] = '[[Acteur|actrice]]',
		['Q2405480'] = '[[Acteur|actrice]]',
		['Q2259451'] = '[[Acteur|actrice]]',
		['Q948329'] = '[[Acteur|actrice]]'
		},
		m = {
		['Q33999'] = '[[acteur]]',
		['Q10798782'] = '[[acteur]]',
		['Q10800557'] = '[[acteur]]',
		['Q10798782'] = '[[acteur]]',
		['Q2405480'] = '[[acteur]]',
		['Q2259451'] = '[[acteur]]',
		['Q948329'] = '[[acteur]]'
		}
	}

	return {
		type = 'row', 
		value = {'activité', 'activités'},
		wikidata = {
			property = 'P106',
			defaultlink = '-',
			defaultlinkquery = {property = {'P425','P1056'}},
			labelformat = genderedlabel,
			speciallabels = speciallabels[gender] or speciallabels['m'],
			removedupes = true,
			showdate = true,
			sorttype = 'chronological',
			stilltrue = not dead,
			excludevalues = { -- les occupations qui ne méritent pas d'être affichées 
				'Q482980', -- auteur
				'Q15980158', --"auteur de non-fiction"
				'Q12144794', --prosateur
				'Q18814623', -- autobiographe
				'Q1209498', -- juriste-poète
				'Q1097498', -- "dirigeant"
				'Q2478141', -- aristocrate
				'Q116', -- monarque
				'Q115088092', -- participant à un forum international
			}
		},
		label = 'Activité',
		plurallabel = 'Activités'
	}
end

function p.haswrittenfor()
	local valueStyle = {}
	valueStyle['font-style'] = 'italic'
	return
		{type = 'row', label =
  		function(localdata, item)
  			if gender == 'f' then
  				return 'Rédactrice à'
  			else
  				return 'Rédacteur à'
  			end
		end, value = 'rédacteur à', wikidata = {property = "P6872", showdate = true}, valueStyle = valueStyle}
end

function p.employer()
	return {
		type = 'row', 
		value = 'employeur',
		wikidata = {property = 'P108', showdate = true, linktopic = '-', sorttype= 'inverted', stilltrue = not dead, conjtype = 'new line'}, 
		label = function() return localdata['intitulé employeur'] or 'A travaillé pour' end,
	}
end

function p.victories() 
	local title, singtitle = 'Victoires', 'Victoire' 
	local localparam = 'victoire'
	local wdconf = {property = 'P2522'}
	local displayformat = 'B'
	
	return timeline(localparam, wdconf, displayformat, title, singtitle)
end


function p.officialposition() 
	local title, singtitle = 'Fonctions', 'Fonction'
	local localparam = 'fonction'
	local wdconf =  {
		property = 'P39',
		showqualifiers = 'P5102',
		qualiflink = '-',
		rank = 'valid',
		sorttype = 'inverted',
		defaultlinkquery =  {property = {'P2354', 'P2389', 'P453', 'P361', 'P108', 'P276', 'P1001'}}, -- liens par défaut : liste, puise organisme dirigé, "membre de", "partie de", employeur, ressort territorial
	}
	-- sur une ligne séparée : gouvernement, législature, juridiction, "de", circonscription, diocèse, affiliation, assemblée, parti, employeur
	local details = function(statement) return wikidata.getFormattedQualifiers(statement, {'P5054', 'P2937', 'P1001', 'P642', 'P2389', 'P768', 'P708', 'P1416', 'P194', 'P108', 'P937' , 'P1268'}, {conjtype = 'new line'}) end
	local displayformat = 'C'
	
	return timeline(localparam, wdconf, displayformat, title, singtitle, details)
end

function p.specialrole() 
	local localparam = 'statut notable'
	local wdconf =  {
		property = 'P2868',
		rank = 'valid',
		sorttype = 'inverted',
		targetsuperclass = 'Q254917',
		defaultlinkquery =  {property = {'P2354'}}, -- lien par défaut : liste d'éléments
	}
	local displayformat = 'C'
	
	return timeline(localparam, wdconf, displayformat)
end

function p.nobilitytitle() 
	local title, singtitle = 'Titres de noblesse', 'Titre de noblesse'
	local localparam = 'titre de noblesse'
	local wdconf = {
		property = 'P97', 
		entity = item, rank = 'valid', 
		showqualifiers =  {'P642'},
		defaultlinkquery =  {property = {'P2354', 'P361'}}, -- liens par défaut : liste, puise organisme dirigé, "membre de" et "partie de"
	}
	local displayformat = 'B'
	
	return timeline(localparam, wdconf, displayformat, title, singtitle)
end


function p.honorifictitle() 
	local title, singtitle = 'Titres honorifiques', 'Titre honorifique'
	local localparam = 'titre honorifique'
	local wdconf = {property = 'P511', entity = item, rank = 'valid'}
	local displayformat = 'C'
	
	return timeline(localparam, wdconf, displayformat, title, singtitle)
end

function p.tombe()
	return {
		type = 'images',
		imageparameters =  {'tombe'},
		defaultimages = nil,
		defaultupright = 1,
		uprightparameter = 'upright tombe',
		sizeparameter = 'taille tombe', -- obsolète
		captionparameter = 'légende tombe',
		defaultcaption = 'Vue de la sépulture.',
		property = 'P1442',
		numval = 1,
	}
end

function p.plaque()
	return {
		type = 'images',
		imageparameters =  {'plaque'},
		defaultimages = nil,
		defaultupright = 1,
		uprightparameter = 'upright plaque',
		sizeparameter = 'taille plaque', -- obsolète
		captionparameter = 'légende plaque',
		defaultcaption = 'Plaque commémorative',
		property = 'P1801',
		numval = 1,
	}
end

function p.blason()
	return {
		type = 'images',
		imageparameters =  {'blason'},
		defaultimages = nil,
		defaultupright = 0.5,
		uprightparameter = 'upright blason',
		sizeparameter = 'taille blason', -- obsolète
		captionparameter = 'légende blason',
		defaultcaption = 'Blason',
		property = 'P94',
		numval = 1,
	}
end

function p.sceau()
	return {
		type = 'images',
		imageparameters =  {'sceau'},
		defaultimages = nil,
		defaultupright = 0.7,
		uprightparameter = 'upright sceau',
		sizeparameter = 'taille sceau', -- obsolète
		captionparameter = 'légende sceau',
		defaultcaption = 'Sceau',
		property = 'P158',
		numval = 1,
	}
end

function p.monogram()
	return {
		type = 'images',
		imageparameters =  {'monogramme'},
		defaultimages = nil,
		defaultsize = 	'100px',
		sizeparameter = 'taille monogramme',
		captionparameter = 'légende monogramme',
		defaultcaption = 'Monogramme',
		property = 'P1543',
		numval = 1,
	}
end

function p.flag()
	return {
		type = 'images',
		imageparameters =  {'drapeau'},
		defaultimages = nil,
		defaultsize = 	'150px',
		sizeparameter = 'taille drapeau',
		captionparameter = 'légende drapeau',
		defaultcaption = 'Drapeau',
		property = 'P41',
		numval = 1,
	}
end

function p.logo()
	return {
		type = 'images',
		imageparameters =  {'logo'},
		defaultimages = nil,
		defaultsize = 	'150px',
		sizeparameter = 'taille logo',
		captionparameter = 'légende logo',
		defaultcaption = 'Marque ou logotype',
		property = 'P154',
		numval = 1,
	}
end

function p.politicalparty()
	return {
		type = 'row', 
		value = 'parti politique',
		label = 'Parti politique',
		plurallabel = 'Partis politiques',
		wikidata = { property = 'P102', sorttype= 'chronological', showdate = true, conjtype = 'new line', excludespecial = true,
			labelformat = function(id) if id == 'Q327591' and gender == 'f' then return 'indépendante' end end}
	}
end

function p.memberof()
	return {type = 'multi', rows = {
{
	type = 'row', 
	value = 'ordre de chevalerie',
	label = 'Ordre de chevalerie',
	plurallabel = 'Ordres de chevalerie',
	wikidata = {property = 'P550', sorttype= 'chronological', showdate = true, stilltrue = not dead}, 
},
{
	type = 'row', 
	label = 'Membre de', 
	value = 'membre de', 
	wikidata = {property = 'P463', sorttype= 'chronological', showdate = true, stilltrue = not dead, precision = 'year', linktopic = '-', textformat = 'minimum', conjtype = 'new line'},
},
	}}
end

local masclabelitems  = {a='Q10855271', b='Q10855195', c='Q10855212', d='Q10855216', e='Q13422138', f='Q13422140', g='Q13422141', h='Q13452524', i='Q13452528', j='Q13452531', k='Q14637182', l='Q14637176', m='Q14637188',}
-- grades de la légion d'Honneur, de l'ordre national du Mérite, de l'ordre des Palmes académiques et de l'ordre des Arts et Lettres en France, de genre grammatical masculin y compris pour les femmes

function p.awards()
	
	local function awardsList()
		local majorawards = require 'Module:Dictionnaire Wikidata/Distinctions'
		local query = {
			entity = item,
			property= 'P166',
			sorttype= 'chronological',
			grouped = true,
			showqualifiers = 'P642',
			showdate= true,
			precision = 'year',
			conjtype = 'new line',
			textformat = 'minimum',
			linktopic = '-',
			defaultlinkquery = {property = {'P2354', 'P361' , 'P1027'}},
			excludevalues = majorawards.exclude, -- membre de la Royal Society, redondance avec le champ « membre de » (P463)
			speciallabels = majorawards,
			labelformat = function(id)
				masclabel = false
				for _, item in pairs(masclabelitems) do
					if id == item then masclabel = true end
				end
				if masclabel then
					return genderedlabel(id, 'm') 
				else
					return genderedlabel(id) 
				end
			end,
		}
		local claims = wikidata.getClaims(query)
		if (not claims) then
			return nil
		end
		local str = wikidata.formatAndCat(query)
		if #claims < 4 then
			return str, #claims
		end

		--si trop de valeurs, n'afficher que les importantes de [[Module:Dictionnaire Wikidata/Distinctions]], et mettre les autrs dans un menu pliant

		--- récupération des importantes
		local majorStr
		local targetvalues = {}
		for i, j in pairs(majorawards) do
			table.insert(targetvalues, i)
		end
		query.targetvalue = targetvalues
		query.value, query.claims, query.valuetable = nil, nil, nil -- apparemment sinon ce n'est pas le cas, pourquoi ? BUG IMPORTANT
		majorStr = wikidata.formatAndCat(query)

		--- repliage des autres
		local message = "'''Liste détaillée'''"
		local allAwardsTable = mw.html.create('div') 
			:addClass('toccolours mw-collapsible mw-collapsed')
			:wikitext(message)
			:css{border = 'none'}
			:tag('div')
				:addClass('mw-collapsible-content')
				:css{['line-height'] = '150%'} -- sinon c'est vraiment serré
				:wikitext( str)
				:done()
			:allDone()

		return linguistic.conj({majorStr, tostring(allAwardsTable)}, '<br>'), #claims
	end
	
	return {
		type = 'row', 
		value = {'prix', 'récompenses', 'distinction', 'distinctions'},
		label = 'Distinctions',
		singularlabel = 'Distinction',
		wikidata = function() return awardsList() end
	}
end

-- Influences 
function p.influencedby()
	return {
		type = 'row',
		label = 
		function(localdata, item)
		if gender == 'f' then
			return 'Influencée par'
		else
			return 'Influencé par'
		end
		end,
		value = 'influencé par',
		wikidata = {property = 'P737'},
    }
end

function p.influenced()
	return {
		type = 'row',
		label = 'A influencé',
		value = {'a influencé', 'influence de'},
}
end

-- Appartenances
function p.movement()
	return
	{
	type = 'row',
	label = 'Mouvement',
	value = 'mouvement',
	plurallabel = 'Mouvements',
	wikidata = {property = 'P135', sorttype= 'chronological', showdate = true, precision = 'year'},
}
end

-- Religion
function p.religion()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Religion',
		value = 'religion',
},
{
		type = 'row',
		label = 'Date de baptême',
		value = 'date de baptême',
		property = 'P1636',
},
--{
--		type = 'row',         En l'état, afficherait "parrain" y compris pour la marraine. Quoi qu'il en soit, pertinence douteuse.
--		label = 'Parrain',
--		plurallabel = 'Parrains',
--		value = 'parrain',
--		property = 'P1290',
--},
{
		type = 'row',
		label = 'Nom en religion',
		plurallabel = 'Noms en religion',
		value = 'nom en religion',
		property = 'P1635',
},
{
		type = 'row',
		label = 'Ordre religieux',
		plurallabel = 'Ordres religieux',
		value = 'ordre religieux',
		wikidata = {property = 'P611', showdate = true, sorttype= 'chronological', precision = 'year', stilltrue = not dead},
},
{
		type = 'row',
		label = 'Consécrateur',
		plurallabel = 'Consécrateurs',
		value = 'consécrateur',
		property = 'P1598',
},
{
		type = 'row',
		label = 
		function(localdata, item) 
		if gender == 'f' then
			return 'Vénérée par'
		elseif gender == 'm' then
			return 'Vénéré par'
		else
			return 'Vénéré par'
		end
		end,
		value = 'vénéré par',
		property = 'P1049',
},
{
		type = 'row',
		label = 
		function(localdata, item) 
		if gender == 'f' then
			return 'Vénérée à'
		elseif gender == 'm' then
			return 'Vénéré à'
		else
			return 'Vénéré à'
		end
		end,
		value = 'vénéré à',
		-- property = ,
},
{
		type = 'row',
		label = 'Étape de canonisation',
		value = 'étape de canonisation',
		wikidata = {
			property = 'P411',
			labelformat = genderedlabel,
		},
},
	}}
end

-- Carrière militaire
function p.military()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Arme',
		plurallabel = 'Armes',
		value = 'arme',
		wikidata = {property = 'P241', showdate = true, stilltrue = not dead, sorttype= 'chronological', precision = 'year'},
},
{
		type = 'row',
		label = 'Unité',
		plurallabel = 'Unités',
		value = 'unité',
		wikidata = {property = 'P7779', showdate = true, stilltrue = not dead, sorttype= 'chronological', precision = 'year', conjtype = 'new line'},
},
{
		type = 'row',
		label = 'Grade militaire',
		plurallabel = 'Grades militaires',
		value = 'grade militaire',
		blockers = {'grade'}, -- paramètre théoriquement dédié aux arts martiaux et au go mais souvent rempli avec des grades militaires
		wikidata = {
			property = 'P410',
			showdate = true, sorttype= 'chronological', precision = 'year',
			speciallabels = militaryranks,
			conjtype ='new line',
			labelformat = genderedlabel,
			stilltrue = not dead
		},
},
{
		type = 'row',
		label = 'Conflit',
		plurallabel = 'Conflits',
		value = 'conflit',
		wikidata = {property = 'P607', conjtype = 'new line', showdate = true, stilltrue = not dead, sorttype= 'chronological', precision = 'year'},
},
	}}
end

-- Carrière de torero
function p.torero()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Alternative',
		value = 'alternative',
		wikidata = function() return wikidata.keyDate('Q2840411', item) end
},
{
		type = 'row',
		label = "Confirmation d'alternative",
		value = 'confirmation alt',
		wikidata = function() return wikidata.keyDate('Q23308805', item) end
},
	}}
end

-- Sport
function p.sport()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Sport',
		plurallabel = 'Sports',
		value = {'sport', 'sport pratiqué'},
		wikidata = {property = 'P641'},
},
{
		type = 'row',
		label = 'Équipe',
		plurallabel = 'Équipes',
		value = 'équipe',
		wikidata = {
			property = 'P54',
			sorttype= 'chronological',
			conjtype = 'new line',
			statementformat = function(statement)
				local str = wikidata.formatStatement(statement, {showdate = true})
				local compets = wikidata.getFormattedQualifiers(statement, {'P1350'})
				if tonumber(compets) and (tonumber(compets) > 1) then
					compets = compets .. ' matchs joués'
				elseif compets then
					compets = compets .. ' match joué'
				end
				local points = wikidata.getFormattedQualifiers(statement, {'P1351'})
				if tonumber(points) and (tonumber(points) > 1) then
					points = points .. ' points marqués'
				elseif points then
					points = points  .. 'point marqué'
				end
				local qualifiers = linguistic.conj{compets, points}
				if qualifiers then
					str= str .. ' <small> – ' .. qualifiers .. ' </small>'
				end
				return str
			end
		}
},
{
		type = 'row',
		label = 'Position',
		plurallabel = 'Positions',
		value = {'position', 'poste', 'spécialité'},
		wikidata = {property = 'P413',
			labelformat = genderedlabel,
			},
},
{
		type = 'row',
		label = 'Discipline sportive',
		plurallabel = 'Disciplines sportives',
		value = 'discipline sportive',
		wikidata = {property = 'P2416'},
},
{
		type = 'row',
		label = 'Prise de raquette',
		value = 'prise de raquette',
		wikidata = {property = 'P741'},
},
{
		type = 'row',
		label = 'Tire de la',
		value = 'tire',
		wikidata = {property = 'P423'},
},
{
		type = 'row',
		label = 'Repêchage par',
		plurallabel = 'Repêchages par',
		value = 'repêchage',
		wikidata = {
			property = 'P647',
			statementformat = function(statement)
				local team = wikidata.formatStatement(statement)
				local moment = wikidata.getFormattedQualifiers(statement, {'P793'}) or  wikidata.getFormattedQualifiers(statement, {'P585'})
				local rank = wikidata.getFormattedQualifiers(statement, {'P1836'})
				if rank then
					rank = require 'Module:Nombre2texte'.ordinal(rank) .. ' choix'
				end
				local qualifs = linguistic.conj({moment, rank}, '&nbsp;– ')
				if not qualifs then
					return team
				end
				return team .. ' <small>(' .. qualifs  .. ')</small>'
			end
					
			},
},
{
		type = 'row',
		label = 'Capes internationales',
		value = 'capes',
		wikidata = {property = 'P1129', numval = 1},
},
{
		type = 'row',
		label = 'Titre aux échecs',
		plurallabel = 'Titres aux échecs',
		value = 'titre aux échecs',
		wikidata = {property = 'P2962', sorttype= 'chronological', showdate = true, stilltrue = not dead, precision = 'year'},
},
{
		type = 'row',
		label = 'Classement Elo',
		value = 'classement elo',
		wikidata = {property = 'P1087', numval = '1', sorttype = 'inverted', showdate = true, precision = 'year', removedupes = true},
},
{
		type = 'row',
		label = 'Record détenu',
		plurallabel = 'Records détenus',
		value = 'record détenu',
		wikidata = {property = 'P1000', sorttype= 'chronological', showdate = true},
},
{
		type = 'row',
		label = 'Entraîneur',
		plurallabel = 'Entraîneurs',
		value = 'entraîneur',
		wikidata = {property = 'P286', sorttype= 'chronological', showdate = true, stilltrue = not dead, precision = 'year'},
},
{
		type = 'row',
		label = 'Copilote',
		plurallabel = 'Copilotes',
		value = 'copilote',
		wikidata = {property = 'P2095', sorttype= 'chronological', showdate = true, stilltrue = not dead, precision = 'year'},
},
{
		type = 'row',
		label = 'Mécène',
		plurallabel = 'Mécènes',
		value = {'mécène', 'mécènes', 'sponsor', 'sponsors'},
		wikidata = {property = 'P859', sorttype= 'chronological', showdate = true, stilltrue = not dead, precision = 'year'},
},
	}}
end

-- Contacts
function p.contacts()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = localdata['intitulé maître'] or 'Maître',
		plurallabel = 'Maîtres',
		value = {'maître', 'maîtres'},
		wikidata = {property = 'P1066', sorttype= 'chronological', showdate = true, stilltrue = not dead, precision = 'year'},
},
{
		type = 'row',
		label = {
			ms = 'Directeur de thèse',
			fs = 'Directrice de thèse',
			mp = 'Directeurs de thèse',
			fp = 'Directrices de thèse',
			default = '<abbr class="abbr" title="Direction">Dir.</abbr> de thèse'
		},
		value = {'directeur de thèse', 'dir. de thèse'},
		wikidata = {property = 'P184', sorttype= 'chronological', showdate = true, precision = 'year'},
},
{
		type = 'row',
		label = 'Agent',
		label = 
		function(localdata, item) 
		if gender == 'f' then
			return 'Représentée par'
		elseif gender == 'm' then
			return 'Représenté par'
		else
			return 'Représenté par'
		end
		end,
		value = 'représenté par',
		wikidata = {property = 'P1875'},
},
{		-- Partenaire professionnel ou sportif
		type = 'row',
		label = 'Partenaire',
		plurallabel = 'Partenaires',
		value = 'partenaire',
		wikidata = {property = 'P1327', showdate = true, sorttype= 'chronological'}, 
},
{
		type = 'row',
		label = localdata['intitulé élève'] or 'Élève',
		plurallabel = 'Élèves',
		value = {'élève', 'élèves'},
		wikidata = {property = 'P802', sorttype= 'chronological', showdate = true, stilltrue = not dead, precision = 'year', numval = '5', expl = ''},
},
{
		type = 'row',
		label = 'Étudiant de thèse',
		plurallabel = 'Étudiants de thèse',
		value = 'étudiant de thèse',
		wikidata = {property = 'P185', sorttype= 'chronological', showdate = true, precision = 'year', numval = '5', expl = ''},
},	
{
		type = 'row',
		label = 'Personne liée',
		plurallabel = 'Personnes liées',
		value = 'personne liée',
		wikidata = {property = 'P3342', numval = 5, showqualifiers = 'P3831',qualiflink="-",qualiflabelformat="objectgender"}, --objectgender à créer dans Module:Wikidata
},
	}}
end

-- Mécénat
function p.patron()
	return {
		type = 'row', 
		label = '[[Mécénat|Mécènes]]',
		singularlabel = '[[Mécénat|Mécène]]',
		plurallabel = '[[Mécénat|Mécènes]]', 
		value = 'mécènes', 
		wikidata = {property = 'P859', showdate = true, stilltrue = not dead, sorttype = 'chronological', conjtype = 'comma'},
		}
end

-- Musique
function p.music()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Tessiture',
		value = 'tessiture',
		property = 'P412',
},
{
		type = 'row',
		label = 'Fach',
		value = 'fach',
		property = 'P1731',
},
{
		type = 'row',
		label = 'Instrument',
		plurallabel = 'Instruments',
		value = 'instrument',
		wikidata = {property = 'P1303', sorttype= 'chronological', excludevalues='Q17172850'}, --probablement jugée redondante avec l'occupation "chanteur"
},
{
		type = 'row',
		label = 'Label',
		plurallabel = 'Labels',
		value = 'label',
		wikidata = {property = 'P264', sorttype= 'chronological', showdate = true, precision = 'year'},
},
	}}
end

-- Victimes
function p.victims()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Victimes',
		value = 'victimes',
		wikidata = {property = 'P1345'},
},
	}}
end

-- Condamnations
function p.penalties()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 
		function(localdata, item) 
		if gender == 'f' then
			return 'Condamnée pour'
		elseif gender == 'm' then
			return 'Condamné pour'
		else
			return 'Condamné pour'
		end
		end,
		value = 'condamné pour',
		wikidata = {property = 'P1399', showdate = true, sorttype = 'chronological', precision = 'year', conjtype = 'comma'},
},
{
		type = 'row', 
		label = 'Condamnation',
		plurallabel = 'Condamnations', 
		value = 'condamnation', 
		wikidata = {property = 'P1596', showdate = true, sorttype = 'chronological', precision = 'year', conjtype = 'comma'},
},
{
		type = 'row', 
		label = 'Lieu de détention',
		plurallabel = 'Lieux de détention', 
		value = 'lieu de détention', 
		wikidata = {property = 'P2632', showdate = true, sorttype = 'chronological', precision = 'year', conjtype = 'comma'},
},
	}}
end

-- Physique
function p.appearance()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Taille',
		value = 'taille',
		wikidata = {property = 'P2048', targetunit = 'metre', rounding = '2'},
},
{
		type = 'row',
		label = '[[masse corporelle|Poids]]',
		value = {'poids','masse'},
		wikidata = {property = 'P2067', targetunit = 'kilogram', conjtype = 'new line', showdate=true, rounding = '1'},
},
{
		type = 'row',
		label = 'Cheveux',
		value = 'cheveux',
		wikidata = {property = 'P1884'},
},
{
		type = 'row',
		label = 'Yeux',
		value = 'yeux',
		wikidata = {property = 'P1340'},
},
	}}
end
-- Famille
function p.gens()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Gens',
		value = 'gens',
		wikidata = {property = 'P5025'},
},
	}}
end
function p.family()
	local  function showkinship(statement)
		local personid = wikidata.getMainId(statement)
		local personlabel = wikidata.formatEntity(personid, {
			labelformat2 = noble.labelInfobox
		})
		local persongender = wikidata.getgender(personid)
		local kintype = wikidata.getFormattedQualifiers(
			statement,
			'P1039', 
			{
				labelformat = function(id) return genderedlabel(id, persongender) end,
				link = '-'
			}
			)
		if kintype then
			return personlabel .. ' ' .. linguistic.inparentheses(kintype)
		end
		return personlabel 
	end
	
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Famille',
		plurallabels = 'Familles',
		value = 'famille',
		property = 'P53',
},
{
		type = 'row',
		label = 'Père', 
		value = 'père',
		wikidata = {
			property = 'P22',
			showqualifiers = "P1039",
			conjtype = ' ou ',
			labelformat2 = noble.labelInfobox
		},
},
{
		type = 'row',
		label = 'Mère',
		value = 'mère',
		wikidata = {property = 'P25',
			showqualifiers = "P1039",
			unknownlabel = 'Inconnue',
			conjtype = ' ou ',
			labelformat2 = noble.labelInfobox
		},
},
{
		type = 'row',
		label = 'Beau-parent',
		plurallabel = 'Beaux-parents',
		value = {'beau-parent', 'beau-père', 'belle-mère'},
		wikidata = {
			property = 'P3448',
			labelformat2 = noble.labelInfobox
		},
},
{
		type = 'row',
		label = 'Fratrie',
		value = 'fratrie',
		wikidata = {
			property = 'P3373',
			sorttype = 'age',
			conjtype = 'new line',
			textformat = 'long',
			precision = 'year',
			stilltrue = not dead,
			statementformat = showkinship,
			excludespecial = true,
			labelformat2 = noble.labelInfobox,
		}
},
{
		type = 'row',
		label = 'Conjoint', -- todo : adapter le libellé en genre ?
		plurallabel = 'Conjoints',
		value = 'conjoint',
		wikidata = {
			property = 'P26',
			showdate = true,
			linktopic = '-',
			sorttype = 'chronological',
			conjtype = 'new line',
			textformat = 'long',
			precision = 'year',
			stilltrue = not dead,
			precision = 'year',
			excludespecial = true,
			labelformat2 = noble.labelInfobox,
		}
},
{
		type = 'row',
		label = localdata['intitulé enfant'] or 'Enfant',-- todo : adapter le libellé en genre ?
		plurallabel = 'Enfants',
		value = 'enfant',
		wikidata = {
			property = 'P40',
			conjtype = 'new line',
			showdate = false,
			sorttype = 'age',
			labelformat2 = noble.labelInfobox,
		}
},
{
	type = 'row',
	label = 'Parentèle',
	value = 'parentèle',
	wikidata = {
		property = 'P1038',
		excludespecial = true,
		conjtype = 'new line',
		statementformat = showkinship
		}
},
	}}
end

-- Esclavage
function p.slavery()
	return {type = 'multi', rows = {
{
		type = 'row',
		label = 'Statut',
		plurallabel = 'Statuts',
		value = 'statut',
		wikidata = {property = 'P3716',
			showdate = true,
			labelformat = genderedlabel,
			excludevalues = {'Q11573099','Q10076267'}, --membre de la famille royale (doublon avec les propriétés familiales) et propriétaire d'esclaves (pas vraiment un statut)
			defaultlinkquery = 'P425'},
},
{
		type = 'row',
		label = 'Propriétaire',
		plurallabels = 'Propriétaires',
		value = 'propriétaire',
		wikidata = {property = 'P127'}, 
},
	}}
end

-- Œuvres
function p.works(params)
	params = params or {}
	local title = params.title or 'Œuvres principales'
	params.title = nil

	local wikidata = {
		excludespecial = true,
		numval = 5,
		property = 'P800',
		defaultlink = 'image',
		showdate= true,
		labelformat = function(id)
			local label =  wikidata.getLabel(id)
			if label then
				if wikidata.isInstance('Q386724', id, 6) then	 --italique pour les instances d' "œuvre" ou ses sous-classes
					if wikidata.isInstance('Q14897293', id, 5) or wikidata.isInstance('Q13226383', id, 5) or wikidata.isInstance('Q3622126', id, 5) or wikidata.isInstance('Q12894677', id, 5) then
						--sauf les instances d'"entité fictionnelle", "équipement", "système de concepts", "moyen pour une fin" ou leurs sous-classes
						return label
					else
						return '<i>' .. label .. '</i>'
					end
				else
					return label
				end
			end
			end,
	}
	
	for i, j in pairs(params) do
		wikidata[i] = j
	end
	
	return 
	{type = 'table', title = title, singulartitle = singulartitle, rows =
		{
			{
			type = 'row',
			value = 'œuvres principales',
			wikidata = wikidata
			}
		}
	}
end

function p.filmography()
	local title = 'Films notables'
	return
	{type = 'row', label = 'Films notables', value = 'films notables', property = 'P1283'}
	end

function p.discography()
	local title = 'Discographie'
	return
	{type = 'row', label = 'Discographie', value = 'discographie', property = 'P358'}
end

-- Signature
function p.signature(default)
	local nom = localdata.nom or mw.title.getCurrentTitle().text
	local alt = 'signature de ' .. nom
	if mw.ustring.match( nom, '^[AEÈÉIOUY]' )  then
		alt = "signature d'" .. nom
	end
	return {
		type = 'images',
		imageparameters =  {'signature'},
		defaultimage = default,
		captionparameter = 'légende signature',
		defaultcaption = 'Signature',
		uprightparameter = 'upright signature',
		defaultupright = 0.75,
		defaultalt = alt,
		property = 'P109',
		numval = 1
	}
end

-- Enregistrement vocal
function p.voice()
	return {
		type		     = 'images',
		style            = {['padding-top'] = '25px'},--{['border-width'] = '10px', ['border-style'] = 'solid'},
		defaultcaption   = 'Enregistrement vocal',
		captionparameter = 'légende voix',
		imageparameters  = 'voix',
		defaultsize      = '280',
		wikidata         = general.selectSound('P990'),
		numval           = 1,
	}
end

-- Site web
p.website = general.website

-- Prononciation
p.prononciation = general.prononciation

-- fête du saint
function p.feast()
	local title = 'Fête'
	return {type = 'row', label = 'Fête', value = 'fête', wikidata = {property = 'P841' , showqualifiers = 'P276'}}
end

-- archivé par
function p.archivesat()
	return {type = 'row', label = 'Archives conservées par', value = "archivé par", 
		wikidata = {
			property = 'P485', conjtype = 'new line', 
			showqualifiers = {'P217','P7328','P585','P7103','P7104'}, qualifprecision = 'year',
			qualifformat = function(statement, qualifs, params) -- basé sur wikidata.getFormattedQualifiers dans [[Module:Wikidata]]
				local str = ''
				if not params then params = {} end
				local qualiftable = wikidata.getQualifiers(statement, qualifs)
				if not qualiftable then
					return nil
				end
				qualiftable = wikidata.filterClaims(qualiftable, params) or {}
				for i, snak in pairs(qualiftable) do
					if (snak.datatype == 'time' and snak.property == 'P7104') then -- fin de période couverte
						str = str .. '-'
					elseif i > 1 then
						str = str .. ', '
					end
					qualiftable[i] = wikidata.formatSnak(snak, params)
					if snak.datatype == 'quantity' and tonumber(snak.datavalue.value.amount) > 1 then -- pluriel
						qualiftable[i] = qualiftable[i] .. 's'
					end
					str = str .. qualiftable[i]
				end
				return str 
			end,
			showsource = true
		}
	}
end

return p