Módulo:Cycling race

Icono de documentación de módulo Documentación del módulo[ver] [editar] [historial] [purgar]

A continuación se muestra la documentación transcluida desde la subpágina /doc. [salta a la caja de código]


Module Cycling race (Modulo de carreras de ciclismo) es un proyecto alojado en Wikidata. La idea nació y se gestiona desde Jérémy-Günther-Heinz Jähnick (que gestiona Wikimedia Cycling y su filial Wikidata Cycling), y actualmente es apoyado por el Wikiproyecto:Ciclismo orientado a mejorar, homogeneizar y mantener los artículos relacionados con el ciclismo, de acuerdo a los estándares y políticas de Wikipedia.

Los colaboradores del proyecto podrán agregar más tareas o actualizar las existentes, ya que este código es de código abierto. Antes de actualizar una funcionalidad principal, por favor primero visitar y revisar la página de discusión del proyecto Module talk:Cycling race, con el fin de llegar a un consenso.

Las funciones principales de este módulo se utilizan para mostrar tablas de datos de carreras de ciclismo con el contenido actualizado desde Wikidata. Esta documentación le mostrará cómo utilizar este módulo y cómo se puede actualizar los datos en la Wikidata, para que este módulo sea capaz de mostrar los datos en su Wikipedia local.

Para conocer mas detalles acerca de este proyecto, pueden visitar la página principal donde encontraran mas detalles adicionales: Module:Cycling race

Funciones

Actualización del código

El Módulo:Cycling race es almacenado en Wikidata, donde el código está siendo desarrollado. Hay muchas versiones de dicho módulo en varios lenguajes y muchas adaptaciones que se hacen sobre el código. NO renombre la copia actual ni cambie el código directamente sobre esta copia en español. Lo anterior puede repercutir en pérdida de la compatibilidad con las copias que están en las otras Wikipedias y hace imposible su actualización. El mecanismo para actualizar el código es hacerlo directamente sobre el módulo original almacenado en Wikidata d:Module:Cycling race o participar en la página de discusión de dicho módulo para solicitar mejoras a otros usuarios o mostrar las mejoras realizadas. Tenga en cuenta que la forma de actualizar esta versión es copiando la sección modificada o la totalidad del código vigente en Wikidata sobre esta copia, por lo que cualquier cambio realizado en esta copia que no esté en el código en Wikidata, se perderá.


Esta documentación está transcluida desde Módulo:Cycling race/doc.
Por favor, añade las categorías en la subpágina de documentación y los interwikis en Wikidata. Subpáginas de este módulo.

 local p = {} local wiki = string.match(mw.site.server, "%a+") if wiki == "www" then 	wiki = "fr" end --import translation local l10n = mw.loadData("Module:Cycling race/l10n")  --import data local data = mw.loadData("Module:Cycling race/data")  local contentLanguage = mw.getContentLanguage() local wikilang = contentLanguage:getCode() local wikibase = mw.wikibase  -- == Structure of the code == -- I) Constant -- II) Translation -- III) Basic functions -- IV) Functions less basic called from other functions -----A) Time functions -----B) Link functions -----C) Functions for the output, like table -----D) Jersey, flag functions -----E) Other (winner) -- V) Main functions ----- A) Function race reference ----- B) Calendar ----- C) Victory ----- Cbis) Function for infobox ----- D) Stage infobox ----- E) List of teams ----- F) Classifications ----- G) Infobox ----- H) Race infobox ----- I) Team roster ----- J) Function list of winners (palmarès) ----- K) List of stages ----- L) List of stages classification ----- M) Start list ----- N) Rider ranking ----- O) Rider infobox ----- P) Team infobox -- .................. ----- Z) Miscellaneous / Other / Tests   --Tip: search "--==" to navigate between the sections  --== I) Classes declared as global == local textalign = "left" local floattable = "left" local floatinfobox = "right" if wiki == "ar" or wiki == "fa" or wiki == "ur" or wiki == "he" then 	textalign = "right" 	floattable = "right" 	floatinfobox = "left" end  local Wikidatalogosize = "12px" if wiki == "ar" then Wikidatalogosize = "15px" end local standardtablecss=data.standardtablecss_part1..textalign..data.standardtablecss_part2  local lang_priority --for lang priority and fallback if l10n["lang_priority"] then 	lang_priority=l10n["lang_priority"] else --default 	lang_priority={} 	table.insert(lang_priority,wikilang) 	for _, lang in ipairs({'mul','en', 'fr', 'de','es','nl','it'}) do 		if lang~=wikilang then 			table.insert(lang_priority,lang) 		end 	end end  --"country" means here, that there will be a separated column containing the country name --otherwise a flag is typically added in another column, for instance before the rider name local no_country_calendar={'ru','ar'} local no_country_victories={'ru','ar'} local no_country_classification={'es','da','no','ru','ar'}  --to avoid wrong display, or country names becoming very long, --available_list==false --> country=false in the old code, --should be implemented here if not l10n["country_name_list"] then 	table.insert(no_country_calendar, wiki) 	table.insert(no_country_victories, wiki) 	table.insert(no_country_classification, wiki) end  --Note about WDlink_on --On some wikipedia small wikidata flag are displayed after all data coming from wikidata --to enable that set WDlink_on on true  local no_roll_startlist={'fr','da','no','ar','ru','de'} local display_language_in_riderinfobox={'ru'} local display_flag_in_riderinfobox={'ru'} local display_birthnameastitle_in_riderinfobox={'ru'} local display_noweight_in_riderinfobox={'fr','pl'} local display_noage_in_riderinfobox={'pl'} local display_nonickname_in_riderinfobox={'pl'} local display_cm_in_riderinfobox={'pl'}  local silver_theme_countries={'da', 'pl'}  local backgroundColor="#FFDF80" local backgroundColorLight="#FFF7DF" for _, value in pairs(silver_theme_countries) do -- get data if country should be printed in this wiki 	if value == wiki then  		backgroundColor="#EAECF0"  		backgroundColorLight="#EFEFEF" 	end end  local function istrue(x)     if x and (x == 1 or x == "1" or x == "true") then return true end     return nil end  --== II) Translation == local function translate(func_name_short, index, w_race, title) 	if index==1000 then --code for some custom function 		return title 	else 		if func_name_short then 			local func_name 			if w_race then 				func_name=func_name_short.."_women_translate" 				if l10n[func_name] and l10n[func_name][index] then  					return l10n[func_name][index] 				end 			end 			func_name=func_name_short.."_translate" 			if l10n[func_name][index] then  				return l10n[func_name][index] 			end 			return "translation for "..func_name.." index ".. tostring(index).." not found" 		else  			error('func_name found') 		end 	end end  local function plural(num) 	local plural=false --latin language 	local gen_singular=false --for slavic language 	local gen_plural=false --for slavic language 	if num then 		if num > 1 then 			plural=true 			if num < 5 then -- 2, 3 and 4 				gen_singular = true 			elseif num > 20 then 				local modulo = math.fmod( num, 10) 				--modulo==1 --> nothing, it is singular 				if modulo>1 and modulo<5 then 					gen_singular = true 				elseif modulo>4 then 					gen_plural=true 				end 			else 				gen_plural=true 			end 		end 	end 	 	return plural, gen_singular, gen_plural end  local function black_list( Label) 	local black_list=l10n.black_list 	--[[ List of Wikipedia articles with the same lemma as the non existing rider article. Those lemmas are printed 		as text "black" in the tables, not "blue" or "red". This way there will be no false wikilinks at the WhatLinksHere entry. 		List should be updated maybe once a year. ]] 	return black_list[Label] end  local function country_name_from_list(countryID) 	if l10n["country_name_list"] and l10n["country_name_list"][countryID] then 		return l10n["country_name_list"][countryID] 	end 	return nil end  local function stageLink(x, a, b) -- x= 10a: a = 10, b = a. x = 5: a = 5, b = "" 	local word1  	local word2=translate("func_prologue",2) --stage 	local word=word2  	if wiki=="ar" then return word2 .. " " .. ( a or "" ) , "#" .. word2 .. " " .. ( a or "" ) end  -- fr: {{1re}} étape, {{2e}} étape 	if wiki=="fr" then 		if b == "" then -- series_ordinal without character 			if a == "1" then word1 = "1<sup>re</sup> "..word else word1 = a.."<sup>e</sup> "..word end -- table text = {{1re}} étape, {{2ae}} étape, 			if a == "1" then word2 = "#1re "..word else word2 = "#"..a.."e  "..word end --text of section header = #1re étape, #2e étape 			return word1, word2 		end 		if b ~= "" then -- series_ordinal with character: instead of eg "1a re" it is "1re a" 			if a == "1" then word1 = "1<sup>re</sup> "..b.." "..word else word1 = a.."<sup>e</sup> "..b.." "..word end -- table text = {{1re}} étape, {{2ae}} étape, 			if a == "1" then word2 = "#1re "..b.." "..word else word2 = "#"..a.."e"..b.." "..word end --text of section header = #1re étape, #2e étape 			return word1, word2 		end 	end 	if wiki=="hu" then 		if b == "" then return a..". "..word, "#"..a..". "..word 		else return a..b.." "..word, "#"..a..b.." "..word end 	end 	if wiki=="de" or wiki=="da" or wiki=="fo" or wiki=="lb" or wiki=="no" then return a..". "..b.." "..word, "#"..a..". "..b.." "..word end 	if wiki=="ca" then return a.."a "..b.." "..word, "#"..a..". "..b.." "..word end 	if wiki=="es" then return a..".ª "..word.." "..b, "#"..a..".ª "..word.." "..b end 	if wiki=="ast" then 		if b == "" then -- series_ordinal without character 			if a == "1" or a == "3" then word1 = a.."ᵉʳ "..word else word1 = a.."ª "..word end -- table text = 1ᵉʳ etapa, 2ª etapa, 3ᵉʳ etapa, 			if a == "1" or a == "3" then word2 = "#"..a.."ᵉʳ "..word else word2 = "#"..a.."ª  "..word end --text of section header = #1ᵉʳ etapa, #2ª etapa, #3ᵉʳ etapa 			return word1, word2 		end 		if b ~= "" then -- series_ordinal with character: instead of eg "1a re" it is "1re a" 			if a == "1" or a == "3" then word1 = a.."ᵉʳ "..b.." "..word else word1 = a.."ª "..b.." "..word end -- table text = {{1ᵉʳ}} etapa, {{2ª}} etapa, 			if a == "1" or a == "3" then word2 = "#"..a.."ᵉʳ "..b.." "..word else word2 = "#"..a.."ª"..b.." "..word end --text of section header = #1ᵉʳ etapa, #2ª etapa 			return word1, word2 		end 	end  	-- default 	word1 = x                  -- table text = 1, 2a, 3 	word2 = "#"..word.." ".. x -- text of section header = #Etappe 2a, #Stage 4 	return word1, word2 end  local function typeofstage(x, typ, noborder) 	-- plain, hilly, inter, ... must be "" or "any text" 	-- l10nDef[""] = {plain = "", hilly="", inter='', mount='', time_prologue='', time_team='', time_indiv='', uphill='', rest=''} 	local l10n=l10n["type_of_stage_translate"]  	local border 	if noborder then border="" else border="|border|right" end     local stages = {         ["plain stage"] = "[[File:Plainstage.svg"..border.."|20px|"..l10n.plain.."]]",         ["hilly stage"] = "[[File:Hillystage.svg"..border.."|20px|"..l10n.hilly.."]]",         ["intermediate stage"] = "[[File:Mediummountainstage.svg"..border.."|20px|"..l10n.inter.."]]",         ["mountain stage"] = "[[File:Mountainstage.svg"..border.."|20px|"..l10n.mount.."]]",         ["uphill time trial stage"] = "[[File:Mountain Time Trial Stage.svg"..border.."|20px|"..l10n.uphill.."]]",         ["rest day"] = "[[File:Stage rest day.svg"..border.."|20px|"..l10n.rest.."]]"     } 	if stages[x] then 		return stages[x] 	end 	if x=='time trial stage' then 		if noborder then border="" else border="|right" end 		local stages2 = { 			["Q2348250"] = "[[File:Team Time Trial Stage.svg"..border.."|20px|"..l10n.time_team.."]]", 			["Q2266066"] = "[[File:Time Trial.svg"..border.."|20px|"..l10n.time_indiv.."]]", 			["Q485321"] = "[[File:Time Trial.svg"..border.."|20px|"..l10n.time_prologue.."]]" 		} 		if stages2[typ] then 			return stages2[typ] 		end 	end end  local function typeofstagelogo(stageID, noborder) 	local sType 	p = mw.wikibase.getBestStatements(stageID, 'P31') -- P31 is 'instance of' 	local stages = { 		["Q20646667"] = {"plain stage", nil}, 		["Q20646670"] = {"hilly stage", nil}, 		["Q20680270"] = {"intermediate stage", nil}, 		["Q20646668"] = {"mountain stage", nil}, 		["Q485321"] = {"time trial stage", "Q485321"}, -- prologue 		["Q2266066"] = {"time trial stage", "Q2266066"}, -- individual time trial 		["Q2348250"] = {"time trial stage", "Q2348250"}, -- team time trial 		["Q20679712"] = {"uphill time trial stage", nil} 	} 	for _, t in pairs(p) do 		if t.mainsnak.snaktype == 'value' then 			local iOf = t.mainsnak.datavalue.value.id 			if stages[iOf] then 				sType = typeofstage(stages[iOf][1], stages[iOf][2], noborder) 				break 			end 		end 	end 	return sType or '' end  --== III) basic functions --[[ Get any value for a property which is not deprecated ]] local function firstValue(QID, PID, field) 	if QID then 		local ss = wikibase.getAllStatements(QID, PID) 		for _, s in pairs(ss) do 			if s.rank ~= 'deprecated' and s.mainsnak.snaktype == 'value' then 				return field and s.mainsnak.datavalue.value[field] or s.mainsnak.datavalue.value 			end 		end 	else 		return nil 	end end  --[[ Go from season of a team to the team ]] local function getParentID(teamID) 	return firstValue(teamID, 'P5138', 'id') -- P361 is 'part of' 		or firstValue(teamID, 'P361', 'id') -- P5138 is 'season of club or team' end  --[[ Get a label in any of the languages in the fallback list of language codes ]] local function getLabelFallback(itemID, fallback) 	local label 	if fallback==nil then --default 		fallback=lang_priority 	end 	for _, lang in ipairs(fallback) do 		label = mw.wikibase.getLabelByLang(itemID, lang) 		if label then break end 	end 	return label end  --[[ Get a sitelink from the local wiki or from the fallback list of language codes ]] local function getSitelinkFallback(itemID, fallback) 	local link = mw.wikibase.getSitelink(itemID) 	if link then return link end 	for _, lang in ipairs(fallback) do 		link = mw.wikibase.getSitelink(itemID, lang .. 'wiki') 		if link then return link end 	end 	return nil end  local arwiki_totemplate = mw.getCurrentFrame():getParent().args["totemplate"] or mw.getCurrentFrame().args["totemplate"] arwiki_totemplate = (wiki == "ar" and arwiki_totemplate and arwiki_totemplate ~= "") or false  local function get_lf(frame) 	local lf = frame 	if string.match(frame:getParent():getTitle(), '%P+') == mw.site.namespaces.Template.name then 		lf = frame:getParent() 	end 	return lf end  local function get_and_checkID(frame) 	local lf = get_lf(frame) 	local entityID = mw.text.trim(lf.args[1]) 	entityID= string.gsub(entityID, "%c", "") --probably redundant 	if type(entityID) ~= 'string' then error('parameter must be a string') end 	if not entityID:match('Q%d+') then error('parameter must be a valid Wikidata item (ex: Q42)') end 	return entityID, lf end  local function make_IllWD2_link(q, arlabel, enlabel, text) 	local argse = { ["المعرف"] = q, target='en' } 	if arlabel and arlabel ~= '' then  		argse.label = arlabel 	elseif enlabel and enlabel ~= '' then 		argse.enlabel = enlabel 	end	 	if text and text ~= "" then 		argse.text = text  	end 	local final = mw.getCurrentFrame():expandTemplate{ title = 'Ill-WD2', args = argse } 	if arwiki_totemplate then 		final = "{{Ill-WD2" 		for k,v in pairs(argse) do             final = final .. "|" .. k .. "=" .. v         end         final = final .. "}}"     end 	return final end  local function change_listofstages(tab, raceID, header, Id) 	-- code used in arwiki only 	return tab end  --[[ Iterator to get all statements for an entity and property which are not deprecated and have a value]] local function nextStatement(state, i) 	repeat 		i = i + 1 		local s = state[i] 		if s and s.rank ~= 'deprecated' and s.mainsnak.snaktype == 'value' then 			return i, s 		end 	until s == nil end local function statements(QID, PID) 	return nextStatement, wikibase.getAllStatements(QID, PID), 0 end  --[[ Iterator to get all qualifier values for a property for a statement]] local function nextQualifier(state, i) 	repeat 		i = i + 1 		local q = state[i] 		if q and q.snaktype == 'value' then 			return i, q.datavalue 		end 	until q == nil end local function qualifiers(statement, PID) 	return nextQualifier, statement.qualifiers and statement.qualifiers[PID] or {}, 0 end  local function qualifieramount(element, property) 	local result 	for _, q in qualifiers(element, property) do 		result = tonumber(q.value.amount) 		break 	end 	return result end  local function dispmoney(amount, unit) 	if amount and unit then 		local cost = contentLanguage:formatNum(tonumber(amount)) 		if wiki == 'fo' then cost = string.gsub(cost, "%.", ",") end 		if unit == "http://www.wikidata.org/entity/Q4916" then  			cost = cost .. ' €' 		elseif unit == "http://www.wikidata.org/entity/Q4917" then  			cost = cost .. ' $' 		end 		return cost 	end 	return nil end  --== IV) Functions less basic called from other functions == --=== A) Time functions === --[[ Get a Wikidata statement for an entity and property valid at the given timevalue ]] local function checktime(s,q, time) 	local start, startPrecision, END, endPrecision, timePrecision 	if not q or not time then 		return s 	end 	local _, _, _, m, _ = string.find(time, "(%d+)%p(%d+)%p(%d+)") 	if m=="00" then 		timePrecision=9 	end 	if q.P580 and q.P580[1] and q.P580[1].snaktype == 'value' then -- P580 is start time 		start = q.P580[1].datavalue.value.time 		startPrecision = q.P580[1].datavalue.value.precision 		if startPrecision == 9 or timePrecision==9 then -- precision is years 			start = string.sub(start, 1, 5) -- Cut of everything after year 		elseif startPrecision == 10 then -- precision is months 			start = string.sub(start, 1, 8) -- Cut of everything after month 		end 	end 	if q.P582 and q.P582[1] and q.P582[1].snaktype == 'value' then -- P582 is end time 		END = q.P582[1].datavalue.value.time 		endPrecision = q.P582[1].datavalue.value.precision 	end 	if not start or start <= time then 		if not END then 			return s 		end 		if endPrecision == 9 or timePrecision==9 then -- precision 9 is 'years' 			END = string.sub(END, 1, 6) .. '13' -- Set month to 13 		elseif endPrecision == 10 then -- precision 10 is 'months' 			END = string.sub(END, 1, 9) .. '32' -- Set day to 32 		end 		if END >= time then 			return s 		end 	end 	return nil end  local function getStatementForTime(ID, property, time) 	local temp 	for _, s in statements(ID, property) do 		temp =checktime(s, s.qualifiers, time) 		if temp then return temp end 	end 	return nil end  --Display date interval in a natural way:  --long: --4-5 January 2020  --4 January - 2 February 2020 --4 January 2020 - 2 February 2021 --small is the same with short month names  --Does not work properly if the precision is not sufficient local function getStartEndTime(sTime, eTime, mode) 	-- Note: Add the 4formats to "formats" and use funcDate 	local lang = contentLanguage 	local starttime, endtime 	 	--local format = formats[wiki] or formats[''] 	if mode==nil then mode='long' end 	-- Timevalues is like "+2015-07-04T00:00:00Z" 	local y, m = string.match(sTime, "(%d+)-(%d+)-%d+") 	local y2, m2 = string.match(eTime, "(%d+)-(%d+)-%d+") 	 	if m=='00' then --manage the 30 November issue 		if  mode=='long' or mode=="verylong" then 			starttime =lang:formatDate( "Y", sTime ) 		else 			starttime ='-' 		end 	else 		if y ~= y2 then 			if mode=='long' or mode=="verylong" then 				starttime = lang:formatDate( "j F Y", sTime ) 			else 				starttime = lang:formatDate( "j M Y", sTime ) 			end 		elseif m ~= m2 then 			if mode=='long' or mode=="verylong" then 				starttime = lang:formatDate( "j F", sTime ) 			else 				starttime = lang:formatDate( "j M", sTime ) 			end 		else 			starttime = lang:formatDate( "j", sTime ) 		end 	 		if wiki == "ar" then 			if y ~= y2 then starttime = lang:formatDate( "d F Y", sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( "d F", sTime ) 			else starttime = lang:formatDate( "d ", sTime ) end 		elseif wiki == "br" then 			if y ~= y2 then starttime = lang:formatDate( "j", sTime ) .." a viz ".. lang:formatDate( "F Y", sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( "j", sTime ) .." a viz ".. lang:formatDate( "F", sTime ) 			else starttime = lang:formatDate( "j", sTime ) .." " 			end 		elseif wiki == "ca" or wiki == "es" or wiki == "ast" then 			if y ~= y2 then 				starttime = lang:formatDate( "j", sTime ) .." de ".. lang:formatDate( "F", sTime ) .." de ".. lang:formatDate( "Y", sTime ) 			elseif m ~= m2 then 				starttime = lang:formatDate( "j", sTime ) .." de ".. lang:formatDate( "F", sTime ) 			else starttime = lang:formatDate( "j", sTime ) .." " 			end 		elseif wiki == "cs" then 			if y ~= y2 then starttime = lang:formatDate( "j. xg Y", sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( "j. xg", sTime ) 			else starttime = lang:formatDate( "j", sTime ) 			end 		elseif wiki == "de" or wiki == "da" or wiki == "fo" or wiki == "lb" or wiki == "no" then 			if y ~= y2 then starttime = lang:formatDate( "j. F Y", sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( "j. F", sTime ) 			else starttime = lang:formatDate( "j.", sTime ) 			end 		elseif wiki == "fi" then 			if y ~= y2 then starttime = lang:formatDate( 'j. F"ta" Y', sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( 'j. F"ta"', sTime ) 			else starttime = lang:formatDate( "j.", sTime ) 			end 		elseif wiki == "eo" then 			if y ~= y2 then starttime = lang:formatDate( "j", sTime ) .."-a de ".. lang:formatDate( "F Y", sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( "j", sTime ) .."-a de ".. lang:formatDate( "F", sTime ) 			else starttime = lang:formatDate( "j", sTime ) .."-a " 			end 		elseif wiki == "eu" then 			if y ~= y2 then starttime = lang:formatDate( "Y", sTime ) ..".eko ".. lang:formatDate( "F", sTime ) .."k ".. lang:formatDate( "j", sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( "F", sTime ) .."k ".. lang:formatDate( "j", sTime ) 			else starttime = lang:formatDate( "F", sTime ) .."k ".. lang:formatDate( "j", sTime ) 			end 		elseif wiki == "hu" then 			starttime = lang:formatDate( "Y. F j.", sTime) 		elseif wiki == "ja" then 			if y ~= y2 then starttime = lang:formatDate( "Y年m月d日", sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( "Y年m月d日", sTime ) 			else starttime = lang:formatDate( "Y年m月d日", sTime ) 			end 		elseif wiki == "lv" then 			if m ~= m2 then starttime = lang:formatDate( "Y. \\g\\a\\d\\a j. F", sTime ) 			else starttime = lang:formatDate( "Y. \\g\\a\\d\\a j.", sTime ) 			end 		elseif wiki == "pl" then 			if y ~= y2 then starttime = lang:formatDate( "j xg Y", sTime ) 			elseif m ~= m2 then starttime = lang:formatDate( "j xg", sTime ) 			else starttime = lang:formatDate( "j", sTime ) 			end 		end 	end 	 	if m2=='00' then --manage the 30 November issue 		if  mode=='long' or mode=="verylong" then 			endtime= lang:formatDate( "Y", eTime ) 		else 			endtime= '-' 		end 	else 		if (mode=='long' and y ~= y2) or mode=="verylong" then 			endtime = lang:formatDate("j F Y", eTime) 		elseif y ~= y2 then --small 			endtime = lang:formatDate("j M Y", eTime) 		elseif mode=='long' then 			endtime = lang:formatDate("j F", eTime) 		else 			endtime = lang:formatDate("j M", eTime)	 		end 		if wiki == "ar" then 			if mode=='long' or mode=="verylong" or y ~= y2 then endtime = lang:formatDate( "d F Y", eTime ) 			elseif m ~= m2 then endtime = lang:formatDate( "d F Y", eTime ) 			else endtime = lang:formatDate( "d F Y", eTime ) 			end 		elseif wiki == "br" then endtime = lang:formatDate( "j", eTime ) .." a viz ".. lang:formatDate( "F Y", eTime ) 		elseif wiki == "ca" or wiki == "es" or wiki == "ast" then 			if mode=='long' or mode=="verylong" or y ~= y2 then 				endtime = lang:formatDate( "j", eTime ) .." de ".. 				lang:formatDate( "F", eTime ) .." de ".. lang:formatDate( "Y", eTime ) 			else 				endtime = lang:formatDate( "j", eTime ) .." de ".. 				lang:formatDate( "F", eTime ) 			end 		elseif wiki == "cs" then endtime = lang:formatDate( "j. xg Y", eTime ) 		elseif wiki == "de" or wiki == "da" or wiki == "fi" or wiki == "fo" or wiki == "lb" or wiki == "no" then 			if mode=='long' or mode=="verylong" or y ~= y2 then 				endtime = lang:formatDate( "j. F Y", eTime ) 			else 				endtime = lang:formatDate( "j. M", eTime ) 			end 		elseif wiki == "eo" then endtime = lang:formatDate( "j", eTime ) .."-a de ".. lang:formatDate( "F Y", eTime ) 		elseif wiki == "eu" then endtime = lang:formatDate( "Y", eTime ) ..".eko ".. lang:formatDate( "F", eTime ) .."k ".. 			lang:formatDate( "j", eTime ) 		elseif wiki == "fi" then endtime = lang:formatDate('j F"ta" Y', eTime) 		elseif wiki == "hu" then 			if y ~= y2 then endtime = lang:formatDate( "Y. F j.", eTime ) 			elseif m ~= m2 then endtime = lang:formatDate( "F j.", eTime ) 			else endtime = lang:formatDate( "j.", eTime ) 			end 			--endtime = lang:formatDate( "Y", eTime ) ..". ".. lang:formatDate( "F j", eTime ) .."." 		elseif wiki == "ja" then 			if y ~= y2 then endtime = lang:formatDate( "Y年m月d日", eTime ) 			elseif m ~= m2 then endtime = lang:formatDate( "m月d日", eTime ) 			else endtime = lang:formatDate( "d日", eTime ) 			end 		elseif wiki == "lv" then 			if y ~= y2 then endtime = lang:formatDate( "Y. \\g\\a\\d\\a j. F", eTime ) 			else endtime = lang:formatDate( "j. F", eTime ) 			end 		elseif wiki == "pl" then endtime = lang:formatDate( "j xg Y", eTime ) 		end 	end 	return starttime, endtime end  local formats = data.formats   -- Display the date, the mode changes the format local function funcDate(date, mode) 	-- local date = '+2016-05-20' 	-- local mode = 'small' 	local format = formats[wiki] or formats['']     local lang = contentLanguage      	--handle problems with lack of precision 	local dispDate = date  	if date == nil then 		mode = 'nodate' 	elseif string.sub(date,7,8)=='00' then	-- lack of month 		dispDate= string.sub(date,1,6).."01-01"..string.sub(date,12) 		if mode == 'long' or mode == 'onlyyear' or mode == 'monthly' then 			mode = 'onlyyear' 		else 			mode = 'nodate' 		end 	elseif string.sub(date,10,11)=='00' then -- lack of day 		dispDate= string.sub(date,1,9).."01"..string.sub(date,12) 		if mode == 'long' then 			mode = 'monthly' 		elseif mode == 'small' then 			mode = 'onlymonth' 		elseif mode == 'onlyday' then 			mode = 'nodate' 		end 	end 	if format[mode] == nil then mode = 'nodate' end 	 	return contentLanguage:formatDate(format[mode], dispDate) end  --[[ get the year for a race as a string, or an empty string]] local function getYear(raceID) 	local year = firstValue(raceID, 'P580', 'time') or -- P580 is 'start time' 		firstValue(raceID, 'P585', 'time') -- P585 is 'point in time' 	if year then 		return string.sub(year, 2, 5) 	end 	return '' end  local function isdisqualified(p,q) --disqualification can use deprecated or P1534 	local cancelled="" 	local disqualified=false 	 	if p and p.rank=='deprecated' then 		cancelled='text-decoration:line-through;' 		disqualified=true 	else 		if q and q.P1534 and q.P1534[1].snaktype == 'value' then 			local tempdsq=q.P1534[1].datavalue.value.id 			if tempdsq=='Q1229261' then  				cancelled='text-decoration:line-through;' 				disqualified=true 			end --disqualified 		end 	end 	return cancelled, disqualified end  --=== B) Link functions === local function getOfficialName(teamID, timeOfRace,season,strict) -- for team 	--return officialName, isLocal 	local strictLang = {mk = true}  	local cyrillic = {mk = true, ru = true} 	local strictLangBool= strictLang[wiki] or strict     local correcttime, best, name, nametemp     local wantedLanguages = {}      	for i, lang in ipairs(lang_priority) do 		wantedLanguages[lang] = i 	end     --case one, one official name / period overloaded with other languages as qualifier     --for instance https://www.wikidata.org/wiki/Q195833     best = 999 	for _, p1448 in statements(teamID, 'P1448') do 		correcttime=true 		if timeOfRace and timeOfRace ~='' then 			correcttime =checktime(p1448, p1448.qualifiers, timeOfRace) 		end 		if correcttime then  			if p1448.qualifiers and p1448.qualifiers.P1448 then 				local q = p1448.qualifiers.P1448 			    best = 999 				for _, l in pairs(q) do 					if l.snaktype == 'value' then 						local lang = l.datavalue.value.language 						if wantedLanguages[lang] and wantedLanguages[lang] < best then 							best = wantedLanguages[lang] 							name = l.datavalue.value.text 						end 					end 				end 				if name then return name, true end 			end 			--p1448 and correct time, look in the not qualifier part 		 			lang=p1448.mainsnak.datavalue.value.language 			if strictLangBool then 				if wiki==lang then 					name = p1448.mainsnak.datavalue.value.text 				end 			elseif wantedLanguages[lang] and wantedLanguages[lang] < best then 				best = wantedLanguages[lang] 				name = p1448.mainsnak.datavalue.value.text 			else 				if cyrillic[lang]==nil then --don't display cyrillic for latin wiki 					nametemp = p1448.mainsnak.datavalue.value.text 				end 			end 		end 	end     if name then      	return name, true     elseif not strictLangBool and nametemp then     	return nametemp, false     end      --no official name, get label 	local label=wikibase.getLabel(teamID) 	if season and season==true then 		if label then return string.sub(label,1,label:len()-5),true end --  	else 		return label, true -- No official name, try label 	end end  local function revertfirstlast(name) 	local nametable = mw.text.split(name, ",") 	if nametable[2] then --there is a coma 		return nametable[2].." "..nametable[1] 	else 		return nametable[1] 	end end  -- RiderID --> RiderLink local function getRiderLink(riderID, startOfSeason) --startOfSeason optional 	--Priority order 	--#1 P1813, short name, in correct alphabet, correct time 	--#2 P1448, official name, in correct alphabet, correct time 	--#3 sitelink (so label from wikipedia) in correct language 	--#4 label from wikidata in correct language 	--#5 label from wikidata in another language 	local strictLang = {mk = true, ru = true} 	local strictLangBool= strictLang[wiki]  	local sitelink = wikibase.getSitelink(riderID) 	local officialname,officialnametemp, language, name 	local correctlanguage=false 	local listOfProperty={'P1813','P1448'}  	for _, prop in ipairs(listOfProperty) do 		for _, p1813 in statements(riderID, prop) do 			if not officialname or not correctlanguage then 				language = p1813.mainsnak.datavalue.value.language 				officialnametemp = p1813.mainsnak.datavalue.value.text 				if strictLangBool then 					if wiki==language then 						name=officialnametemp --only exact language 						correctlanguage=true 					end 				else 					if wiki==language then --exact language --> ok 						name=officialnametemp 						correctlanguage=true 					elseif strictLang[language]==nil and not officialname then 						--normally all "latin" languages use the same name, except for cyrillic translation 						local russianLabel= wikibase.getLabelByLang(riderID, "ru") 						if russianLabel then 							local russianEnd=string.sub(russianLabel, -3) 							if russianEnd~="вна" and russianEnd~="вич" then --otherwise rejected 								name=officialnametemp  								correctlanguage=false 							end 						else -- no russian label, it is most probably not a cyrillic translation 							name=officialnametemp --any language latin 							correctlanguage=false 						end 					end 				end 				if startOfSeason~= nil then 					local q = p1813.qualifiers 					if q then 						local temp = checktime(name,q,startOfSeason) 						if temp then officialname = name end--if the time is correct than it is finished 					else 						officialname = name 					end 				else 					officialname = name 				end 			end 		end 	end  	if sitelink and officialname then --if there is an official name, then use it 		return "[[" .. sitelink .. "|" ..officialname.."]]", correctlanguage 	else 		if officialname then return officialname end 		if sitelink then 			if wiki == "de" then 				local label = wikibase.getLabelByLang(riderID, wiki) 				if label then 					local p27 = wikibase.getBestStatements(riderID, 'P27') -- P27 is country of citizenship 					if p27[1] and p27[1].mainsnak.snaktype == 'value' then 						local c = p27[1].mainsnak.datavalue.value.id 						if c=="Q159" or c=="Q184" or c=="Q212" or c=="Q232" then -- Q159, Q184, Q212, Q232 is Russia, Belarus, Ukraine, Kazakhstan 							return "[[" .. sitelink .. "|" .. label .. "]]", correctlanguage 						end 					end 				end 			end 			if wiki == 'ru' then 				local label = revertfirstlast(mw.text.trim(string.gsub(sitelink, "%b()", ""))) 				return "[[" .. sitelink .. "|" .. label.. "]]", correctlanguage 			else 				return "[[" .. sitelink .. "|" .. mw.text.trim(string.gsub(sitelink, "%b()", "")) .. "]]", correctlanguage 			end 		end  		-- No WP article. Display label, and make it a red link if no other article uses the title 		local link 		local label = wikibase.getLabelByLang(riderID, wiki) 		if label then 			if wiki == 'ar' then 				link = make_IllWD2_link(riderID, label) 			else 				if wiki=='ru' then 					label=revertfirstlast(label) 				end  				if black_list( label) then 					link = label 				else 					local title = mw.title.new(label) 					if title and title.exists then 						link = label 					else 						link = "[[" .. label.. "]]" 					end 				end 			end 			return link, correctlanguage 		end  		-- No label in the local language. Try other languages, but don't link. 		correctlanguage=false 		if wiki == 'ar' then 			link = make_IllWD2_link(riderID) 		else 			link = getLabelFallback(riderID) 			if link then 				link = string.gsub(link, "%b()", "") 			else 				link = "(label missing)" 			end 		end 		return link, correctlanguage 	end end  -- Get the countryID, return a single one, not a list local function getCountryID(entityID, timeOfRace) 	local countryID 	 	if entityID then 		local stm = getStatementForTime(entityID, 'P1532', timeOfRace) -- P1532 is country for sport 		if stm == nil then 			stm = getStatementForTime(entityID, 'P17', timeOfRace) -- P17 is country 		end 		if stm then countryID = stm.mainsnak.datavalue.value.id end 	end 	return countryID end  --[[ Get the name of a country ]] local function getCountryName(countryID) 	local name = country_name_from_list(countryID) 	if name == nil then 		local label, lang = wikibase.getLabelWithLang(countryID) 		--[[ Uses standard language fallback. Should not return nil, nil, as all countries have English labels. ]] 		if lang == wikilang then 			name = label 		elseif lang then 			name = label .. ' (' .. lang .. ')' 		end 	end 	return name or '' end  --[[ Get sitelink with no wiki no formating ]] local function getRawTeamLink(teamID) 	local sitelink 	local parentID = getParentID(teamID) 	if parentID then -- try parent team first 		sitelink = mw.wikibase.getSitelink(parentID) 	end 	if not sitelink then 		sitelink = mw.wikibase.getSitelink(teamID) 	end 	return sitelink end  --[[ Get sitelink, categoryID and maybe country for a team. 	Returns sitelink, team category ID, countryID (only countryID if country arg is true ]] local function getTeamLinkCat(teamID, timeOfRace, country, forceParentlink) 	local name, sitelink, catID, countryID, p31 	local parentID = getParentID(teamID) 	local season=false 	-- Find team category 	--Hypothesis, it is a season, look in P2094 	for _, p2094 in statements(teamID, 'P2094') do 		if checktime(p2094, p2094.qualifiers, timeOfRace) then 			if data.teamCats[p2094.mainsnak.datavalue.value.id] then 				catID = p2094.mainsnak.datavalue.value.id 				season=true 				break 			end 		end 	end	 	--check if season 	if season==false then --otherwise already clear 		for _, p in statements(teamID, 'P31') do 			local natureID = p.mainsnak.datavalue.value.id 			if natureID=="Q53534649" then 				season=true 				break 			end 		end 	end  	--look by the parent, then P31 is used for the category 	if (not catID and parentID and season) then 		p31 = getStatementForTime(parentID, 'P31', timeOfRace) 	elseif not season then --it is the team look in the team directly 		p31 = getStatementForTime(teamID, 'P31', timeOfRace) 	end 	if p31 and data.teamCats[p31.mainsnak.datavalue.value.id] then  		catID = p31.mainsnak.datavalue.value.id  	end 	-- Find country if needed 	if country or data.natTeamCats[catID] then 		countryID = getCountryID(teamID, timeOfRace) 	end 	if countryID and data.natTeamCats[catID] then 		if countryID=='Q145' then 			name = getCountryName('Q23666') 		else --to solve the United-Kingdom/Great Britain problem by national team 			name = getCountryName(countryID) 		end 		local t={Q20738667=34, Q54555994=35, Q99658502=36} 		if t[catID] then --add U23, U19, B, (note: why "B" and not B) 			name = name ..' '..translate("headoftableIII",t[catID]) 		end 		sitelink = getRawTeamLink(teamID) 	else 		-- It is not a national cycling team 		local isLocal 		if season and not forceParentlink then 			sitelink = wikibase.getSitelink(teamID) 			name, isLocal = getOfficialName(teamID, timeOfRace,true) --problem here is that the label will be used if no official name, official name of the parent would actually be better... 			if not sitelink and parentID then 				sitelink = wikibase.getSitelink(parentID) 			end 		else 			if parentID then -- try parent team first 				sitelink = wikibase.getSitelink(parentID) 				name, isLocal = getOfficialName(parentID, timeOfRace) 			end 			if not sitelink then 				sitelink = wikibase.getSitelink(teamID) 			end 		end          		if not name or (not isLocal and l10n["lang_priority"]) then 			local partName, partIsLocal = getOfficialName(teamID, timeOfRace) 			if partName and (not name or partIsLocal) then 				name = partName 			end 		end 	end 	if sitelink then 		if name then 			sitelink = '[[' .. sitelink .. '|' .. name .. ']]' 		else 			sitelink = '[[' .. sitelink .. ']]' 		end 	else         if wiki == "ar" then 			local arlabel = mw.wikibase.getLabelByLang((parentID or ''), 'ar') or ""             local texte = mw.wikibase.getLabelByLang(teamID, 'ar') or ""             sitelink = make_IllWD2_link((parentID or teamID), arlabel, name, texte)         else             if name then                 sitelink = name             else                 sitelink = (parentID and wikibase.getLabel(parentID)) or                     wikibase.getLabel(teamID) or 'No name'             end         end 	end 	return sitelink, catID, countryID end  local function getTeamCodeCat(teamID, timeOfRace) 	-- Find team category 	local codeUCI 	local p1998 =getStatementForTime(teamID, 'P1998', timeOfRace) 	if p1998 then 		codeUCI = p1998.mainsnak.datavalue.value 	else 		local parentID = getParentID(teamID) 		if parentID then 			p1998 =getStatementForTime(parentID, 'P1998', timeOfRace) 			if p1998 then 				codeUCI = p1998.mainsnak.datavalue.value 			end 		end 	end 	return codeUCI end  local function getReference(lf,statement, outputLocal) 	local function formatRefDate(date, precision) 		if precision == 9 then -- Precision is year 			return string.sub(date, 2, 5) 		elseif precision == 10 then -- Precision is month 			return contentLanguage:formatDate("F Y", string.sub(date, 2, 8)) 		elseif precision >= 11 then -- Precision is day (or less) 			return funcDate(date, 'long') 		end 	end  	local ref = statement.references 	if not ref or not ref[1] then 		return nil 	end 	ref = ref[1].snaks 	if ref.P854 and ref.P854[1] and ref.P854[1].snaktype == 'value' then -- P854 is 'reference URL' 		local refURL = ref.P854[1].datavalue.value 		local refTitle = '' 		local refDate = '' 		local refRetrieved = '' 		local refLang = '' 		if ref.P1476 and ref.P1476[1] and ref.P1476[1].snaktype == 'value' then -- P1476 is 'title URL' 			refTitle = ref.P1476[1].datavalue.value.text 			local lang = ref.P1476[1].datavalue.value.language 			if lang ~= wikilang then 				refLang = '(' .. lang .. ')'                 if wiki == 'ar' then refLang = lang end             end 		end 		if ref.P577 and ref.P577[1] and ref.P577[1].snaktype == 'value' then -- P577 is 'publication date' 			local value = ref.P577[1].datavalue.value 			refDate = formatRefDate(value.time, value.precision) 			if (wiki == 'ar') then refDate = refDate 			else refDate = ', ' .. refDate 			end 		end 		if ref.P813 and ref.P813[1] and ref.P813[1].snaktype == 'value' then -- P813 is 'retrieved' 			local value = ref.P813[1].datavalue.value 			refRetrieved = formatRefDate(value.time, value.precision) 			if wiki == "de" then 				refRetrieved = ", (abgerufen am " .. refRetrieved .. ')' 			elseif wiki == "ar" then 				refRetrieved = refRetrieved 			elseif wiki == "fr" then 				refRetrieved = " (consulté le " .. refRetrieved .. ')' 			elseif wiki == "da" then 				refRetrieved = " Hentet " .. refRetrieved .. '.' 			else 				refRetrieved = " Retrieved " .. refRetrieved .. '.' 			end 		end 		local domain = string.match(refURL, '//([^/]+)') 		if string.sub(domain, 1, 4) == 'www.' then 			domain = string.sub(domain, 5) 		end 		local refText 		if wiki == "ar" then             refText = '{{web cite' .. 			'|url = ' .. refURL .. 			'|title= ' .. refTitle .. 			'|lang = ' .. refLang ..  			'|website=' .. domain ..  			'|date=' .. refDate .. 			'|accessdate=' .. refRetrieved .. 			'}}'         elseif wiki == "fr" then                 -- fr: "(en) « Lloyd Mondory ... EPO », sur velonews.competitor.com (consulté le 30 april 2016), 30 octobre 2015." 			local sur = ', sur <span style="font-style:italic;"> ' .. domain .. '</span>' 			refText = refLang .. ' « ['.. refURL .. ' '.. refTitle .. '] »' .. sur .. refRetrieved .. refDate .. '.' 		elseif wiki == "de" then 			local In = ' In: <span style="font-style:italic;">' .. domain .. '</span>' 			refText = '<span style="font-style:italic;">['.. refURL.. ' '.. refTitle.. '.]</span> ' .. 				In .. refDate .. refRetrieved ..'.' 		else 			local at = ', <span style="font-style:italic;"> ' .. domain .. '</span>' 			refText = refLang .. ' [' .. refURL .. ' ' .. refTitle .. ']' .. at .. refDate .. '.' .. refRetrieved 		end 		if outputLocal==1 then 			return refText 		else             local refargs = {}             if wiki ~= "ar" then                  refargs.name = refText             end 			return lf:extensionTag('ref', refText, refargs) 		end 	end end  --Some wikipedia, like WP:ar, don't use model like --{{#invoke:Cycling race/infobox|Q123}} --But have the module included in another module --{{#invoke:wikidata|Cycling race/infobox|... --in this case frame does not refer to the arguments of /infobox but to the wanted ones --read https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#frame-object  local function get_arg(index, lf, number) 	if lf.args[index] then 		if number then 			return tonumber(lf.args[index]) 		else 			return string.gsub(lf.args[index], "%c", "") 		end 	end 	return nil end  local function getImageOrMap(QID, PID) 	local p18 = wikibase.getBestStatements(QID, PID) -- P18 is 'image' 	local first 	for _, image in pairs(p18) do 		if image.mainsnak.snaktype == 'value' then 			if not first then 				first = image.mainsnak.datavalue.value 			end 			local q = image.qualifiers 			if q and q.P2096 then 				for _, caption in pairs(q.P2096) do -- P2096 is 'caption' 					if caption.snaktype == 'value' and caption.datavalue.value.language == wikilang then 						return image.mainsnak.datavalue.value, caption.datavalue.value.text 					end 				end 			end 		end 	end 	return first end  local function getLogo(QID) 	return getImageOrMap(QID, 'P154') end  local function getImage(QID) 	return getImageOrMap(QID, 'P18') end  local function getMap(QID) 	return getImageOrMap(QID, 'P242') end  local function getSectionalView(QID) 	return getImageOrMap(QID, 'P2713') end  --[[ Get link for race or competition]] local function raceLink(QID) 	local sitelink = wikibase.getSitelink(QID) 	local instanceOf = firstValue(QID, 'P3450', 'id') 	if instanceOf == nil then 		instanceOf = firstValue(QID, 'P31', 'id') -- P31 is 'instance of' 	end 	if instanceOf == 'Q1137352' then -- Q1137352 is 'French Road Cycling Cup' 		local label2 = wikibase.getLabel(instanceOf) 		if sitelink then 			if label2 then return '[[' .. sitelink .. '|' .. label2 .. ']]' end 			return '[[' .. sitelink .. ']]' 		end 		local sitelink2 = wikibase.getSitelink(instanceOf) 		if sitelink2 then return '[[' .. sitelink2 ..'|' .. string.gsub(sitelink2, " %b()", "") .. ']]' end 		if label2 then return label2 end 	end 	if sitelink then return "[[".. sitelink.. "]]" end 	return wikibase.getLabel(QID) or '' end  local function getPlaceLink(placeID,timeOfRace) 	local sitelink = wikibase.getSitelink(placeID) 	local name = country_name_from_list(placeID) 	if name==nil then 		name=getOfficialName(placeID, timeOfRace,nil,true) --name should be in the right language 	end 	if sitelink then 		-- Delete " (...)" form e.g. "Unley (South Australia)" 		if name ~=nil then 			return '[[' .. sitelink .. '|' .. name .. ']]' 		else 			return '[[' .. sitelink .. '|' .. string.gsub(sitelink, ' %b()', '') .. ']]' 		end 	end 	local label = wikibase.getLabel(placeID) or '' 	if wiki == 'ar' then 		arlabel = wikibase.getLabelByLang(placeID, "ar") 		return make_IllWD2_link(placeID, arlabel) 	end 	return contentLanguage:ucfirst(label) end	  -- ClassID --> ClassLink -- some WPs use a unique article for this case local function classLinkFn(classID, circuitID) 	local link, label 	if wiki~="fr" then --not used 		link= wikibase.getSitelink('Q22348500') -- Q22348500 is 'cycling race class' 	elseif circuitID then 		link =wikibase.getSitelink(circuitID) --optional parameter to obtain [circuitlink|class label]  	end  	if classID=="Q18536594" then  		if wiki=="fr" then 			label="JO" 		else 			label="OG" 		end 	else 		 label = getLabelFallback(classID) 	end  	if label and link then 		link = '[[' .. link .. '|' .. label .. ']]' 	elseif link then 		link = '[[' .. link .. ']]' 	elseif label then 		link = label 	else 		link='' 	end 	if wiki == "ar" then-- right now Q22348500 has no link in "ar" 		link = make_IllWD2_link(classID , "", label) 	end 	return link end --[[ Get local content to a infoboxe from template args ]] local function getLocalContent(contents, args) 	for _, content in pairs(contents) do 		local name = content.name 		if not name then error('translation missing in Module:Cycling race/l10n of your wikipedia') end 		local nameNoShy = string.gsub(name, '&#173;', '')  -- filter soft hyphen out 		local nameNoShyLow, name_pluralNoShyLow 		if nameNoShy then 			nameNoShyLow = mw.ustring.lower(nameNoShy) 		end 		local name_plural = content.name_plural 		local name_pluralNoShy = name_plural and string.gsub(name_plural, '&#173;', '')  -- filter soft hyphen out 		if name_pluralNoShy then 			name_pluralNoShyLow = mw.ustring.lower(name_pluralNoShy) 		end 		 		if args[nameNoShy] and args[nameNoShy] ~= '' then 			if content.special then 				local newname, value = string.match(args[nameNoShy], '([^:]+):(.*)') 				if value and mw.text.trim(value) ~= '' then 					content.name = mw.text.trim(newname) 					content.content = mw.text.trim(value) 				end 			else 				content.content = mw.text.trim(args[nameNoShy]) 			end 		elseif nameNoShyLow and args[nameNoShyLow] and args[nameNoShyLow] ~= '' then 			if content.special then 				local newname, value = string.match(args[nameNoShyLow], '([^:]+):(.*)') 				if value and mw.text.trim(value) ~= '' then 					content.name = mw.text.trim(newname) 					content.content = mw.text.trim(value) 				end 			else 				content.content = mw.text.trim(args[nameNoShyLow]) 			end 		elseif args[name_pluralNoShy] and args[name_pluralNoShy] ~= '' then 			content.name = content.name_plural 			content.content = mw.text.trim(args[name_pluralNoShy]) 		elseif name_pluralNoShyLow and args[name_pluralNoShyLow] and args[name_pluralNoShyLow] ~= '' then 			content.name = content.name_plural 			content.content = mw.text.trim(args[name_pluralNoShyLow]) 		end 	end end  local function checkDis(q) 	dis="road" 	if q and q.P642 and q.P642[1] and q.P642[1].snaktype == 'value' then 		if q.P642[1].datavalue.value.id == 'Q520611' or q.P642[1].datavalue.value.id =='Q1031445' then 			onlyRoad=false 			dis="mountainBike" 		elseif  q.P642[1].datavalue.value.id == 'Q335638' then 			onlyRoad=false 			dis="cycloCross" 		elseif q.P642[1].datavalue.value.id == 'Q221635' then 			onlyRoad=false 			dis="track"			 		end 	end 	return dis end  -- Rider --> Team link local function getTeam(riderID, timeOfRace, q) 	-- q: qualifiers of statement in race entity where the rider is the value 	local teamID, link, catID, countryID 	if q and q.P54 and q.P54[1].snaktype == 'value' then -- P54 is member of sports team 		teamID = q.P54[1].datavalue.value.id 		link, catID, countryID = getTeamLinkCat(teamID, timeOfRace) 	else 		for _, s in statements(riderID, 'P54') do 			if not link then --like a break 				p54 =checktime(s, s.qualifiers, timeOfRace)  				if p54 then 					dis=checkDis(p54.qualifiers) 			    	if dis=='road' then --by default 						teamID = p54.mainsnak.datavalue.value.id 						link, catID, countryID = getTeamLinkCat(teamID, timeOfRace) 					end 				end 			end 		end 	end 	return link, teamID, catID, countryID end  --RiderID --> UCI code local function getTeamCode(riderID, timeOfRace, q) 	-- q: qualifiers of statement in race entity where the rider is the value 	local teamID, code 	if q and q.P54 and q.P54[1].snaktype == 'value' then -- P54 is member of sports team 		teamID = q.P54[1].datavalue.value.id 		code = getTeamCodeCat(teamID, timeOfRace) 	else 		local p54 = getStatementForTime(riderID, 'P54', timeOfRace) 		if p54 then 			teamID = p54.mainsnak.datavalue.value.id 			code= getTeamCodeCat(teamID, timeOfRace) 		end 	end 	return code end  local function seasonToTeamID(teamID) 	if teamID then 		local parentID=getParentID(teamID) 		if parentID then--season was used 			return parentID 		else 			return teamID 		end 	else 		return nil 	end end  local function wdLink(id) 	local text = "[[File:Wikidata-logo S.svg| " .. Wikidatalogosize .. "|link=d:" .. id .. "]]"	  	if arwiki_totemplate then         text = '{{عدل في ويكي بيانات|type1=1|id=' .. id .. '}}'     end     return text end  local function WPlinkpure(Qnumber) 	local link='' 	local Sitelink = wikibase.getSitelink(Qnumber) -- link to WParticle 	local Label = getLabelFallback(Qnumber) or ''  	if Sitelink ~= nil then link = "[[" .. Sitelink .. "|" .. mw.text.trim(string.gsub(Sitelink, "%b()", "")..' ') .. "]]" 	elseif wiki == 'ar' then 		arlabel = mw.wikibase.getLabelByLang(Qnumber, 'ar') or "" 		link = make_IllWD2_link(Qnumber , arlabel , Label) 	else          link = mw.ustring.gsub(Label, "^(%a)", function (x) return mw.ustring.upper(x) end) 	end  	return link end  --=== C) Function for the output === local function getCountryBool(no_country_list) 	local country = true 	if no_country_list then 		for _, value in pairs(no_country_list) do -- get data if country should be printed in this wiki 			if value == wiki then country = false end 		end 	end 	return country end  local function handle_error_message(s) 	local error_message='' 	if s.error_message and s.error_message ~= 0 then 		error_message = func_error_message( 1) 		error_message = mw.ustring.gsub(error_message, "<1>", s.property) 		error_message = mw.ustring.gsub(error_message, "<2>", mw.wikibase.label( s.item )) 		error_message = mw.ustring.gsub(error_message, "<3>", s.item) 		error_message = ' [[File:Exclam icon.svg|12px|'.. error_message .. ']]' 	end 	return error_message  end  local function tableA(s) 	local error_message=handle_error_message(s)  	local t = mw.html.create('table') 		:addClass('sortable') 		:attr('cellpadding', '0') 		:attr('cellspacing', '0') 		:css('border' , '1px solid rgb(200,200,200)') 		:css('padding', '3px') 	 	local title =translate(s.header_function,s.header_1, s.w_race, s.title)  	if s.header_1 == 19 and wiki == "ar" then title = title .. " " .. s.year end	 		 	local wd_link = mw.html.create('span'):cssText('float:left; margin: 0 5px'):wikitext(wdLink(s.item..'#'..s.property)) 	if arwiki_totemplate then wd_link = wdLink(s.item..'#'..s.property) end 	local caption = t:tag('tr'):tag('th'):attr('colspan', tostring(#s.header_2 + 1)) 	:cssText('padding:2px; text-align:center; line-height: 1.8em;') 	:css('background-color',backgroundColor) 	caption:wikitext(tostring(wd_link)..' '..error_message ..' '..title)  	local country=getCountryBool(s.no_country)  	local header = t:tag('tr') 	for i,k in ipairs(s.header_2) do 		if i == s.country_column then 			if country == true then 				header:tag('th') 					:cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap') 					:wikitext(translate(s.header_function,k,s.w_race)) 			end 		end 		if i ~= s.country_column then 			local column = header:tag('th') 					:cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap') 					:wikitext(translate(s.header_function,k,s.w_race)) 			if s.data_sort_type[i] == 'unsortable' then 				column:addClass('unsortable') 			end 		end 	end  	return t end  local function tableB(s) --for startlist 	local error_message=handle_error_message(s) 	 	local roll = true 	for _, value in pairs(s.no_roll_startlist) do -- get data if country should be printed in this wiki 		if value == wiki then roll = false end 	end  	local cssTable= "border: 1px solid rgb(200,200,200); margin: 0 0 0 0;".. 				"background-color: rgb(255, 255, 255); padding: 0px; float: left;".. 				"clear: left; ; text-align: left; vertical-align: top; font-size: 85%; line-height: 1.8em;" 	local wdlink_span = mw.html.create('span'):css('float',floattable):wikitext(wdLink(s.item.. '#'.. s.property)..' '..error_message) 	if arwiki_totemplate then wdlink_span = wdLink(s.item..'#'..s.property) end 	if roll == true then 		local rollTable1 = mw.html.create('div'):addClass("NavFrame") 		:cssText('center = margin: 0 0.5em 0;clear:both; border: 1px solid rgb(200,200,200);' .. 		'cellpadding="4" cellspacing="0" style="width:100%; background-color: rgb(255, 255, 255);padding: 5px;'.. 		'margin-bottom:1em; background-color:'..backgroundColor..';') 		:attr('title','['..translate("startlist",14)..']/['..translate("startlist",15)..']') 		local tDiv= rollTable1:tag('div'):addClass("NavHead") 		:cssText('text-align:'.. textalign .." =;height:1.8em; color:black;font-weight:bold;") 		:css('background-color',backgroundColor) 		tDiv:tag('span')  		local tSpan=tDiv:wikitext(tostring(wdlink_span)) 		tDiv:wikitext(translate("startlist",1,s.w_race or false)) 		 		tDiv = rollTable1:tag('div'):addClass("NavContent"):cssText("margin:0; background:white; display:block; text-align:left;") 	 		local tTable= tDiv:tag('table'):cssText("border:1px solid rgb(200,200,200)") 		local tCell = tTable:tag('tr'):tag('td') 		local insideTable =tCell:tag('table'):attr('cellpadding','4')  -- cellspacing="0" style="width:100%;"  color: black; 		:cssText(cssTable)  		return rollTable1, insideTable 	else 		--otherwise problem of clear 		local tab = mw.html.create('table') 		tCell=tab:tag('td') 		 		local tTable =tCell:tag('table') 		:attr('cellpadding','0') 		:cssText(cssTable) 		tCell = tTable:tag('tr'):tag('th') 		:css("background-color",backgroundColor) 		:attr('colspan','3'):attr('align','center') 		tCell:node(wdlink_span) 		tCell:wikitext(translate("startlist",1,s.w_race or false)) 	    local tRow=tCell:tag('tr')  		return tab, tRow 	end end  --=== D) Jersey, flag functions === --used from 2 functions local flags = { 		Q16 = {'CAN', {'Flag of Canada.svg', '+1965-02-15'}}, 		Q17 = {'JPN', {'Flag of Japan.svg', '+1999-08-13'}, 			{'Flag of Japan (1870–1999).svg', '+1870-02-27', '+1999-08-12'}}, 		Q20 = {'NOR', {'Flag of Norway.svg', '+1821-07-13'}}, 		Q27 = {'IRL', {'Flag of Ireland.svg', '+1937-12-29'}}, 		Q28 = {'HUN', {'Flag of Hungary.svg', '+1957-05-23'}}, 		Q29 = {'ESP', {'Flag of Spain.svg', '+1981-12-06'}, 			{'Flag of Spain (1977–1981).svg', '+1977-01-21', '+1981-12-06'}, 			{'Flag of Spain (1945–1977).svg', '+1945-10-11', '+1977-01-21'}, 			{'Flag of Spain (1938–1945).svg', '+1939', '+1945-10-11'}, 			{'Flag of the Second Spanish Republic.svg', '+1931-04-14', '+1939'}, 			{'Flag of Spain (1785–1873, 1875–1931).svg', '+1874', '+1931-04-13'}}, 		Q30 = {'USA', {'Flag of the United States.svg', '+1960-07-04'}}, 		Q31 = {'BEL', {'Flag of Belgium (civil).svg'}}, 		Q32 = {'LUX', {'Flag of Luxembourg.svg'}}, 		Q33 = {'FIN', {'Flag of Finland.svg', '+1918-05-29'}}, 		Q34 = {'SWE', {'Flag of Sweden.svg'}}, 		Q35 = {'DEN', {'Flag of Denmark.svg'}}, 		Q36 = {'POL', {'Flag of Poland.svg'}}, 		Q37 = {'LTU', {'Flag of Lithuania.svg', '+2004-09-01'}, 			{'Flag of Lithuania (1988-2004).svg', '+1990-03-11', '+2004-09-01'}}, 		Q38 = {'ITA', {'Flag of Italy.svg', '+1946-06-19'}, 			{'Flag of Italy (1861–1946).svg', '+1861', '+1946-06-19'}}, 		Q39 = {'SUI', {'Flag of Switzerland.svg', '+1889-12-12'}, 			{'Flag of Switzerland.svg', '+1879-01-01'}}, 		Q40 = {'AUT', {'Flag of Austria.svg', '+1945-05-01'}, 			{'Flag of Austria.svg', '+1919-10-21', '+1938-03-13'}}, 		Q41 = {'GRE', {'Flag of Greece.svg', '+1978'}}, 		Q43 = {'TUR', {'Flag of Turkey.svg'}}, 		Q45 = {'POR', {'Flag of Portugal.svg', '+1911-06-30'}}, 		Q55 = {'NED', {'Flag of the Netherlands.svg', '+1806'}}, 		Q77 = {'URU', {'Flag of Uruguay.svg'}}, 		Q96 = {'MEX', {'Flag of Mexico.svg', '+1968-09-16'}, 			{'Flag of Mexico (1934-1968).svg', '+1934', '+1968-09-16'}}, 		Q114 = {'KEN', {'Flag of Kenya.svg'}}, 		Q115 = {'ETH', {'Flag of Ethiopia.svg', '+1996-10-31'}}, 		Q117 = {'GHA', {'Flag of Ghana.svg', '+1966-02-28'}}, 		Q142 = {'FRA', {'Flag of France.svg', '+1794-05-20'}}, 		Q145 = {'GBR', {'Flag of the United Kingdom (3-5).svg'}}, 		Q148 = {'CHN', {"Flag of the People's Republic of China.svg", '+1985'}}, 		Q155 = {'BRA', {'Flag of Brazil.svg', '+1992-05-11'}, 			{'Flag of Brazil (1968–1992).svg', '+1968-05-28', '+1992-05-11'}}, 		Q159 = {'RUS', {'Flag of Russia.svg', '+1993-12-11'}, 			{'Flag of Russia (1991–1993).svg', '+1991-08-22', '+1993-12-11'}, 			{'Flag of the Russian Soviet Federative Socialist Republic.svg', '+1954', '+1991-08-22'}, 			{'Flag of the Russian Soviet Federative Socialist Republic (1937–1954).svg', '+1937', '+1954'}}, 		Q183 = {'GER', {'Flag of Germany.svg', '+1949-05-23'}, 			{'Flag of the German Reich (1935–1945).svg', '+1935-09-15', '+1945-05-23'}, 			{'Flag of the German Reich (1933–1935).svg', '+1933-03-12', '+1935-09-15'}, 			{'Flag of Germany (3-2 aspect ratio).svg', '+1919-04-11', '+1933-03-12'}, 			{'Flag of the German Empire.svg', '+1871-04-16', '+1919-04-11'}}, 		Q184 = {'BLR', {'Flag of Belarus.svg', '+2012-05-11'}, 			{'Flag of Belarus (1995–2012).svg', '+1995-06-07', '+2012-05-11'}, 			{'Flag of Belarus (1918, 1991–1995).svg', '+1991-09-19', '1995-06-07'}}, 		Q189 = {'ISL', {'Flag of Iceland.svg', '+1944-06-17'}}, 		Q191 = {'EST', {'Flag of Estonia.svg'}}, 		Q211 = {'LAT', {'Flag of Latvia.svg'}}, 		Q212 = {'UKR', {'Flag of Ukraine.svg', '+1992-01-28'}}, 		Q213 = {'CZE', {'Flag of the Czech Republic.svg', '+1920-03-30'}}, 		Q214 = {'SVK', {'Flag of Slovakia.svg'}}, 		Q215 = {'SLO', {'Flag of Slovenia.svg'}}, 		Q217 = {'MDA', {'Flag of Moldova.svg'}}, 		Q218 = {'ROU', {'Flag of Romania.svg', '+1989-12-27'}, 			{'Flag of Romania (1965-1989).svg', '+1989-12-27', '+1965'}, 			{'Flag of Romania (1952-1965).svg', '+1952', '+1965'}, 			{'Flag of Romania (1948-1952).svg', '+1948-01-08', '+1952'}, 			{'Flag of Romania.svg', '12. april 1867-04-12', '+1948-01-08'}}, 		Q219 = {'BUL', {'Flag of Bulgaria.svg', '+1990-11-22'}, 			{'Flag of Bulgaria (1971 – 1990).svg', '+1971-05-18', '+1990-11-22'}}, 		Q222 = {'ALB', {'Flag of Albania.svg', '+1992'}}, 		Q224 = {'CRO', {'Flag of Croatia.svg', '+1990-12-21'}, 			{'Flag of Croatia (white chequy).svg', '+1990-06-27', '+1990-12-21'}}, 		Q227 = {'AZE', {'Flag of Azerbaijan.svg'}}, 		Q228 = {'AND', {'Flag of Andorra.svg'}}, 		Q229 = {'CYP', {'Flag of Cyprus.svg', '+2006-08-20'}, 			{'Flag of Cyprus (1960-2006).svg', '+1960-08-16', '+2006-08-20'}}, 		Q232 = {'KAZ', {'Flag of Kazakhstan.svg'}}, 		Q235 = {'MON', {'Flag of Monaco.svg'}}, 		Q238 = {'SMR', {'Flag of San Marino.svg'}}, 		Q241 = {'CUB', {'Flag of Cuba.svg'}}, 		Q244 = {'BAR', {'Flag of Barbados.svg'}}, 		Q252 = {'INA', {'Flag of Indonesia.svg'}}, 		Q258 = {'RSA', {'Flag of South Africa.svg', '+1994-04-27'}, 			{'Flag of South Africa (1928–1994).svg', '+1928-05-31', '+1994-04-27'}}, 		Q262 = {'ALG', {'Flag of Algeria.svg'}}, 		Q265 = {'UZB', {'Flag of Uzbekistan.svg'}}, 		Q298 = {'CHI', {'Flag of Chile.svg'}}, 		Q334 = {'SGP', {'Flag of Singapore.svg'}}, 		Q347 = {'LIE', {'Flag of Liechtenstein.svg'}}, 		Q398 = {'BRN', {'Flag of Bahrain.svg', '+2002-02-14'}}, 		Q403 = {'SRB', {'Flag of Serbia.svg', '+2004-08-18'}, 			{'Flag of Serbia (1992–2004).svg', '+1992-04-27', '+2004-08-17'}}, 		Q408 = {'AUS', {'Flag of Australia.svg'}}, 		Q414 = {'ARG', {'Flag of Argentina.svg'}}, 		Q419 = {'PER', {'Flag of Peru.svg', '+1950'}, 			{'Flag of Peru (1825-1950).svg', '+1825-02-25', '+1950'}}, 		Q424 = {'CAM', {'Flag of Cambodia.svg', '+1993-06-30'}, 			{'Flag of Cambodia.svg', '+1948-10-20', '+1970-10-09'}},		 		Q664 = {'NZL', {'Flag of New Zealand.svg'}}, 		Q711 = {'MGL', {'Flag of Mongolia.svg'}}, 		Q717 = {'VEN', {'Flag of Venezuela.svg', '+2006-03-12'}, 			{'Flag of Venezuela (1930–2006).svg', '+1930','+2006-03-12'}}, 		Q733 = {'PAR', {'Flag of Paraguay.svg', '+2013-07-15'}, 			{'Flag of Paraguay (1990–2013).svg', '+1990', '+2013-07-14'}}, 		Q736 = {'ECU', {'Flag of Ecuador.svg'}}, 		Q739 = {'COL', {'Flag of Colombia.svg'}}, 		Q750 = {'BOL', {'Flag of Bolivia.svg', '+1851-10-31'}}, 		Q754 = {'TTO', {'Flag of Trinidad and Tobago.svg'}}, 		Q769 = {'GRN', {'Flag of Grenada.svg'}}, 		Q774 = {'GUA', {'Flag of Guatemala.svg'}}, 		Q778 = {'BAH', {'Flag of the Bahamas.svg'}, '+1973-07-10'}, 		Q783 = {'HON', {'Flag of Honduras.svg'}, '+1949'}, 		Q786 = {'DOM', {'Flag of the Dominican Republic.svg'}}, 		Q794 = {'IRI', {'Flag of Iran.svg', '+1980-07-29'}, 			{'Flag of Iran (1964–1980).svg', '+1964', '+1980-07-29'}}, 		Q800 = {'CRC', {'Flag of Costa Rica (state).svg', '+1906-11-27'}}, 		Q801 = {'ISR', {'Flag of Israel.svg'}}, 		Q804 = {'PAN', {'Flag of Panama.svg'}}, 		Q813 = {'KGZ', {'Flag of Kyrgyzstan.svg', '+1992-03-03'}}, 		Q817 = {'KUW', {'Flag of Kuwait.svg', '+1961-09-07'}}, 		Q833 = {'MAS', {'Flag of Malaysia.svg', '+1963-09-16'}}, 		Q842 = {'OMA', {'Flag of Oman.svg', '+1995'}}, 		Q846 = {'QAT', {'Flag of Qatar.svg'}}, 		Q858 = {'SYR', {'Flag of Syria.svg', '+1980-03-29'}}, 		Q865 = {'TPE', {'Flag of the Republic of China.svg', '+1928-12-17'}}, 		Q869 = {'THA', {'Flag of Thailand.svg'}}, 		Q878 = {'UAE', {'Flag of the United Arab Emirates.svg'}}, 		Q881 = {'VIE', {'Flag of Vietnam.svg', '+1976-02-07'}}, 		Q884 = {'KOR', {'Flag of South Korea.svg', '+1997-10'}}, 		Q916 = {'ANG', {'Flag of Angola.svg', '+1975-11-11'}}, 		Q921 = {'BRU', {'Flag of Brunei.svg', '+1959-09-29'}}, 		Q928 = {'PHI', {'Flag of the Philippines.svg', '+1998'}}, 		Q948 = {'TUN', {'Flag of Tunisia.svg', '+1999-07-03'}}, 		Q954 = {'ZIM', {'Flag of Zimbabwe.svg', '+1980-04-18'}}, 		Q965 = {'BUR', {'Flag of Burkina Faso.svg'}}, 		Q983 = {'GEQ', {'Flag of Equatorial Guinea.svg', '+1979-08-21'}, 			{'Flag of Equatorial Guinea (1973–1979).svg', '+1973', '+1979-08-21'}, 			{'Flag of Equatorial Guinea (without coat of arms).svg', '+1968-10-12', '+1973'}}, 		Q986 = {'ERI', {'Flag of Eritrea.svg'}}, 		Q1000 = {'GAB', {'Flag of Gabon.svg', '+1960-08-09'}}, 		Q1007 = {'GBS', {'Flag of Guinea-Bissau.svg', '+1973-09-24'}}, 		Q1008 = {'CIV', {"Flag of Côte d'Ivoire.svg"}}, 		Q1009 = {'CMR', {'Flag of Cameroon.svg'}}, 		Q1027 = {'MRI', {'Flag of Mauritius.svg', '+1968-03-13'}}, 		Q1028 = {'MAR', {'Flag of Morocco.svg'}}, 		Q1030 = {'NAM', {'Flag of Namibia.svg', '+1990-03-21'}}, 		Q1036 = {'UGA', {'Flag of Uganda.svg', '+1962-10-09'}}, 		Q1037 = {'RWA', {'Flag of Rwanda.svg', '+2001-10-25'}, 			{'Flag of Rwanda (1962–2001).svg', '+1962', '+2001-10-25'}}, 		Q1183 = {'PUR', {'Flag of Puerto Rico.svg'}}, 		Q9676 = {'IMN', {'Flag of the Isle of Man.svg'}}, 		Q15180 = {'URS', {'Flag of the Soviet Union.svg', '+1980-08-15', '+1991-12-25'}, 			{'Flag of the Soviet Union (1955–1980).svg', '+1955-08-19', '+1980-08-14'}, 			{'Flag of the Soviet Union (1924–1955).svg', '+1923-11-13', '+1955-08-18'}}, 		Q16957 = {'GDR', {'Flag of East Germany.svg', '+1959-10-01'}, 			{'Flag of Germany.svg', '+1949-10-07', '+1959-10-01'}}, --German Democratic Republic 		Q8646 = {'HKG', {'Flag of Hong Kong.svg'}}, 		Q25228 = {'AIA', {'Flag of Anguilla.svg'}}, 		Q29999 = {'NED', {'Flag of the Netherlands.svg', '+1690'}}, --Kingdom of the Netherlands 		Q33946 = {'TCH', {'Flag of the Czech Republic.svg', '+1920'}}, -- Czechoslovakia (1918–1992) 		Q36704 = {'YUG', {'Flag of Yugoslavia (1992–2003).svg', '+1992-04-27', '+2003-02-04'}, --Yugoslavia 			{'Flag of Yugoslavia (1943–1992).svg', '+1946', '+1992-04-27'}}, 		Q41304 = {'GER', {'Flag of Germany (3-2 aspect ratio).svg', '+1918-11-09'}}, -- Weimar Republic 		Q47588 = {'EU', {'Flag_of_the_Basque_Country.svg'}}, 		Q83286 = {'YUG', {'Flag of Yugoslavia (1943–1992).svg'}}, --Socialist Federal Republic of Yugoslavia 		Q172579 = {'ITA', {'Flag of Italy (1861–1946).svg'}}, --Kingdom of Italy (1861-1946) 		Q216923 = {'TPE', {'Flag of Chinese Taipei for Olympic games.svg'}}, -- Chinese Taipei 		Q268970 = {'AUT', {'Flag of Austria.svg', '+1918-11-12', '+1919-09-10'}}, -- German-Austria (1918-1919) 		Q713750 = {'FRG', {'Flag of Germany.svg'}}, --West Germany 		Q853348 = {'TCH', {'Flag of the Czech Republic.svg'}, '+1960-07-11', '+1990-03-29'}, -- Czechoslovak Socialist Republic (1960-1990) 		Q2415901 = {'GER', {'Merchant flag of Germany (1946–1949).svg', '+1945-05-09', '+1949-05-23'}}, -- Allied-occupied Germany 		Q13474305 = {'ESP', {'Flag of Spain (1945–1977).svg', '+1945-10-11', '+1977-01-21'}, -- Francoist Spain (1935-1976) 			{'Flag of Spain (1938–1945).svg', '+1939', '+1945-10-11'}, 			{'Flag of the Second Spanish Republic.svg', '+1931-04-14', '+1939'}}, 		Q113486069={'NEUTRAL', {'Flag white.svg'}} --Russia and Belarus during the ban, cannot replace the flags above, because there are cases where it does not apply 	}  local function flag(countryID, date) 	local trackingCategory = '' 	--[[ If you uncomment the line under this comment, all pages with look-up misses in 	the flag table will be placed in a tracking category. You can use this to find more flags 	to add to the table. ]] 	-- trackingCategory = '[[Category:Missing flag in Module:Cycling race]]'  	local entry = flags[countryID] 	local IOC 	local file 	local result = "" 	if entry then 		for i, v in ipairs(entry) do 			if i == 1 then 				IOC = v 			else 				if not date then 					file = v[1] 					break 				else 					local from = v[2] 					local to = v[3] 					if (not from or from <= date) and (not to or to > date) then 						file = v[1] 						break 					end 				end 			end 		end 	end 	local flagpxSize = '20px' 	if countryID == 'Q39' then flagpxSize = '16px'end -- Small size for an square flag as Switzerland 	if file then 		result = '[[File:' .. file .. '|border|' .. flagpxSize ..'|' .. IOC .. ']]' 		if arwiki_totemplate then 			result = '{{flagicon|' .. IOC .. '}}' 		end 	elseif not date then 		local p41 = firstValue(countryID, "P41") -- P41 is flag image 		if p41 then 			result = '[[File:' .. p41 .. '|border|' .. flagpxSize ..'|(Wikidata:' .. countryID .. ')]]' 			if arwiki_totemplate then 				result = '{{flagicon image|' .. p41 .. '}}' 			end 		end 	else 		-- Search flag for specific date 		local p41 = getStatementForTime(countryID, "P41", date) -- P41 is flag image 		if p41 then 			result = '[[File:' .. p41.mainsnak.datavalue.value .. '|border|' .. flagpxSize ..'|(Wikidata:' .. countryID .. ')]]' 			if arwiki_totemplate then 				result = '{{flagicon image|' .. p41.mainsnak.datavalue.value .. '}}' 			end 		end 	end 	return result .. trackingCategory end  -- countryID --> shape ([[France|FRA]]) local function uciCodeCountry(countryID)     local uciCode, countryName      local blacklist={Q736=true} 	if countryID then 		--get UCI code 		if flags[countryID] then 			uciCode=flags[countryID][1] 		end 		--get link, assumed for a country the label is equal to the link, where not correct in the blacklist 		--if the black list becomes too long, we could create a second list for the sitelinks 		countryName=country_name_from_list(countryID) 		if countryName == nil or blacklist[countryID] then 			countryName = mw.wikibase.getSitelink(countryID) 		end 		if uciCode and countryName then 			return ' <small>([['..countryName..'|'..uciCode..']])</small> ' 		end 	end 	return '' --else end  local function jersey_infobox( winner_classification, item, timeOfRace) 	local jersey, jersey_name = '', '' 	local jerseyWPID = ''  	-- 1. Item of race, e.g. Tour de France = 'Q33881' 	-- 2. type of winner, names are the ones in variable t_s 	-- 3. and 4. start and end time. '+2500' means year 2500. Always beginning with a '+' 	-- 5. item of the jersey 	-- 6. item of the Wikipedia article of that jersey  	--timeOfRace = '+1968-07-01T00:00:00Z' 	timeOfRace = string.match(timeOfRace, "+%d%d%d%d") or '' 	for _, v in pairs(item) do 		for _, value in pairs(data.stageinfobox_jersey) do 			if v == value[1] then 				if winner_classification == value[2] then 					if (timeOfRace >= value[3]) and (timeOfRace <= value[4]) then 						jersey = value[5] 						jerseyWPID = value[6] 					end 				end 			end 		end 	end  	-- local starttime, endtime = '', '+2500' 	if jersey ~= '' then --and (timeOfRace > starttime) and (timeOfRace < endtime) then 		local entity_jersey = mw.wikibase.getEntity(jersey) 			jersey = entity_jersey.claims['P18'][1].mainsnak.datavalue.value 			jersey_name = entity_jersey:getLabel(wikilang) or '' 		if jerseyWPID ~= '' then 			local entity = mw.wikibase.getEntity( jerseyWPID ) 			local Sitelink = entity:getSitelink(wiki..'wiki') -- link to WParticle 			if Sitelink ~= nil then jerseyWPID = wiki..':'..Sitelink else jerseyWPID = '' end 		end 		return jersey, jersey_name, jerseyWPID 	else return '', '', '' 	end end  local function jersey(h) 	local jersey_string = ' ' 	local jerseys = { 	['Q24257871'] = {file = 'Jersey yellow.svg', 		name_ar = 'قميص أصفر لمتصدر الترتيب العام', 		name_fr = 'maillot jaune de leader du classement général', 		name_es = 'maillot amarillo de líder de la clasificación general', 		name_ru = 'жёлтая майка лидера генеральной классификации' 		}, 	['Q24645209'] = {file = 'Jersey green.svg', 		name_ar = 'قميص أخضر لمتصدر ترتيب النقاط', 		name_fr = 'maillot vert de leader du classement par points', 		name_es = 'maillot verde de líder de la clasificación por puntos', 		name_ca = 'mallot verd del líder de la classificació per punts', 		name_ru = 'зелёная майка лидера очковой классификации' 		}, 	['Q640430'] = {file = 'Jersey white.svg', 		name_ar = 'قميص أبيض لمتصدر ترتيب الشباب', 		name_fr = 'maillot blanc de leader du classement du meilleur jeune', 		name_es = 'maillot blanco de líder de la clasificación de los jóvenes', 		name_ru = 'белая майка лидера молодёжной классификации', 		name_de = 'weißes Trikot des Führenden der Nachwuchswertung' 		}, 	}  	if type(h) == 'table' and h[1] then 		for _, v in ipairs(h) do 			local jersey_name 			if jerseys[v] then 				jersey_string = jersey_string .. '[[File:' .. jerseys[v].file .. '|20px' 				jersey_name = jerseys[v]['name_' .. wiki] or mw.wikibase.getLabel(v) or jerseys[v]['name_fr'] 				if jersey_name then 					jersey_string = jersey_string .. '|' .. jersey_name 				end 				jersey_string = jersey_string .. ']]' 			else 				local p18 = mw.wikibase.getBestStatements(v, 'P18') 				if p18[1] and p18[1].mainsnak.snaktype == 'value' then 					jersey_string = jersey_string .. '[[File:' .. p18[1].mainsnak.datavalue.value .. '|20px' 					jersey_name = getLabelFallback(v) 					if jersey_name then 						jersey_string = jersey_string .. '|' .. jersey_name 					end 					jersey_string = jersey_string .. ']]' 				end 			end 		end 	end 	return jersey_string end -- function end  --=== E) Other (winner) === local function isHuman(riderId) 	local isHuman = false 	if riderId then 		local p31 = wikibase.getBestStatements(riderId, 'P31') 		for _, iOf in pairs (p31) do 			if iOf.mainsnak.snaktype == 'value' and iOf.mainsnak.datavalue.value.id == "Q5" then 				isHuman = true 				break 			end 		end 	end 	return isHuman end  local function isCountry(inputID) 	local isCountry = false 	if inputID then 		local p31 = wikibase.getBestStatements(inputID, 'P31') 		for _, iOf in pairs (p31) do 			-- exception Hong-Kong and Taiwan 			if iOf.mainsnak.snaktype == 'value' and (iOf.mainsnak.datavalue.value.id == "Q6256" or iOf.mainsnak.datavalue.value.id =="Q15634554" or iOf.mainsnak.datavalue.value.id =="Q779415") then 				isCountry = true 				break 			end 		end 	end 	return isCountry end  local function isWomenrace(raceID) --for translation 	for _, p2094 in statements(raceID, 'P2094') do  		if p2094.mainsnak.datavalue.value.id == "Q1451845" then 			return true 		end 	end 	return false end  local function isWomenteam(teamID, timeOfRace) 	if isWomenrace(teamID) then --simplest way 		return true 	end 	--else we can identify with teamCat 	local _, catID= getTeamLinkCat(teamID, timeOfRace, false) 	if data.womenCats[catID] then 		return true 	end 	return false end  local function getNationality(wID, timeOfRace,q) --for a rider 	local p27, countryID 	--allow overload of the property, for cases like Russian/BLR ban, or Commonwealth games, only for P1532 	if q and q.P1532 and q.P1532[1].snaktype == 'value' then 		countryID = q.P1532[1].datavalue.value.id 	else 		local listOfProperty={'P1532','P27'} 		if wID then 			for _, prop in ipairs(listOfProperty) do 				if countryID==nil then 					p27 = getStatementForTime(wID, prop, timeOfRace) --P27 is country of citizenshi 					if p27 then 						countryID = p27.mainsnak.datavalue.value.id 					end 				end 			end 		end 		 		if wiki=='eu' and (countryID=="Q142" or countryID=="Q29") then --look for people or location in the Basque Country, quite expensive function 			local birth_place = firstValue(wID, 'P19','id') --birth place 			if data.BasqueTown[birth_place] then 				return "Q47588" 			end 		end 	end 	return countryID end  local function subwinner(riderId, timeOfRace, q) 	local outTable={} 	local riderTeam, riderLink, countryID  	if riderId then 		if isHuman(riderId) then 			riderLink = getRiderLink(riderId, timeOfRace) 			countryID = getNationality(riderId, timeOfRace,q) 			if countryID then 				riderLink = flag(countryID, timeOfRace) .. ' ' .. riderLink 			end 			riderTeam = getTeam(riderId, timeOfRace, q) or '' 		else 			local _ 			riderLink, _, countryID = getTeamLinkCat(riderId, timeOfRace, true) 			if countryID then 				riderLink = flag(countryID, timeOfRace) .. ' ' .. riderLink 			end 		end 	end 	return riderLink, riderTeam end  local function winner(lf,raceID, winners, timeOfRace, country, WDlink_on, team, ref, winnersId) 	local p1346 = wikibase.getAllStatements(raceID, 'P1346') -- P1346 is 'winner' 	for _, winner in pairs(p1346) do 		local wID = winner.mainsnak.snaktype == 'value' and winner.mainsnak.datavalue.value.id 		local wOf, wCause, wCriterion, riderLink 		local q = winner.qualifiers 		if q then 			local _, disqualified =isdisqualified(winner,q) 			 			if q.P642 and q.P642[1].snaktype == 'value' then 				for _, q642 in pairs(q.P642) do 					wOf = q642.datavalue.value.id -- P642 is 'of' 					if not wOf then 						-- Try P1346 (winner) instead 						-- Assume Q20882667 ('overall winner general classification') if neither are found 						wOf = q.P1346 and q.P1346[1].snaktype == 'value' and q.P1346[1].datavalue.value.id or 'Q20882667' 					end 					wCause = q.P828 and q.P828[1].snaktype == 'value' and q.P828[1].datavalue.value.id 						-- P828 is 'has cause' 					wCriterion = q.P1013 and q.P1013[1].snaktype == 'value' and q.P1013[1].datavalue.value.id 						-- P1013 is 'criterion used'  					if winners[wOf] then 						if wID then 							local reference = ref and getReference(lf,winner) 							local _, countryID 							if isHuman(wID) then 								riderLink = getRiderLink(wID, timeOfRace) 								if reference then 									riderLink = riderLink .. reference 								end 								if team then 									local riderTeam = getTeam(wID, timeOfRace, q) 									if riderTeam then 										riderLink = riderLink .. ' (' .. riderTeam .. ')' 									end 								end 							elseif isCountry(wID) then 								riderLink = flag(wID, timeOfRace).." "..getCountryName(wID)  								if reference then 									riderLink = riderLink .. reference 								end 								country=true	 							else --team 								local _ 								riderLink, _, countryID = getTeamLinkCat(wID, timeOfRace, country) 								if reference then 									riderLink = riderLink .. reference 								end 							end 							if not country then 								if not countryID then 									if isHuman(wID) then 										countryID = getNationality(wID, timeOfRace,q) 									else 										countryID = getCountryID(wID, timeOfRace) 									end 								end 								if countryID then 									riderLink = flag(countryID, timeOfRace) .. ' ' .. riderLink 								end 							end 							if WDlink_on then 								riderLink = riderLink .. ' ' .. wdLink(wID) 							end 						else 							riderLink = wCriterion and contentLanguage:ucfirst(wikibase.getLabel(wCriterion) or '') or '' 							if wCause then 								local cause = wikibase.getLabel(wCause) 								if cause then 									riderLink = riderLink .. ' (' .. cause .. ')' 								end 							end 						end 						if disqualified==true then 							riderLink='<s>'..riderLink..'</s>' 						end 						if winnersId and winnersId[wOf] then 							if disqualified or ((not wID) and wCriterion) then  								winnersId[wOf]= 'Q666' --to identify disqualification 							else 								winnersId[wOf]= wID --identify cancelled 							end 						end 						if winners[wOf] == '' then 							winners[wOf] = riderLink 						else 							winners[wOf] = winners[wOf] .. '<br/>' .. riderLink 						end 					end 				end 			end 		end 	end end  local function sortAndConcat(t_Body, resultTable) 	table.sort(t_Body, function(a, b) return a[1] < b[1] end) 	for _, m in ipairs(t_Body) do resultTable:node(m[2]) end 	return resultTable end  --------- Definition sub-functions for calendar and victory ------ local function getTimeOfRace(raceID, mandatory, p582_prio) 	local timeOfRace, properties 	if p582_prio then --for case like  UCI Europe Tour 2006 (Q1455600) where most of the competition is in the next year 		properties={'P582','P585','P580'} 	else 		properties={'P580','P585','P582'} 	end 	 	for _, prop in ipairs(properties) do 		timeOfRace= firstValue(raceID, prop, 'time') 		if timeOfRace ~= nil then return timeOfRace end 	end  	local link = getSitelinkFallback(raceID, {'en', 'fr', 'de','es'}) --language is not important here, it is just to get the year 	if link then 		local year = string.match(link, '%d%d%d%d') 		if year then 			return year .. '-01-01T00:00:00Z' 		end 	end 	if wiki == "ar" then 		return '+1970-01-01T00:00:00Z' 	end 	if mandatory then 		error('> Wikidata is missing data about start time (P580) or point in time (P582)') 	end 	return nil end  local function get_formatted_date(entityID, functionName) 	local sTime = firstValue(entityID, 'P580', 'time') -- P580 is 'start time' 	local eTime = firstValue(entityID, 'P582', 'time') -- P582 is 'end time' 	 	local style1, style2  	if functionName=="infobox" then 		style1='verylong' --force to display the year 		style2='long' 	else 		style1='small' 		style2='small' 	end 	 	if sTime and eTime then 		local startTime, endTime = getStartEndTime(sTime, eTime, style1) 		if functionName==nil or functionName=='infobox' then --calendar, infobox         	return startTime .. ' – ' .. endTime, sTime, true         else --victory, general classification         	return endTime, eTime, true 		end 	else 		local pTime = firstValue(entityID, 'P585', 'time') -- P585 is 'point in time' 		if pTime then 			return funcDate(pTime, style2), pTime, false 		end 	end 	return nil end  local function fn_date(entityID, functionName)  --to move as a general function 	local tempdate, timeOfRace, _ = get_formatted_date(entityID, functionName) --is there a reason why timeofrace cannot be sTime??  	local _, _, y, m, d = string.find(timeOfRace or "", "(%d+)-(%d+)-(%d+)") 	local sortkey=(y or '')..(m or '')..(d or '') 	if sortkey =='' then sortkey = '0000' end  	local tCell = mw.html.create('td'):attr('data-sort-value',sortkey) 	:cssText("style=text-align:right;padding:0 0.5em") 	:wikitext(tempdate)  	return timeOfRace, tostring(tCell), sortkey end  local function fn_country(entityID, timeOfRace,country, raceCell, parentID) 	-- This function gives countries where the race take place 	-- parentID taken from fn_race, optional 	local country_str, country_name, country_flag 	local cssCell="text-align:" .. textalign .. ";padding:0 0.5em" 	local tCell= mw.html.create('td'):cssText(cssCell)  	local countryID = getCountryID(entityID, timeOfRace) 	if countryID==nil then countryID = getCountryID(parentID, timeOfRace) end 	 	if countryID then 		country_flag=flag(countryID, timeOfRace) 		country_str=country_flag 		country_name = getCountryName(countryID) 		if country_name~='' then 			tCell:attr('data-sort-value',country_name) 			if country~= false then  				country_str=country_str.." "..country_name 			end 		end 	else 		country_flag="no flag" 	end  	if country==false then 		tCell:wikitext(country_flag.." "..(raceCell or '')) 		country_name='' 	else 		if country_str then  			tCell:wikitext(country_str)  		end 	end 	return country_flag, country_name, tCell end  local function commaStage(stageID,raceLabel) --how to write "stage, " 	local outTable={} 	local stageNumber='' 	local subStage = '' 	local stageNumberonly, stageLetter  	local temp=firstValue(stageID, 'P1545') 	if temp then stageNumber = temp end  	if stageNumber=='0' then --prologue 		stageNumber= translate("victories",9) 	else 		if stageNumber==nil then 			stageNumber= translate("victories",8) 		else 			--look for subStage 			local i,j = string.find(stageNumber, "%a+") --if letter in the stage number 			if i ~= nil then --we have to do something 				local k,l = string.find(stageNumber, "%d+") --select the number in the stage number 				stageNumberonly = string.sub(stageNumber, k, l)--cut the string in 2 				stageLetter = string.sub(stageNumber, i, j) 				stageNumber=stageNumberonly 				if stageLetter ~= nil then subStage=stageLetter end 			end 			if wiki == 'ar' then 				stageNumber= translate("victories",8)..' '..number('f', tonumber(stageNumber), wiki) 			else 				stageNumber= number('f', tonumber(stageNumber), wiki)..subStage..' '..translate("victories",8) 			end 		end 	end  	local comma = ", " 	if wiki == 'ar' then comma = " ، " end 	if wiki == 'fr' then 		local correpondance={ 		{name="^Trois", article= " des "}, 		{name="^Quatre", article= " des "}, 		{name="^Boucles", article= " des "}, 		{name="^Triptyque", article= " du "}, 		{name="^Tour", article= " du "}, 		{name="^Grand Prix", article= " du "}, 		{name="^Circuit", article= " du "}, 		{name="^Mémorial", article= " du "}, 		{name="^Trophée", article= " du "}, 		{name="^Ronde", article= " de la "}, 		{name="^Semaine", article= " de la "}, 		{name="^Classica", article= " de la "}, 		{name="^Flèche", article= " de la "}, 		{name="^Course", article= " de la "}, 		{name="^Classique", article= " de la "}, 		{name="Race", article= " de la "}, 		{name="^Étoile", article= " de l'"}, 		{name="^La", article= " de "} 		}  		for _, v in ipairs(correpondance) do 			if string.find(raceLabel, v.name) then 				comma = v.article 				break 			end 		end 	end  	if wiki == 'fr' or wiki=="ca" or wiki=="es" or wiki=="ast" then 		outTable["prefix"]=stageNumber..comma 		outTable["postfix"]='' 	else 		--if wiki=="de" or wiki=="da" or wiki=="fo" or wiki == "lb" or wiki=="no" or wiki=="ru" or wiki=="ar" or wiki=="lv" or wiki=="pl" then 		outTable["prefix"]='' 		outTable["postfix"]=comma..stageNumber 	end 	return outTable end  local function getMainRaceLink(entityID,entity_type,stageID, functionName,timeOfRace) --the link to the edition but with a general name 	local instanceOf, instanceOfTemp, label, Sitelink, isclass, prefix, postfix 	local arlabel 	local stage_link=false 	 	if stageID then 		Sitelink=wikibase.getSitelink(stageID) 		if Sitelink then stage_link=true end 	end 	if Sitelink==nil then 		Sitelink=wikibase.getSitelink(entityID) 	end 	prefix=''; postfix='' --general classification 	listOfProperty={'P2561','P1448'}          --main race link is in the parent	--can be improved 	for _, p31 in statements(entityID, 'P31') do 		instanceOfTemp = p31.mainsnak.datavalue.value.id 		if instanceOfTemp ~= "Q27020041" and instanceOfTemp ~= 'Q88903067' and data.class_dic[instanceOfTemp]==nil then	--but the main race 			instanceOf=instanceOfTemp 		end 	end      --get information from the parent 	if instanceOf then 		--look for 		for _, prop in ipairs(listOfProperty) do 			for _, p2561 in statements(instanceOf, prop) do --name for championship 				if label==nil then 					local lang_WD = p2561.mainsnak.datavalue.value.language 					if wiki == lang_WD then 						local nametemp = p2561.mainsnak.datavalue.value.text 						if timeOfRace~= nil then 							local q = p2561.qualifiers 							if q then 								local temp = checktime(nametemp,q,timeOfRace) 								if temp then label = nametemp end--if the time is correct than it is finished 							else 								label = nametemp 								arlabel = label 							end 						end 					end 				end 			end 		end  		if label==nil then 			label=getLabelFallback(instanceOf,lang_priority) --the case of 'ar' should be handled in lang_priority 			if not label then 				label=getLabelFallback(entityID,lang_priority) or '' 			end 		end 		if Sitelink==nil and entity_type~=0 then --only if no link to the race direct 			Sitelink=wikibase.getSitelink(instanceOf) 		end 		if Sitelink==nil and entity_type==0 then --only for champ 			local temp=firstValue(entityID, 'P361','id') --temp is NC France 2019 for instance 			if temp then  				Sitelink= wikibase.getSitelink(temp)  			end 			if Sitelink == nil then 				local temp2=firstValue(entityID, 'P31','id') -- French NC Men ITT 				if temp2 then 					Sitelink= wikibase.getSitelink(temp2)   					if Sitelink == nil then 						local temp3=firstValue(temp2, 'P361','id') -- French NC ITT 						if not temp3 then temp3=firstValue(temp2, 'P31','id') end 						if temp3 then 							Sitelink= wikibase.getSitelink(temp3)   							if Sitelink == nil then 								local temp4=firstValue(temp3, 'P361','id') -- French NC  								if not temp4 then temp4=firstValue(temp3, 'P31','id') end 								if temp4 then 									Sitelink= wikibase.getSitelink(temp4)   								end 							end 						end 					end 				end 			end	 		end 	end 	--affect the label 	if label==nil then 		label=getLabelFallback(entityID,lang_priority) or '' 	end 	--look for link to the race if nothing 	--if different languages have to be added, a language table can be created 	if entity_type==2 then 		if functionName~=nil then --calendar=nil 			if wiki == 'fr' then prefix= translate("victories",1)..', ' --general classification 			elseif wiki == 'ar' then postfix ='، '..translate("victories",1) 			else postfix = ', '..translate("victories",1) 			end 		end 	elseif entity_type=='stage' then 		--how to write "stage, " is concentrated in one function 		local commaTable=commaStage(stageID, label) 		prefix= commaTable["prefix"] 		postfix=commaTable["postfix"] 	end  	if Sitelink == nil then 		if wiki == 'ar' then  			label = make_IllWD2_link(entityID,arlabel,label) 		end 		return prefix..label..postfix 	elseif stage_link then 		return '[['..Sitelink..'|'..prefix..label..postfix..']]' 	else 		return prefix..'[['..Sitelink..'|'..label..']]'..postfix 	end end  --look for the circuitID to create a link as [[World Tour|1.UWT]] --a bit redundant with classLink which needs less computation --for infobox classLink gives enough info local function classToCircuit(classID, entityID, child, q)  	local displayedCircuitID, circuitID 	 	if classID then 		if classID=='Q23005601' or classID=='Q23005603' then --1WWT 2WWT clear 			displayedCircuitID = 'Q21075974' 		elseif classID=='Q22231106' or classID=='Q22231107' then --1UWT 2UWT clear 			displayedCircuitID = 'Q635366' 		else --we have to look in the item 			if child then --for instance Flèche wallonne 2020 				for _, p361 in statements(entityID, 'P361') do 					circuitID = p361.mainsnak.datavalue.value.id 					for _, p31 in statements(circuitID, 'P31') do --is it a UCI circuit? 						parentCircuitID = p31.mainsnak.datavalue.value.id 						if data.UCI_Circuits[parentCircuitID] then 							displayedCircuitID=circuitID 						end 					end 				end 			else --for instance Flèche wallonne 				if q then 					if q.P642 and q.P642[1].snaktype == 'value' and q.P642[1].datavalue.value.id then	 						displayedCircuitID = q.P642[1].datavalue.value.id 					end 				end 			end 		end 	end 	return displayedCircuitID end  local function getStartEndfromQuali(q) --return sTime and eTime as date 	local sTime, eTime 	if q then 		if q.P580 and q.P580[1] and q.P580[1].snaktype == 'value' then -- P580 is start time 			sTime = q.P580[1].datavalue.value.time 		end 		if q.P582 and q.P582[1] and q.P582[1].snaktype == 'value' then -- P582 is end time 			eTime = q.P582[1].datavalue.value.time 		end 	end 	return sTime, eTime end  local function funcDateFigure(date,mode) 	local y, m = string.match(date, "(%d+)-(%d+)-%d+") 	 	if mode=='Y' or m=='00' or not m then 		return y 	elseif y then 		return string.gsub(m,'0','').."."..y 	else 		return nil 	end end  local function getPeriodSubSub(sTime, eTime, startTime,endTime,brackets) 	local period 	if sTime and eTime then 		if startTime==endTime then 			period=startTime --only (1990) 		else 			period=startTime .. '-'..endTime 		end 	elseif sTime then 		period=startTime .. '-' 	elseif eTime then 		period='-'..endTime 	else 		period="" 	end 	 	if brackets and period~="" then 		period="("..period..")" 	end 	return period end 	 local function getPeriodSub(sTime, eTime, brackets)  	local startTime, endTime, y, m, y2, m2  	if sTime then 		y, m = string.match(sTime, "(%d+)-(%d+)-%d+") 		if m=='00' or m=='01' then  			startTime= funcDateFigure(sTime, 'Y') 		else 			startTime= funcDateFigure(sTime,'m')  		end 	end 	 	if eTime then 		y2, m2 = string.match(eTime, "(%d+)-(%d+)-%d+") 		if m2=='00' or m2=='12' then 			endTime=funcDateFigure(eTime, 'Y') 		else 			endTime=funcDateFigure(eTime, 'm') 		end 	end 	return getPeriodSubSub(sTime, eTime, startTime,endTime,brackets) end  local function getPeriodSub_season(sTime, eTime, brackets)  	local startTime, endTime 	if sTime and eTime then 		startTime, endTime = getStartEndTime(sTime, eTime, 'small') 	elseif sTime then 		startTime=funcDate(sTime, 'small') 	elseif eTime then 		endTime=funcDate(eTime, 'small') 	end 	return getPeriodSubSub(sTime, eTime, startTime,endTime,brackets) end -- for display period with only year, for instance (2020-2021) local function getPeriod(q, brackets,season) 	local sTime, eTime = getStartEndfromQuali(q) 	if season then 		return getPeriodSub_season(sTime, eTime, brackets), sTime 	else 		return getPeriodSub(sTime, eTime, brackets), sTime 	end end  -- For infobox local function getClass(entityID) 	local classLink, circuitID, circuitLink 	local classTable={}  	for ii, p279 in statements(entityID, 'P279') do 		if p279 and p279.mainsnak.snaktype == 'value' then 			local classID = p279.mainsnak.datavalue.value.id  			if data.class_dic[classID]~=nil then  			    circuitID=classToCircuit(classID, entityID, false, p279.qualifiers)  			    classLink=classLinkFn(classID,circuitID) 			    if classLink then 			    	local period, sTime=getPeriod(p279.qualifiers, true) 			    	local classStr = classLink .. " <small>"..period.."</small>" 					table.insert(classTable, {sTime, classStr, circuitID}) 				end 			end 		end 	end 	if #classTable~=0 then 		table.sort(classTable, function(a, b) return a[1] < b[1] end) 	end 	for _, class in pairs(classTable) do 		if not str then str='' else str=str..'<br>' end 		str=str..class[2] 		if class[3] then 			circuitLink=WPlinkpure(class[3]) 		end 	end     return str, circuitLink, #classTable end  local function fn_race(entityID,displayed_class,display_class,timeOfRace, functionName,country)--return link to the race and class 	--first function read from victory main 	local Sitelink, entity_type, classID, stageID, race_tCell, class_tCell, parentID  	for _, p31 in statements(entityID, 'P31') do 		if data.stages[p31.mainsnak.datavalue.value.id] then 			entity_type = 'stage'  --then the class is one stage above! 			parentID = getParentID(entityID) 			classID=firstValue(parentID, 'P279', 'id')  			stageID= entityID --everything slide from one rank 			entityID = parentID 		end 	end 	--Now we have the class and know the type of race it is 	if entity_type == 'stage' then 		Sitelink=getMainRaceLink(entityID,entity_type,stageID, functionName,timeOfRace) 	else 		classID=firstValue(entityID, 'P279', 'id') 		Sitelink=getMainRaceLink(entityID,data.class_dic[classID],nil, functionName,timeOfRace) 	end 	 	if country~=false then 		local tCell=mw.html.create('td'):cssText("text-align:".. textalign ..";padding:0 2.3em"):wikitext(Sitelink) 		race_tCell=tostring(tCell) 	else 		race_tCell=Sitelink --already opened 	end 	 	if display_class == true and classID~=nil and (displayed_class==nil or displayed_class[classID]~=nil) then 		local circuitID=classToCircuit(classID, entityID, true,nil)  		local classLink=classLinkFn(classID,circuitID) --return '' worst case  		class_tCell=mw.html.create('td') 		:attr('data-sort-value',data.class_sort[classID]) --sortkey 		:cssText("text-align:center;padding:0 0.5em") 		:wikitext(classLink) 	end 	return parentID, race_tCell, class_tCell end  local function fn_rider(lf,entityID,timeOfRace,display_team,only_winner,country) 	local winners, countrytemp, result 	local WDlink_on = (wiki == "mk" or wiki == "ja") 	local thereisawinner=false 	 	if only_winner == 1 then 		winners = {Q20882667 = '', Q20882747=''} -- first, general or stage 	elseif only_winner == 0 then 		winners = { Q20882667 = '', Q20882668 = '',Q20882669 = ''} -- Q20882668 is 'second overall' 	else --3 		winners = { Q47640757='' } -- World Tour -- name not used here 	end 	if country==nil then countrytemp=false else countrytemp=country end 	winner(lf,entityID, winners, timeOfRace, countrytemp, WDlink_on, display_team, true) 	 	local tCell=mw.html.create('td'):css("text-align:".. textalign ..";padding:0 0.5em") 	 	if only_winner == 0 then 		tCell:wikitext(winners.Q20882667) 		result=tostring(tCell) 		tCell=mw.html.create('td'):css("text-align:".. textalign ..";padding:0 0.5em"):wikitext(winners.Q20882668) 		result=result..tostring(tCell) 		tCell=mw.html.create('td'):css("text-align:".. textalign ..";padding:0 0.5em"):wikitext(winners.Q20882669) 		return result..tostring(tCell) 	else 		local tempwinner 		if only_winner == 1 then 			if winners.Q20882667~=nil and winners.Q20882667~='' then 				tempwinner=winners.Q20882667 			else 				tempwinner=winners.Q20882747 			end 		else 			tempwinner=winners.Q47640757 		end 		if tempwinner~='' and tempwinner~=nil then thereisawinner=true end 		return tCell:wikitext(tempwinner), thereisawinner 	end end  local function compareDate(tdate) --test future 	if tdate then 		local today=os.date("*t")  		local _, _, y, m, d = string.find(tdate, "(%d+)%p(%d+)%p(%d+)") 		local tYear=tonumber(y) 		local tMonth=tonumber(m) 		local tDay=tonumber(d) 		 		if tYear>today['year'] then 			return true 		elseif tYear<today['year'] then 			return false  --the last race is the future 		else 			if tMonth>today['month'] then 				return true 			elseif  tMonth<today['month'] then 				return false 			else 				if tDay>today['day'] then	 					return true 				elseif  tDay<today['day'] then	 					return false 				else 					return false --arbitrary 				end 			end 		end 	else 		return false --arbitrary 	end end  local function calculateAge(birthDate, endDate) --test future 	local eYear, eMonth, eDay 	local longestcontractyears=10 	if birthDate then 		if not endDate then 			local today=os.date("*t")  		    eYear=today['year'] 		    eMonth=today['month'] 		    eDay=today['day'] 		else 			local _, _, y, m, d = string.find(endDate, "(%d+)%p(%d+)%p(%d+)") 			eYear=tonumber(y) 			eMonth=tonumber(m) 			eDay=tonumber(d) 		end  		local _, _, y, m, d = string.find(birthDate, "(%d+)%p(%d+)%p(%d+)") 		local tYear=tonumber(y) 		local tMonth=tonumber(m) 		local tDay=tonumber(d) 		local alreadyThisYear  		if eMonth>tMonth then 			alreadyThisYear=true	 		elseif  eMonth<tMonth then 			alreadyThisYear=false 		else 			if eDay>tDay then	 				alreadyThisYear=true 			elseif  eDay<tDay then	 				alreadyThisYear=false 			else 				alreadyThisYear=true 			end 		end 		 		if alreadyThisYear then 			return eYear-tYear, tYear, eYear+longestcontractyears 		else 			return eYear-tYear-1, tYear, eYear+longestcontractyears 		end 	else 		return 0, tYear, eYear+longestcontractyears 	end end 			  local function evaluateWinnerMax(t) 	local winners = t.vainqueur 	local result 	local most_wins = 0 	local most_wins_ID = {} 	for winnerID, winner in pairs(winners) do 		if winner.count > most_wins then 			most_wins = winner.count 			most_wins_ID = { winnerID } 		elseif winner.count == most_wins then 			most_wins_ID[#most_wins_ID + 1] = winnerID 		end 	end  	if most_wins > 1 then 		for _, id in pairs(most_wins_ID) do 			if not result then 				result=winners[id].link 			else 				result=result.."<br>"..winners[id].link 			end 		end 		 		local _, gen_singular, gen_plural=plural(most_wins) 		if gen_singular then --slavic plural, 1 victory is not displayed 			word_victory=translate("raceinfobox",29) 		elseif gen_plural then 			word_victory=translate("raceinfobox",30) 		else 			word_victory=translate("raceinfobox",32) --singular 		end 		result=result.."<br>("..tostring(most_wins).." "..word_victory..")" 	end 	t.maxWinner=result end  local function listOfWinners(itemID,t, team,lf, mandatory_prop) 	local winners = {	Q20882667 = '',}-- Q20882667 is 'overall winner general classification' 	local winnersId={	Q20882667 = '',}--to detect disqualification 	local WDlink_on, sitelink  	if wiki == "mk" or wiki == "ja" or wiki == "ru" then WDlink_on = true else WDlink_on = false end      -- Get the date to sort the editions 	for _, p527 in statements(itemID, 'P527') do  --_, p527 		local raceDate, year, raceID, entity_race, a, b  		raceId = p527.mainsnak.datavalue.value.id -- Qnumbers of the parts of a tour 		raceDate=getTimeOfRace(raceId) 		table.insert(t.race, { raceId=raceId, raceDate=raceDate, future=compareDate(raceDate)} ) --check if future 		table.sort(t.race, function(a,b) return a['raceDate'] < b['raceDate'] end) -- t.race is sorted after year 	end  	--look for the next race 	local lastRunEdition, lastEditionDate, nextEdition 	 	for num, race in ipairs(t.race) do 		if race['future'] then 			nextEdition=num 			break 		end 	end 		--Get the winners 	local numberOfEditions=0 	local lastWinner, winnerId  	if not team then --for race, a test shall be performed 		for num=1,#t.race do 			winners.Q20882667='' 			winnersId.Q20882667='' 			winner(lf,t.race[num]['raceId'], winners, t.race[num]['raceDate'], false, WDlink_on, nil, nil, winnersId ) 			if t.race[num]['future']==false then --in the past 				if winnersId.Q20882667~="Q30108381" then --cancelled 					numberOfEditions=numberOfEditions+1 					lastRunEdition=num 					lastEditionDate=t.race[num]['raceDate'] 					lastWinner=winners.Q20882667 				end 			end 		 			winnerId=winnersId.Q20882667 			if winnerId~=nil and winnerId~='' and winnerId~='Q666' and winnerId~='Q30108381' then --code for disqualification 				if not t.vainqueur[winnerId] then 					t.vainqueur[winnerId]={} 					t.vainqueur[winnerId].link=winners.Q20882667 					t.vainqueur[winnerId].count=0 				end 				t.vainqueur[winnerId].count=t.vainqueur[winnerId].count+1 			end	 		end 	else --for team the check is lighter 		for num=1,#t.race do 			if t.race[num]['future']==false then --in the past 				if mandatory_prop==nil then 					numberOfEditions=num 					lastRunEdition=num 					lastEditionDate=t.race[num]['raceDate'] 				else 					local ss = wikibase.getAllStatements(t.race[num]['raceId'], mandatory_prop) 					if #ss >0 then 						numberOfEditions=num 						lastRunEdition=num 						lastEditionDate=t.race[num]['raceDate'] 					end 				end 			end 		end		 	end  	local monthId=firstValue(itemID, 'P2922','id')  	if monthId then  		t.lastEditionMonth=getLabelFallback(monthId) or '' 	else 		t.lastEditionMonth=contentLanguage:formatDate("M", lastEditionDate) 	end  	if lastEditionDate then 		t.lastEditionYear=funcDate(lastEditionDate,"onlyyear")    	end 	t.numberOfEditions=numberOfEditions 	if not team then evaluateWinnerMax(t) end 	 	if lastRunEdition then 		t.lastWinner=lastWinner or '' --t.vainqueur[lastRunEdition]['link'] 		t.lastID=t.race[lastRunEdition]['raceId'] 		sitelink = wikibase.getSitelink(t.lastID) 		if sitelink ~= nil then 			t.lastLink = "[[" .. sitelink .. "]]" 		else 			t.lastLink = nil 		end 	end 	 	if nextEdition then  		t.nextID=t.race[nextEdition]['raceId'] 		sitelink = wikibase.getSitelink(t.nextID) 		if sitelink ~= nil then 			t.nextLink = "[[" .. sitelink .. "]]" 		else 			t.nextLink = nil 		end 	end	 end  local function getPeriodicity(itemID, t) 	local p = wikibase.getBestStatements(itemID, 'P2257') 	if p[1] and p[1].mainsnak.snaktype == 'value' then 		local period=p[1].mainsnak.datavalue.value.amount 		local periodunit=p[1].mainsnak.datavalue.value.unit 		if tonumber(period)==1 and periodunit == 'http://www.wikidata.org/entity/Q577' then 			return translate("raceinfobox",1).." ("..t.lastEditionMonth ..")" 		elseif tonumber(period)==1 and periodunit == 'http://www.wikidata.org/entity/Q5151' then 			return translate("raceinfobox",2) 		else 			return nil 		end 	else 		return nil 	end end  local function getType(itemID) 	local result, typeID 	typeID =firstValue(itemID, 'P31', 'id') 	if typeID ~= nil then 		if typeID=="Q2912397" and wiki=="fr" then 			result="[[Cyclisme_sur_route#Épreuve_d'un_jour|Course d'un jour]]" 		else 			result=WPlinkpure(typeID) 		end 	end --else result=nil    	return result   end  local function getFormerNames(itemID, PID, season) 	local listOfNames={} 	local officialname,language  	local kk=1 	while #listOfNames == 0 and kk<=#lang_priority do 		lang=lang_priority[kk] 		kk=kk+1 		for _, prop in ipairs({PID}) do 			for _, p1813 in statements(itemID, prop) do 				language = p1813.mainsnak.datavalue.value.language 				officialname = p1813.mainsnak.datavalue.value.text 				if lang==language then --only exact language 					local period, sTime=getPeriod(p1813.qualifiers, nil, season) 					if not sTime then sTime="+1900-01-01T00:00:00Z" end --first 					table.insert(listOfNames,{sTime, period, officialname, language}) 				end 			end 		end 	end			 	table.sort(listOfNames, function(a, b) return a[1] < b[1] end) 	return listOfNames end  local function officialSite(itemID) 	local url=firstValue(itemID, 'P856') 	if url then  		return '['..url.." "..translate("raceinfobox",3)..']' 	end 	return nil end  local function checkkm(p) 	local km, unit 	if p[1] and p[1].mainsnak.snaktype == 'value' then 		km = tonumber(p[1].mainsnak.datavalue.value.amount) 		unit = p[1].mainsnak.datavalue.value.unit 		if unit == 'http://www.wikidata.org/entity/Q828224' then 			return km 		end 	end 	return nil end  local function checkm(p, in_cm) 	local m, unit, res 	if p[1] and p[1].mainsnak.snaktype == 'value' then 		m = tonumber(p[1].mainsnak.datavalue.value.amount) 		unit = p[1].mainsnak.datavalue.value.unit 		if unit == 'http://www.wikidata.org/entity/Q11573' then 			res=m 		elseif unit=='http://www.wikidata.org/entity/Q174728' then --cm 			res=m*0.01 		end 		if res then 			if in_cm then 				res=res*100 			end 			return res 		end 	end 	return nil end  local function checkkmh(p) 	if p[1] and p[1].mainsnak.snaktype == 'value' then 		kmh = tonumber(p[1].mainsnak.datavalue.value.amount) 		unit = p[1].mainsnak.datavalue.value.unit 		if unit == 'http://www.wikidata.org/entity/Q180154' then -- Q180154 is 'kilometre per hour' 			return kmh 		end 	end 	return nil end  local function checkkg(p) 	local kg, unit 	if p[1] and p[1].mainsnak.snaktype == 'value' then 		kg = tonumber(p[1].mainsnak.datavalue.value.amount) 		unit = p[1].mainsnak.datavalue.value.unit 		if unit == 'http://www.wikidata.org/entity/Q11570' then 			return kg 		end 	end 	return nil end  local function formatNumber(e, addUnit, trans) 	local text 	if e then 		text = contentLanguage:formatNum(e) 		if wiki == 'fo' then 			text = string.gsub(text, "%.", ",") 		end 		if addUnit then 			local t=translate("unit",trans) 			if string.find( t," ")==1 then 				text = text ..t 			else 				text = text .. ' ' ..t 			end 		end 	end 	return text end   local function getHeight(entityID, in_cm) 	local p = mw.wikibase.getBestStatements(entityID, 'P2048') 	if in_cm then 		return formatNumber(checkm(p, in_cm), true, 11) 	else 		return formatNumber(checkm(p, in_cm), true, 9) 	end end  local function getWeight(entityID) 	local p = mw.wikibase.getBestStatements(entityID, 'P2067')	 	return formatNumber(checkkg(p), true, 10) end  local function getDistance(raceID, addUnit) 	local p = mw.wikibase.getBestStatements(raceID, 'P3157') -- P3157 is 'event distance' 	local km =checkkm(p) 	if not km then --for stage race we can sum the distances from each stage 		local stagep, tempkm 		for _, p527 in statements(raceID,'P527') do 			stagep=mw.wikibase.getBestStatements(p527.mainsnak.datavalue.value.id, 'P3157') 			tempkm=checkkm(stagep) 			if tempkm then 				if not km then km=0 end 				km=km+tempkm 			end 		end 	end 	return formatNumber(km, addUnit, 8), km end  local function getElevation(raceID) 	local p =mw.wikibase.getBestStatements(raceID, 'P7297') 	return formatNumber(checkm(p), true, 9) end  local function getSpeed(raceID, addUnit,kmdistance, property) 	local timeOfRace 	local p = mw.wikibase.getBestStatements(raceID, 'P2052') -- P2052 is 'speed' 	local kmh=checkkmh(p)  	if not kmh and kmdistance then --calculate speed 		local p2321= wikibase.getBestStatements(raceID, property) --winner supposed to be first of overall classification 		if p2321 and p2321[1] and p2321[1].mainsnak.snaktype == 'value' then 			local q = p2321[1].qualifiers 			if q and q.P1352 and q.P1352[1].snaktype == 'value' then --rank 				for _, q1352 in pairs(q.P1352) do 					rank = tonumber(q1352.datavalue.value.amount) 				end 				if rank == 1 then 					timeOfRace=qualifieramount(p2321[1], 'P2781') --get time 				end 			end  			if timeOfRace then 				kmh=math.modf(1000*kmdistance/(timeOfRace/3600))/1000 			end 		end 	end 	return formatNumber(kmh, addUnit, 5) end  local function getGenderCode(riderID, default) 	local gender=default -- default is for teams, n or f 	local g = firstValue(riderID, 'P21', 'id') 	if g == 'Q6581097' then gender = 'm' -- Male 	elseif g == 'Q6581072' then gender = 'f' -- Female 	elseif g == 'Q1052281' then gender = 't' -- Transgenre 	end 	return gender  end  function number(gender, b, wiki) 	local str 	if b==nil or b=="" then return "" end 	if wiki=="ar" then 		str = b 	elseif wiki == "ca" then 	if b==1 then str = b.."r" 		elseif b==2 then str = b.."n" 		elseif b==3 then str = b.."r" 		elseif b==4 then str = b.."t" 		else str = b.."è" 		end 	elseif wiki=="es" then 		if gender == 'm' or gender == 'n' then str = b..".º" 		elseif gender == 'f' then str = b..".ª" 		else str = b.."." 		end 	elseif wiki=="fr" then 		if b==1 then 			if gender == 'm' then str="1<sup>er</sup>" 			elseif gender == 'f' or gender == 'n' then str="1<sup>re</sup>" 			else str="1<sup>e</sup>" 			end 		else str=b.."<sup>e</sup>" 		end 	elseif wiki=="nl" then str=b.."e" 	elseif wiki=="ru" then str=b.."-й" 	elseif wiki=="eo" then str=b.."-a" 	elseif wiki=="ast" then 		if gender == 'm' or gender == 'n' then str = b.."ᵘ" 		elseif gender == 'f' then str = b.."ª" 		else str = b.."." 		end 	else str = b .. ". " 	end 	return str end  local function calculateTime(t) 	local time = tonumber(t) 	local h, m, s = 0, 0, 0 	local str = ''  	if time == nil then return '' end 	if time < 60 then s = time 	elseif time < 3600 then m = math.modf(time/60) s = time - m*60 	else h = math.modf(time/3600) m = math.modf((time - h*3600)/60) s = time - h*3600 - m*60 	end  	if h>0 then str = str..mw.ustring.format ('%i'..translate("unit",2), h) end 	if m>=0 and h>0 then str = str.. mw.ustring.format('%02i'..translate("unit",3), m) end 	if m>0 and h==0 then str = str.. mw.ustring.format('%i'..translate("unit",3), m) end 	if s>=0 and (h>0 or m>0) then str = str.. mw.ustring.format('%02i'..translate("unit",4), s) end 	if s>=0 and h==0 and m==0 then str = str.. mw.ustring.format('%i'..translate("unit",4), s) end 	return str --time..': '..h..' '..m..' '..s end  local function func_error_message(x) 	local l10nDef = { 		["fr"] = {"La propriété <1> est manquante dans l'item <2> (<3>)"}, 		["en"] = {'Property <1> is missing in item "<2>" (<3>)'}, 		["ar"] = {'الخاصية <1> غير موجودة في العنصر "<2>" (<3>)'}, 	} 	local l10n = l10nDef[wiki] 	if not l10n then l10n = l10nDef["en"] end  -- default 	return l10n[x] end  local function getMissingLabelTrackingCategory() 	local l10nDef = { 		["cs"] = '[[Kategorie:Údržba:Doplnit štítek na Wikidatech]]', 		["lv"] = '[[Category:Vikidatos trūkst nosaukuma latviešu valodā]]', 		["he"] = '[[קטגוריה:ויקינתונים:ערכים חסרי תווית בעברית: קבוצת אופניים]]', 	} 	local l10n = l10nDef[wiki] 	if not l10n then 		l10n = '' 	end 	return l10n end  local function getStageLabel(inp) 	local a 	local b=''  	local this_label='' 	if inp then 		a, _ = string.gsub(inp, "%a", "") -- 20, not 20a 		if string.find(inp, "%a") then  			b = string.sub(inp, string.find(inp, "%a")) 		end 		if inp == "0" then  			this_label = translate("func_prologue",1) 		else 		    this_label = stageLink(inp, a, b) 		end 	end 	return this_label end  --[[ Make a table row for infoboxes with links to previous and next ]] local function getPreviousNextLine(raceID, stage) 	local previousID = firstValue(raceID, 'P155', 'id') -- P155 is 'follows' 	local nextID = firstValue(raceID, 'P156', 'id') -- P156 is 'followed by' 	if not nextID or not previousID then 		for _, s in statements(raceID, 'P3450') do		-- for items using P3450 			local q = s.qualifiers 			if q then 				if not previousID and q.P155 and q.P155[1] and	q.P155[1].snaktype == 'value' then 					previousID = q.P155[1].datavalue.value.id 				end 				if not nextID and q.P156 and q.P156[1] and	q.P156[1].snaktype == 'value' then 					nextID = q.P156[1].datavalue.value.id 				end 			end 		end 	end 	if not previousID and not nextID then 		return '' 	end  	local previousText, nextText = '', '' 	 	local direction = contentLanguage:getDir() 	local previous_sign = (direction == 'ltr') and '&#x25C0;' or '&#x25B6;' 	local next_sign = (direction == 'ltr') and '&#x25B6;' or '&#x25C0;' 	 	local this_label 	if previousID then 		if stage  then 			 local series_ordinal= firstValue(previousID, 'P1545', 'value') 			 this_label=getStageLabel(series_ordinal) 		else 			this_label = getYear(previousID) 		end 		local link = wikibase.getSitelink(previousID) 		if link then 			previousText = '<span style="color:#3366CC">[[' .. link .. '| ' .. previous_sign .. this_label .. ']]</span>' 		else 			previousText = '<span style="color:#3366CC">' .. previous_sign .. '</span> ' .. this_label 		end 	end 	if nextID then 		if stage then 			local series_ordinal= firstValue(nextID, 'P1545', 'value') 			this_label=getStageLabel(series_ordinal) 		else 			this_label = getYear(nextID) 		end 		local link = wikibase.getSitelink(nextID) 		if link then 			nextText = '<span style="color:#3366CC">[[' .. link .. '|' .. this_label .. next_sign .. ']]</span>' 		else 			nextText = this_label .. ' <span style="color:#3366CC">' .. next_sign .. '</span>' 		end 	end 	local direction = contentLanguage:getDir() 	 	local outTable = mw.html.create('tr') 	local tCell=outTable:tag('td') 	tCell:cssText("text-align:" .. ((direction == 'ltr') and 'left' or 'right')):wikitext(previousText) 	if stage ~= nil and wiki=="ar" then  		tCell:css('width','50%') 	end 	 tCell=outTable:tag('td') 	 :cssText("text-align:" .. ((direction == 'ltr') and 'right' or 'left')):wikitext( nextText)     if stage ~= nil and wiki=="ar" then  		tCell:css('width','50%') 	end 	return outTable end  --== Functions for infobox -- functions for infoboxs  local function get_others_dic() 	return { 		{ name = translate("infobox",29,w_race)}, -- picture 		{ name = translate("infobox",30,w_race)}, -- caption 		{ name = translate("infobox",31,w_race)}, -- map 		{ name = 'sectional'},             -- sectional 		{ name = translate("infobox",30,w_race)}, -- caption map 		{ name = translate("infobox",30,w_race)}, -- caption sectional 	} end  local function infoGetOthers(others, entityID) 	if not others[1].content then --picture 		others[1].content, others[2].content = getLogo(entityID) 		if not others[1].content then 			others[1].content, others[2].content = getImage(entityID) -- picture, caption 		end 	end  	if not others[3].content then  -- map 		others[3].content, others[5].content = getMap(entityID)  -- P242 is 'locator map image' 	end 	 	if not others[4].content then  -- map 		others[4].content, others[6].content = getSectionalView(entityID) -- sectional_view 	end	 end  local function infoGetPlaceOrCountry(details,index, entityID, timeOfRace, PID) --generalized infoGetCountry 	if not details[index].content then -- country 		-- This function gives countries where the race take place 		local place = {}  	    if not place[1] then  			for _, p17 in statements(entityID, PID) do -- P17 is 'country' 				local countryID = p17.mainsnak.datavalue.value.id 				if PID=='P17' then 					place[#place + 1] = flag(countryID, timeOfRace) .. ' ' .. getCountryName(countryID)  				else 					place[#place + 1] =  wikibase.getLabel(countryID) 				end 			end 		end  		if place[1] then 			if #place > 1 then 				details[index].name = details[index].name_plural 			end 			details[index].content = table.concat(place, '<br/>') 		end 	end end  local function infoGetPlace(details,index, entityID, timeOfRace) 	infoGetPlaceOrCountry(details,index, entityID, timeOfRace, "P276") end  local function infoGetCountry(details,index, entityID, timeOfRace) 	infoGetPlaceOrCountry(details,index, entityID, timeOfRace, "P17") end  local function infoGetStartEnd(details,index, entityID, timeOfRace) 	if not details[index].content then -- start place 		local place = firstValue(entityID, 'P1427', 'id') -- P1427 is 'start point' 		details[index].content = place and getPlaceLink(place, timeOfRace) 	end  	if not details[index+1].content then -- end place 		local place = firstValue(entityID, 'P1444', 'id') -- P1444 is 'destination point' 		details[index+1].content = place and getPlaceLink(place, timeOfRace) 	end end  local function infoGetParticipants(details,index, entityID) 		-- Function that give the number of cyclists at the beginning and at the finishing of a race 	for _, p1132 in statements(entityID, 'P1132') do -- P1132 is 'number of participants' 		local amount = tonumber(p1132.mainsnak.datavalue.value.amount) -- tonumber to remove starting '+' 		for _, q in qualifiers(p1132, 'P276') do -- P276 is 'location' 			local location = q.value.id 			if location == "Q529711" then -- Q529711 is 'beginning' 				if not details[index].content then details[index].content = amount end -- participants at start 			elseif location == "Q12769393" then -- Q12769393 is 'end' 				if not details[index+1].content then details[index+1].content = amount end -- participants at end 			end 		end 	end end  local function infoInitTab(width, name, icon, cellpadding) 	if width==nil then width= '320px' end 	 	local tab = mw.html.create('table') 	if wiki == "eo" then 		tab:cssText(standardtablecss):css('width','23em') 		:addClass('infobox') 	else 		cellpadding=tostring(cellpadding or 4) 		tab:attr('cellpadding',cellpadding) 		:attr('cellspacing','0') 		:cssText(standardtablecss) 		:cssText("float:"..floatinfobox.."; max-width:"..width) 	end 	local tCell=tab:tag('tr'):tag('td'):attr('colspan','2') 	:cssText('border-bottom:5px solid white; font-size:175%; text-align:center') 	:css('background-color',backgroundColor) 	local topTable = tCell:tag('table') 	:cssText('width:100%') 	local tRow=topTable:tag('tr') 	tRow:tag('td'):wikitext(name or '') 	tRow:tag('td'):wikitext(icon or '') 	 	return tab end  local function addARow(name, content) 	local tRow 	if content then 		tRow= mw.html.create('tr'):css('vertical-align','top') 		tRow:tag('td'):css('width','40%'):css('font-weight','bold') 		:wikitext(name) 		tRow:tag('td'):wikitext(content) 	end 	return tRow end  local function addATitle(title) 	local tRow 	if title then 		tRow= mw.html.create('tr'):tag('td'):attr('colspan','2') 		:css('text-align','center') 		:css('background-color',backgroundColor) 		:css('font-weight','bold') 		:wikitext(title) 	end 	return tRow end  local function infoFillOthersDetails(tab, others, details,title, pxmax) 	if not pxmax then 		pxmax="300px" 	end 	 	if others and others[1].content then -- picture 		tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center') 		:wikitext("[[File:" .. others[1].content .."|center|"..pxmax.."]]") 		if others and others[2].content then -- caption 			tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%') 			:wikitext(others[2].content) 		end 	end 	if details then 		tab:node(addATitle(title)) 		for _, row in ipairs(details) do 	    	tab:node(addARow(row.name, row.content)) --node check itself if nil 		end 	end end  local function infoFillOthersMap(tab, others) 	if others[3].content then -- map 		tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center') 		:wikitext("[[File:".. others[3].content .. "|center|300px]]") 		if others[5].content then -- caption 			tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%') 			:wikitext(others[5].content) 		end 	end 	if others[4].content then -- map 		tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center') 		:wikitext("[[File:".. others[4].content .. "|center|300px]]") 		if others[6].content then -- caption 			tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%') 			:wikitext(others[6].content) 		end 	end end  local function wdDoc(tab, s, translation, ID) 	local tCell=tab:tag('tr'):tag('td') 	local tC, link 	local commons_cat=firstValue(ID, 'P373', 'id') 	 	if commons_cat then 		commons_cat=string.gsub(commons_cat, '%s', '_')  		local icon="[[File:Commons-logo.svg|12px|link=https://commons.wikimedia.org/wiki/Category:"..commons_cat.."]]" 		tC=tCell:cssText('text-align:left; border-top:3px solid '..backgroundColor..'; font-size:75%') 		:wikitext(icon):tag('td') 	else 		tC=tCell:attr('colspan','2') 	end 	if wiki == "ar" then 		link = wdLink(ID) .." [[" .. s .. "|" .. translation .. "]]" 	else 		link = "[[" .. s .. "|" .. translation .. "]] "..wdLink(ID) 	end 	tC:cssText('text-align:right; border-top:3px solid '..backgroundColor..'; font-size:75%') 	:wikitext(link) end  local function listWPlink(details, index, entityID, PID, bool_link) 	local org={} 	for _, p in statements(entityID, PID) do  		if p and p.mainsnak.snaktype == 'value' then 			if bool_link then 				table.insert(org,WPlinkpure(p.mainsnak.datavalue.value.id)) 			else 				local label=wikibase.getLabelByLang(p.mainsnak.datavalue.value.id, wiki) 				table.insert(org,label) 			end 		end 	end 	if org[1] then 		if #org > 1 then 			details[index].name = details[index].name_plural 		end 		details[index].content = table.concat(org, '<br/>') 	end	 end  --Display in a chronological order fields in a table local function listWPlinkChrono(details, index, entityID, listOfProperty, option, initialYear, display_flag, comma,season) 	local period, sTime, value, ID, temp 	local list={} 	 	if not initialYear then initialYear="1900" end 	 	if not details[index].content then	 		for _, prop in ipairs(listOfProperty) do 			if #list==0 then --if P1532 is used P17 is not used 				for _, p in statements(entityID, prop) do 					if p and p.mainsnak.snaktype == 'value' then 						ID=p.mainsnak.datavalue.value.id		 						if p.qualifiers then 							period, sTime=getPeriod( p.qualifiers, true,season) 						end 						if not sTime then sTime="+"..initialYear.."-01-01T00:00:00Z" end --first 					 						if option =='label' then 							value=wikibase.getLabelByLang(ID, wiki)	 						elseif option == 'country' then 							value=getCountryName(ID) 							if display_flag then	 								value= flag(ID, sTime).." "..value 							end 						elseif option=='officialname' then 							value=getOfficialName(ID, sTime,false) --official name is necessary because of continental team change in ProTeam 						elseif option =='place' then 							value=getPlaceLink(ID, sTime) 						elseif option=='UCIcode' then 							value=getTeamCodeCat(entityID, sTime) --! getTeamCodeCat uses teamID 						elseif option=='money' then 							local amount=p.mainsnak.datavalue.value.amount 							local unit=p.mainsnak.datavalue.value.unit 							value=dispmoney(amount, unit) or '' 						else --rider 							value=getRiderLink(ID, sTime) 						end 						if value then 							table.insert(list,{sTime,period,value}) 						end 					end 				end 			end 		end 		if #list ~=0 then 			table.sort(list, function(a, b) return a[1] < b[1] end) 		end 		local separator='<br/>' 		if comma then separator=', ' end 		 		 		if list and #list==1 then		 			details[index].content=list[1][3] or '' 		elseif list and #list~=0 then 			details[index].name = details[index].name_plural	 			details[index].content=''			 			for _, v in pairs(list) do 				temp=v[3] or '' 				if v[2] then 					temp=temp..' <small>'..v[2]..'</small>'..separator 				else 					temp=temp..separator 				end 				details[index].content=details[index].content..temp 			end	 		end 	end	 end  -- == Functions for team roster local function getReason(riderReason, riderRef, p527,timeOfRace,riderEnd,lf) --reason for end 	local listofproperty={'P1642','P1643','P1534'} 	local outTable={} 	local seasonYear, endYear 	if timeOfRace then 		seasonYear=tonumber(string.sub(timeOfRace, 2, 5)) 	end 	if riderEnd then 		endYear=tonumber(string.sub(riderEnd, 2, 5)) 	end 	 	--if not the last season, do not display the reason for end 	if (riderReason == nil and (not endYear or  		(seasonYear and endYear and (seasonYear== endYear)))) then --if no riderReason before then look for it, otherwise don't touch it 		for _,v in ipairs(listofproperty) do 			for _, q in qualifiers(p527, v) do 				riderReason = q.value.id 			end 		end 		if riderReason then 			local label =string.gsub(getLabelFallback(riderReason,lang_priority), "%b()", "") 			riderRef = getReference(lf,p527, 1) 			riderReason = ', ' .. label 		end 	end 	return riderReason, riderRef end  local function getPosition(riderPosition,v) 	local stagiaire 	if riderPosition == nil then -- find the 'position' (P39) of a rider 		for _, q in qualifiers(v, 'P39') do 			stagiaire = q.value.id 			local label = string.gsub(getLabelFallback(stagiaire,lang_priority), "%b()", "") 			Sitelink = wikibase.getSitelink('Q2328847') 			if Sitelink then  				riderPosition=', ' .. "[["..Sitelink .."|"..label.."]]"  			else 				riderPosition =', ' .. label 			end 		end 	end 	return riderPosition end  local function trans(date, month, day) 	if date ~= '' and date~=nil then 		local _, _, y, m, d = string.find(date, "(%d+)-(%d+)-(%d+)") 		if m == '00' then m = month end 		if d == '00' then d = day end 		date = '+'..y..'-'..m..'-'..d..'T00:00:00Z' 		return date 	end 	return nil end  local function parseDate(date, defaultYear, defaultMonth, defaultDay, errortext, etext) 	local y, m, d 	local date=trans(date, defaultMonth, defaultDay) 	if not date then 	 		date = '+'..defaultYear..'-'..defaultMonth..'-'..defaultDay..'T00:00:00Z' 		y=defaultYear 		m=defaultMonth 		d=defaultDay 		errortext=errortext..etext 	else 		_, _, y, m, d = string.find(date, "(%d+)-(%d+)-(%d+)") 		if not y or y=="0000" then  			y=defaultYear  			errortext=errortext..etext 		end 		date = '+'..y..'-'..m..'-'..d..'T00:00:00Z' 	end 	 	return date, y, m, d, errortext end  local function findLastName(label,wiki) 	if not label then label = '' end 	local _, count = string.gsub(label, " ", " ") 	local names 	local a,b,c,d = '', '', '', '' 	local done = false 	if count ~= nil then count = count + 1 else count = 1 end  	if count > 1 then 		if count == 2 then 			if label ~= '' then 				a, b = string.match(label, "(%S+)%s+(%S+)") 				names = b..' '..a 			end 		else 			local name_parts_mk = {'да', 'ди', 'де', 'Де', 'ла', 'Ле', 'тен', 'ван', 'Ван'} 			local name_parts_ru = {'да', 'ди', 'де', 'Де', 'ла', 'Ле', 'тен', 'ван', 'Ван'} 			local name_parts    = {'da', 'de', 'di', 'De', 'la', 'Le', 'ten', 'van', 'Van'} 			if count == 3 and label ~= '' then 				a, b, c = string.match(label, "(%S+)%s+(%S+)%s+(%S+)") 				if wiki == 'mk' then 					for _,v in ipairs(name_parts_mk) do if b == v then names = b..' '..c..' '..a done = true break end end 				elseif wiki == 'ru' then 					for _,v in ipairs(name_parts_ru) do if b == v then names = b..' '..c..' '..a done = true break end end 				else 					for _,v in ipairs(name_parts) do if b == v then names = b..' '..c..' '..a done = true break end end 				end 				if not done then 					names = tostring(c)..' '..tostring(a)..' '..tostring(b) 					done = true 				end 			end 			if count > 3 and label ~= '' then 				a, b, c, d = string.match(label, "(%S+)%s+(%S+)%s+(%S+)%s+(%S+)") 				if wiki == 'mk' then 					for _,v in ipairs(name_parts_mk) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end end 					for _,v in ipairs(name_parts_mk) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end end 				elseif wiki == 'ru' then 					for _,v in ipairs(name_parts_ru) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end end 					for _,v in ipairs(name_parts_ru) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end end 				else 					for _,v in ipairs(name_parts) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end end 					for _,v in ipairs(name_parts) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end end   				end 				if not done then names = label.."%"..b end --b..' '..c..' '..d..' '..a end 			end 		end 	end 	return names or '' end  local function findSortKey(riderID, correctlanguage, wikiIsSlavic) 	--find the last name to sort 	if wikiIsSlavic and correctlanguage then 		local label = wikibase.getLabelByLang(riderID, wiki) 		if label then 			local nametable = mw.text.split(label, ",") 			if nametable[2] then --there is a coma so the lastname is first 				return nametable[1]..nametable[2] 			else --no coma 				return findLastName(label,wiki)  			end 		end 	end 	--all other cases 	label = getLabelFallback(riderID) 	return findLastName(label,wiki) end  --== V) Main functions == --=== A) Function race reference === local function race_reference(raceID,lf) 	-- Allow to display the reference below the classifications -- 	local bases={ 		{"ProCyclingStats", "P2327", "http://www.procyclingstats.com/race.php?id="}, 		{"Cycling Quotient", "P2648", "http://www.cqranking.com/men/asp/gen/race.asp?raceid="}, 		{"Cycling Archives", "P2330", "http://www.cyclingarchives.com/ritfiche.php?ritid="}, 		{"Cycling Quotient", "P2708", "http://www.cqranking.com/women/asp/gen/race.asp?raceid="} 	} 	local links = {} 	local ref 	for _, base in pairs(bases) do 		local p = mw.wikibase.getBestStatements(raceID, base[2]) 		if p[1] and p[1].mainsnak.snaktype == 'value' then 		    if base[2]=="P2648" and p[1].mainsnak.datavalue.value=="1" then --code for general reference of results 				ref=getReference(lf,p[1], 1) 				if ref then	table.insert(links, ref) end 			else 				table.insert(links, ' [' .. base[3] .. p[1].mainsnak.datavalue.value .. " " .. base[1] ..']') 			end 		end 	end 	if #links == 1 then 		return translate("race_reference", 1) .. table.concat(links) 	elseif #links > 1 then 		return translate("race_reference", 2) .. table.concat(links) 	else 		return '' 	end end  --=== B) Calendar === function p.calendarcustom(frame) 	local headers={2} --date 	local calendarID, lf =get_and_checkID(frame)  	local display_numbering=false --default 	local country_column=2 	if istrue(get_arg('display_numbering',frame)) then 		display_numbering=true 		table.insert(headers, 3) 		country_column=3 	end     --no_country modify the way the country is displayed     local no_country={}     if istrue(get_arg('no_country',frame)) or wiki == "ar" then 		no_country={wiki} 	end 	-- country -- 	table.insert(headers, 5) 	--race-- 	table.insert(headers, 4)  	local display_class=false 	if istrue(get_arg('display_class',frame)) or wiki == "ar" then 		display_class=true 		table.insert(headers, 6) 	end 	     table.insert(headers, 7) --winner 	local only_winner=1 	if istrue(get_arg('podium',frame)) or wiki == "ar" then 		only_winner =0 		table.insert(headers, 8) --second 		table.insert(headers, 9)	--third	 	end 	 	local display_leader=false 	if istrue(get_arg('display_leader',frame)) then 		 display_leader=true 		 table.insert(headers, 10) 	end 	local display_team =false 	if istrue(get_arg('display_team',frame)) then 		display_team =true 	end  	local data_type={} 	for ii=1,#headers do 		table.insert(data_type,'') 	end 	     local w_race=isWomenrace(calendarID) 	local s = { 		header_function = "calendar", -- translations are in function Calendar 		header_1 = 1000, -- translation 1 in function Calendar is printed in the upper part of the table header 		header_2 = headers,-- translations 2, 3, 4, 5, 6 in function Calendar are printed in this order 		title=wikibase.getLabel(calendarID),  -- in the lower part of the table header. The second value 3 in {4, 3} tells where the icon will go. 		country_column = country_column, 		data_sort_type = data_type, -- see https://meta.wikimedia.org/wiki/Help:Sorting 		item = calendarID, 		property = 'P527', 		no_country = no_country, 		only_winner = only_winner, 		display_numbering =  display_numbering, 		displayed_class =nil, 		display_team=display_team, 		display_class=display_class, 		display_leader= display_leader, 		w_race=w_race, 		lf=lf 	} 	return calendar_main(s, tableA(s)) end  function p.calendar(frame) 	----- function to display UCI calendar of one year ---- 	----- based on WWTcalendar function ----- 	----- author: Mr. Ibrahem ----- 	local calendarID --determined later 	local lf = get_lf(frame) 	local UCI = data.UCIYearToQ 	 	local header_1_tab = {["UWT"]=13 ,["europe"]=14 ,["asia"]=15,["america"]=16 ,["africa"]=17 ,["oceania"]=18, ["WWT"]=11, ["women"]=1, ["Pro"]=22} 	local display_code_tab=  {["UWT"]=1 ,["europe"]=2 ,["asia"]=2,["america"]=2 ,["africa"]=2 ,["oceania"]=2, ["WWT"]=1, ["women"]=2, ["Pro"]=2} 	local header_1_number = 12 	 	local tempdic, year, keyk, yeary 	local tempdic1 = { 		header_2 =  {2, 3,5, 4, 7, 8, 9, 10}, 		only_winner =0, 		display_numbering=true, 		display_team=false, 		display_class=false, 		display_leader=true 	}	 	local tempdic2 = { 		header_2 =   {2, 5, 4, 6, 7}, 		only_winner =1, 		display_numbering=false, 		display_team=true, 		display_class=true, 		display_leader=false 	}  	for key, v in pairs(UCI) do 		year = get_arg(key,frame) --with lf does not work 		if not calendarID  and year then 			if v[year] then 				calendarID = v[year] 				header_1_number = header_1_tab[key] 				display_code = display_code_tab[key] 				keyk=key 				yeary=year				 			end 		end 	end 	if wiki == "ar" then 		if not (frame.args["code"] and frame.args["code"] == "2") then 			display_code = 1 		end 		if calendarID == "" and frame.args.test then 			calendarID = frame.args.test 		end 	end 	if not calendarID or calendarID == "" then return "" end 	if display_code == 1 then 		tempdic=tempdic1 		if keyk=="UWT" and tonumber(yeary) > 2018 then 			tempdic.display_leader=false --no more leader after 2018 			tempdic.header_2 ={2, 3,5, 4, 7, 8, 9} 		end 	else 		tempdic=tempdic2 	end 	if istrue(get_arg('display_numbering',lf)) then 		tempdic.display_numbering=true 	elseif get_arg('display_numbering',lf) and istrue(get_arg('display_numbering',lf)) == nil then 		tempdic.display_numbering=false 	end 	local w_race=isWomenrace(calendarID) 	local s = { 		header_function = "calendar", -- translations are in function Calendar 		header_1 = header_1_number, -- t 		header_2 = tempdic.header_2, 					-- in the lower part of the table header. The second value 3 in {4, 3} tells where the icon will go. 		country_column = 3, 		data_sort_type ={'', 'unsortable', '', '', '','',''},   -- -- see https://meta.wikimedia.org/wiki/Help:Sorting 		item = calendarID, 		property = 'P527', 		no_country = no_country_calendar, 		only_winner = tempdic.only_winner, 		display_numbering = tempdic.display_numbering, 		displayed_class = nil, --all 		display_team=tempdic.display_team, 		display_class=tempdic.display_class, 		display_leader=tempdic.display_leader, 		w_race=w_race, 		lf=lf 	} 	return calendar_main(s, tableA(s)) end  function calendar_main(s, resultTable)--Display the UCI women calendar of one year 	local lf = s.lf 	local calendarID=s.item 	local t_Body ={} 	local w_race=isWomenrace(calendarID)  	local temp=firstValue(calendarID, s.property) 	if not temp or temp=="" then  		s.error_message = 2  		if wiki == "ar" then return "" end 	end 	local country=getCountryBool(s.no_country)  	----- Begin of the main part of the code 	for kk, p527 in statements(calendarID, 'P527') do 		local RaceID = p527.mainsnak.datavalue.value.id 		---- Create a row ---- 		local timeOfRace, date_tCell, date_sortkey = fn_date(RaceID) 		local parentID, race_tCell, class_tCell= fn_race(RaceID,s.displayed_class,s.display_class,timeOfRace,nil,country)  		if race_tCell~=nil then --otherwise the class is not display 			local country_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID)  			--create the table 			local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;") 			tRow:node(date_tCell) 			if s.display_numbering == true then 				tRow:tag('td'):cssText("text-align:center;padding:0 0.5em"):wikitext(tostring(kk)) 			end 			tRow:node(country_tCell) 			if country then	tRow:node(race_tCell) end 			if class_tCell then tRow:node(class_tCell) end 			local rider_tCell =fn_rider(lf,RaceID,timeOfRace,s.display_team,s.only_winner) 			tRow:node(rider_tCell) 			if s.display_leader==true then 				local leader_tCell=fn_rider(lf,RaceID,timeOfRace,s.display_team,3) 				tRow:node(leader_tCell) 			end 			---- Add the row to the table 			t_Body[#t_Body + 1] = {date_sortkey, tRow} 		end  	end  	return sortAndConcat(t_Body, resultTable) end  function p.nationalchampionships(frame) 	local calendarroadID, calendarITTID, year 	local lf=get_lf(frame) 	local listOfCalendar={data.NationalRoadCyclingChampionships,data.NationalITTCyclingChampionships}  	for ii, thisCalendar in pairs(listOfCalendar) do --road/ITT 		for key, v in pairs(thisCalendar) do --look for the key of the dictionnary, here women/men 			year = get_arg(key,frame) --with lf does not work 			if ((ii==1 and calendarroadID==nil) or (ii==2 and calendarITTID ==nil)) and year then 				if v[year] then 					if ii==1 then 						calendarroadID = v[year] 					else 						calendarITTID = v[year] 					end 				end 			end 		end 	end 	 	local w_race=isWomenrace(calendarroadID) 	local s = { 		header_function = "calendar", -- translations are in function Calendar 		header_1 = 19, -- 		header_2 = {5, 20, 21}, 		country_column = 1, 		data_sort_type = {'', '', ''},   -- -- see https://meta.wikimedia.org/wiki/Help:Sorting 		item= calendarroadID, 		calendarroadID = calendarroadID, 		calendarITTID = calendarITTID, 		property = 'P527', 		year = year, 		no_country = {}, --no sense here to hide the country 		display_team = true, 		display_countrylink = false, --too expensive 		w_race=w_race, 		lf=lf 	} 	return nationalchampionships_main(s,tableA(s)) end  function nationalchampionships_main(s, resultTable)--Display the list of national champions for one year 	local lf = s.lf 	local tableChamp, t_Body = {}, {}, {} 	local timeOfRace ='+'..tostring(s.year).."-01-01T00:00:00Z" 	local rider_tCell, thereisawinner, parentID, parentParentID, sitelink 	local country_flag, country_name, country_tCell  	local temp=firstValue(s.calendarroadID, s.property) 	if not temp or temp=="" then  		s.error_message = 2  		if wiki == "ar" then return "" end 	end  	local listOfCalendarID={s.calendarroadID, s.calendarITTID}  	--create the table with the information 	for ii, thisCalendarID in ipairs(listOfCalendarID) do 		if thisCalendarID ~= nil then 			for _, p527 in statements(thisCalendarID, 'P527') do 				thisID = p527.mainsnak.datavalue.value.id 				country_flag, country_name, country_tCell=fn_country(thisID,timeOfRace,s.country) 				if country_name == nil then	country_name="country not found" end 				sortkey=string.gsub(country_name, 'É', 'E') --case États Unis 				--create the table 				if tableChamp[sortkey]==nil then  					tableChamp[sortkey]={} 					tableChamp[sortkey]['countryname']=country_name 					tableChamp[sortkey]['roadwinner']='<td></td>' 					tableChamp[sortkey]['ITTwinner']='<td></td>' 					--look for sitelink to championship 					sitelink=nil --reinit 					if s.display_countrylink then --expensive 						parentID = firstValue(thisID, 'P361', 'id') --part of 						if parentID then  							parentParentID = firstValue(parentID, 'P31', 'id')  							if parentParentID then sitelink = wikibase.getSitelink(parentParentID) end 						end 					end 					tableChamp[sortkey]['sitelink']=sitelink 					tableChamp[sortkey]['flag']=country_flag 				end 				 				--fill the table 				rider_tCell, thereisawinner=fn_rider(lf,thisID,timeOfRace,s.display_team,1,true) 				if tableChamp[sortkey]['thereisawinner']~=true then --all other cases 					tableChamp[sortkey]['thereisawinner']=thereisawinner  				end 				 				if ii==1 then 					tableChamp[sortkey]['roadwinner']=rider_tCell 				else 					tableChamp[sortkey]['ITTwinner']=rider_tCell 				end 			end 		end 	end  	-- structure the display 	for key, thisRow in pairs(tableChamp) do 		if thisRow['thereisawinner'] then --there is a winner 			local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;") 			if thisRow['sitelink']~=nil then 				tRow:tag('td'):wikitext(thisRow['flag']..' [['..thisRow['sitelink']..'|'..thisRow['countryname']..']]') 			else 				tRow:tag('td'):wikitext(thisRow['flag']..' '..thisRow['countryname']) 			end 			tRow:node(thisRow['roadwinner']) 			tRow:node(thisRow['ITTwinner']) 			t_Body[#t_Body + 1] = {key, tRow} 		end --no winner 	end --end list of key  	return sortAndConcat(t_Body, resultTable)   end  --=== C) Victory === function p.victories(frame) 	local tempID, lf=get_and_checkID(frame) 	local w_race=isWomenrace(tempID) 	 	local s = { 		header_function = "victories", -- translations are in function victories 		header_1 = 2, -- translation 1 in function victories is printed in the upper part of the table header 		header_2 = {3, 4, 5, 6, 7},-- translations 2, 3, 4, 5, 6 in function victories are printed in this order 										-- in the lower part of the table header. The second value 3 in {4, 3} tells where the icon will go. 		data_type = {'date', 'race', 'country', 'class', 'rider'}, 		country_column = 3, 		data_sort_type = {'', 'unsortable', '', '', ''}, -- see https://meta.wikimedia.org/wiki/Help:Sorting 		item = tempID, 		property = 'P2522', 		no_country = no_country_victories, 		lf=lf, 		w_race=w_race 	} 	return victory_main(s ,tableA(s)) end  function victory_main(s, resultTable) 	local lf = s.lf 	local _ 	_, _, s.item = string.find(s.item, "(%w+)")  	local temp=firstValue(s.item, s.property,'id') 	if not temp or temp=="" then  		s.error_message = 2  		if wiki == "ar" then return "" end 	end  	local country=getCountryBool(s.no_country) 	local t_Body = {}  	for _, p2522 in statements(s.item, 'P2522') do 		local RaceID = p2522.mainsnak.datavalue.value.id 		local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;")  		local timeOfRace, date_tCell, date_sortkey = fn_date(RaceID, 'victory') 		local parentID, race_tCell, class_tCell=fn_race(RaceID,nil ,true,timeOfRace, 'victory',country)--displayed_class=nil 		 		if race_tCell~= nil then --otherwise class not to be displayed 			country_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID) 			--Build the table 			tRow:node(date_tCell) 			if country==true then 				tRow:node(race_tCell)  --race site link is in fn_countrytable 			end 			tRow:node(country_tCell)  			tRow:node(class_tCell) --class 			local rider_tCell =fn_rider(lf,RaceID,timeOfRace,false,1) 			tRow:node(rider_tCell) 			t_Body[#t_Body + 1] = {date_sortkey, tRow} 		end --no winner 	end --end list of key 	 	return sortAndConcat(t_Body, resultTable) end  --== D) Stage infobox function p.stageinfobox(frame) 	local stageID, lf = get_and_checkID(frame) 	local w_race=isWomenrace(stageID) 		 	local details = { 		{ name = translate("stageinfobox",2,w_race)}, -- course / not used 		{ name =  translate("stageinfobox",2,w_race)}, -- competition 		{ name = translate("stageinfobox",3,w_race), name_plural = translate("infobox",4,w_race)}, -- stage type  		{ name = translate("stageinfobox",4,w_race), name_plural = translate("infobox",7,w_race)}, -- date 		{ name = translate("stageinfobox",6,w_race)}, -- distance 		{ name = translate("stageinfobox",7,w_race), name_plural = translate("infobox",10,w_race)}, -- country 		{ name = translate("stageinfobox",9,w_race)}, -- start place 		{ name = translate("stageinfobox",10,w_race)}, -- endplace 		{ name = translate("stageinfobox",11,w_race)}, -- participants at start 		{ name = translate("stageinfobox",12,w_race)}, -- participants at end 		{ name = translate("stageinfobox",13,w_race)}, -- speed 		{ name = translate("stageinfobox",44,w_race)}, -- elevation 		{ name = translate("infobox",32,w_race), special = true}, -- special 1 		{ name = translate("infobox",33,w_race), special = true}, -- special 2 	} 	local others = get_others_dic() 			--begin of the function 	local t_P642 = { 			Q20882747={'results', 'first'},  			Q20882748={'results', 'second'},  			Q20882749={'results', 'third'},  			Q21686770={'results', 'winner_fighting'}, 			Q2250962={'results', 'cima_coppi'},  			Q10452933={'results', 'cima_pantani'}, 			Q20882763={'gen', 'leader'},  			Q20882764={'gen', 'deuxieme'},  			Q20882765={'gen', 'troisieme'}, 			Q20883213={'annex', 'montagne'},  			Q20883140={'annex', 'jeune'},  			Q20883008={'annex', 'points'}, 			Q20883329={'annex', 'sprints'},  			Q20893984={'annex', 'super_combatif'},  			Q20965880={'annex', 'combine'}, 			Q27104688={'annex', 'stage_volantes'},  			Q27104684={'annex', 'regularite'},  			Q20882922={'annex', 'equipe'}, 			Q27104271={'annex', 'equipe_points'}, 			Q20882667={'gen', 'leader'},  			Q20882668={'gen', 'deuxieme'},  			Q20882669={'gen', 'troisieme'}, 			Q20883212={'annex', 'montagne'},  			Q20883139={'annex', 'jeune'},  			Q20883007={'annex', 'points'}, 			Q20883328={'annex', 'sprints'},  			Q20893983={'annex', 'super_combatif'},  			Q20893979={'annex', 'combine'}, 			Q27067359={'annex', 'stage_volantes'},  			Q27067170={'annex', 'regularite'}, 			Q27907747={'annex', 'azzurri_ditalia'},  			Q27907748={'annex', 'azzurri_ditalia'}, 			Q27907714={'annex', 'breakaway'},  			Q27907715={'annex', 'breakaway'}, 			Q20882921={'annex', 'equipe'},  			Q27104269={'annex', 'equipe_points'} 	} 	 	getLocalContent(details, lf.args) 	getLocalContent(others, lf.args)  	local timeOfRace 	local temp = firstValue(stageID, 'P31','id') 	icon = '' 	if temp and temp ~= 'Q18131152' then 		if temp=='Q2266066' or temp=='Q2348250' or temp=='Q485321' then  			icon = " [[File:Cycling (track) pictogram.svg|35px]]" 		else  			icon = " [[File:Cycling (road) pictogram.svg|35px]]"  		end 		details[3].content = typeofstagelogo(stageID, true).." "..WPlinkpure(temp) 	end 	 	local name =  getLabelFallback(stageID) or '' 	if wiki == 'fr' and name ~= nil then  		name= mw.ustring.gsub(name, "^(%d+)([re]+)", "%1<sup>%2</sup> ")  	end     name= mw.ustring.gsub(name, "^(%a)",function (x) return mw.ustring.upper(x) end) 		 	infoGetOthers(others, stageID)	  	--name 	local race={} 	 	if course==nil then 		temp = firstValue(stageID, 'P1545') 		if temp then 			details[2].content =getStageLabel(temp) 			raceId = getParentID(stageID) --for instance Tour de France 2020 			if raceId then 				details[2].content = (details[2].content or '') .. '، '.. WPlinkpure(raceId) 				for k, p31 in statements(raceId, 'P31') do --get Tour de France 					race[k] = p31.mainsnak.datavalue.value.id --for the jersey 				end 			end 		end 	end  	-- This function give a format to dates when P585 (date) is used in a single day race 	local pTime = firstValue(stageID, 'P585', 'time') -- P585 is 'point in time' 	if pTime then 		details[4].content = funcDate(pTime, 'long') 		timeOfRace = pTime 	end 	 	local kmdistance 	if not details[5].content then details[5].content, kmdistance = getDistance(stageID, true) end -- distance 	 	infoGetCountry(details,6, stageID, timeOfRace) 	infoGetStartEnd(details,7, stageID, timeOfRace) 	infoGetParticipants(details,9, stageID) 	if not details[11].content then details[11].content = getSpeed(stageID, true, kmdistance, 'P2417') end --speed 	if not details[12].content then  		local elevation=getElevation(stageID)  		if  elevation ~= nil then details[12].content =elevation else details[12].content = nil end 	end --Elevation  	local jerseyWPID, jersey_name 	local t_s = { 		order={'results', 'gen', 'annex'}, 		results={show=false,  			header=15,  			order = {'first','second','third','winner_fighting','winner_fighting2','cima_coppi','cima_pantani'}, 			first={translation=16}, 			second={translation=17}, 			third={translation=18}, 			winner_fighting={translation=19}, 			winner_fighting2={translation=19}, -- two winner_fighting possible 			cima_coppi={translation=40}, 			cima_pantani={translation=41} 			}, 		gen={show=false,  			header=20,  			order = {"leader", "deuxieme", "troisieme"}, 			leader={translation=21}, 			deuxieme={translation=22}, 			troisieme={translation=23} 			}, 		annex={show=false,  			header=24,  			order={"points","montagne","sprints","jeune","super_combatif","combine", 			"stage_volantes","regularite","azzurri_ditalia","breakaway","equipe","equipe_points"}, 			points={translation=25}, 			montagne={translation=26}, 			sprints={translation=27}, 			jeune={translation=28}, 			super_combatif={translation=29}, 			combine={translation=30}, 			stage_volantes={translation=31}, 			regularite={translation=32}, 			azzurri_ditalia={translation=42}, 			breakaway={translation=43}, 			equipe={translation=33}, 			equipe_points={translation=34} 			} 		}  	--Winner 	for _, p1346 in statements(stageID, 'P1346') do 		local id_speed, id_time, id_time_gap, id_points_a, id_points_b, type_ofclas, name_ofclas 		local q = p1346.qualifiers 		local riderId = p1346.mainsnak.datavalue.value.id  		id_time = qualifieramount(p1346, 'P2781') 		id_time_gap =qualifieramount(p1346, 'P2911') 		id_speed =qualifieramount(p1346, 'P2052') 		id_points_a = qualifieramount(p1346, 'P1358') 		id_points_b =qualifieramount(p1346, 'P1351')  		if riderId ~= nil then 			local riderLink,riderTeam  = subwinner(riderId, timeOfRace, q) --sub function to avoid code in double 			-- looks into race item if the winner has a P642 statement for showing the type of winner(points, mountain, ..) 			if q.P642 and q.P642[1].snaktype == 'value' then 				for _, vv in pairs(q.P642) do 					local qual = vv.datavalue.value.id 					if qual~=nil and deprecated~='deprecated' and t_P642[qual] then 						if qual=="Q21686770" and t_s['results']['winner_fighting'][1] ~= "" then  							t_P642[qual][2] = 'winner_fighting2'  						end 						type_ofclas=t_P642[qual][1] --annex or gen 						name_ofclas=t_P642[qual][2] --name of ranking 						local v=t_s[type_ofclas][name_ofclas]  						v['link']=riderLink     						v['team']=riderTeam  						v['rank']=isdisqualified(p1346,q)  						v['time']=id_time  						v['gap']=id_time_gap  						if id_points_a then v['points']=id_points_a end  						if id_points_b then v['points']=id_points_b end 						v['speed']=id_speed  						if qual=="Q27104271" and t_s.annex.equipe_points['link']==nil then 							t_s.annex.equipe_points['link']=riderId  						end 						if qual=="Q20882922" and t_s.annex.equipe['link']==nil then  							t_s.annex.equipe['link']=riderId  						end 						v['genre'] = getGenderCode(riderId,'f') 					end 				end 			end 		end 	end 	local rank, deprecated, prop, order, thisorder  	-- look into P2417, stage classification, then p2321 gen classification 	for ii, thistable in ipairs({'results','gen'}) do 		if ii==1 then 			prop='P2417' 			order = {'first', 'second', 'third'} 		else 			prop='P2321' 			order = {'leader', 'deuxieme', 'troisieme'} 		end 		 		for _, p2417 in statements(stageID, prop) do 			local q = p2417.qualifiers 			if q.P1352 and q.P1352[1].snaktype == 'value' then 				for _, q1352 in pairs(q.P1352) do 					rank = tonumber(q1352.datavalue.value.amount) 				end 				if rank == 1 or rank == 2 or rank == 3 then 					thisorder=order[rank] 					local v=t_s[thistable][thisorder] 					v['rank'] = isdisqualified(p2417, q) 					local thisid= p2417.mainsnak.datavalue.value.id 					v['link'],_  = subwinner(thisid, timeOfRace, q)   					if v['gap'] == nil and v['time'] == nil then 						v['gap'] = qualifieramount(p2417, 'P2911')  					end 					if v['gap'] == nil and v['time'] == nil then 						v['time'] = qualifieramount(p2417, 'P2781')  					end 					v['speed'] = qualifieramount(p2417, 'P2052')  					v['genre'] = getGenderCode(thisid, 'f') 				end 			end 		end 	end  	for _, thistable in ipairs({t_s.results,t_s.gen,t_s.annex}) do 		for _, v in ipairs(thistable.order) do --order is the list of all classification names 			if thistable[v]['link'] then 				thistable.show = true  			end 		end 	end 	 	---General table 	local temp 	local width= '320px' -- size standard 320px, special 340px 	if t_s.annex.show == true and (wiki == 'no' or wiki == '..') then width= '340px' end 	tab= infoInitTab(width, name, icon) 	infoFillOthersDetails(tab, others, details,translate("stageinfobox",1,w_race))  -- ranking table, general and stage 	for _, value_order in ipairs(t_s.order) do 		local thistable =t_s[value_order] --results or gen or annex 		 		if thistable.show then -- if a section of the stageinfobox should be shown 			tCell=tab:tag('tr'):tag('td'):attr('colspan','2') 			tTab=tCell:tag('table'):attr('cellpadding','0'):attr('cellspacing','0'):css('width','100%') 			tCell=tTab:tag('tr'):tag('td'):attr('colspan','3') 			:cssText('border-bottom:5px solid '..backgroundColorLight..'; background-color:'..backgroundColor..'; text-align:center') 			:css('font-weight','bold') 			:wikitext(translate("stageinfobox",thistable.header,w_race))  			for key, value in ipairs(thistable.order) do --value is the name of the class 				local v=thistable[value] 				if v['link'] then 					local a1 					a1, jersey_name, jerseyWPID = jersey_infobox( value, race, timeOfRace) 					if a1~='' then v['jersey'] = a1 end 					if v['speed']  then 						if wiki == 'fo' then 							v['speed'] = string.gsub(v['speed'], "%.", ",")  						else 							local lang = mw.language.getContentLanguage() 							v['speed'] = '('.. lang:formatNum(v['speed'])..translate("unit",5,w_race)..')' 						end 					end 					if v['points'] then 						if v['points'] > 1 then  							temp=translate("unit",7,w_race) 						else  						    temp=translate("unit",6,w_race)  						end  						v['points'] = v['points']..temp 					end 					local title, k = string.gsub(translate("stageinfobox",v['translation'],w_race), " ", "&nbsp;") 					if k > 0 then title = string.gsub(title, "&nbsp;", "<br>", 1) end --&#32; 				 					--Create an empty column on the left 					tRow=tTab:tag('tr'):css('vertical-align','top') 					tCell=tRow:tag('td') 					:css('font-weight','bold') 					if v['team']~=nil or v['speed'] ~=nil then 						tCell:attr('rowspan','2') 					end 					tCell:cssText("width:1%;background-color:"..backgroundColorLight..";text-align:" ..  					textalign .. ";padding:0 2px 0 2px;white-space:nowrap") 				 					if value_order~='annex' and v['translation']~=40 and v['translation']~=41 then -- Cima Coppi, Cima Pantani with a line break 						if v['jersey'] == nil then 							if (value_order=='results') and (value=='winner_fighting' or value=='winner_fighting2' or value=='cima_coppi' or value=='cima_pantanii') then 								tCell:wikitext(translate("stageinfobox",v['translation'],w_race)) 							else 								tCell:wikitext(number(v['genre'], key, wiki)) 							end 						else 							temp='' 							if jerseyWPID~='' then 								temp="|link="..jerseyWPID 							end 							tCell:wikitext("[[File:"..v['jersey'].."|20px|"..title..temp.."]]") 						end 					else 						if v['jersey'] == nil then  							tCell:wikitext(title) 						else 							if jerseyWPID=='' then 								if jersey_name ~= '' then  									temp = "|"..jersey_name 								else 									temp='' 								end 							else  								temp= "|link="..jerseyWPID 							end 							tCell:wikitext("[[File:"..v['jersey'].."|20px"..temp.."]]" .. title) 						end 					end 					 					tRow:tag('td'):cssText("padding:0 0.5em 0 0.5em;"..v['rank']) 					:wikitext( v['link']) 					tCell=tRow:tag('td'):cssText('text-align:right;font-size:85%;white-space:nowrap')  					if v['time'] then  						tCell:wikitext(calculateTime(v['time'])) 					end 					if v['gap'] then  						tCell:wikitext('+ '.. calculateTime(v['gap'])) 					end 					tCell:wikitext(v['points']) 				end 				 				tCell=tTab:tag('tr'):tag('td'):attr('colspan','2') 				if v['team']~=nil and v['speed'] ~=nil then -- team row 					tTab2=tCell:tag('table'):attr('cellpadding','0'):attr('cellspacing','0'):css('width','100%') 					tRow = tTab2:tag('tr') 					tRow:tag('td'):cssText('width:100%;text-align:" .. textalign .. ";padding-left:2px') 					:wikitext("("..v['team']..")") --add the team 					tRow:tag('td'):cssText('font-size:85%;vertical-align:top;white-space:nowrap') 					:wikitext(v['speed']) 				else 					if v['team']~=nil or v['speed'] ~=nil then 						tCell:cssText("text-align:" .. textalign .. ";padding-left:2px") 						if v['team'] ~= nil then 							tCell:wikitext("("..v['team']..")") --add the team 						end 						tCell:tag('span'):cssText("float:right;font-size:85%;"):wikitext(v['speed']) 					end 				end 			end 		end 	end 	 	infoFillOthersMap(tab, others) 	tab:node(getPreviousNextLine(stageID,true)) 	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/stageinfobox", translate("stageinfobox",39,w_race), stageID) 	return tab end  --== E) List of teams function p.listofteams(frame) 	local raceID, lf = get_and_checkID(frame) 	local teams = {} -- values will be {teamLink, teamCat, sortkey, index} 	local WDlink_on = (wiki == "mk" or wiki == "ja")  	local timeOfRace = getTimeOfRace(raceID, true) 	local w_race=isWomenrace(raceID)  	local teamCats_lot = { -- {c,d,e} c = singular team type, d = plural team type, e = print order of the team types 		["Q6154783"]  = {4,5,1},   -- WorldTeam 		["Q80425135"] = {4,5,2},   -- UCI Women’s WorldTeam 		["Q20638319"] = {6,7,3},   -- ProTeam (2005-2014) 		["Q78464255"] = {6,7,4},   -- ProTeam (2020-) 		["Q382927"]   = {8,9,5},   -- UCI Professional Continental Team (2005-2019) 		["Q1756006"]  = {10,11,6}, -- UCI Continental Team 		["Q20639847"] = {16,17,7}, -- professional cycling team		 		["Q20653563"] = {20,21,8}, -- Groupe Sportif I 		["Q20653564"] = {22,23,9}, -- Groupe Sportif II 		["Q20653566"] = {24,25,10}, -- Groupe Sportif III	 		["Q2466826"]  = {28,29,11}, -- UCI Women’s Team 		["Q23726798"] = {12,13,12}, -- national cycling team 		["Q99658502"] = {12,13,13}, -- national cycling team "B" 		["Q20738667"] = {12,13,14}, -- national cycling team U23 		["Q54555994"] = {12,13,15}, -- national cycling team U19		 		["Q28492441"] = {12,13,16}, -- national cycling team with sponsor name 		["Q20652655"] = {18,19,17}, -- amateur cycling team 		["Q26849121"] = {30,31,18}, -- Women's amateur cycling team 		["Q20639848"] = {14,15,19}, -- club and region cycling team 		["Q20653570"] = {14,15,20}, -- club and region cycling team 	}  	local p1923 = mw.wikibase.getBestStatements(raceID, 'P1923') -- P1923 is participating teams 	local no = 0 -- Index used for stable sorting 	for _, v in pairs(p1923) do 		if v.mainsnak.snaktype == 'value' then 			no = no + 1 			local teamLink, teamCat, countryID = getTeamLinkCat(v.mainsnak.datavalue.value.id, timeOfRace, true) 			local flagImage = countryID and flag(countryID, timeOfRace) or '' 			teams[#teams + 1] = {flagImage .. ' ' .. teamLink, teamCat, 				teamCats_lot[teamCat] and teamCats_lot[teamCat][3] or 999, no} 		end 	end  	table.sort(teams, function(a,b) 		if a[3] < b[3] then return true end -- First sort key: Order from table teamCats_lot 		if a[3] > b[3] then return false end 		return a[4] < b[4] -- Second key is the index to ensure stable sorting 	end)  	local function getHeader(CatID, count) 		local header, sitelink 		if teamCats_lot[CatID] then 			local done=false 			if CatID=="Q2466826" then --name changed after 2020 				local year = timeOfRace and tonumber(string.sub(timeOfRace, 2, 5)) 				if year and year>2019 then 					if count == 1 then 						header_label = translate("headoftableIII",32, w_race) -- singular name 					else 						header_label = translate("headoftableIII",33, w_race) -- plural name 					end 					done=true 				end 			end 			 			if done==false then 				if count == 1 then 					header_label = translate("headoftableIII",teamCats_lot[CatID][1], w_race) -- singular name 				else 					header_label = translate("headoftableIII",teamCats_lot[CatID][2], w_race) -- plural name 				end 			end 			if CatID=='Q78464255' then 				sitelink=wikibase.getSitelink('Q382927') --continental 			else 				sitelink=wikibase.getSitelink(CatID) 			end  			if sitelink ~= nil then  				header = '[['..sitelink..'|'..header_label..']]' 			else 				header= header_label 			end 		end  		local tHeader=  mw.html.create('span'):css('font-size','1.2em'):css('font-weight','bold') 		if not header then 			-- Unknown team category. Get the label for the entity to display if possible 			header = (CatID and getLabelFallback(CatID)) or 'Unknown team category' 			tHeader:css('text-transform','capitalize') 		end 		tHeader:wikitext(header) 		 		-- Set parameter to show team count in front of each category 		local tTag='' 		local showcounter = 2 		if count >= showcounter then 			tTag=mw.html.create('small'):wikitext(' (' .. count ..')') 		end 		return tostring(tHeader)..tostring(tTag) 	end  	local oldOrder = 0 	local oldCatID 	local count = 0 	local list = '' 	local header 	 	local resultTable = mw.html.create('table') 	:cssText("max-width:95%; padding:0.5em; margin-right:1em; border:1px solid rgb(200,200,200)") 	local tCell = resultTable:tag('tr'):tag('td')  	for _, team in ipairs(teams) do 		local order = team[3] 		if order ~= oldOrder then --new cat 			if oldOrder > 0 then 				header = getHeader(oldCatID, count) 				tCell:wikitext(header) 				tCell:node(tOl) 			end 			count = 1 			oldOrder = order 			tOl = mw.html.create('ul') --reinit 		else 			count = count + 1 		end 		oldCatID = team[2]         tOl:tag('li') 		:cssText("width:20em;display:inline-block;vertical-align:text-top") 		:wikitext(team[1]) 	end 	--add last row 	header = getHeader(oldCatID, count) 	tCell:wikitext(header) 	tCell:node(tOl)  	local wd_link = mw.html.create('span'):css('float',floattable):wikitext(wdLink(raceID .. '#P1923')) 	if arwiki_totemplate then wd_link = wdLink(raceID .. '#P1923') end 	local tableFooter1=mw.html.create('tr') 	tCell=tableFooter1:tag('td') 	:addClass('navigation-only') 	:cssText('border-top: 2px '..backgroundColor..' solid; font-size: 80%;') 	tCell:wikitext(tostring(wd_link)) 	 	resultTable:node(tableFooter1) 	return resultTable end  --== F) Classifications function p.UCIclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 19, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item =tempID, 		property = 'P3494', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		display_team=false, 		max_rank_displayed=100000, --unlimited the whole team must be displayed 		lf=lf 		} 	return new_classification(s, frame) end  function p.pointsclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 10, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P3494', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.teamsclassificationbytime(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 14, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {3, 2, 4}, -- translations 3, 2, 4 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P3497', -- property to use for this table 		team_classification = true, -- it is a team classification table, its not a rider classification table 		background = 'strong', -- there is no background color for the first row, but the first row is formated strong 		max_rank_displayed=10, 		lf=lf 	} 	return new_classification(s, frame) end  function p.teamsclassificationbypoints(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 15, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {3, 2, 7}, -- translations 3, 2, 7 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P3496', -- property to use for this table 		team_classification = true, -- it is a team classification table, its not a rider classification table 		background = 'strong', -- there is no background color for the first row, but the first row is formated strong 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.stageclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 8, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 4 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P2417', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = false, -- there is no background color for the first row 		display_ref = get_arg(2, frame,true) == 0 and 0 or 1, 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.generalclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 4 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P2321', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		display_ref = get_arg(2, frame,true) == 0 and 0 or 1, 		max_rank_displayed=25, 		lf=lf 		} 	return new_classification(s, frame) end  function p.generalclassificationpoint(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = {	 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P2321', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		display_ref = get_arg(2, frame,true) == 0 and 0 or 1, 		max_rank_displayed=25, 		lf=lf 		} 	return new_classification(s, frame)	 end		  function p.generalclassificationforttt(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {3, 2, 4, 5, 6}, -- translations 3, 2, 4, 5, 6 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P2321', -- property to use for this table 		team_classification = true, -- it is a team classification table, its not a rider classification table 		background = false, -- there is no background color for the first row 		display_ref =get_arg(2, frame,true) == 0 and 0 or 1, 		max_rank_displayed=25, 		lf=lf 	} 	return new_classification(s, frame) end  function p.teamtimetrialclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 8, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {3, 2, 4, 5, 6}, -- translations 3, 2, 4, 5, 6 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P2417', -- property to use for this table 		team_classification = true, -- it is a team classification table, its not a rider classification table 		background = false, -- there is no background color for the first row 		display_ref = get_arg(2, frame,true) == 0 and 0 or 1, 		max_rank_displayed=25, 		lf=lf 	} 	return new_classification(s, frame) end  function p.mountainsclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 11, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item =  tempID, 		property = 'P4320', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.sprintsclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 12, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item =  tempID, 		property = 'P4322', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.bestyoungclassificationbypoints(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 13, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item =  tempID, 		property = 'P4323', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.bestyoungclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 13, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item =  tempID, 		property = 'P4323', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.u23classification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 18, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item =  tempID, 		property = 'P4323', -- property to use for this table (same as best young classification) 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.combinationclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 16, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item = tempID, 		property = 'P4324', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.combativeclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_1 = 17, -- translation 10 in function headoftableII is printed in the upper part of the table header 		header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		item =  tempID, 		property = 'P4321', -- property to use for this table 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.custompointsclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	 	local team_title 	local temp=get_arg(4,frame) 	if temp and string.find(temp,"{{{")==nil then  		team_title=temp 	end 	 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		header_1_text=get_arg(3,frame) or '', --with lf does not work 		item =  tempID, 		property = get_arg(2,frame), -- property to use for this table 		team_title=team_title, --for old races where there was no team, only bike brands 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function p.customtimeclassification(frame) 	local tempID, lf=get_and_checkID(frame) 	local team_title 	local temp=get_arg(4,frame) 	if temp and string.find(temp,"{{{")==nil then  		team_title=temp 	end 	 	local s = { 		header_function = "headoftableII", -- translations are in function headoftableII 		header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header 		header_1_text=get_arg(3,frame) or '', 		item = tempID, 		property = get_arg(2,frame), -- property to use for this table 		team_title=team_title, --for old races where there was no team, only bike brands 		team_classification = false, -- it is not a team classification table, its a rider classification table 		background = 'color', -- there is a background color for the first row 		max_rank_displayed=10, 		lf=lf 		} 	return new_classification(s, frame) end  function new_classification(s, frame) 	local country = getCountryBool(no_country_classification) 	local lf = s.lf 	local raceID = s.item 	local w_race=isWomenrace(raceID)  	--[=[ It is possible to give the classification tables in the article commands to change the standard behaviour. They could look like this: 	{{Cycling race/teamsclassificationbytime|Q18574623|newline=false|country=true}} 	{{Cycling race/teamsclassificationbytime|Q18574623|country= false|newline=false}} 	{{Cycling race/teamsclassificationbypoints|Q18574623|newline =true|country=true}} 	{{Cycling race/teamsclassificationbypoints|Q18574623|newline= true}} 	{{Cycling race/teamsclassificationbypoints|Q18574623|newline = false|country=false}} 	{{Cycling race/teamsclassificationbytime|Q18574623|newline=true|country=true}}  	One additional parameter is "newline" with the values "true" or "false". "newline" says, if there is a line brake after the table. Standard is 	no line break after the tables stageclassification and teamtimetrialclassification. 	The second parameter is "country" with the values "true" or "false". "country" tells the module to print the country column or not. 	Most wikis have as standard to print the country columns, some wikis prefer as standard not to show the country column. A few lines above, 	the command "if wiki == 'da' then country = false end" tells that daWiki do not want to see the country colums as standard. You can add your wiki 	here in, if you do not want to see them as standard. With the new parameter editors are able to tell the module in the article what to do. 	]=]  	local timeOfRace = getTimeOfRace(raceID, true)  	local plus = ''  	if get_arg('country',frame)~=nil then -- switch country column on or off in the article 		if get_arg('country',frame) == 'true' and l10n["country_name_list"] then country = true end 		if get_arg('country',frame) == 'false' then country = false end 	end 	local tableHeader2_size = #s.header_2 	 	local max_rank_displayed=s.max_rank_displayed 	for _, p31 in statements(raceID, 'P31') do 		if data.stages[p31.mainsnak.datavalue.value.id] then	 			max_rank_displayed=10 --limit general ranking to 10 except for not stage 		end 	end 	local temp=get_arg('max_rank_displayed',frame) 	if temp and temp~='' and string.find(temp,"{{{")==nil then 		max_rank_displayed=tonumber(temp) 	end  	if s.header_1_text ==nil then s.header_1_text=translate(s.header_function,s.header_1,w_race) end --for custom title 	local team_translation_index=3 	if s.team_title == nil then s.team_title=translate(s.header_function,team_translation_index,w_race) end --translation for team has index "3" 	 	local tableBody = mw.html.create('table') 		:addClass('sortable') 		:attr('cellpadding', '0') 		:attr('cellspacing', '0') 		:css('border' , '0')  	local wd_link = wdLink( raceID .. '#' .. s.property ) 	local wd_span = mw.html.create('span'):css('float','left'):wikitext(wd_link) 	if wiki == "ar" then 		if arwiki_totemplate then wd_span = wd_link 		else wd_span = mw.html.create('span'):css('float','right'):wikitext(wd_link) 		end end  	tableBody:tag('tr'):tag('th')     :attr('colspan', tostring(tableHeader2_size + 1)):cssText("padding:2px 2px; text-align:center; background-color:"..backgroundColor) 	:wikitext(tostring(wd_span)..s.header_1_text)  	header= tableBody:tag('tr'):cssText("text-align:center;padding:2px 2px;white-space:nowrap") 	for i, k in ipairs(s.header_2) do 		if i ~= 2 or country then 			local header_text 			if k == team_translation_index then --for team 			    header_text=s.team_title 			else 			    header_text=translate(s.header_function,k,w_race) 			end 			local head =header:tag('th'):wikitext(header_text) 			if i == 1 then 				head:attr('colspan','2') 			end 		end 	end  	local t_Body = {} --contains all rows 	local tCell, bg_color, tStyle, temp, temp2 	local claims = mw.wikibase.getAllStatements(raceID, s.property) 	for l, m in pairs(claims) do -- look into all statements 		if m.mainsnak.snaktype == 'value' then 			local riderID = m.mainsnak.datavalue.value.id 			local q = m.qualifiers or {} 			local rank, riderLink, gender, countryID, teamLink 			local flagLink, countryName = '', '' 			local h = { 				jersey = {}, -- lots of jerseyID 				value = {'', '', '', ''} -- points, time, time_gap, speed 			} 			 			if q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is ranking 				rank = tonumber(q.P1352[1].datavalue.value.amount) 			else 				rank = '' 			end 			 			if q.P1534 and q.P1534[1].snaktype == 'value' then 				local dnf=q.P1534[1].datavalue.value.id 				if dnf=='Q1210380' then riderDNF =translate("startlist",6,w_race)--"HD","NP","DQ" 					elseif dnf=='Q54881674' or dnf=='Q7113430' then riderDNF =translate("startlist",7,w_race) 					elseif dnf=='Q1210382' then riderDNF =translate("startlist",8,w_race) 					elseif dnf=='Q1229261' then riderDNF =translate("startlist",9,w_race) 					else riderDNF='' 				end 			else  				riderDNF=''	 			end  			local cancelled=isdisqualified(m,q)  			if wiki == 'es' or wiki == 'fr' or wiki == 'ast' then 				--[[ These wikis need the gender to display the rank correct. Other wikis can skip this. ]] 				gender = getGenderCode(riderID, 'n') 			end  			h.value[1] = qualifieramount(m, 'P1358') 			h.value[2] = qualifieramount(m, 'P2781') 			if q.P2911 and q.P2911[1].snaktype == 'value' then -- P2911 is time gap 				h.value[3] = tonumber(q.P2911[1].datavalue.value.amount) 				plus = '+ ' 			end 			h.value[4] = qualifieramount(m, 'P2052') 			if q.P2912 then -- P2912 is distinctive jersey 				for _, v in pairs(q.P2912) do 					if v.snaktype == 'value' then 						table.insert(h.jersey, v.datavalue.value.id) 					end 				end 			end  			if s.team_classification then 				local _ 				teamLink, _, countryID = getTeamLinkCat(riderID, timeOfRace, true) 			else 				riderLink = getRiderLink(riderID,timeOfRace)..(getReference(lf,m) or '') 				teamLink = getTeam(riderID, timeOfRace, q) 				countryID = getNationality(riderID, timeOfRace,q) 			end 			if countryID then 				flagLink = flag(countryID, timeOfRace) 				if country then 					countryName = getCountryName(countryID) 				end 			end  			-- find the right background color if a rider has more then one jersey 			-- see Wikidata:WikiProject Cycling/Kit to translate/Jerseys 			bg_color=nil 			if h.jersey[1] then 				for _, jersey in pairs(h.jersey) do 					if data.bg_color_table[jersey] then 						bg_color = data.bg_color_table[jersey] 						break 					end 				end 			end 			 			tStyle='' 			if rank == 1 then 				if s.background then -- values are 'strong' or 'color' 					tStyle = tStyle ..'font-weight:bold;' -- winner is formated bold 					if s.background == 'color' then 						if h.jersey[1] and bg_color then -- background color of winner depending on jersey 							tStyle = tStyle .. 'background-color:' ..bg_color 						end 					end 				end 			end  			local tBody = mw.html.create('tr'):cssText(tStyle) -- a row 			tBody:tag('td'):cssText("text-align:center;padding:2px 0.5em 2px 0.5em;white-space:nowrap;"..cancelled) 			:wikitext(number(gender, rank, wiki)) 			tCell= tBody:tag('td'):cssText("text-align:" .. textalign .. ";padding:0 0.2em 0 0.2em;"..cancelled)  			if not s.team_classification then 				if country then 					tCell:wikitext(riderLink .. jersey(h.jersey) ) 					tBody:tag('td'):wikitext( flagLink ..' '.. countryName) 				else 					tCell:wikitext(flagLink .. ' ' .. riderLink .. jersey(h.jersey)) 				end 				if s.display_team~=false then 					tBody:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.2em 0 0.2em") 					:wikitext(teamLink or '') 				end 			else --team 				if country then 					tCell:wikitext(teamLink .. jersey(h.jersey)) 					tBody:tag('td'):wikitext(flagLink .. ' ' .. countryName) 				else 					tCell:wikitext(flagLink .. ' ' .. teamLink .. jersey(h.jersey)) 				end 			end  			if s.header_2[4] == 4 then -- for table stageclassification, generalclassification, adds time and time gap 				if riderDNF=='' then 					if rank == 1 and h.value[2] then 						temp=calculateTime(h.value[2]) 					elseif rank == 1 and h.value[3]==nil then --avoid a plus with nothing 						temp='' 					else 						temp=plus .. calculateTime(h.value[3]) 					end 				else 					temp=riderDNF 				end 				tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp) 			end  			if s.header_2[4] == 7 or (s.header_2[3] == 7 and s.header_2[1] == 1) then -- for table pointsclassification, adds points 				--trick for UCI classification 				if riderDNF=='' then 					if h.value[1] then temp=h.value[1] else temp='' end 					tCell=tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em") 					:wikitext(temp)	 					if type(h.value[1]) == "number" then 						if h.value[1] > 1 then 							temp2=translate("unit",7,w_race) 						else 							temp2=translate("unit",6,w_race) 						end 						tCell:tag('span'):cssText("font-size:80%"):wikitext(temp2)	 					end 				else 					tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(riderDNF)	 				end 			end  			if s.header_2[3] == 4 then 				if s.property == 'P2417' or s.property == 'P2321' then 					-- for tables teamtimetrialclassification or generaltttclassification, adds time 					tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em") 					:wikitext(calculateTime(h.value[2])) 				end 			end  			if s.property == 'P3497' then -- for table teambytimeclassification, adds time and time gap 				if rank == 1 then  					temp=calculateTime(h.value[2]) 				else 					temp=plus .. calculateTime(h.value[3]) 				end 				tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp) 			end  			if s.property == 'P3496' then -- for table teambypointsclassification, adds points 				tCell=tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em") 			    :wikitext(h.value[1]) 				if type(h.value[1]) == "number" then 					if h.value[1] > 1 then 						temp2=translate("unit",7,w_race) 					else 						temp2=translate("unit",6,w_race) 					end 					tCell:tag('span'):cssText("font-size:80%"):wikitext(temp2)	 				end 			end  			if s.header_2[4] == 5 then -- for table teamtimetrialclassification, adds time gap 				if l > 1 then temp= plus else temp='' end 				tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp..calculateTime(h.value[3]))	 			end  			if s.header_2[5] == 6 then -- for table teamtimetrialclassification, adds speed 				tCell=tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em") 				if type(h.value[4]) == "number" then  					tCell:wikitext(mw.ustring.format('%.3f', h.value[4])) 					:tag('span'):cssText("font-size:80%"):wikitext(translate("unit",5,w_race)) 				end 			end 			 			if rank~='' and rank<=max_rank_displayed then --else no display 				if riderDNF=='' then 					t_Body[#t_Body + 1] = {(type(rank) == 'number') and rank or 999, tostring(tBody)} 				else --disqualified should be higher than not disqualified if the ranking was revided 					t_Body[#t_Body + 1] = {(type(rank) == 'number') and rank-0.1 or 999, tostring(tBody)} 				end 			end 		end 	end 	     tableBody=sortAndConcat(t_Body, tableBody) 	local tableFooter1,tableFooter2 	if s.display_ref == 1 or wiki == "ar" then 		tableFooter1=mw.html.create('tr') 		tCell=tableFooter1:tag('td') 		:addClass('navigation-only') 		:cssText('border-top: 2px '..backgroundColor..' solid; font-size: 80%;') 		tableFooter2=mw.html.create('tr') 		tCell=tableFooter2:tag('td') 		:cssText("text-align:right") 		tCell:tag('small') 		:wikitext(race_reference(raceID,lf)) 	end 	 	--general table style and last line 	local tableStyle, tableNewline 	if get_arg('newline',frame) == 'false' then -- parameter newline in WP article is 'false' 		tableStyle = "float:" .. floattable .. "; margin-right:0.5em; border:1px solid rgb(200,200,200)" 		tableNewline = '' 	end 	if get_arg('newline',frame) == 'true' then -- parameter newline in WP article is 'true' 		tableStyle = "border:1px solid rgb(200,200,200)" 		tableNewline = '<br style="clear:left;">' 	end 	if get_arg('newline',frame) == nil then -- no second parameter, compatible to the old code 		if s.property == 'P2417' then --stageclassification 			tableStyle = "float:"..floattable.."; margin-right:0.5em; border:1px solid rgb(200,200,200)" 			tableNewline = '' 		else 			tableStyle = "border:1px solid rgb(200,200,200)" 			tableNewline = '<br style="clear:left;">' -- everything else 		end 	end  	local finalTable= mw.html.create('table'):cssText(tableStyle) 	finalTable:tag('tr'):tag('td') 	:node(tableBody) 	if tableFooter1 then 		finalTable:node(tableFooter1) 		finalTable:node(tableFooter2) 	end  	return tostring(finalTable)..tableNewline end  --=== G) Infobox === function p.infobox(frame) 	return infobox_main(frame,0) end  function p.infoboxseason(frame) 	return infobox_main(frame,1) end  function p.infoboxChamp(frame) 	return infobox_main(frame,2) end  function infobox_main(frame, selector) 	local WDlink_on = (wiki == "mk" or wiki == "ja")  	-- If true, winners will the team of the cyclist 	local team = true 	local details, others, winners, plural 	 	local entityID, lf = get_and_checkID(frame) 	local w_race=isWomenrace(entityID) 	 	if selector==0 then --normal infobox 		details = { 			{ name = translate("infobox",2,w_race)}, -- course 			{ name = translate("infobox",3,w_race), name_plural = translate("infobox",4,w_race)}, -- competition 			{ name = translate("infobox",5,w_race)}, -- stages 			{ name = translate("infobox",6,w_race), name_plural = translate("infobox",7,w_race)}, -- date 			{ name = translate("infobox",8,w_race)}, -- distance 			{ name = translate("infobox",9,w_race), name_plural = translate("infobox",10,w_race)}, -- country 			{ name = translate("infobox",11,w_race)}, -- start place 			{ name = translate("infobox",12,w_race)}, -- endplace 			{ name = translate("infobox",13,w_race)}, -- teams 			{ name = translate("infobox",14,w_race)}, -- participants at start 			{ name = translate("infobox",15,w_race)}, -- participants at end 			{ name = translate("infobox",16,w_race)}, -- speed 			{ name = translate("infobox",43,w_race)}, -- elevation 			{ name = translate("infobox",17,w_race)}, -- cost 			{ name = translate("infobox",32,w_race), special = true}, -- special 1 			{ name = translate("infobox",33,w_race), special = true}, -- special 2 		} 	elseif selector==1 then  --season infobox 		details = { 			{ name = translate("infobox",46,w_race)}, -- edition (1) 			{ name = translate("infobox",3,w_race), name_plural = translate("infobox",4,w_race)}, -- competition (2) 			{ name = translate("infobox",6,w_race), name_plural = translate("infobox",7,w_race)}, -- date (3) 			{ name = translate("infobox",45,w_race)}, -- rasing (4)		 			{ name = translate("infobox",47,w_race), name_plural = translate("infobox",48,w_race)}, -- location (country) (5) 			{ name = translate("infobox",49,w_race), name_plural = translate("infobox",50,w_race)}, -- organizer (6) 			{ name = translate("infobox",63,w_race), name_plural = translate("infobox",63,w_race)}, -- team class (7)	 			{ name = translate("infobox",32,w_race), special = true}, -- special 1 			{ name = translate("infobox",33,w_race), special = true}, -- special 2 		} 	else  --champ 		 details = { 			{ name = translate("infobox",46,w_race)}, -- edition (1) 			{ name = translate("infobox",6,w_race), name_plural = translate("infobox",7,w_race)}, -- date (2) 			{ name = translate("infobox",9,w_race), name_plural = translate("infobox",10,w_race)}, -- country (3)	 			{ name = translate("infobox",67,w_race), name_plural = translate("infobox",68,w_race)}, -- location (city) (4) 			{ name = translate("infobox",61,w_race), name_plural = translate("infobox",62,w_race)}, -- arena / stadion (5) 			{ name = translate("infobox",60,w_race)}, -- medals (6) 			{ name = translate("infobox",13,w_race)}, -- team (7)			 			{ name = translate("infobox",49,w_race), name_plural = translate("infobox",50,w_race)}, -- organizer (8) 			{ name = translate("infobox",32,w_race), special = true}, -- special 1 			{ name = translate("infobox",33,w_race), special = true}, -- special 2 		} 	end 	others = get_others_dic()  	if selector==0 then 		 winners = { 			{ name = translate("infobox",19,w_race), QID = 'Q20882667' }, -- first 			{ name = translate("infobox",20,w_race), QID = 'Q20882668' }, -- second 			{ name = translate("infobox",21,w_race), QID = 'Q20882669' }, -- third 			{ name = translate("infobox",22,w_race), QID = 'Q20883007' }, -- points 			{ name = translate("infobox",23,w_race), QID = 'Q20883212' }, -- mountains 			{ name = translate("infobox",24,w_race), QID = 'Q20883328' }, -- sprints 			{ name = translate("infobox",25,w_race), QID = 'Q20883139' }, -- youth 			{ name = translate("infobox",26,w_race), QID = 'Q101246973' }, -- supercombativity			 			{ name = translate("infobox",26,w_race), QID = 'Q20893983' }, -- combativity 			{ name = translate("infobox",35,w_race), QID = 'Q27067359' }, -- volantes 			{ name = translate("infobox",36,w_race), QID = 'Q27067170' }, -- regularity 			{ name = translate("infobox",27,w_race), QID = 'Q20893979' }, -- combination 			{ name = translate("infobox",38,w_race), QID = 'Q27907715' }, -- breakaway 			{ name = translate("infobox",39,w_race), QID = 'Q27907747' }, -- azzurri 			{ name = translate("infobox",40,w_race), QID = 'Q28092831' }, -- rookie 			{ name = translate("infobox",28,w_race), QID = 'Q20882921' }, -- teams 			{ name = translate("infobox",37,w_race), QID = 'Q27104269' }, -- teamspoints 			{ name = translate("infobox",41,w_race), QID ='Q61976850' },-- amateur 			{ name = translate("infobox",42,w_race), QID ='Q61976872' } --nationality 		} 	elseif selector==1 then 		 winners = { 			{ name = translate("infobox",52,w_race), QID = 'Q20882667' }, -- individual (first) 			{ name = translate("infobox",53,w_race), QID = 'Q20883139' }, -- youth 			{ name = translate("infobox",54,w_race), QID = 'Q27104269' }, -- team (teamspoints) 			{ name = translate("infobox",55,w_race), QID = 'Q98959152' }, -- team GS-I 			{ name = translate("infobox",56,w_race), QID = 'Q98959153' }, -- team GS-II 			{ name = translate("infobox",57,w_race), QID = 'Q98959155' }, -- team GS-III 			{ name = translate("infobox",58,w_race), QID = 'Q72068715' }, -- country 			{ name = translate("infobox",59,w_race), QID = 'Q72068724' }  -- country U23 		} 	end --Champ has no winners      	getLocalContent(details, lf.args) 	getLocalContent(others, lf.args) 	 	if selector==0 or selector==1 then 		getLocalContent(winners, lf.args) 	end  	local timeOfRace, class 	local icon = (firstValue(entityID, 'P641','id') == "Q3609") and -- P641 is 'sport', Q3609 is 'road bicycle racing' 		' [[File:Cycling (road) pictogram.svg|35px]]' or ''  	local name =  getLabelFallback(entityID) or '' 	infoGetOthers(others, entityID)	  	if not details[1].content then -- course 		-- For FR Wiki and Wikidata, exception that permit to display 1er, 2e... for the edition number ; 		-- for RU  -й is written after the value of P393 		local nr = firstValue(entityID, 'P393') -- P393 is 'edition number' 		if nr then 			if wiki == 'fr' then nr = (nr == 1) and "1<sup>re</sup> " or (nr .. "<sup>e</sup> ") 			elseif wiki == "nl" then nr = nr .. "e " 			elseif wiki == "ru" then nr = nr .. "-й " 			elseif wiki == "eo" then nr = nr .. "-a " 			elseif wiki == "hu" then nr = nr .. ". " 			else nr = nr .. ". " 			end 		end 		local is_a  		local classID = firstValue(entityID, 'P279', 'id') 		--fallback 		if classID then  			class = classLinkFn(classID) 		else 			for _, p31 in statements(entityID, 'P31') do -- P31 is 'instance of' 				local instanceOf = p31.mainsnak.datavalue.value.id 				if instanceOf ~= "Q27020041" and data.class_dic[instanceOf] then 					class = classLinkFn(instanceOf) 					break 				end 			end 		end 		 		local season = firstValue(entityID, 'P3450', 'id') -- P3450 is 'sports season of league or competition' 		if season then 			is_a = raceLink(season) 		else 			--normally there should be only a p31 			for _, p31 in statements(entityID, 'P31') do -- P31 is 'instance of' 				local instanceOf = p31.mainsnak.datavalue.value.id 				if instanceOf ~= 'Q27968055' and instanceOf ~= 'Q27020041' then -- Q27020041 is 'sports season' 					is_a = raceLink(instanceOf) 					break 				end 			end 		end  		if nr and is_a then 			details[1].content = nr .. ' ' .. is_a 		end 	end  	if selector==0 or selector==1 then 		if not details[2].content then -- competition 			-- Class of a cycling race. Class is: 1.UWT, 2.UWT, 1.HC, ... add new classes, no problem 			-- Competition of the cycling race : UCI World Tour 2016, UCI Europe Tour 2016... 			local tours = {} 			for _, p361 in statements(entityID, 'P361') do -- P361 is 'part of' 				tours[#tours + 1] = raceLink(p361.mainsnak.datavalue.value.id) 			end 			if tours[1] then 				if #tours > 1 then 					details[2].name = details[2].name_plural 				end 				if class then 					tours[1] = tours[1] .. ' ' .. class 				end 				details[2].content = table.concat(tours, '<br/>') 			end 		end 	end 	 	if selector==0 then 		if not details[3].content then -- stages 			local stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part' 			if stages > 0 then 				details[3].content = stages 			end 		end 	end  	local index_date 	if selector==0 then 		index_date=4 	elseif selector==1 then 		index_date=3 	else  		index_date=2 	end  	if selector==0 or selector==1 then 		if not details[index_date].content then -- date 			details[index_date].content, timeOfRace, plural = get_formatted_date(entityID, 'infobox') 			if plural then 				details[index_date].name = details[index_date].name_plural 			end 		end 	end 	 	--from this point the functions differ fundamentally 	if selector==0 then 		local kmdistance 		if not details[5].content then details[5].content, kmdistance = getDistance(entityID, true) end -- distance 	 		infoGetCountry(details,6, entityID, timeOfRace) 		infoGetStartEnd(details,7, entityID, timeOfRace) 	 		if not details[9].content then -- teams 			local teams = #wikibase.getBestStatements(entityID, 'P1923') -- P1923 is 'participating teams' 			if teams > 0 then 				details[9].content = teams 			end 		end 	 		infoGetParticipants(details,10, entityID) 		if not details[10].content or not details[11].content then 			local Allp710= wikibase.getAllStatements(entityID, 'P710') 			if Allp710 and #Allp710~=0 then 				if not details[10].content then details[10].content=#Allp710 end 				if not details[11].content then 					local maxrank=1 					for _, p710 in pairs(Allp710) do -- look into all statements 						local q = p710.qualifiers 						if q and q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is ranking 							local riderRank = tonumber(q.P1352[1].datavalue.value.amount) 							if riderRank > maxrank then maxrank = riderRank end 						end 					end 					if maxrank~=1 then details[11].content=maxrank end 				end 			end 		end 	 		if not details[12].content then details[12].content = getSpeed(entityID, true, kmdistance, 'P2321') end --speed 		if not details[13].content then  			local elevation=getElevation(entityID)  			if  elevation then details[13].content =elevation else details[13].content = nil end 		end --Elevation 		 		if not details[14].content then -- cost 			local cost = firstValue(entityID, 'P2130') -- P2130 is cost 			if cost then 				details[14].content = dispmoney(cost.amount, cost.unit) 			end 		end  	elseif selector==1 then 		if not details[4].content then -- racing 			local stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part' 			if stages > 0 then 				details[4].content = stages 			end 		end 		if not details[5].content then -- location 			infoGetPlace(details,5, entityID, timeOfRace) --in GAN version, the separator is , not <br /> 		end 		if not details[6].content then -- organizer sitelink 			listWPlink(details, 6, entityID,'P644',true) --org 		end 		if not details[7].content then -- organizer sitelink 			listWPlink(details, 7, entityID,'P2670',true) --team ???? 		end 	else --champ 		infoGetCountry(details,3, entityID, timeOfRace) 		if not details[4].content then -- location 			infoGetPlace(details,4, entityID, timeOfRace) --in GAN version, the separator is , not <br /> 		end 		if not details[5].content then -- arena / stadion 			listWPlink(details, 5, entityID,'P115',true)  		end	 		if not details[6].content then -- racing 			local stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part' 			if stages > 0 then 				details[6].content = stages 			end 		end 		if not details[7].content then -- teams 			local teams = #wikibase.getBestStatements(entityID, 'P1923') -- P1923 is 'participating teams' 			if teams > 0 then 				details[7].content = teams 			end 		end 		if not details[8].content then -- organizer sitelink 			listWPlink(details, 8, entityID,'P644',true) --org 		end 	end  	tab = infoInitTab("300px", name, icon) 	infoFillOthersDetails(tab, others, details,translate("infobox",1,w_race)) 	 	if selector==0 or selector==1 then --no winners for champ 		local winRows='' 		local win = {} 		for _, v in pairs(winners) do 			if not v.content then 				win[v.QID] = '' 			end 		end 		winner(lf,entityID, win, timeOfRace, false, WDlink_on, team, true) 		for _, v in pairs(winners) do 			if not v.content then 				if win[v.QID] ~= '' then 					v.content = win[v.QID] 				end 			end 			if v.content then 				tRow= mw.html.create('tr') :css('vertical-align','top') 				tRow:tag('td'):css('font-weight','bold'):wikitext(v.name) 				tRow:tag('td'):wikitext(v.content) 				winRows=winRows..tostring(tRow) --not elegant 			end 		end 		if winRows~= '' then 			tab:tag('tr'):tag('td'):attr('colspan','2') 			:cssText('border-bottom:5px solid white; background-color:'..backgroundColor..'; text-align:center') 			:css('font-weight','bold') 			:wikitext(translate("infobox",18,w_race)) 			tab:wikitext(winRows) 		end 	end  	if others[3].content then -- map 		tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center') 		:wikitext("[[File:".. others[3].content .. "|center|300px]]") 		if others[5].content then -- caption 			tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%') 			:wikitext(others[5].content) 		end 	end 	 	tab:node(getPreviousNextLine(entityID)) 	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/infobox", translate("infobox",34,w_race), entityID) 	return tab end  --=== H) race infobox function p.raceinfobox(frame) 	local lang = contentLanguage 	local WDlink_on = (wiki == "mk" or wiki == "ja") 	 	local tRace = {race={ 			raceId, 			raceDate, 			future, 			},  		  vainqueur= {}, 		  }  	local entityID, lf = get_and_checkID(frame) 	local w_race= isWomenrace(entityID) 	 	local details = { 		{ name = translate("raceinfobox",4,w_race)}, -- sport 		{ name = translate("raceinfobox",5,w_race)}, -- creation date 		{ name = translate("raceinfobox",6,w_race)}, -- disparition date 		{ name = translate("raceinfobox",7,w_race)}, -- number of editions 		{ name = translate("raceinfobox",8,w_race)}, -- periodicity 		{ name = translate("raceinfobox",9,w_race)}, -- type , name_plural = translate("infobox",10) 		{ name = translate("raceinfobox",33,w_race), name_plural = translate("raceinfobox",34,w_race)},													--country 		{ name = translate("raceinfobox",10,w_race), name_plural = translate("raceinfobox",11,w_race)}, -- place 		{ name = translate("raceinfobox",12,w_race), name_plural = translate("raceinfobox",13,w_race)}, --org 		{ name = translate("raceinfobox",27,w_race), name_plural = translate("raceinfobox",28,w_race)}, --race director 		{ name = translate("raceinfobox",15,w_race), name_plural = translate("raceinfobox",16,w_race)}, -- Cat 		{ name = translate("raceinfobox",17,w_race)}, -- circuit 		{ name = translate("raceinfobox",14,w_race)}, -- official web site 	} 	local others = get_others_dic()  	local name =  getLabelFallback(entityID) or '' 	infoGetOthers(others, entityID)	 	getLocalContent(details, lf.args) 	getLocalContent(others, lf.args) 	 	local timeOfRace, class      local listOfNames=getFormerNames(entityID, 'P1448') 	 	local sport_id=firstValue(entityID, 'P641', 'id') 	local icon = (sport_id == "Q3609") and -- P641 is 'sport', Q3609 is 'road bicycle racing' 		' [[File:Cycling (road) pictogram.svg|35px]]' or ''  	--1st ist sport 	if not details[1].content and sport_id then 		details[1].content = WPlinkpure(sport_id) 	end 	 	--creation 	local creation=firstValue(entityID, 'P571', 'time') 	if not details[2].content and creation then 		details[2].content = funcDate(creation, "onlyyear" ) 	end  	--disparition 	local disparition=firstValue(entityID, 'P576', 'time') 	if not details[3].content and disparition then 		details[3].content =  funcDate(disparition,"onlyyear") 	end 	 	--populate tRace 	listOfWinners(entityID, tRace,nil,lf) 	 	--number of editions 	if not details[4].content and tRace.numberOfEditions and tRace.lastEditionYear then 		details[4].content = tostring(tRace.numberOfEditions).." (" .. translate("raceinfobox",31,w_race) .. " "..tostring(tRace.lastEditionYear)..")" 	end 	--periodicity 	if not details[5].content then 		details[5].content = getPeriodicity(entityID, tRace) 	end 	--type 	if not details[6].content then 		details[6].content = getType(entityID) 	end 	timeOfRace=nil --could be from last edition 	if not details[7].content then 		infoGetCountry(details,7, entityID, timeOfRace) 	end 	if not details[8].content then 		infoGetPlace(details,8, entityID, timeOfRace) 	end 	 	if not details[9].content then 		listWPlinkChrono(details, 9, entityID, {'P664'}, true, initialYear) --organiser 	end 	 	if not details[10].content then 		listWPlinkChrono(details, 10, entityID, {'P488'}, 'rider', initialYear)	 --race dir 	end 	 	--Class and circuit	 	 	local classContent, circuitLink, numberClass= getClass(entityID) 	if not details[11].content then 		details[11].content = classContent 		if numberClass >1 then 	 		details[11].name = details[11].name_plural 		end  	end  	  	if not details[12].content then 		details[12].content = circuitLink  	end  	--Official web site 	if not details[13].content then 		details[13].content = officialSite(entityID) 	end 	--Build the table 	tab = infoInitTab("300px", name, icon) 	--former names 	wiki_listOfNamesAtBottom={'ru'} 	 	local listOfNamesAtBottom = false 	for _, value in pairs(wiki_listOfNamesAtBottom) do --  		if value == wiki then listOfNamesAtBottom = true end 	end 	--picture at the top 	infoFillOthersDetails(tab, others, nil,translate("raceinfobox",19,w_race),"260px") 	if not listOfNamesAtBottom then 		if listOfNames and #listOfNames>1 then 			tab:node(addATitle(translate("raceinfobox",18,w_race)))   			for _, v in pairs(listOfNames) do 				tab:node(addARow(v[2],v[3])) --period, name 			end 		end 	end      	infoFillOthersDetails(tab, nil, details,translate("raceinfobox",19,w_race),"260px")  	if listOfNamesAtBottom then 		if listOfNames and #listOfNames>0 then -- except for the ru-wiki, no one uses the display of official names at the bottom anyway  			tab:node(addATitle(translate("raceinfobox",18,w_race)))   			for _, v in pairs(listOfNames) do 				tab:node(addARow(v[2],v[3])) --period, name 			end 		end 	end  	if (tRace.lastWinner and tRace.lastWinner~='') or  	(tRace.maxWinner and tRace.maxWinner~='') then 		tab:node(addATitle(translate("raceinfobox",20,w_race))) 		if (tRace.lastWinner and tRace.lastWinner~='') then 			tab:node(addARow(translate("raceinfobox",21,w_race),tRace.lastWinner)) 		end 		if (tRace.maxWinner and tRace.maxWinner~='') then 			tab:node(addARow(translate("raceinfobox",22,w_race),tRace.maxWinner)) 		end 	end  	if tRace.nextLink or tRace.lastLink then 		tab:node(addATitle(translate("raceinfobox",23,w_race))) 		local outTable   		if tRace.lastLink then 		    outTable = mw.html.create('tr') 			local tCell=outTable:tag('td'):attr('colspan','2'):css('text-align','center') 			local lastText="[[File:Crystal Clear app kworldclock.png|left|37px]]".. 			translate("raceinfobox",24,w_race).. 			":<br>'''".. 			tRace.lastLink.."'''" 			tCell:wikitext(lastText) 			tab:node(outTable) 		end	 		 		if tRace.nextLink then 			outTable = mw.html.create('tr') 			local tCell=outTable:tag('td'):attr('colspan','2'):css('text-align','center') 		    local nextText = "[[File:Crystal Clear app kworldclock.png|left|37px]]".. 		    translate("raceinfobox",25,w_race).. 		    ":<br>'''".. 		    tRace.nextLink.."'''" 			tCell:cssText("text-align:center"):wikitext(nextText) 			tab:node(outTable) 		end 	end 	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/raceinfobox", translate("raceinfobox",26,w_race), entityID) 	return tab end  --=== I) Team roster function p.lastteamroster(frame) 	local teamID, lf = get_and_checkID(frame) 	 	local tRace = {race={ 		raceId, 		raceDate, 		future, 		},  	  vainqueur= {}, 	} 	 	listOfWinners(teamID, tRace,true,lf,"P527") 	 	if get_arg(2,frame) ~= nil then 		if mw.ustring.find(mw.ustring.lower(get_arg(2,frame)), "sort") or wiki == "lv" or wiki == "mk" or wiki == "ru" then  			sort = true  		else  			sort = false  		end 	end	  	local s = { 		sort=sort, 		seasonID=tRace.lastID, 		lf=lf, 		year=tRace.lastEditionYear 	}	  	if tRace.lastID then 		return teamroster_main(s) 	end end  function p.teamroster(frame) 	local seasonID, lf = get_and_checkID(frame) 	local sort 	--[[ 	The word 'sort' is used to sort the riders after the surname. It could look like this in the Wikipedia article 	{{Cycling race/teamroster|Q21769847 	| sort 	}} 	A rider called 'Laurens De Vreese' is sorted after 'De Vreese Laurens'. If you want to sort after 'Vreese Laurens De' 	change that in the code. In lv mkWiki and ruWiki sorting is standard, there is no need to switch sorting on in the article 	]] 	if get_arg(2,frame) ~= nil then 		if mw.ustring.find(mw.ustring.lower(get_arg(2,frame)), "sort") or wiki == "lv" or wiki == "mk" or wiki == "ru" then  			sort = true  		else  			sort = false  		end 	end	 	 	local s = { 		sort=sort, 		seasonID=seasonID, 		lf=lf 	} 	 	return teamroster_main(s) end  function teamroster_main(s) 	local flags, pays = {}, {} 	local riderName, riderBirthday,riderTeam, timeTeam, correctlanguage,riderStart, riderEnd 	local riderPosition, riderReason, riderRef, errortext 	local riderReasonTable, riderTablecorrect, riderTablenotcorrect, riderTable = {}, {}, {}, {} 	local labelMissing = false 	local teamID, stagiaire  	local slavicWikis = {mk = true, ru = true} 	local wikiIsSlavic = slavicWikis[wiki] 	local WDlink_on = wiki == "mk" or wiki == "ja" or wiki == "ru" or wiki == "he" 	local tableEndText = ''  	local w_race=isWomenrace(s.seasonID) 	local temp = firstValue(s.seasonID, 'P361', 'id') 	if temp then teamID = temp end  	local startOfSeason = getTimeOfRace(s.seasonID, true) 	 	if not s.year then	 		label=getLabelFallback(s.seasonID) 		local second_occurrence 		local first_occurrence=string.find(label, "%d%d%d%d") 		if first_occurrence~=nil then 			second_occurrence=string.find(label, "%d%d%d%d",first_occurrence+1) 			if second_occurrence~=nil then 				s.year=string.match(label, "%d%d%d%d",first_occurrence+1) --case Tartu2024 			else 				s.year=string.match(label, "%d%d%d%d") 			end 		end 	end  	for _, p527 in statements(s.seasonID, 'P527') do 		--re-init 		riderName, riderBirthday, correctlanguage=nil, nil, nil 		riderTeam, timeTeam, riderReason, riderRef=nil, nil, nil, nil 		riderStart, riderEnd=nil, nil  		local riderID = p527.mainsnak.datavalue.value.id 		riderName, correctlanguage =getRiderLink(riderID, startOfSeason) --label 		if WDlink_on==true then riderName=riderName..wdLink(riderID) end 		local timeOfRace = startOfSeason 		_, startOfSeasonYear, startOfSeasonMonth, startOfSeasonDay, _=parseDate(startOfSeason, '2040', '12', '31', '','')  		riderBirthday=firstValue(riderID, 'P569','time')  		if not wikiIsSlavic then correctlanguage=true end  --actually we never take a cyrillic name if no latin is found 		local sortkey = findSortKey(riderID, correctlanguage,  wikiIsSlavic)  		for _, q in qualifiers(p527, 'P580') do 			local startdate = q.value['time'] 			timeOfRace = startdate 			riderStart = funcDate(trans(startdate,'01', '01') or '', 'small') 		end 		for _, q in qualifiers(p527, 'P582') do 			local enddate=q.value['time'] 			riderEnd = funcDate(trans(enddate,'12', '31') or '', 'small') 		end 		riderPosition=getPosition(riderPosition,p527) 		riderReason, riderRef=getReason(riderReason,riderRef,p527, timeOfRace,enddate,s.lf)  		local beginYear, beginMonth, beginDay, endYear, endMonth, endDay, beginDate, endDate, endDatefound, endDatetemp 		local changedTime = '+0000-00-00'  		if teamID == nil then 			local p54 = getStatementForTime(riderID, 'P54', timeOfRace) 			if p54 then teamID = p54.mainsnak.datavalue.value.id end 		else 			for _, v in statements(riderID, 'P54') do -- look into all P54 teams 				stagiaire=nil  				errortext='' 				local thisteamID = v.mainsnak.datavalue.value.id 				if thisteamID == teamID then 					endDatefound=true 					beginDate, endDate = getStartEndfromQuali(v.qualifiers) 					beginDate, beginYear, beginMonth, beginDay, errortext = parseDate(beginDate, '2040', '01', '01', errortext, ' missing qualifiers by rider')  					if not endDate then endDatefound=false end 					endDate, endYear, endMonth, endDay, _ = parseDate(endDate, beginYear, '12', '31', errortext,'') 					riderReason, riderRef=getReason(riderReason,riderRef,v,timeOfRace,endDate,s.lf)  					if (beginYear == startOfSeasonYear or endYear == startOfSeasonYear) and ((beginYear == startOfSeasonYear and (beginMonth ~= '01' or beginDay ~= '01')) or (endYear == startOfSeasonYear and (endMonth ~= '12' or endDay ~= '31'))) then 						-- riders who start after 1 January or end earlier then 31 December in the season 						riderStart = funcDate(beginDate, 'small') 						if endDatefound then  							riderEnd = funcDate(endDate, 'small') 						else 							riderEnd = funcDate('+'..beginYear..'-12-31T00:00:00Z', 'small') 						end 						riderPosition=getPosition(riderPosition,v) 					end 				else 					for _, q in qualifiers(v, 'P39') do 						stagiaire =q.value.id 					end 					if not stagiaire then 						endDatefound=true 						beginDate, endDatetemp=getStartEndfromQuali(v.qualifiers) 						if not endDatetemp then endDatefound=false end 						beginDate, beginYear, beginMonth, beginDay, errortext = parseDate(beginDate, '2040', '01', '01', errortext, ' missing qualifiers by rider') 					    endDate, endYear, endMonth, endDay, _ = parseDate(endDatetemp, beginYear, '12', '31', errortext, '')  						if beginYear < startOfSeasonYear or (beginYear == startOfSeasonYear and beginMonth < startOfSeasonMonth) or  						(beginYear == startOfSeasonYear and beginMonth == startOfSeasonMonth and beginDay < startOfSeasonDay) then -- start time < season time 							if endDatefound then 								if (endDate or '') >= changedTime then -- find maximum end time 									-- Case Pierre-Roger Latour: Chambéry CF (2012 - 2014), time season at 2013 									-- Task: changedTime should be after start time, but before startOfSeason 									if endYear > startOfSeasonYear then  										changedTime = '+'..startOfSeasonYear..'-12-31T00:00:00Z'  									else  										changedTime = endDate or '' 									end 								end 							end 						end 						if changedTime ~= '+0000-00-00' then 							riderTeam = getTeam(riderID, changedTime, nil) 							local _, _, endYear, _, _ = string.find(changedTime, "(%d+)-(%d+)-(%d+)") 							timeTeam = ' ('..endYear..')' 							if wiki == "ar" then timeTeam = endYear end 						end 					end 				end 			end 		end 		--get the country 		local countryID = getNationality(riderID, timeOfRace,q) 		if countryID then 			pays = getCountryName(countryID) 			flags = flag(countryID, timeOfRace) 		end 		--save 		local tRider={ 				sortkey=sortkey,  				riderName=riderName,  				riderBirthday=riderBirthday,  				riderTeam=riderTeam,  				timeTeam=timeTeam, 				riderStart=riderStart,  				riderEnd=riderEnd,  				riderPosition=riderPosition,  				riderReason=riderReason,  				riderRef=riderRef,  				errortext=errortext,  				pays=pays, 				flags=flags 				} 		 		if correctlanguage == true then 			table.insert(riderTablecorrect,tRider ) 		else 			table.insert(riderTablenotcorrect, tRider) 		end 	end  	-- sorting names --	if sort == true and #riderTablecorrect~=0 and #riderTablenotcorrect~=0 then -- It was 	if s.sort == true and #riderTablecorrect==0 and #riderTablenotcorrect==0 then -- replaced with this to display the team roster in the ru-wiki 		table.sort(riderTablecorrect, function(a,b) return a[1]<b[1] end) 		table.sort(riderTablenotcorrect, function(a,b) return a[1]<b[1] end) 	end 	--merge 	for _, v in pairs (riderTablecorrect) do 		table.insert(riderTable, v) 	end 	for _, v in pairs (riderTablenotcorrect) do 		table.insert(riderTable, v) 	end 	local wd_link = mw.html.create('span'):css('float','left'):wikitext(wdLink(s.seasonID..'#P527')) 	if arwiki_totemplate then wd_link = wdLink(s.seasonID .. '#P527') end 	local outTable = mw.html.create('table') 	                        :addClass('sortable') 	                        :attr('cellpadding', '2') 	                        :attr('cellspacing', '0') 	                        :css('border' , '1px solid rgb(200,200,200)') 	                        :css('padding', '3px') 	local th_colspan = 4 	if wiki == "ar" then th_colspan = 5 end 	local tRow=outTable:tag('tr'):css('line-height','1.8em') 	    :css('background-color',backgroundColor) 	    :tag('th'):attr('colspan', th_colspan):cssText('text-align:center;white-space:nowrap') 		:wikitext(tostring(wd_link)) 	if s.year then	 	    tRow:wikitext(translate("getSquadTableColumn",7,w_race).." "..s.year) 	else 		tRow:wikitext(translate("getSquadTableColumn",7,w_race)) 	end 	local header = outTable:tag('tr') 	header:tag('th'):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",1,w_race)) 	local textalign = 'center' 	if wiki=='ar' then textalign = 'right' end 	header:tag('th'):cssText('text-align:'..textalign..';padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",2,w_race)) 	if l10n["country_name_list"] and wiki ~= 'lv' then 	    header:tag('th'):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",6,w_race)) 	end 	if wiki == "ar" then 		header:tag('th'):attr('colspan', 2):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",3,w_race)) 	else 		header:tag('th'):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",3,w_race)) 	end 	local temp 	local iii = 1 	for i, v in pairs (riderTable) do 		local tRow=outTable:tag('tr'):css('line-height','1.8em') 		local tCell= tRow:tag('td'):cssText("padding:0 1em 0 0;white-space:nowrap")  		if not l10n["country_name_list"] or wiki == 'lv' or wiki == 'ar' then temp=v['flags']..' ' else temp='' end 		tCell:wikitext(temp..v['riderName']):attr('data-sort-value',v['sortkey'])  		if v['riderStart']~=nil or v['riderEnd']~=nil then 			tCell:tag('span'):cssText("font-size:80%; color:#686868") 			local note='' 			if v['riderReason'] ~= nil then 				note = ', [[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]' 				if wiki == "ar" then note = '، [[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]' end 			end 			tCell:wikitext(' ('..(v['riderStart'] or '')..'–'..(v['riderEnd'] or '') 				.. (v['riderPosition'] or '')..note..')') 		elseif v['riderReason'] then 			tCell:tag('span'):cssText("font-size:80%; color:#686868") 			:wikitext('([[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]'.. ')') 		end 		tCell=tRow:tag('td'):cssText("text-align:right;white-space:nowrap") 		if wiki == 'lv' then 			local _, _, beginYear, beginMonth, beginDay = string.find(startOfSeason,"(%d+)-(%d+)-0*(%d+)") 			local _, _, endYear, endMonth, endDay = string.find(v['riderBirthday'] or '',"(%d+)-(%d+)-0*(%d+)") 			tCell:wikitext(s.lf:expandTemplate{ title = 'Template:Birth date and age2', args = { beginYear, beginMonth, beginDay, endYear, endMonth, endDay } }) 		else 			tCell:wikitext(funcDate(v['riderBirthday'] or '', 'long')) 			if l10n["country_name_list"] and wiki ~= 'ar' then  				tRow:tag('td'):wikitext(v['flags'].. ' '..v['pays']) 			end 		end  		if wiki =='he' then 			local isRtl = (mw.ustring.find(v['riderTeam'], '|.*[א-ת]') or (not mw.ustring.find(v['riderTeam'], '|') and mw.ustring.find(riderTeam, '[א-ת]'))) 			if isRtl then 				tCell=tRow:tag('td'):cssText("padding:0 0.5em; text-align:right") 			else 				labelMissing = true -- FIXME: labelMissing is not functional in most languages. once we have infra support for it, move it there 				tCell=tRow:tag('td'):cssText("padding:0 0.5em; text-align:left") 			end 		elseif wiki == "ar" then             tCell=tRow:tag('td'):cssText("padding:0 0.5em")         else  		    tCell=tRow:tag('td'):cssText("padding:0 0.5em; text-align:left") 		end 		if v['riderTeam'] then  			if wiki == "ar" then 				tCell:wikitext( v['riderTeam'] ) 				tCell=tRow:tag('td'):cssText("padding:0 0.5em") 				tCell:wikitext( v['timeTeam']..v['errortext'] ) 			else 				tCell:wikitext(v['riderTeam'].. v['timeTeam']..v['errortext']) 			end 		end 		--tableEndText is not a table 		if v['riderReason'] ~= nil or v['errortext'] ~= '' then 			local temp=(v['riderReason'] or '')..(v['errortext'] or '') 			if iii == 1 then 				tableEndText = tableEndText.. translate("getSquadTableColumn",5,w_race)..': '.. v['riderName'].. temp 			else 				tableEndText = tableEndText.. '<span style="color:white">'.. translate("getSquadTableColumn",5,w_race)..': </span>'.. riderName.. temp 			end 			iii = iii + 1 			if riderRef ~= nil then tableEndText = tableEndText.. 				s.lf:extensionTag{name='ref', content=v['riderRef'], args = {name='tr_'..iii..s.seasonID}} end 			tableEndText = tableEndText.. '<br>' 		end 	end 	if labelMissing then outTable:wikitext(getMissingLabelTrackingCategory()) end 	 	local UCIlink 	if wiki=="fr" then 		UCIlink="https://www.uci.org/fr/route/%C3%A9quipe" 	else 		UCIlink="https://www.uci.org/road/teams" 	end 	 	outTable:tag('tr'):tag('td'):addClass("navigation-only") 	:attr('data-sort-value','zz') 	:attr('colspan',th_colspan) 	:cssText("border-top: 2px "..backgroundColor.." solid; font-size: 80%;") 	:tag('tr') 	:tag('td'):attr('colspan',th_colspan) 	:attr('data-sort-value','zzz') 	:cssText("text-align:right") 	:tag('small'):wikitext(translate("race_reference", 1,w_race).."["..UCIlink..' UCI]') 	 	return tostring(outTable)..tableEndText end  --== J) List of winners == function p.listofwinners(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q20882667','Q20882668','Q20882669'}  	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 	}  	return listofwinners_main(s) end  function p.listofwinnersyoung(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q20883139','Q72099969','Q72099972'} 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 		} 	return listofwinners_main(s) end  function p.listofwinnersChamp(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q20882667','Q20882668','Q20882669'} 	local s = { 		countryflag=false, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		winnersProperty=winnersProperty, 		display_team = false, 		custom=false, 		lf=lf 		} 	return listofwinners_main(s) end  --listofwinnerssecondpart and so on can be coded with p.listofwinners function p.listofwinnersnowiki(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q20882667','Q20882668','Q20882669'} 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 	} 	return frame:extensionTag{ name = 'nowiki', content = listofwinners_main(s)} end  function p.listofwinnersteamofpoint(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q27104269','Q72065970','Q72065977'} 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 		} 	return listofwinners_main(s) end  function p.listofwinnersGSI(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q98959152','Q98959192','Q98959196'} 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 		} 	return listofwinners_main(s) end  function p.listofwinnersGSII(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q98959153','Q98959194','Q98959197'} 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 		} 	return listofwinners_main(s) end  function p.listofwinnersGSIII(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q98959155','Q98959195','Q98959198'} 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 		} 	return listofwinners_main(s) end  function p.listofwinnerscountry(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q72068715','Q72068718','Q72068721'} 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team		 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 		} 	return listofwinners_main(s) end  function p.listofwinnerscountryU23(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty = {'Q72068724','Q72068725','Q72068729'} 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team 		winnersProperty=winnersProperty, 		custom=false, 		lf=lf 		} 	return listofwinners_main(s) end  function p.listofwinnerscustom(frame) 	local raceID, lf =get_and_checkID(frame) 	local winnersProperty ={} 	 	if istrue(get_arg('general',frame)) then table.insert( winnersProperty,'Q20882667') end 	if istrue(get_arg('podium',frame)) then  		table.insert( winnersProperty,'Q20882668')  		table.insert( winnersProperty,'Q20882669')  	end 	if istrue(get_arg('points',frame)) then table.insert( winnersProperty, 'Q20883007' ) end 	if istrue(get_arg('mountain',frame)) then table.insert( winnersProperty, 'Q20883212' ) end 	if istrue(get_arg('sprints',frame)) then table.insert( winnersProperty, 'Q20883328' ) end 	if istrue(get_arg('youth',frame)) then table.insert( winnersProperty, 'Q20883139' ) end 	if istrue(get_arg('combativity',frame)) then table.insert( winnersProperty, 'Q101246973' ) table.insert( winnersProperty, 'Q20893983' ) end 	if istrue(get_arg('volante',frame)) then table.insert( winnersProperty, 'Q27067359' ) end 	if istrue(get_arg('regularity',frame)) then table.insert( winnersProperty, 'Q27067170' ) end 	if istrue(get_arg('combination',frame)) then table.insert( winnersProperty, 'Q20893979' ) end 	if istrue(get_arg('breakaway',frame)) then table.insert( winnersProperty, 'Q27907715' ) end 	if istrue(get_arg('azzurri',frame)) then table.insert( winnersProperty, 'Q27907747' ) end 	if istrue(get_arg('rookie',frame)) then table.insert( winnersProperty, 'Q28092831' )	end  	if istrue(get_arg('teams',frame)) then table.insert( winnersProperty, 'Q20882921' )	end 	if istrue(get_arg('teamspoints',frame)) then table.insert( winnersProperty, 'Q27104269' ) end	 	if istrue(get_arg('amateur',frame)) then table.insert( winnersProperty, 'Q61976850' ) end	 	if istrue(get_arg('nationality',frame)) then table.insert( winnersProperty, 'Q61976872' ) end	 	if istrue(get_arg('country',frame)) then table.insert( winnersProperty, 'Q72068715' ) end	 	if istrue(get_arg('countryU23',frame)) then table.insert( winnersProperty, 'Q72068724' ) end 	 	local s = { 		countryflag=true, 		raceID=raceID, 		beginyear=get_arg(2,frame,true),			 		endyear=get_arg(3,frame,true), 		shapka=get_arg(4,frame,true), 		display_team = false, 		winnersProperty=winnersProperty, 		custom=true, 		lf=lf 		} 	return listofwinners_main(s) end  function listofwinners_main(s) 	local lf=s.lf 	local raceID=s.raceID 	local rows = {} 	local WDlink_on = (wiki == "mk") or (wiki == "ja") or (wiki == "ru") 	local WPcontent = { 		row ={}, 		code = {} 	} 	local beginyear=s.beginyear or 0 	local endyear=s.endyear or 0 	local shapka=s.shapka or 0 	local titletable 	 	local w_race=isWomenrace(raceID) 	 	if s.custom then 		titletable={ 		[ 'Q20882667' ]=translate("listofwinners",2, w_race), -- winner 		[ 'Q20882668' ]=translate("listofwinners",3, w_race), -- second		 		[ 'Q20882669' ]=translate("listofwinners",4, w_race), -- third		 		[ 'Q20883007' ]=translate("listofwinners",5, w_race), -- points   		[ 'Q20883212' ]=translate("listofwinners",6, w_race), -- mountains 		[ 'Q20883328' ]=translate("listofwinners",7, w_race), -- sprints 		[ 'Q20883139' ]=translate("listofwinners",8, w_race), -- youth 		[ 'Q101246973' ]=translate("listofwinners",9, w_race), -- supercombativity		 		[ 'Q20893983' ]=translate("listofwinners",9, w_race), -- combativity 		[ 'Q20893979' ]=translate("listofwinners",10, w_race), -- combination 		[ 'Q20882921' ]=translate("listofwinners",11, w_race), -- teams 		[ 'Q27067359' ]=translate("listofwinners",12, w_race), -- volantes 		[ 'Q27067170' ]=translate("listofwinners",13, w_race), -- regularity 		[ 'Q27104269' ]=translate("listofwinners",14, w_race), -- teamspoints 		[ 'Q27907715' ]=translate("listofwinners",15, w_race), -- breakaway 		[ 'Q27907747' ]=translate("listofwinners",16, w_race), -- azzurri 		[ 'Q28092831' ]=translate("listofwinners",17, w_race), -- rookie 		[ 'Q61976850' ]=translate("listofwinners",18, w_race), -- amateur 		[ 'Q61976872' ]=translate("listofwinners",19, w_race), -- nationality 		[ 'Q72068715' ]=translate("listofwinners",23, w_race), -- winner country 		[ 'Q72068724' ]=translate("listofwinners",24, w_race), -- winner countryU23 	} 	else --main 	     titletable={ -- winner: 		[ 'Q20882667' ]=translate("listofwinners",2, w_race), -- winner 		[ 'Q20883007' ]=translate("listofwinners",2, w_race), -- points   		[ 'Q20883212' ]=translate("listofwinners",2, w_race), -- mountains 		[ 'Q20883328' ]=translate("listofwinners",2, w_race), -- sprints 		[ 'Q20883139' ]=translate("listofwinners",2, w_race), -- youth (time or point) 		[ 'Q101246973' ]=translate("listofwinners",2, w_race), -- supercombativity		 		[ 'Q20893983' ]=translate("listofwinners",2, w_race), -- combativity 		[ 'Q20893979' ]=translate("listofwinners",2, w_race), -- combination 		[ 'Q20882921' ]=translate("listofwinners",2, w_race), -- team (time) 		[ 'Q27067359' ]=translate("listofwinners",2, w_race), -- volantes 		[ 'Q27067170' ]=translate("listofwinners",2, w_race), -- regularity 		[ 'Q27104269' ]=translate("listofwinners",2, w_race), -- teampoints 		[ 'Q27907715' ]=translate("listofwinners",2, w_race), -- breakaway 		[ 'Q27907747' ]=translate("listofwinners",2, w_race), -- azzurri 		[ 'Q28092831' ]=translate("listofwinners",2, w_race), -- rookie 		[ 'Q61976850' ]=translate("listofwinners",2, w_race), -- amateur 		[ 'Q61976872' ]=translate("listofwinners",2, w_race), -- nationality 		[ 'Q72068715' ]=translate("listofwinners",2, w_race), -- winner country 		[ 'Q72068724' ]=translate("listofwinners",2, w_race), -- winner countryU23 		[ 'Q98959152' ]=translate("listofwinners",2, w_race), -- winner team GS-I 		[ 'Q98959153' ]=translate("listofwinners",2, w_race), -- winner team GS-II 		[ 'Q98959155' ]=translate("listofwinners",2, w_race), -- winner team GS-III		 -- 2 place: 		[ 'Q20882668' ]=translate("listofwinners",3, w_race), -- second		 		[ 'Q72065970' ]=translate("listofwinners",3, w_race), -- second teampoints 		[ 'Q72099969' ]=translate("listofwinners",3, w_race), -- youth (time or point)		 		[ 'Q72068718' ]=translate("listofwinners",3, w_race), -- second country 		[ 'Q72068725' ]=translate("listofwinners",3, w_race), -- second countryU23 		[ 'Q98959192' ]=translate("listofwinners",3, w_race), -- second team GS-I 		[ 'Q98959194' ]=translate("listofwinners",3, w_race), -- second team GS-II 		[ 'Q98959195' ]=translate("listofwinners",3, w_race), -- second team GS-III		 -- 3 place: 		[ 'Q20882669' ]=translate("listofwinners",4, w_race), -- third	 		[ 'Q72065977' ]=translate("listofwinners",4, w_race), -- third teampoints	 		[ 'Q72099972' ]=translate("listofwinners",4, w_race), -- youth (time or point)		 		[ 'Q72068721' ]=translate("listofwinners",4, w_race), -- third country 		[ 'Q72068729' ]=translate("listofwinners",4, w_race), -- third countryU23 		[ 'Q98959196' ]=translate("listofwinners",4, w_race), -- third team GS-I 		[ 'Q98959197' ]=translate("listofwinners",4, w_race), -- third team GS-II 		[ 'Q98959198' ]=translate("listofwinners",4, w_race), -- third team GS-III		 	} 	end  --[=[ It is possible to give the table listofwinners in the article commands. It could look like this: {{Cycling race/listofwinners|Q18574623 | above row 1: '''[[aaa bbb ccc]]''' xxx }} "above row x" inserts a new row above row x into the table. Content is what is behind the ":". ]=] 	if get_arg(2,lf) then 		for num, _ in pairs(lf.args) do 			if num > 1 and mw.ustring.find(mw.ustring.lower(get_arg(num,lf)), 'row') then 				local _, _, kebeginYear, val = mw.ustring.find(get_arg(num,lf), "([^:]+)%s*:%s*(%C+)") 				local _, _, key01, kebeginYear1, kebeginYear2 = mw.ustring.find(kebeginYear, "(%a+)%s*(%a+)%s*(%d+)") 				kebeginYear2 = tonumber(kebeginYear2) kebeginYear1 = mw.ustring.lower(key01..kebeginYear1) 				if kebeginYear1 == 'aboverow' then WPcontent.row[kebeginYear2] = val WPcontent.code[kebeginYear2] = 0  end --0 is above 				if kebeginYear1 == 'belowrow' then WPcontent.row[kebeginYear2] = val WPcontent.code[kebeginYear2] = 1  end --0 is above	 			end 		end 	end 	 	local firstyeartodisplay=2100 	local parts = mw.wikibase.getAllStatements(raceID, 'P527') -- P527 is 'has part' 	for _, part in ipairs(parts) do 		if part.rank ~= 'deprecated' and part.mainsnak.snaktype == 'value' then 			local partID = part.mainsnak.datavalue.value.id 			local timeOfRace=getTimeOfRace(partID,true,true) --original P585 and P580 inverted here 			local year = timeOfRace and string.sub(timeOfRace, 2, 5) or '?' 			local month = timeOfRace and string.sub(timeOfRace, 7, 8) or '01'	 			if year == "?" then mw.log("no year at " .. partID ) end 			if endyear==0 or (tonumber(year) or 0)<=endyear then 					if (tonumber(year) or 0) >= beginyear then 						local thereisawinner=false 						 						local sitelink = mw.wikibase.getSitelink(partID) 						if sitelink then 							sitelink = '[[' .. sitelink .. '|' .. year .. ']]' 						else 							sitelink = year 						end 						if WDlink_on then 							sitelink = sitelink .. ' ' .. wdLink(partID) 						end 						local winners = {} 						for _, property in ipairs(s.winnersProperty) do winners[property]='' end 						local tCell 						local tCellstr='' 						 		 				local temp=firstValue(partID, 'P1346','id') 						if temp and temp=='Q30108381' then --race cancelled 							local cancelledlabel = getLabelFallback('Q30108381') 							tCell=mw.html.create('td'):attr('colspan','4') 							:cssText('text-align:center; font-style: italic') 							:wikitext(cancelledlabel) 							tCellstr=tostring(tCell) 						else 							winner(lf,partID, winners, timeOfRace, not s.countryflag, WDlink_on,s.display_team,true) 							for _, property in ipairs(s.winnersProperty) do 								tCell=mw.html.create('td'):wikitext(winners[property]) 								if winners[property]~='' then  									thereisawinner=true  									if tonumber(year)<firstyeartodisplay then firstyeartodisplay=tonumber(year) end 								end 								tCellstr= tCellstr..tostring(tCell) 							end 						end 						if firstyeartodisplay<=tonumber(year) then 						    rows[#rows+1]={year..month, sitelink, tCellstr} 						end 					end 				end 			end 		end 	table.sort(rows, function(a, b) return a[1] < b[1] end) -- Sort by year 	 	local clear = "left" 	if wiki == "ar" then clear = "right" end 	 	--do not use hw.html here otherwise the begin and end year won't work 	local table_first = "<table cellpadding='4' cellspacing='0' style='"..standardtablecss.."'>"  	local tTitleRow=mw.html.create('tr') 	:css('text-align','center') 	:css('background-color',backgroundColor) 	local tCell=tTitleRow:tag('th') 	local wd_link = mw.html.create('span'):css('float','left'):wikitext(wdLink(raceID .. "#P527")) 	if arwiki_totemplate then wd_link = wdLink(tostring(raceID) .. "#P527") end 	if WDlink_on == false then 		tCell:wikitext(tostring(wd_link)) 	end 	tCell:wikitext(translate("listofwinners",1,w_race)) --year 	for _, pp in ipairs(s.winnersProperty) do 		tTitleRow:tag('th'):wikitext(titletable[pp]) 	end 	 	local table_center='' 	local nb_year_inrow=1 	local lastyear 	 	for i, row in ipairs(rows) do 		sitelink=row[2]  		local tRowWD=mw.html.create('tr') 		local tCell=tRowWD:tag('td'):css('text-align','left') 		 		if lastyear and mw.ustring.sub(row[1],1,4)==lastyear then 				nb_year_inrow=nb_year_inrow+1 				tCell:wikitext(sitelink..' ('..tostring(nb_year_inrow)..')')  		else 			tCell:wikitext(sitelink) 			nb_year_inrow=1 		end 		lastyear=mw.ustring.sub(row[1],1,4) 		tRowWD:node(row[3]) --add the end of the row 		 		if WPcontent.row[i] then 			tRow=mw.html.create('tr'):tag('td'):attr('colspan','4') 			:css('text-align','center') 			tRow:wikitext(WPcontent.row[i])  			if WPcontent.code[i]==0 then --above 				table_center=table_center..tostring(tRow) 				table_center=table_center..tostring(tRowWD) 			else --below 				table_center=table_center..tostring(tRowWD) 				table_center=table_center..tostring(tRow) 			end 		else 			table_center=table_center..tostring(tRowWD) 		end 	end 	--firstpart with header no foot 	if shapka == 1 then -- standard header 		return table_center .. "</table>"	 	elseif shapka == 2 then	-- you need to add a title and you can add text at the beginning 		return table_center  	else -- you need to add a title and you can add anything and anywhere 		return table_first .. tostring(tTitleRow) .. table_center .. "</table>" 	end end  --== K) List of stages function check_basque_place(sPoint, sPointID) 	local eu=false 	--check if it is a town 	local town=false 	for _, p31 in statements(sPointID, 'P31') do 		if p31.mainsnak.datavalue.value.id == "Q2074737" or p31.mainsnak.datavalue.value.id == "Q484170" then --Spanish and French towns 			town=true 		end 	end 	 	if not town then --if it not a town look for parent 		for _, p131 in statements(sPointID, 'P131') do 			if data.BasqueTown[p131.mainsnak.datavalue.value.id] then 				eu=true 			end 		end 	else 		if data.BasqueTown[sPointID] then 			eu=true 		end 	end 	if eu then 		sPoint = flag("Q47588", timeOfRace).." "..sPoint 	end 	return sPoint, eu end  function p.listofstages(frame) 	local WDlink_on = wiki == "mk" or wiki == "ja" 	local WPcontent = {} 	local raceID, lf = get_and_checkID(frame) 	local thereiselevation=false 	local result, tableBody 	local w_race=isWomenrace(raceID) --[=[ It is possible to give the table listofstages in the article commands which overwrites data from Wikidata. It could look like this: {{Cycling race/listofstages|Q18574623 | RoW 1: locaTION Ab : [[1a1b]] | after row 1 : date : 99 août | after row 1 : icon : [[File:Stage rest day.svg|vbght frthzt fdgtr]] | after row 1: text : rest day at [[aaa bbb ccc]] | row 4:  location A : [[4a4a]]abc | row 3 : winner a : <sup>tzhgt</sup> | row 4 : winner b : kjuzhgt<br />bbjje | row 4 : icon : [[File:Mediummountainstage.svg|xcvbbgf fgtr]] | row 4 : distance : <s>141.8</s> 122<ref>test</ref> }} The first paramer is "row x" or "after row x". "after row" adds a new row after row x into the table to print e.g. a rest day. The second parameters are "location [a/b/ab]", "date", "icon", "text", "winner [a/b]" and "distance". "a" and "b" means the first and the second location or winner. "ab" could be used if start location and end location are the same. The file data for the icon looks this way: [[File:Stage rest day.svg|any text]] ]=] 	if get_arg(2,lf) then 		local WProw, WPnew_row, WPcourse, WPtext, WPdate, WPwinner, WPicon, WPdistance 			= 'row', 'afterrow', 'location', 'text', 'date', 'winner', 'icon', 'distance' 		local _, kebeginYear, key2, val 		local key01, kebeginYear1, kebeginYear2 		local key21, key22 		for num, var in pairs(lf.args) do 			if num > 1 and mw.ustring.find(mw.ustring.lower(var), WProw) then 				_, _, kebeginYear, key2, val = mw.ustring.find(var, "([^:]+)%s*:?%s*([^:]*)%s*:%s*(%C+)") 				_, _, key01, kebeginYear1, kebeginYear2 = mw.ustring.find(kebeginYear, "(%a+)%s*(%a+)%s*(%d+)") 				kebeginYear2 = tonumber(kebeginYear2) 				kebeginYear1 = mw.ustring.lower(key01 .. kebeginYear1) 				key2 = mw.ustring.lower(mw.text.trim(key2)) 				_, _, key21, key22 = mw.ustring.find(key2, "(%a+)%s*(%a*)")  				if not WPcontent[kebeginYear2] then WPcontent[kebeginYear2] = {} end 				if kebeginYear1 == WProw and key21 == WPcourse then WPcontent[kebeginYear2][key22] = val end 				if kebeginYear1 == WPnew_row and key2 == WPdate then 					WPcontent[kebeginYear2]['date'] = val 					WPcontent[kebeginYear2]['text'] = WPcontent[kebeginYear2]['text'] or '' 					WPcontent[kebeginYear2]['icon (new row)'] = WPcontent[kebeginYear2]['icon (new row)'] or '' 				end 				if kebeginYear1 == WPnew_row and key2 == WPtext then 					WPcontent[kebeginYear2]['text'] = val 					WPcontent[kebeginYear2]['date'] = WPcontent[kebeginYear2]['date'] or '' 					WPcontent[kebeginYear2]['icon (new row)'] = WPcontent[kebeginYear2]['icon (new row)'] or '' 				end 				if kebeginYear1 == WPnew_row and key2 == WPicon then 					val = string.gsub(val, "|", "|border|right|20px|", 1) 					WPcontent[kebeginYear2]['icon (new row)'] = val 					WPcontent[kebeginYear2]['date'] = WPcontent[kebeginYear2]['date'] or '' 					WPcontent[kebeginYear2]['text'] = WPcontent[kebeginYear2]['text'] or '' 				end 				if kebeginYear1 == WProw and key21 == WPwinner and key22 == 'a' then WPcontent[kebeginYear2]['stage winner'] = val end 				if kebeginYear1 == WProw and key21 == WPwinner and key22 == 'b' then WPcontent[kebeginYear2]['general winner'] = val end 				if kebeginYear1 == WProw and key21 == WPicon then 					val = string.gsub(val, "|", "|border|right|20px|", 1) 					WPcontent[kebeginYear2]['icon'] = val end 				if kebeginYear1 == WProw and key21 == WPdistance then WPcontent[kebeginYear2]['distance'] = val end 			end 		end 	end 	local countries = wikibase.getAllStatements(raceID, 'P17') 	local onecountry, firstcountryID 	if countries and #countries>1 then 		onecountry=false 		if countries[1] then 			firstcountryID=countries[1].mainsnak.datavalue.value.id 		end 	else 		onecountry=true 	end  	local rows = {} 	local stages = mw.wikibase.getBestStatements(raceID, 'P527') -- P527 is 'has part' 	for _, v in pairs(stages) do 		if v.mainsnak.snaktype == 'value' then 			local stageID = v.mainsnak.datavalue.value.id 			local p = mw.wikibase.getBestStatements(stageID, 'P1545') -- P1545 is 'series ordinal' 			local sOrdinal = p[1] and p[1].mainsnak.snaktype == 'value' and p[1].mainsnak.datavalue.value 				or '' 			local _, _, sNumber, sLetter = string.find(sOrdinal, '(%d+)(.*)') 			if not sNumber then sNumber = '' end 			if not sLetter then sLetter = '' end 			local WDLink = WDlink_on and wdLink(stageID) or '' 			local sitelink = mw.wikibase.getSitelink(stageID) 			local timeOfRace =getTimeOfRace(stageID) 			 			local sPointID = firstValue(stageID, 'P1427', 'id') 			local sPoint = (sPointID and getPlaceLink(sPointID, timeOfRace)) or '' 			local eu=false 			if wiki=="eu" and sPointID then 				sPoint, eu=check_basque_place(sPoint, sPointID) 			end  			if sPointID and not onecountry and not eu then 				local startcountryID=getCountryID(sPointID, timeOfRace) 				if startcountryID and firstcountryID ~= startcountryID then 					sPoint = flag(startcountryID, timeOfRace).." "..sPoint 				end 			end  			local dPointID = firstValue(stageID, 'P1444', 'id') 			local dPoint = (dPointID and getPlaceLink(dPointID, timeOfRace)) or ''  			eu=false 			if wiki=="eu" and dPointID then 				dPoint, eu=check_basque_place(dPoint, dPointID) 			end  			if dPointID and not onecountry and not eu then 				local dcountryID=getCountryID(dPointID, timeOfRace) 				if dcountryID and firstcountryID ~= dcountryID then 					dPoint = flag(dcountryID, timeOfRace).." "..dPoint 				end 			end  			local sDistance = getDistance(stageID, false) or '' 			local sElevation = getElevation(stageID)  			if sElevation then thereiselevation=true end 			 			local winners = { 				Q20882747 = '', -- Q20882747 is 'stage winner' 				Q20882763 = '', -- Q20882763 is 'overall leader at the end of the stage' 				Q20882667 = '', -- Q20882667 is 'overall winner' not supposed to be used 			} 			winner(lf,stageID, winners, timeOfRace, false, WDlink_on)  			-- find the type of stage 			local sType = typeofstagelogo(stageID) 			local label, section_title 			if sOrdinal == "0" then 				label, section_title = translate("func_prologue",1), "#" .. translate("func_prologue",1) 			else 				label, section_title = stageLink(sOrdinal, sNumber, sLetter) 			end 			-- if there is a Wikipedia article of that stage show it or show the section 			local sLink = sitelink and ("[[" .. sitelink .. "|" .. label .. "]]") or 				("[[" .. section_title .. "|" .. label .. "]]")  			local sDate = funcDate(timeOfRace, 'small') 			local tempoverall 			if  winners['Q20882763']~='' then tempoverall=winners['Q20882763'] else	tempoverall=winners['Q20882667'] end 			rows[#rows + 1] = { 				rank=tonumber(sNumber) or 0,  				sortkey=sLetter,  -- Sort keys 				sLink=sLink, 				sDate=sDate,  				WDLink=WDLink,  				sPoint=sPoint,  				dPoint=dPoint,  				sType=sType,  				sDistance=sDistance,  				sElevation=sElevation,  				sSWin=winners['Q20882747'],  				sGWin=tempoverall -- Content 			} 		end 	end  	table.sort(rows, function(a, b) 		if a["rank"] ~= b["rank"] then return a["rank"] < b["rank"] end 		return a["sortkey"] < b["sortkey"] 	end) 	local Id = ((not WDlink_on and wdLink(string.gsub(raceID, '%s', '') .. "#P527")) or "") 	 	tab=mw.html.create('table') 	:attr('cellpadding','4' ) 	:attr('cellspacing','0') 	:cssText(standardtablecss)  	local tRow=tab:tag('tr'):css('background-color',backgroundColor) 	:css('text-align','center') 	tRow:tag('th'):css('white-space','nowrap') 	:wikitext(Id..translate("headoftable",1,w_race)) 	tRow:tag('th'):wikitext(translate("headoftable",2,w_race)) 	tRow:tag('th'):wikitext(translate("headoftable",3,w_race)) 	tRow:tag('th'):css('color',backgroundColor):wikitext("type") 	tRow:tag('th'):wikitext(translate("headoftable",4,w_race)) 	if thereiselevation then  		tRow:tag('th'):wikitext(translate("headoftable",7,w_race)) 	end 	tRow:tag('th'):wikitext(translate("headoftable",5,w_race)) 	tRow:tag('th'):wikitext(translate("headoftable",6,w_race)) 	local header = tostring(tRow) 	for num, row in pairs(rows) do 		local sPoint=row["sPoint"] 		local dPoint=row["dPoint"] 		local sType=row["sType"] 		local sDistance=row["sDistance"] 		 		local WPc = WPcontent[num] 		if WPc then 			if WPc['a'] then sPoint = WPc['a'] end 			if WPc['b'] then dPoint = WPc['b'] end 			if WPc['ab'] then sPoint, dPoint = WPc['ab'], '' end 			if WPc['icon'] then sType = WPc['icon'] end 			if WPc['distance'] then sDistance = WPc['distance'] end 		end  		local tRow = tab:tag('tr') 		local tCell= tRow:tag('td'):cssText('text-align:center; white-space:nowrap'):wikitext(row["sLink"]) 		tCell:tag('span'):css('white-space','nowrap'):wikitext("&nbsp;".. row["WDLink"]) 		tRow:tag('td'):css('white-space','nowrap'):cssText("text-align:right; padding-right:0px") 		:wikitext(row["sDate"]) 		tCell=tRow:tag('td'):cssText("padding-right:0px"):wikitext( sPoint) 		if dPoint ~= '' then 			tCell:wikitext(" – " .. dPoint) 		end 		tRow:tag('td'):cssText("padding-right:0px"):wikitext(sType) 		tRow:tag('td'):css('text-align','center'):wikitext( sDistance) 		if thereiselevation then 			tRow:tag('td'):css('text-align','center'):wikitext(row["sElevation"]) 		end  		if WPc and WPc['stage winner'] then 			tRow:tag('td'):css('text-align',textalign):wikitext( WPc['stage winner']) 		else 			tRow:tag('td'):wikitext(row["sSWin"]) 		end 		if WPc and WPc['general winner'] then 			tRow:tag('td'):css('text-align',textalign):wikitext( WPc['general winner']) 		else 			tRow:tag('td'):wikitext(row["sGWin"]) 		end 		if WPc and (WPc['date'] or WPc['text'] or WPc['icon (new row)']) then 			tRow = tab:tag('tr') 			tRow:tag('td') --empty  			if WPc['icon (new row)'] == '' then 				tRow:tag('td'):cssText('text-align:right; padding:3px 0px 10px 0px;white-space:nowrap') 				:wikitext(WPc['date']) 				tRow:tag('td'):cssText("text-align:" .. textalign .. "; padding:3px 4px 10px") 				:wikitext(WPc['text']) 			else 				tRow:tag('td'):cssText('text-align:right; padding-right:0px') 				:wikitext(WPc['date']) 				tRow:tag('td'):cssText("text-align:" .. textalign) 				:wikitext(WPc['text']) 			end 			tRow:tag('td'):css('padding-top','10px'):wikitext(WPc['icon (new row)']) 			tRow:tag('td'):attr('colspan','3') 		end 	end 	if arwiki_totemplate then 		tab = change_listofstages(tab, raceID, header, Id) 	end 	return tab end  function p.stagetitle(frame) 	local stageID = get_and_checkID(frame) 	-- from to  	local sPointID = firstValue(stageID, 'P1427', 'id') 	local sPoint = sPointID and getPlaceLink(sPointID) or ''  	local dPointID = firstValue(stageID, 'P1444', 'id') 	local dPoint = (dPointID and getPlaceLink(dPointID)) or ''  	local sDistance = getDistance(stageID, true) or '' 	local sType = typeofstagelogo(stageID) -- find the type of stage 	 	tab=mw.html.create('table') 	tab:tag('th'):wikitext(sPoint.." - "..dPoint) 	tab:tag('td'):wikitext(sType) 	tab:tag('td'):css('font-weight','bold'):wikitext("("..sDistance..")") 	return tab end  local function champtitle(h) --!h is h.jersey 	local road, ITT, result 	local hcountry, hnotcountry = {},{} 	local w_race=nil --to be defined if needed 	 	--the jersey for a stage race and the jersey from national championship should be differentiated 	--to avoid to look every time, below is a list of all national championships  	if type(h) == 'table' and h[1] then 		for _, v in ipairs(h) do 			roadtemp=false 			ITTtemp=false 			if data.womenNcRoadtable[v] or data.menNcRoadtable[v] then 				 road = true 				 roadtemp=true 			elseif data.womenNcITTtable[v] or data.menNcITTtable[v] then 				 ITT = true 				 ITTtemp=true 	    	else 		    	local raceLabel = mw.wikibase.getLabelByLang(v,"fr") 				if raceLabel then 					local testMenRoadrace, testMenITT, testWomenRoadrace, testWomenITT 					local raceLabelmod = string.gsub(raceLabel, '-', 'x') 					testMenRoadrace = string.find( raceLabel, 'Course en ligne masculine aux' )  					testMenITT = string.find( raceLabelmod, 'Contrexlaxmontre masculin aux' )  					testWomenRoadrace = string.find( raceLabel, 'Course en ligne féminine aux' )  					testWomenITT = string.find( raceLabelmod, 'Contrexlaxmontre féminin aux' )  					if testWomenRoadrace or testMenRoadrace then road = true roadtemp=true end 					if testWomenITT or testMenITT then ITT = true ITTtemp=true end 				end 			end 			if roadtemp or ITTtemp then 				table.insert(hcountry,v) 			else 				table.insert(hnotcountry,v)	 			end 		end 	end 	if road and ITT then 		local image = {} 		for ii, v in ipairs(hcountry) do 			local p18 = mw.wikibase.getBestStatements(v, 'P18') 			if p18[1] and p18[1].mainsnak.snaktype == 'value' then 				local temp = p18[1].mainsnak.datavalue.value 				local alreadythere = 0 				for _, vv in ipairs(image) do 					if vv==temp then alreadythere = 1 end 				end 				if alreadythere==0 then 					table.insert(image,temp) 				else hcountry[ii] = nil 				end 			end 		end 		--avoid double display of jersey 		result = "<small>("..translate("startlist",10,w_race).." "..translate("startlist",12,w_race).." "..translate("startlist",11,w_race)..")</small>" 	elseif road then 		result = "<small>("..translate("startlist",10,w_race)..")</small>" 	elseif ITT then 		result = "<small>("..translate("startlist",11,w_race)..")</small>" 	else 		result = "" 	end 	return jersey(hcountry)..result..jersey(hnotcountry) end  -- L) List of stages classification local function winnerjersey(raceID, winners) 	local jerseytable, bgcolortable={}, {} 	local p1346 = wikibase.getAllStatements(raceID, 'P1346') -- P1346 is 'winner' 	for _, winner in pairs(p1346) do 		local wOf, thisjersey, bg_color 		local q = winner.qualifiers 		if q then 			if q.P642 and q.P642[1].snaktype == 'value' then 				wOf = q.P642[1].datavalue.value.id -- P642 is 'of' 			end 			if q.P2912 and q.P2912[1].snaktype == 'value' then 				thisjersey=q.P2912[1].datavalue.value.id 				if data.bg_color_table[thisjersey] then 					bg_color = data.bg_color_table[thisjersey] 				end 			end 		end 		if winners[wOf] and thisjersey then 			jerseytable={} 			table.insert(jerseytable,thisjersey) 			winners[wOf] = jersey(jerseytable) 			bgcolortable[wOf] = bg_color 		end 	end 	return winners, bgcolortable end  function p.listofstagesclassification(frame) 	-- WDlink_on is used to decide if a Wikidata logo will be shown 	local WDlink_on = wiki == "mk" or wiki == "ja" 	local displaytypeofstage = true 	local stageinfotable = {} 	local raceID, lf = get_and_checkID(frame) 	local w_race=isWomenrace(raceID) 	local sType  	--link for Grand Tour 	local GTid={['Q33881']=true,['Q33861']=true,['Q33937']=true} 	local thisGT  	for _, p31 in statements(raceID, 'P31') do 		if GTid[p31.mainsnak.datavalue.value.id]==true then thisGT=p31.mainsnak.datavalue.value.id break end 	end  	local Sitelink,overallname, pointsname, mountainname, youngname, teamname, combativityname, supercombativityname, combinedname 	if thisGT then 		if thisGT=='Q33881' then 			Sitelink = wikibase.getSitelink('Q2267539') 			if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q175399') 			if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q927157') 			if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q641662') 			if Sitelink then youngname="[["..Sitelink .."|"..translate("infobox",25,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q1436680') 			if Sitelink then teamname="[["..Sitelink .."|"..translate("infobox",28,w_race).."]]" end  			Sitelink = wikibase.getSitelink('Q2094179') 			if Sitelink then combativityname="[["..Sitelink .."|"..translate("infobox",26,w_race).."]]" end  			Sitelink = wikibase.getSitelink('Q2094179') 			if Sitelink then supercombativityname="[["..Sitelink .."|"..translate("infobox",26,w_race).."]]" end   			Sitelink = wikibase.getSitelink('Q1835362') 			if Sitelink then combinedname="[["..Sitelink .."|"..translate("infobox",27,w_race).."]]" end 		elseif thisGT=='Q33861' then 			Sitelink = wikibase.getSitelink('Q1164275') 			if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q641083') 			if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q641060') 			if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q641662') 			if Sitelink then youngname="[["..Sitelink .."|"..translate("infobox",25,w_race).."]]" end 		else 			Sitelink = wikibase.getSitelink('Q2532554') 			if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q2241695') 			if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q1118296') 			if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" end 			Sitelink = wikibase.getSitelink('Q2330008') 			if Sitelink then combinedname="[["..Sitelink .."|"..translate("infobox",27,w_race).."]]" end 		end 	end  	local winners = { 		{ name = translate("infobox",19,w_race), QID = 'Q20882747'}, -- stage 		{ name = overallname or translate("headoftableII",9,w_race), QID = 'Q20882763' }, -- overall 		{ name = pointsname or translate("infobox",22,w_race), QID = 'Q20883008' }, -- points 		{ name = mountainname or translate("infobox",23,w_race), QID = 'Q20883213' }, -- mountains 		{ name = translate("infobox",24,w_race), QID= 'Q20883329' }, -- sprints 		{ name = youngname or translate("infobox",25,w_race), QID='Q20883140' }, -- youth 		{ name = combativityname or translate("infobox",26,w_race), QID= 'Q21686770' }, -- combativity 		{ name = supercombativityname or translate("infobox",26,w_race), QID= 'Q20893984' }, -- combativity 		{ name = translate("infobox",35,w_race), QID= 'Q27104688' }, -- volantes 		{ name = translate("infobox",36,w_race), QID= 'Q27104684' }, -- regularity 		{ name = combinedname or translate("infobox",27,w_race), QID='Q20965880' }, -- combination 		{ name = translate("infobox",38,w_race), QID='Q27907714' }, -- breakaway 		{ name = translate("infobox",39,w_race), QID='Q27907748' }, -- azzurri 		{ name = translate("infobox",40,w_race), QID='Q28096780'}, -- rookie 		{ name = teamname or translate("infobox",28,w_race), QID='Q20882922' }, -- teams 		{ name = translate("infobox",37,w_race), QID ='Q27104271' }, -- teamspoints 		{ name = translate("infobox",41,w_race), QID ='Q61976847' },-- amateur 		{ name = translate("infobox",42,w_race), QID ='Q61976871' } --nationality 	}  	local winnersgen = { 		{ QID = 'Q20882667' }, -- overall 		{ QID = 'Q20883007' }, -- points 		{ QID = 'Q20883212' }, -- mountains 		{ QID = 'Q20883328' }, -- sprints 		{ QID = 'Q20883139' }, -- youth 		{ QID = 'Q101246973' }, -- supercombativity		 		{ QID = 'Q20893983' }, -- combativity 		{ QID = 'Q27067359' }, -- volantes 		{ QID = 'Q27067170' }, -- regularity 		{ QID = 'Q20893979' }, -- combination 		{ QID = 'Q27907715' }, -- breakaway 		{ QID = 'Q27907747' }, -- azzurri 		{ QID = 'Q28092831' }, -- rookie 		{ QID = 'Q20882921' },  -- teams 		{ QID = 'Q27104269' }, -- teamspoints 		{ QID = 'Q61976850' },  -- amateur 		{ QID = 'Q61976872' } --nationality 	}  	local generaltoleader = { 		['Q20882747']= nil, 		['Q20882667']= 'Q20882763', -- overall 		['Q20883007']= 'Q20883008', -- points 		['Q20883212']= 'Q20883213', -- mountains 		['Q20883328']= 'Q20883329', -- sprints 		['Q20883139']= 'Q20883140', -- youth 		['Q20893983']= 'Q20893984', -- combativity 		['Q101246973']= 'Q21686770', -- supercombativity			 		['Q27067359']= 'Q27104688', -- volantes 		['Q27067170']= 'Q27104684', -- regularity 		['Q20893979']= 'Q20965880', -- combination 		['Q27907715']= 'Q27907714', -- breakaway 		['Q27907747']= 'Q27907748', -- azzurri 		['Q28092831']= 'Q28096780', -- rookie 		['Q20882921']= 'Q20882922', -- teams 		['Q27104269']= 'Q27104271', -- teamspoints 		['Q61976850']= 'Q61976847', -- amateur 		['Q61976872']= 'Q61976871'  --nationality 	}  	--read stages 	local stages = mw.wikibase.getBestStatements(raceID, 'P527') -- P527 is 'has part' 	local columntable, jerseytable, bgcolortable={}, {}, {} 	for ii, v in ipairs(winners) do 		if v.QID then 			local t = {key=ii, name=v.name, jersey='', bg_color='', used=false} 			for jj = 1, #stages+1 do 				t[jj] = { {}, {}, {} }  -- leader, first stage, number of stages consecutive (for rowspan) 			end 			columntable[v.QID] = t 		end 	end 	--to have the columns in the same order as defined, otherwise they would be sorted according to the order in wikidata 	--make "Q123", "Q456" --> 1, 2 	local function itercolumns(columntable) 		local keys = {} 		for k, v in pairs(columntable) do 			keys[v.key] = k --v.key is just the order of the columns 		end 		local upto = 1 		return function () 			while keys[upto] do 				upto = upto + 1 				return columntable[keys[upto-1]] 			end 		end 	end  	local timeOfRace 	for ii, v in pairs(stages) do 		if v.mainsnak.snaktype == 'value' then 			local somewinner = false --show the stage 			local stageID = v.mainsnak.datavalue.value.id 			local sitelink = mw.wikibase.getSitelink(stageID) 			if displaytypeofstage==true then 				sType = typeofstagelogo(stageID) 			end 			local p = mw.wikibase.getBestStatements(stageID, 'P1545') -- P1545 is 'series ordinal' 			local sOrdinal = p[1] and p[1].mainsnak.snaktype == 'value' and p[1].mainsnak.datavalue.value 				or '' 			local _, _, sNumber, sLetter = string.find(sOrdinal, '(%d+)(.*)') 			sNumber=sNumber or '' 			sLetter=sLetter or ''  			local label, section_title 			if sOrdinal == "0" then 				label, section_title = translate("func_prologue",1), "#" .. translate("func_prologue",1) 			else 				label, section_title = stageLink(sOrdinal, sNumber, sLetter) 			end 			-- If there is a Wikipedia article of that stage show it or show the section. 			local sLink = sitelink and ("[[" .. sitelink .. "|" .. label .. "]]") or 				("[[" .. section_title .. "|" .. label .. "]]")  			timeOfRace =getTimeOfRace(stageID)  			local win= {} 			for _, v in pairs(winners) do 				win[v.QID] = '' 				if ii==1 then jerseytable[v.QID]='' end 			end 			winner(lf,stageID, win, timeOfRace, false, WDlink_on, false, false) --fill win table 			if ii<=2 then --only two first stages 				jerseytable, bgcolortable=winnerjersey(stageID, jerseytable) 			end 			for _, v in pairs(winners) do 				if v.QID and win[v.QID] ~= '' then 					--column info 					somewinner=true 					columntable[v.QID][ii]["leader"]=win[v.QID] 					if ii==1 then --first stage 						columntable[v.QID][ii]["start"]=1  --start at row 1 						columntable[v.QID][ii]["rowspan"]=1  --1 consecutive stage 					elseif columntable[v.QID][ii-1]["leader"]==win[v.QID] then --same winner as past stage ,make previous longer and delete this one 						local initialstage=columntable[v.QID][ii-1]["start"] 						columntable[v.QID][ii]["start"]=initialstage --need because of the row above 						columntable[v.QID][initialstage]["rowspan"]=columntable[v.QID][initialstage]["rowspan"]+1 --one more consecutive stage 						columntable[v.QID][ii]["rowspan"]=0 					else --new winner 						columntable[v.QID][ii]["start"]=ii --start at this row/stage 						columntable[v.QID][ii]["rowspan"]=1  --1 consecutive stage 					end 					columntable[v.QID].used=true 					if ii<=2 then --read the jersey in the two first stages of a race 						if columntable[v.QID].jersey == '' or columntable[v.QID].jersey==nil then 							columntable[v.QID].jersey=jerseytable[v.QID] 							columntable[v.QID].bg_color=bgcolortable[v.QID] 						end 					end 				end 			end 			table.insert(stageinfotable,{sLink=sLink, sType=sType, somewinner=somewinner}) 		end 	end  	--read parent 	local win= {} 	for _, v in pairs(winnersgen) do 		if v.QID then 			win[v.QID] = '' 			jerseytable[v.QID]='' 		end 	end 	local thiskey 	somewinner = false 	jerseytable, bgcolortable=winnerjersey(raceID, jerseytable) 	winner(lf,raceID, win, timeOfRace, false, WDlink_on, false, false) 	for _, v in pairs(winnersgen) do 		if win[v.QID] and win[v.QID] ~= '' then 			somewinner=true 			thiskey=generaltoleader[v.QID] 			--fill the final classification 			columntable[thiskey][#stages+1]["leader"]=win[v.QID] 			columntable[thiskey][#stages+1]["start"]=#stages+1 			columntable[thiskey][#stages+1]["rowspan"]=1 			--#stages is the last stage 			if (type(columntable[thiskey][#stages]["leader"])~="string"  --combativity is not extrapolated 			    and thiskey~='Q20893984') then --check nil actually, but it is a table.. 			     				columntable[thiskey][#stages]["leader"]= win[v.QID] --extrapolate the winner 				if (type(columntable[thiskey][#stages-1]["leader"])=="string" and  				    win[v.QID]==columntable[thiskey][#stages-1]["leader"]) then --if there is a leader at forelast stage 				 					local initialstage=columntable[thiskey][#stages-1]["start"] 					columntable[thiskey][#stages]["start"]=initialstage --needed because of row above 					columntable[thiskey][initialstage]["rowspan"]=columntable[thiskey][initialstage]["rowspan"]+1 					columntable[thiskey][#stages]["rowspan"]=0 				else 					columntable[thiskey][#stages]["start"]=#stages 					columntable[thiskey][#stages]["rowspan"]=1 				end 			end 			if jerseytable[v.QID] and jerseytable[v.QID]~='' then 				columntable[thiskey].jersey=jerseytable[v.QID] 				columntable[thiskey].bg_color=bgcolortable[v.QID] 			end 		end 	end 	table.insert(stageinfotable,{sLink=translate("listofstagesclassification",2,w_race), sType=nil, somewinner=somewinner})   	--build the table 	local	tab=mw.html.create('table') 	:attr('cellpadding','4' ) 	:attr('cellspacing','0') 	:cssText(standardtablecss) 	local tRow=tab:tag('tr'):css('background-color',backgroundColor) 	:css('text-align','center') 	tRow:tag('th'):css('white-space','nowrap') 	:wikitext(((not WDlink_on and wdLink(string.gsub(raceID, '%s', '') .. "#P527")) or "").. 	translate("headoftable",1,w_race)) 	 	if displaytypeofstage==true then tRow:tag('th') end  	for v in itercolumns(columntable) do 		if v.used == true then 			if v.jersey == '' then v.jersey = "_" end 			tRow:tag('th'):wikitext(v.name.."<br />"..v.jersey) 		end 	end  	local style 	--then fill the table 	for ii, v in pairs(stageinfotable) do --one stage=one row 		--stages link 		tRow=tab:tag('tr') 		local tCell=tRow:tag('td') 		if ii==#stageinfotable then  			tCell:attr('colspan','2'):cssText('font-weight:bold; border-top: 2px black solid;') 		end 		tCell:wikitext(v.sLink) 		 		if displaytypeofstage == true then 			tCell=tRow:tag('td') 			if ii==#stageinfotable then --general row 				tCell:cssText('font-weight:bold; border-top: 2px black solid;') 			end 			if v.sType then 				tCell:wikitext(v.sType) --picture type of stage 			end 		end  		--add winners 		for y in itercolumns(columntable) do 			if y.used==true and not (ii==#stageinfotable and columntable['Q20882747']==y) then --only display used QID 				if type(y[ii]["leader"])=="string" and type(y[ii]["rowspan"])=="number" then --actually check nil but it is a table 					style="" 					if y[ii]["rowspan"]~=0 and (columntable['Q20882747']==y)==false then 						if ii~=1 and ii~=#stageinfotable then style=style.." border-top:1px gray solid;" end 						if y.bg_color then style=style.." background-color:"..y.bg_color..";" end 						if ii==#stageinfotable then style=style.."font-weight:bold; border-top: 2px black solid;" end 						tRow:tag('td'):attr('rowspan',tostring(y[ii]["rowspan"])):cssText(style):wikitext(y[ii]["leader"]) 					elseif (columntable['Q20882747']==y) then --no rowspan for stages 						tRow:tag('td'):wikitext(y[ii]["leader"]) 					end 				else 					tCell=tRow:tag('td') 					if ii~=#stageinfotable and v.somewinner==true then 						tCell:wikitext(translate("listofstagesclassification",1,w_race)) --not attributed  					elseif ii~=#stageinfotable then 						 --empty 					elseif v.somewinner==true then  --general row 						tCell:cssText('border-top: 2px black solid') 						:wikitext(translate("listofstagesclassification",1,w_race)) --not attributed  					else 						tCell:cssText('border-top: 2px black solid') --empty 					end 				end 			end 		end 	end 	return tab end  --M) Start list function p.startlist(frame) 	local tempID, lf=get_and_checkID(frame) 	local w_race=isWomenrace(tempID) 	local s = { 		header_function = "startlist", 		header_1 = 1, -- translation 1 in function victories is printed in the upper part of the table header 		header_2 = {2, 3,4,5}, 		item=tempID, 		title="Start list", 		data_sort_type={'unsortable', 'unsortable', 'unsortable'}, 		property ='P710', 		no_roll_startlist=no_roll_startlist, 		w_race=w_race, 		lf=lf 	}  	local resultTable, tag = tableB(s) 	return startlist_main(s, resultTable, tag)   end  function p.startlisttable(frame) 	local tempID, lf=get_and_checkID(frame) 	local w_race=isWomenrace(tempID)  	local s = { 		header_function = "startlisttable", 		header_1 = 1, -- translation 1 in function victories is printed in the upper part of the table header 		header_2 = {2, 3,4,5},-- translations 2, 3, 4, 5, 6 in function victories are printed in this order 		item=tempID, 		title="Start list", -- in the lower part of the table header. The second value 3 in {4, 3} tells where the icon will go. 		no_country ={'fr'}, 		data_sort_type={'', '', ''}, 		property ='P710', 		no_roll_startlist=no_roll_startlist, 		w_race=w_race, 		lf=lf 	} 	return startlisttable_main(s, tableA(s)) end  local function startlist_sub(p710, timeOfRace,  WDlink_on, istable,w_race) 	local h, resultTable= {}, {} 	local tBody = '' --row in our case 	local riderID, riderTeamLink, riderTeamID, riderDossard, riderLink, riderRank 	local q, gender, riderTeamCode, riderDNF, DSQ, catID, countryID, national_team_boolean  	riderID = p710.mainsnak.datavalue.value.id 	q= p710.qualifiers 	riderLink= getRiderLink(riderID, timeOfRace) 	if WDlink_on then riderLink=riderLink..wdLink(riderID) end 	if q and q.P1618 and q.P1618[1].snaktype == 'value' then 		riderDossard = q.P1618[1].datavalue.value or '' 	else 		riderDossard = '' 	end 	riderDNF='' riderRank = '' DSQ='' 	if q and q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is ranking 		riderRank = tonumber(q.P1352[1].datavalue.value.amount) 		--look for DSQ-- 		DSQ=isdisqualified(p710, q) 	else 		--look for DNF... 		if q and q.P1534 and q.P1534[1].snaktype == 'value' then 			local dnf=q.P1534[1].datavalue.value.id 			if dnf=='Q1210380' then riderDNF =translate("startlist",6,w_race)--"HD","NP","DQ" 			elseif dnf=='Q54881674' or dnf=='Q7113430' then riderDNF =translate("startlist",7,w_race) 			elseif dnf=='Q1210382' then riderDNF =translate("startlist",8,w_race) 			elseif dnf=='Q1229261' then riderDNF =translate("startlist",9,w_race) 			else riderDNF='' 			end 			if q.P1545 and q.P1545[1].snaktype == 'value' then 				local stageofdnf=q.P1545[1].datavalue.value 				if stageofdnf and string.len(stageofdnf)>1 then 					riderDNF='<small>'..riderDNF.."-"..stageofdnf..'</small>' 				else 					riderDNF=riderDNF.."-"..stageofdnf 				end 			end 		end 	end  	h = { 		jersey = {}, -- lots of jerseyID 		value = {'', '', '', ''} -- points, time, time_gap, speed 	}  	if q and q.P2912 then -- P2912 is distinctive jersey 		for _, v in pairs(q.P2912) do 			if v.snaktype == 'value' then 				table.insert(h.jersey, v.datavalue.value.id) 			end 		end 	end  	if wiki == 'es' or wiki == 'fr' or wiki == 'ast' then 		--[[ These wikis need the gender to display the rank correct. Other wikis can skip this. ]] 		gender = getGenderCode(riderID, 'n') 	end 	local countryID = getNationality(riderID, timeOfRace,q) 	local uciCode='' 	local jerseytemp='' 	if countryID then 		if wiki ~= "ar" then  			uciCode=uciCodeCountry(countryID) 		end 		riderLink = flag(countryID, timeOfRace) ..' '.. riderLink  	end  	if h.jersey[1] then 		jerseytemp=champtitle(h.jersey) -- champtitle manages also the jersey 	end 	 	riderTeamLink, riderTeamID, catID, countryID = getTeam(riderID, timeOfRace, q) 	riderTeamID=seasonToTeamID(riderTeamID) 	riderTeamCode= getTeamCode(riderID, timeOfRace, q) 	 	--Custom display for national selection 	if data.natTeamCats[catID] and countryID then 		if riderTeamCode and wikibase.getSitelink(countryID) then --for the refugee case 			riderTeamCode='[['..wikibase.getSitelink(countryID)..'|'..riderTeamCode..']]' 		end 		riderTeamLink=flag(countryID, timeOfRace)..' '..riderTeamLink 	else --for non national selection display "ridername (FRA)"" 		riderLink =riderLink..uciCode 	end 	riderLink =riderLink..jerseytemp  	if riderTeamLink == nil then riderTeamLink ="" end 	local sortkey = riderDossard == "" and 0 or tonumber(riderDossard)  	tBody =   mw.html.create('tr'):cssText("line-height: 1.8em; padding: 5px;") 	tBody:tag('td'):cssText("text-align:right;padding:0 0.5em"):wikitext(riderDossard) 	tBody:tag('td'):cssText('text-align:'..textalign.. ';padding:0 0.5em;'..DSQ):wikitext(riderLink)  	local td_css = "text-align:left;padding:0 0.5em" 	if wiki == "ar" then td_css = "text-align:right;padding:0 0.5em" end 	if istable then 		tBody:tag('td'):cssText(td_css):wikitext(riderTeamLink) 	end 	tBody:tag('td'):cssText('text-align:'..textalign.. ';padding:0 0.5em;'..DSQ):wikitext(number(gender,riderRank,wiki)..riderDNF)  	table.insert(resultTable, {sortkey=sortkey, riderTeamLink=riderTeamLink,riderTeamID=riderTeamID,riderTeamCode=riderTeamCode, tBody=tBody}) 	return resultTable end  function startlist_main(s, resultTable, tag) 	local ridertable, DStable, subtable	 = {}, {}, {} 	local DSID, DSLink, DSteamID, DSteam 	local WDlink_on = (wiki == "mk" or wiki == "ja" or wiki == "ru")  	local timeOfRace=getTimeOfRace(s.item) 	local w_race=isWomenrace(s.item)  	for _,p286 in statements(s.item, 'P286') do--look for DS 		DSID = p286.mainsnak.datavalue.value.id 		DSLink= getRiderLink(DSID, timeOfRace) 		q= p286.qualifiers 		if q.P642 and q.P642[1].snaktype == 'value' then 			DSteamID=q.P642[1].datavalue.value.id 			DSteamID=seasonToTeamID(DSteamID) 		end 		table.insert(DStable, {DSLink=DSLink, DSteamID=DSteamID}) 	end  	for _, p710 in statements(s.item, 'P710') do -- P710 is participants 		subtable=startlist_sub(p710, timeOfRace, WDlink_on, false,w_race) 		ridertable[#ridertable + 1] = { 			subtable[1].sortkey,  			riderTeamLink=subtable[1].riderTeamLink,  			riderTeamID=subtable[1].riderTeamID,  			riderTeamCode=subtable[1].riderTeamCode,  			tBody=subtable[1].tBody 		} 	end 	 	--sort 	table.sort(ridertable, function(a, b) return a[1] < b[1] end)  	local thisTableRow, thisTeamTable, thisDS, insideTable, test 	local tSubtitle, tTitle 	 	if wiki == "ar" then 		tSubtitle=mw.html.create('tr') 		tSubtitle:tag('td'):attr('width','30px') 		:css("align:right;text-align:right") 		:wikitext(translate("startlist",2,w_race)) 		tSubtitle:tag('td'):attr('width','200px') 		:css("align:right;text-align:right") 		:wikitext(translate("startlist",3,w_race)) 		tSubtitle:tag('td'):attr('width','85px') 		:css("align:right;text-align:right") 		:wikitext(translate("startlist",4,w_race)) 	else 		tSubtitle=mw.html.create('tr') 		tSubtitle:tag('td'):attr('width','30px'):wikitext(translate("startlist",2,w_race)) 		tSubtitle:tag('td'):attr('width','250px'):wikitext(translate("startlist",3,w_race)) 		tSubtitle:tag('td'):attr('width','35px'):wikitext(translate("startlist",4,w_race)) 	end  	--look for transition between teams 	local numberofteam=0 	local tDS  	if #ridertable==0 then--empty table 		return nil 	else 		for ii=1,#ridertable  do 			if ridertable[ii].riderTeamLink==nil then ridertable[ii].riderTeamLink=translate("startlist",13,w_race) end 			if ii~=1 and ridertable[ii].riderTeamID and ridertable[ii].riderTeamID==ridertable[ii-1].riderTeamID then test=0 else test=1 end--team change 				--new team 			if test==1 or ii==1 then 				if thisDS and ii~=1 then 					tDS=insideTable:tag('tr') 					tDS:tag('td'):attr('colspan','3'):attr('align','center') 					:wikitext(translate("startlist",5,w_race).." "..thisDS) 					thisDS=nil 				end 				 				numberofteam=numberofteam+1 				if math.fmod(numberofteam, 3 )==1 then 					if ii~=1 then 						tag:node(thisTableRow) --a row with 3 tables inside, save and re-init 					end 					thisTableRow=mw.html.create('tr')  				end 				thisTeamTable= thisTableRow:tag('td'):cssText("width:33%;"):attr('valign','top') 				insideTable=thisTeamTable:tag('table') --reinit 				:attr('cellpadding','4') --solid rgb(200,200,200) 				:attr('background-color','rgb(255, 255, 255)') 				:attr('margin', '0 0 0.5em 0') 				:attr('padding','5px') 				:attr('float','left') 				:attr('text-align',textalign) 				:attr('line-height','1.8em') 				:attr('clear',floattable)  				tTitle =  mw.html.create('tr') 				:css("background-color",backgroundColor) 				:attr('align','center') 				local tCell=tTitle:tag('th'):attr('colspan','3') 				tCell:tag('big'):wikitext(ridertable[ii].riderTeamLink.."<br/>"..(ridertable[ii].riderTeamCode or "___")) 				 				insideTable:node(tTitle) 				insideTable:node(tSubtitle) 				 				tDS=nil 				--look for the DS of this team 				for _,v in pairs(DStable) do 					if v.DSteamID==ridertable[ii].riderTeamID then 						if not thisDS then 							thisDS=v.DSLink 						else 							thisDS=thisDS..", "..v.DSLink 						end 					end 				end 			end 			insideTable:node(ridertable[ii].tBody) 		end 		--last DS 		if thisDS then 			tDS=insideTable:tag('tr') 			tDS:tag('td'):attr('colspan','3'):attr('align','center') 			:wikitext(translate("startlist",5,w_race).." "..thisDS) 		end 		tag:node(thisTableRow)  		return resultTable 	end end  local KeytoRiderRankingCode={ 		["women"]=	2,  		['WWT']=	3,  		['WWC']=	4,	 		["UWT"]=	5, 		["europe"]=	6,  		["asia"]=	7, 		["oceania"]=8, 		["america"]=9, 		["africa"]=	10,  		["WR"]=	 11,  		["WC"]=		12,  		["UPT"]=	13, --WC is world calendar here 		["UCImen"]=	14,  		["WCmen"]=	15, --UCImen = UCI ranking 1984-2004, WC= World cup men 		["Pernod"]=	16,  		["Desgrange"]=17, 	}  function startlisttable_main(s, resultTable) 	local t_Body = {} 	local WDlink_on = (wiki == "mk" or wiki == "ja" or wiki == "ru")  	local timeOfRace=getTimeOfRace(s.item)  	for _, p710 in statements(s.item, 'P710') do -- P710 is participants 		local subtable=startlist_sub(p710, timeOfRace, WDlink_on, true) 		t_Body[#t_Body + 1] = {subtable[1].sortkey, tostring(subtable[1].tBody)} 	end 	return sortAndConcat(t_Body, resultTable) end  -- N) Rider ranking local function checkminmaxyear(minmaxyear,thisyear) 	if minmaxyear.minimum ==0 or thisyear<minmaxyear.minimum then 		minmaxyear.minimum=thisyear 	end 	if minmaxyear.maximum==0 or thisyear>minmaxyear.maximum then 		minmaxyear.maximum=thisyear 	end    return minmaxyear end  function p.riderranking(frame) 	local tempID, lf=get_and_checkID(frame) 	local s = { 		item = tempID, 		lf=lf 	} 	return riderranking_main(s) end  local function checkWorldTourTeam(itemID,year) 	local thisdate='+'..tostring(year).."-07-01T00:00:00Z" 	local catID 	 	for _, s in statements(itemID, 'P54') do 		p54 =checktime(s, s.qualifiers, thisdate) --present Team 		if p54 then 			teamId= p54.mainsnak.datavalue.value.id 			_, catID=getTeamLinkCat(teamId, thisdate) 			if catID=="Q6154783" or catID=="Q20638319" then 				return true 			end 		end 	end 	return false end  local function ranking_legend() 	local UCIlink, legend 	if wiki=="fr" then 		UCIlink="https://www.uci.org/fr/route/classements" --see also https://dataride.uci.org/iframe/Rankings/10/ 		legend= "  Légende : nc = non classé" 	else 		UCIlink="https://www.uci.org/road/rankings"  		legend="" 	end 	return UCIlink, legend end  local function riderranking_sub(w_race) 	local listofcalendar=data.listofmencalendar 	if w_race then 		listofcalendar=data.listofwomencalendar 	end  	local UCIQtoYear={} 	for k,v in pairs(data.UCIYearToQ) do 		UCIQtoYear[k]={} 		for kk, vv in pairs(v) do 			UCIQtoYear[k][vv]=kk  --calendar/Q = year 		end 	end 	return listofcalendar, UCIQtoYear end  function riderranking_main(s) 	local lf=s.lf 	local thisCompetition, rank, thisyear, sitelink, q, gender, DSQ     local calendarlistpresent={}  	local gender=getGenderCode(s.item, 'm') 	local w_race=false 	if gender=="f" then w_race=true end  	local minmaxyear= {	minimum = 0, maximum = 0 } 	local listofcalendar, UCIQtoYear=riderranking_sub(w_race)  	local resultTable={} 	for ii=1900,2100,1 do 		resultTable[tostring(ii)]={} 		for _, calendar  in pairs(listofcalendar) do 			resultTable[tostring(ii)][calendar]={} 		end 	end  	--build the table 	for _, p1344 in statements(s.item, 'P1344') do 		thisCompetition = p1344.mainsnak.datavalue.value.id 		for _, calendar  in pairs(listofcalendar) do 			if UCIQtoYear[calendar][thisCompetition] then 				thisyear=UCIQtoYear[calendar][thisCompetition] 				minmaxyear=checkminmaxyear(minmaxyear,thisyear) 				q = p1344.qualifiers 				if q and q.P1352 and q.P1352[1].snaktype == 'value' then --rank 					resultTable[thisyear][calendar]["rank"] = tostring(tonumber(q.P1352[1].datavalue.value.amount)) --without the tonumber, there can be +1 instead of 1 					resultTable[thisyear][calendar]["DSQ"] = isdisqualified(p1344, q) or "" 					calendarlistpresent[calendar]=true 					sitelink=mw.wikibase.getSitelink(thisCompetition) 					resultTable[thisyear][calendar]["sitelink"]=sitelink 				end 			end 		end 	end  	--display result 	if minmaxyear.minimum~=0 then 		local finalTable =mw.html.create('table'):attr('cellspacing','0') 		:attr("align","center"):cssText("text-align:center; border: 1px solid #999;  line-height: 1.8em;") 		 		local wdLin = wdLink(string.gsub(s.item, '%s', '') .. "#P1344") 		local tRow= finalTable:tag('tr'):tag('th') 		:css("background-color",backgroundColor) 		:wikitext(wdLin..' '..translate("riderranking",1,w_race)) --year  		for ii=minmaxyear.minimum,minmaxyear.maximum,1 do 			tRow:tag('th'):attr("width","50px") 			:css('background-color',backgroundColor) 			:css("text-align","center") 			:css("padding","1px 1px") 			:wikitext(tostring(ii)) 		end  		for _, calendar  in pairs(listofcalendar) do 			if calendarlistpresent[calendar] then 				sitelink=mw.wikibase.getSitelink(data.UCImaster[calendar]) 				local tRow=finalTable:tag('tr') 				local tCell = tRow:tag('th'):cssText("text-align:" .. textalign .. ";") -- left 				local calendar_name=translate("riderranking",data.KeytoRiderRankingCode[calendar],w_race) 				if sitelink then 					tCell:wikitext('[['..sitelink..'|'..calendar_name..']]') 				else 					tCell:wikitext(calendar_name) 				end 				 				for yy=minmaxyear.minimum,minmaxyear.maximum,1 do 					thisyear=tostring(yy) 					color="white" 					local impossible=false 					--we need to check the impossibility here, as it is impossible even if nothing is in P1344 					if data.continental_calendar[calendar] then 						--between 2005 and 2015 WorldTour team member cannot score by continental calendars. 						if tonumber(thisyear)>=2005 and tonumber(thisyear)<=2015 then 							if checkWorldTourTeam(s.item,thisyear) then 								impossible=true 							end 						--between 2016 and 2018 no contradiction 						--after 2019, it depends on the nationality 						elseif tonumber(thisyear)>=2019 then 							local countryID=getNationality(s.item,'+'..tostring(year).."-07-01T00:00:00Z") 							if data.continental_calendar[calendar] and not data.continental_calendar[calendar][countryID] then 								impossible=true 							end 						end 					elseif calendar=="UWT" then 						--non member of World Tour team cannot point in the WT 						if tonumber(thisyear)>=2005 and tonumber(thisyear)<=2015 then 							if not checkWorldTourTeam(s.item,thisyear) then 								impossible=true 							end 						end 					end  					if resultTable[	thisyear][calendar]["rank"] or impossible then 						if impossible then 							tRow:tag('td'):css('background-color',backgroundColorLight) 						else 							if resultTable[thisyear][calendar]["rank"]=="1" then 								color="gold" 							elseif (2<=tonumber(resultTable[thisyear][calendar]["rank"])) and (tonumber(resultTable[thisyear][calendar]["rank"])<=3) then 								color="YellowGreen" 							elseif (4<=tonumber(resultTable[thisyear][calendar]["rank"])) and (tonumber(resultTable[thisyear][calendar]["rank"])<=10) then 								color="silver" 							end  							tCell=tRow:tag('td'):attr("bgcolor",color):cssText(resultTable[thisyear][calendar]["DSQ"]) 							local rank=tonumber(resultTable[thisyear][calendar]["rank"]) 							rank=number(gender,rank,wiki) 							if resultTable[thisyear][calendar]["sitelink"] then 								tCell:wikitext('[['..resultTable[thisyear][calendar]["sitelink"]..'|'..rank..']]') 							else 								tCell:wikitext(rank) 							end 						end 					--this ranking exist for this year, but the rider is not ranked 					elseif yy>=data.UCIcalendarstartend[calendar].b and 						(data.UCIcalendarstartend[calendar].e==0 or yy<=data.UCIcalendarstartend[calendar].e) then  						if wiki=="fr" then 							tRow:tag('td'):wikitext(' nc ') 						else 							tRow:tag('td'):wikitext(' - ') 						end 					--this ranking does not exist for this year 					else  						tRow:tag('td'):css('background-color',backgroundColorLight) 					end 				end 			end 		end 	 		local tableyearsize=minmaxyear.maximum-minmaxyear.minimum+2 		local UCIlink, legend=ranking_legend() 		 		finalTable:tag('tr'):tag('td'):addClass("navigation-only") 		:attr('colspan',tostring(tableyearsize)) 		:cssText("border-top: 2px "..backgroundColor.." solid; font-size: 80%;") 		 		tCell=finalTable:tag('tr'):tag('td'):attr('colspan',tostring(tableyearsize)) 		:tag('small') 		 		tCell:tag('span'):css("float","left") 		:wikitext(legend) 		tCell:tag('span'):css("float","right") 		:wikitext(translate("race_reference", 1,w_race).."["..UCIlink..' UCI]')  		return  finalTable 	end end	  function p.teamranking(frame) 	local tempID, lf=get_and_checkID(frame) 	local calendar_key=get_arg(2,frame) 	if not calendar_key or calendar_key == "" then return "" end 	 	local w_race=false 	if calendar_key=="women" or calendar_key=="WWT" or calendar_key=="WWC" then 		w_race=true 	end  	local s = { 		header_function = "riderranking",  	    header_1 = data.KeytoRiderRankingCode[calendar_key] or 1,  		header_2 = {1, 18, 19}, 		property="P527", 		data_sort_type = {'unsortable', 'unsortable', 'unsortable'},  		item = tempID, 		calendar_key=calendar_key, 		lf=lf, 		w_race=w_race 	} 	return teamranking_main(s,tableA(s)) end  local function get_teamranking(seasonID, w_race, UCIQtoYear,listofcalendar, tTable,gender) 	--fill resultTable 	local done, thisyear, q, done, rider, riderLink, countryID, rank, thisdate, teamrank 	 	for _, p1344 in statements(seasonID, 'P1344') do 		thisCompetition = p1344.mainsnak.datavalue.value.id  		for _, calendar  in pairs(listofcalendar) do 			if UCIQtoYear[calendar][thisCompetition] then 				thisyear=UCIQtoYear[calendar][thisCompetition] 				thisdate='+'..tostring(thisyear).."-07-01T00:00:00Z" 				rank=nil 				 				if tTable[calendar] then 					tTable[calendar][thisyear]={} 				else 					error("tTable badly initialized") 				end 				q = p1344.qualifiers 				done=false 				--get team rank 				local suffix="" 				if calendar== "UCImen" then --case of GSI  (Q20653563), GSII (Q20653564) and GSIII (Q20653566) 					if q and q.P642 and q.P642[1].snaktype == 'value' then 						if q.P642[1].datavalue.value.id=="Q20653564" then 							suffix=" (GSII)" 						elseif q.P642[1].datavalue.value.id=="Q20653566" then 							suffix=" (GSIII)" 						end 					end 				end  				if q and q.P1352 and q.P1352[1].snaktype == 'value' then --rank 					teamrank= tonumber(q.P1352[1].datavalue.value.amount)  					tTable[calendar][thisyear]["teamrank"]=number(gender,teamrank,wiki)..suffix 					done=true 				end 				--get best rider rank 				if q and q.P1545 and q.P1545[1].snaktype == 'value' then --participant 					rank = tostring(tonumber(q.P1545[1].datavalue.value)) 					done=true 				end 				--get best rider 				if q and q.P710 and q.P710[1].snaktype == 'value' then --participant 					rider = q.P710[1].datavalue.value.id 					riderLink = getRiderLink(rider, thisdate) 					countryID = getNationality(rider, thisdate) 					if countryID then 						riderLink = flag(countryID, thisdate) .. ' ' .. riderLink 					end 					if rank then 						rank=number(gender,tonumber(rank),wiki) 						riderLink=riderLink.." ("..rank..")" 					end 					tTable[calendar][thisyear]["rider"]=riderLink 					done=true 				end				  				sitelink=mw.wikibase.getSitelink(thisCompetition) 				tTable[calendar][thisyear]["sitelink"]=sitelink 			end	 		end 	end 	return tTable end  function teamranking_main(s, resultTable) 	local lf=s.lf 	local t_Body = {} 	 	local gender="m" 	if s.w_race then gender="f" end  	--init, reverse UCIQtoYear 	local UCIQtoYear={} 	UCIQtoYear[s.calendar_key]={} 	if data.UCIYearToQ[s.calendar_key] then 		local v=data.UCIYearToQ[s.calendar_key] 		for kk, vv in pairs(v) do 			UCIQtoYear[s.calendar_key][vv]=kk 		end 	end  	local tTable={} 	tTable[s.calendar_key]={} 	for ii, p527 in statements(s.item, "P527") do 		tTable=get_teamranking(p527.mainsnak.datavalue.value.id, w_race,  			                        UCIQtoYear,{s.calendar_key}, tTable,gender) 	end 	 	local t=tTable[s.calendar_key] 	if t then 		for thisyear, v in pairs(t) do 			local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 0.5em;") 			local tCell=tRow:tag('td'):css("text-align",textalign) 			 			if v["sitelink"] then 				tCell:wikitext('[['..v["sitelink"]..'|'..thisyear..']]') 			else 				tCell:wikitext(thisyear) 			end 			 			if v["teamrank"] then 				tRow:tag('td'):wikitext(v["teamrank"]):css("text-align","center") 			else 				tRow:tag('td'):wikitext(" - "):css("text-align","center") 			end 			if v["rider"] then 				tRow:tag('td'):wikitext(v["rider"]) 			else 				tRow:tag('td'):wikitext(" - ") 			end 			t_Body[#t_Body + 1] = {thisyear, tRow} 		end 	end 	 	resultTable=sortAndConcat(t_Body, resultTable) 	local UCIlink, _=ranking_legend() 	 	local tRow=resultTable:tag('tr') 	tRow:tag('td'):addClass("navigation-only") 	:attr('colspan',tostring(3)) 	:cssText("border-top: 2px "..backgroundColor.." solid; font-size: 80%;") 	tRow=resultTable:tag('tr') 	local tCell=tRow:tag('td'):attr('colspan',tostring(3)):tag('small') 	tCell:tag('span'):css("float","right") 	:wikitext(translate("race_reference", 1,w_race).."["..UCIlink..' UCI]') 	 	return resultTable end   local function toboolean(str) 	if str=="true" then 		return true 	elseif str=="false" then 		return false 	else 		return str 	end end  --=== O) Rider infobox local function convertDate(date1, beginOrEnd, initialYear, finalYear) 	if not date1 then 		if beginOrEnd==0 then --begin 			y1=tostring(initialYear) 			m1="01" 			d1="01" 		else 			y1=tostring(finalYear) 			m1="12" 			d1="31" 		end 	else 		_, _, y1,m1,d1 = string.find(date1, "(%d+)-(%d+)-(%d+)") 		if m1 ==nil or m1=="00" then 			if beginOrEnd==0 then --begin 				m1="01" 				d1="01" 			else--end 				m1="12" 				d1="31" 			end 		end 	end 	return '+'..y1.."-"..m1.."-"..d1.."T00:00:00Z" end  local function listofTeam(itemID, initialYear, finalYear, PID)  	--first we have to read P54 of the rider 	--alternative P6087 for managed team 	local riderteam={} 	local stagiaire 	--initially initialYear is the birthyear of the rider 	--end year is now +10 years, or the death date 	--let's reduce the range (note: it may be slightly over-engineered, maybe it can be deleted and just assume 10 years in the future is sufficient) 	local today=os.date("*t") 	local t1=tonumber(today['year']) 	local t2=math.min(finalYear, tonumber(today['year']))  	local t_initialYear=t1 	local t_finalYear=t2  	for ii, p54 in statements(itemID, PID) do --itemID loaded in presentTeam 		local q = p54.qualifiers 		if q then 			local sTime, eTime=getStartEndfromQuali(q) 			--min/max  			if sTime then 				y=tonumber(string.sub(sTime, 2, 5)) 				if y < t_initialYear then 					t_initialYear=y 				end 				if y>t_finalYear then 					t_finalYear=y 				end 			end 			if eTime then 				y=tonumber(string.sub(eTime, 2, 5)) 				if y < t_initialYear then 					t_initialYear=y 				end 				if y>t_finalYear then 					t_finalYear=y 				end 			end	 		end 	end 	 	if t_initialYear~=t1 then initialYear=t_initialYear end 	if t_finalYear~=t2 then finalYear=t_finalYear end  	for ii, p54 in statements(itemID, PID) do --itemID loaded in presentTeam 		if p54 then 			teamId=p54.mainsnak.datavalue.value.id 		else 			teamId=nil 		end 		local q = p54.qualifiers 		if q then 			local sTime, eTime=getStartEndfromQuali(q) 			sTime=convertDate(sTime, 0, initialYear, finalYear) 			eTime=convertDate(eTime, 1, initialYear, finalYear) 			if q.P39 and q.P39[1] and	q.P39[1].snaktype == 'value' then 				stagiaire = q.P39[1].datavalue.value 			else 				stagiaire = nil 			end 			dis=checkDis(q) 			table.insert(riderteam,{teamId=teamId, startTime=sTime, endTime=eTime, stagiaire=stagiaire, dis=dis}) 		end 	end 	return riderteam, initialYear, finalYear end  --format the date for display of the team local function riderFormatDate(thisDate)  	if thisDate=='' then 		return '' 	else 		local month=math.ceil(thisDate['month']/2) 		if month==12 or month==1 then 			return thisDate['year'] 		else 			local date1='+'..thisDate['year'].."-"..month.."-".."01".."T00:00:00Z" 		--	local newobj = Complexedate.splitDate(date1)   			if month == 0 or month==nil then 				return thisDate['year'] 			else 				return month..'.'..thisDate['year'] 			end 		end 	end end  local function getTeamInfo(teamId,mm,yy,dd,managedTeam) 	--get the nature and name of the team for the date mm,yy 	mm=tostring(mm) 	yy=tostring(yy) 	dd=tostring(dd) 	if mw.ustring.len(mm)==1 then mm='0'..mm end 	if mw.ustring.len(dd)==1 then dd='0'..dd end 	 	thistime='+'..yy.."-"..mm.."-"..dd.."T00:00:00Z" 	local sitelink, teamNature=getTeamLinkCat(teamId, thistime, false)  	local cat, boolean  	if managedTeam then 	   cat=data.nationalcat 	else 	   cat=data.amateurcat 	end  	if cat[teamNature] then --club 		boolean=true--amateur / national selection  	else 		boolean=false--pro  / not national selection 	end 	return boolean, sitelink end  --for managed team, the table should be splat, as we can be national trainer and team trainer at the same time local function analyzeManagedTeam(teamRider, initialYear,finalYear) 	local natTeamOut, managedTeamOut={},{} 	local dis="road" 	local managedTeam=true 	 	for i=1,24 do --init table 		natTeamOut[i]={} 		managedTeamOut[i]={} 		for j=initialYear,finalYear do 			natTeamOut[i][j]={ amateurTeam, link, stagiaire=nil} 			managedTeamOut[i][j]={amateurTeam,link, stagiaire=nil} 		end 	end  	local teamId, natTeam, sitelink 	local sYear, sMonth,eYear, eMonth, sDay, eDay  	if teamRider==nil then return nil end 	 	for _, v in pairs(teamRider) do --for each team where was the rider 		if v['dis']==dis then  			--exception managed at the reading 			_, _, sYear,sMonth,sDay = string.find(v['startTime'], "(%d+)-(%d+)-(%d+)") 			_, _, eYear,eMonth,eDay = string.find(v['endTime'], "(%d+)-(%d+)-(%d+)") 	 			sYear=tonumber(sYear) 			sMonth=tonumber(sMonth) 			eYear=tonumber(eYear) 			eMonth=tonumber(eMonth) 	 			if sYear<=eYear then --test of congruence 				for yy=sYear,eYear do  					for mm=1,12 do 						local mmindex=(mm-1)*2+1 						--avoid reading info where the team is not the one of the rider 						getinfo=true 						if (yy==sYear and mm<sMonth) or (yy==eYear and mm>eMonth) then 							getinfo=false 						end 	 						if getinfo then 							if (yy==sYear) and (mm==sMonth) and (sDay~='01' and sDay~='00' and sDay~=nil)then  								natTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,sDay, managedTeam) 								if natTeam then 									natTeamOut[mmindex+1][yy]['amateurTeam']=true 									natTeamOut[mmindex+1][yy]['link']=sitelink 								else 									managedTeamOut[mmindex+1][yy]['amateurTeam']=false 									managedTeamOut[mmindex+1][yy]['link']=sitelink 								end	 							else 								natTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'01', managedTeam) 								if natTeam then 									natTeamOut[mmindex][yy]['amateurTeam']=true 									natTeamOut[mmindex][yy]['link']=sitelink 									if natTeamOut[mmindex+1][yy]['amateurTeam']==nil or v['stagiaire'] then --to avoid problem with team name change during the month 										natTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam) 										natTeamOut[mmindex+1][yy]['amateurTeam']=true --a nat team stays a nat team 										natTeamOut[mmindex+1][yy]['link']=sitelink 									end 								else 									managedTeamOut[mmindex][yy]['amateurTeam']=false 									managedTeamOut[mmindex][yy]['link']=sitelink 									if managedTeamOut[mmindex+1][yy]['amateurTeam']==nil or v['stagiaire'] then --to avoid problem with team name change during the month 										natTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam) 										managedTeamOut[mmindex+1][yy]['amateurTeam']=false --a nat team stays a nat team 										managedTeamOut[mmindex+1][yy]['link']=sitelink 									end 								end 							end 						end 					end 				end 			end 		end 	end 	return natTeamOut, managedTeamOut --a filled matrix with the link and nature of the teams end  local function analyzeTeam(teamRider, initialYear,finalYear, dis) 	local teamOut={} 	local managedTeam=false 	 	for i=1,24 do --init table 		teamOut[i]={} 		for j=initialYear,finalYear do 			teamOut[i][j]={ amateurTeam, link, stagiaire} 		end 	end  	local teamId, amateurTeam, sitelink 	local sYear, sMonth,eYear, eMonth, sDay, eDay  	if teamRider==nil then return nil end 	 	for _, v in pairs(teamRider) do --for each team where was the rider 		if v['dis']==dis then  			--exception managed at the reading 			_, _, sYear,sMonth,sDay = string.find(v['startTime'], "(%d+)-(%d+)-(%d+)") 			_, _, eYear,eMonth,eDay = string.find(v['endTime'], "(%d+)-(%d+)-(%d+)") 	 			sYear=tonumber(sYear) 			sMonth=tonumber(sMonth) 			eYear=tonumber(eYear) 			eMonth=tonumber(eMonth) 	 			if sYear<=eYear then --test of congruence 				for yy=sYear,eYear do  					for mm=1,12 do 						local mmindex=(mm-1)*2+1 						--avoid reading info where the team is not the one of the rider 						getinfo=true 						if (yy==sYear and mm<sMonth) or (yy==eYear and mm>eMonth) then 							getinfo=false 						end 	 						if getinfo then 							if (yy==sYear) and (mm==sMonth) and (sDay~='01' and sDay~='00' and sDay~=nil)then  								amateurTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,sDay, managedTeam) 								teamOut[mmindex+1][yy]['amateurTeam']=amateurTeam 								teamOut[mmindex+1][yy]['link']=sitelink 								teamOut[mmindex+1][yy]['stagiaire']=v['stagiaire'] 							else 								amateurTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'01', managedTeam) 								teamOut[mmindex][yy]['amateurTeam']=amateurTeam 								teamOut[mmindex][yy]['link']=sitelink 								teamOut[mmindex][yy]['stagiaire']=v['stagiaire'] 								if teamOut[mmindex+1][yy]['amateurTeam']==nil or v['stagiaire'] then --to avoid problem with team name change during the month 									amateurTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam) 									teamOut[mmindex+1][yy]['amateurTeam']=amateurTeam 									teamOut[mmindex+1][yy]['link']=sitelink 									teamOut[mmindex+1][yy]['stagiaire']=v['stagiaire'] 								end 							end 						end 					end 				end 			end 		end 	end 	return teamOut --a filled matrix with the link and nature of the teams end  local function insertTeam(teamAmateur,teamPro,sDate,eDate,v) 	local sDate2=riderFormatDate(sDate) 	local eDate2=riderFormatDate(eDate) 	local ins = {link=v['link'], sDate=sDate2,eDate=eDate2,stagiaire=v['stagiaire']} 	  	if v['amateurTeam'] then 		table.insert(teamAmateur,ins) 	else 		table.insert(teamPro,ins) 	end 	return teamAmateur,teamPro end  local function synthetizeTable(analyzedTeam, initialYear,finalYear) 	local teamPro, teamAmateur, tempTeam, tempsDate, tempeDate={}, {},{},{},{} 	local empty=true 	local active=false     --bring together successive month with identical content 	for yy=initialYear,finalYear do 		for mm=1,24 do 			local v=analyzedTeam[mm][yy] 			if v['amateurTeam']~=nil then 				if empty then --first line 					active=true 					empty=false 					tempTeam=v 					tempsDate['month']=mm 					tempsDate['year']=yy 				else 					if tempTeam['amateurTeam']==v['amateurTeam'] and tempTeam['link']==v['link'] 					and tempTeam['stagiaire']==v['stagiaire'] then --no change 						if yy==finalYear and mm==24 then--present team 							teamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,'',tempTeam) 						end 					else--change 						--save the old 						if active then --if active false then it was already saved 							if mm==1 then 								tempeDate['year']=yy-1 								tempeDate['month']=24 							else 								tempeDate['year']=yy 								tempeDate['month']=mm-1 							end 							teamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,tempeDate,tempTeam) 						end 						--save the new 						active=true 						tempTeam=v 						tempsDate['month']=mm 						tempsDate['year']=yy 					end --change 				end--first line 			elseif active then --there was a team and now there is an empty period 				active=false 				--save the old 				if mm==1 then 					tempeDate['year']=yy-1 					tempeDate['month']=24 				else 					tempeDate['year']=yy 					tempeDate['month']=mm-1 				end 				teamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,tempeDate,tempTeam) 				tempTeam['link']=nil --avoid problem if the rider comes back in the same team 			end   		end-- for mm 	end--for yy 	return teamAmateur,teamPro end  local function listOfManagedTeamTable(itemID, initialYear,finalYear) 	local managedTeamRider, initialYear, finalYear = listofTeam(itemID, initialYear,finalYear,'P6087')--raw list of team 	if not managedTeamRider then 		return nil, nil 	end 	 	local natTeamOut, managedTeamOut=analyzeManagedTeam(managedTeamRider, initialYear,finalYear) --table with links and nature of teams 	local nationalTeam,_=synthetizeTable(natTeamOut, initialYear,finalYear) 	local _,managedTeam=synthetizeTable(managedTeamOut, initialYear,finalYear) 	 	return nationalTeam,managedTeam end  local function listOfTeamTable(itemID, initialYear,finalYear) 	local teamRider, initialYear, finalYear = listofTeam(itemID, initialYear,finalYear,'P54')--raw list of team 	if not teamRider then 		return nil, nil 	end 	local analyzedTeam1=analyzeTeam(teamRider, initialYear,finalYear, "road") --table with links and nature of teams 	local teamAmateur,teamPro=synthetizeTable(analyzedTeam1, initialYear,finalYear) --table formated, global 	local analyzedTeam2=analyzeTeam(teamRider, initialYear,finalYear, "mountainBike")     local _, teamMountainBike=synthetizeTable(analyzedTeam2, initialYear,finalYear)     local analyzedTeam3=analyzeTeam(teamRider, initialYear,finalYear, "cycloCross") 	local _, teamCycloCross=synthetizeTable(analyzedTeam3, initialYear,finalYear) 	local analyzedTeam4=analyzeTeam(teamRider, initialYear,finalYear, "track") 	local _, teamTrack=synthetizeTable(analyzedTeam4, initialYear,finalYear)	 	 	return teamAmateur,teamPro, teamMountainBike, teamCycloCross, teamTrack end	  local function getBirthDeathDate(entityID, display_age) 	local birthDate=firstValue(entityID, 'P569', 'time') 	local deathDate=firstValue(entityID, 'P570', 'time') 	local temp2, temp3, birth, death, initialYear, finalYear, age 	 	local gender=getGenderCode(entityID, 'm') 	local w_race=false 	if gender=="f" then w_race=true end  	if birthDate then 		local birthDateFormatted= funcDate(birthDate, 'long') 		age, initialYear, finalYear=calculateAge(birthDate) 		local birthPlace = firstValue(entityID, 'P19', 'id') 		local birthPlaceLink='' 		if birthPlace then birthPlaceLink=getPlaceLink(birthPlace, birthDate) end  	    local plural, gen_singular, gen_plural = plural(age) 	    local ans 	    if gen_singular then 	    	ans=translate("riderinfobox",48,w_race) 	    elseif gen_plural then 	    	ans=translate("riderinfobox",49,w_race) 	    else 	    	ans=translate("riderinfobox",50,w_race) 	    end  		if not deathDate and display_age~=false then 			temp2=' ('..tostring(age)..' '..ans..')<br/>' 		else 			temp2='<br/>' 		end     	birth=birthDateFormatted..temp2..birthPlaceLink 	else 	    birth=nil 	end 	 	if deathDate then 		local deathDateFormatted= funcDate(deathDate, 'long') 		local deathPlace= firstValue(entityID, 'P20', 'id') 		local deathPlaceLink='' 		if deathPlace then deathPlaceLink=getPlaceLink(deathPlace, deathDate) end 		 		if birthDate then 		    local age=calculateAge(birthDate, deathDate) 		    local plural, gen_singular, gen_plural = plural(age) 		    local ans 		    if gen_singular then 		    	ans=translate("riderinfobox",48,w_race) 		    elseif gen_plural then 		    	ans=translate("riderinfobox",49,w_race) 		    else 		    	ans=translate("riderinfobox",50,w_race) 		    end 		    if display_age==false then 		    	temp2='<br/>' 		    else 				temp2=' ('..tostring(age)..' '..ans..')<br/>' 			end 		else 			temp2='<br/>' 		end  		death=deathDateFormatted..temp2..deathPlaceLink 	else 	    death=nil 	end  	return birth, death, initialYear, finalYear end  local function presentTeam(itemID) 	local tToday=os.date("*t")   	if mw.ustring.len(tToday["month"])==1 then tToday["month"]='0'..tToday["month"] end 	if mw.ustring.len(tToday["day"])==1 then tToday["day"]='0'..tToday["day"] end	 	local today='+'..tToday["year"].."-"..tToday["month"].."-"..tToday["day"].."T00:00:00Z" 	local plural=false     local teamId, result, teamLink, teamLinkRoad, row  	for _, s in statements(itemID, 'P54') do 		p54 =checktime(s, s.qualifiers, today) --present Team 		if p54 then 			teamId= p54.mainsnak.datavalue.value.id 			teamLink=getTeamLinkCat(teamId, today) 		    dis=checkDis(p54.qualifiers) 		    row=nil 		    if dis=='road' then 		    	teamLinkRoad=teamLink 		    elseif dis=='mountainBike' then 		    	row=teamLink..' ('..translate("riderinfobox",56,w_race)..')' 		    elseif dis=='cycloCross' then 		    	row=teamLink..' ('..translate("riderinfobox",57,w_race)..')' 		    else  		    	row=teamLink..' ('..translate("riderinfobox",58,w_race)..')' 		    end 		    if row then 			    if not result then 			    	result = row 			    else 			    	result= result..'<br/>'..row 			    	plural = true 			    end 		    end 		end 	end 	if teamLinkRoad and result then --put road first 		result = teamLinkRoad..' (route)<br/>'..result 		plural= true 	elseif teamLinkRoad then 		result = teamLinkRoad 	end 	return result, plural end  local function getSomeNames(details,entityID, PID, index, display_language) 	local rows={} 	if not details[index].content then 		local listOfNames=getFormerNames(entityID, PID) 		if listOfNames then 			for _, v in pairs(listOfNames) do 				rows[#rows + 1]=v[3] 				if v[2] and v[2]~='' then 					rows[#rows]=rows[#rows]..' <small>('..v[2]..')</small>' 				end 				if display_language then 					rows[#rows]=rows[#rows]..' <b><small>('..v[4]..')</small></b>' 				end 			end 			if #rows>0 then 				details[index].content = table.concat(rows, '<br/>')  			end 		end 	end end  --for wikidata input local function teamTable(tab, teamAmateur, title_singular, title_plural) 	if teamAmateur and #teamAmateur>0 then 		if #teamAmateur==1 then 			tab:node(addATitle(title_singular))  		else 			tab:node(addATitle(title_plural))  		end 		for _, v in pairs(teamAmateur) do  			local nametemp=v['link'] 			if v['sDate']==v['eDate'] then 				periodtemp=v['sDate'] 			else 				periodtemp=v['sDate']..'-'..v['eDate'] 			end 			if v['stagiaire'] then 				local stagiaire = string.gsub(getLabelFallback('Q2328847',lang_priority), "%b()", "") 				nametemp=nametemp..' ('..stagiaire..')' 			end 			tab:node(addARow(periodtemp or '',nametemp)) --period, name 		end 	end end  --for local data local function localTeamTable(tab, names, periods, title_singular, title_plural) 	if names then 		names =  mw.text.split(names, '<br />') 		periods = mw.text.split(periods or '', '<br />') 	 		if #names==1 then 			tab:node(addATitle(title_singular))  		else 			tab:node(addATitle(title_plural))  		end 		for i, name in pairs(names) do 			tab:node(addARow(periods[i] or '', name)) 		end 	end end	  function p.riderinfobox(frame) 	local WDlink_on = (wiki == "mk" or wiki == "ja") 	local entityID, lf = get_and_checkID(frame)  	local gender=getGenderCode(entityID, 'm') 	local w_race=false 	if gender=="f" then w_race=true end  	local details = { 		{ name = translate("riderinfobox",1,w_race), name_plural =translate("riderinfobox",2,w_race)}, -- birth name 		{ name = translate("riderinfobox",3,w_race), name_plural =translate("riderinfobox",4,w_race)}, -- nick name 		{ name = translate("riderinfobox",5,w_race), name_plural =translate("riderinfobox",6,w_race)}, -- official name 		{ name = translate("riderinfobox",7,w_race), name_plural =translate("riderinfobox",8,w_race)}, -- official name 		{ name = translate("riderinfobox",9,w_race) }, -- birth translate("riderinfobox",9) 		{ name = translate("riderinfobox",10,w_race)}, -- death 		{ name = translate("riderinfobox",11,w_race), name_plural =translate("riderinfobox",12,w_race)}, -- country 		{ name = translate("riderinfobox",13,w_race), name_plural =translate("riderinfobox",14,w_race)}, -- present team 		{ name = translate("riderinfobox",15,w_race), name_plural =translate("riderinfobox",16,w_race)}, -- speciality 		{ name = translate("riderinfobox",17,w_race) }, -- lateralisation 		{ name = translate("riderinfobox",18,w_race) }, -- blood group 		{ name = translate("riderinfobox",19,w_race) },  -- height 		{ name = translate("riderinfobox",20,w_race) }, -- weight 		{ name = translate("riderinfobox",21,w_race), name_plural =translate("riderinfobox",22,w_race)}, -- awards 	} 	 	local teams = { 		{ name = translate("riderinfobox",23,w_race), name_plural =translate("riderinfobox",24,w_race)}, -- directed teams 		{ name = translate("riderinfobox",25,w_race)}, -- directed years 		{ name =  translate("riderinfobox",26,w_race), name_plural =translate("riderinfobox",27,w_race)}, -- amateur names   		{ name = translate("riderinfobox",28,w_race)}, -- amateur periods 		{ name = translate("riderinfobox",29,w_race), name_plural =translate("riderinfobox",30,w_race)}, -- nonUCI names 		{ name = translate("riderinfobox",31,w_race)}, -- nonUCI periods 		{ name = translate("riderinfobox",32,w_race), name_plural =translate("riderinfobox",33,w_race)}, -- pro names 		{ name = translate("riderinfobox",34,w_race)}, -- pro periods 		{ name = translate("riderinfobox",35,w_race), name_plural =translate("riderinfobox",36,w_race)}, -- UCI names 		{ name = translate("riderinfobox",37,w_race)}, -- UCI periods 		{ name = translate("riderinfobox",52,w_race), name_plural =translate("riderinfobox",53,w_race)}, -- national selections 		{ name = translate("riderinfobox",54,w_race)}, -- national selection years 		}      --separated to have a title 	local subtitle = { 		{ name = translate("riderinfobox",51,w_race)}, -- insertion of a sub-title 	} 	     --separated to have a title 	local victories = { 		{ name = translate("riderinfobox",38,w_race)}, -- main victories 	} 	 	--separated to have a title 	local medals = { 		{ name = translate("riderinfobox",47,w_race)}, -- main victories 	} 	local others = get_others_dic()  	local name =  getLabelFallback(entityID) or ''  	local display_birthnameastitle=false 	for _, value in pairs(display_birthnameastitle_in_riderinfobox) do -- get data if country should be printed in this wiki 		if value == wiki then display_birthnameastitle=true end 	end 	getLocalContent(subtitle, lf.args) 	 	if not subtitle[1].content and display_birthnameastitle then 		local p1477 = mw.wikibase.getBestStatements(entityID, "P1477")  		if p1477[1] and p1477[1].mainsnak.snaktype == 'value' then 			subtitle[1].content = p1477[1].mainsnak.datavalue.value.text..' <b><small>('.. 			p1477[1].mainsnak.datavalue.value.language..')</small></b>' 		end 		if not subtitle[1].content then 		    local p1559 = mw.wikibase.getBestStatements(entityID, "P1559") -- P580 is start time 			if p1559[1] and p1559[1].mainsnak.snaktype == 'value' then 				subtitle[1].content = p1559[1].mainsnak.datavalue.value.text..' <b><small>('.. 			    p1559[1].mainsnak.datavalue.value.language..')</small></b>' 			end 		end 	end  	infoGetOthers(others, entityID)	  	getLocalContent(details, lf.args) 	getLocalContent(teams, lf.args) 	getLocalContent(others, lf.args)     getLocalContent(victories, lf.args)     getLocalContent(medals, lf.args)  	local listOfBirthNames, listOfNickNames, listOfOfficialNames, listOfShortNames 	 	local icon = ' [[File:Cycling (road) pictogram.svg|35px]]'  	local display_language=false 	for _, value in pairs(display_language_in_riderinfobox) do -- get data if country should be printed in this wiki 		if value == wiki then display_language=true end 	end 	 	local display_age=true 	for _, value in pairs(display_noage_in_riderinfobox) do -- get data if country should be printed in this wiki 		if value == wiki then display_age=false end 	end 	 	local display_nickname=true 	for _, value in pairs(display_nonickname_in_riderinfobox) do -- get data if country should be printed in this wiki 		if value == wiki then display_nickname=false end 	end	  	local display_cm=false 	for _, value in pairs(display_cm_in_riderinfobox) do -- get data if country should be printed in this wiki 		if value == wiki then display_cm=true end 	end	 --	getSomeNames(details, entityID, 'P1477', 1, display_language) --birthname 	--less prio than P1477 	if display_nickname then 		getSomeNames(details, entityID, 'P1559', 1, display_language) --birthname, bis 		getSomeNames(details, entityID, 'P1449', 2, display_language) --nick name 	end 	 	getSomeNames(details, entityID, 'P1448', 3, display_language) --official name 	 	if display_nickname then 		getSomeNames(details, entityID, 'P1813', 4, display_language) --short name 	end  	local birth, death, initialYear, finalYear=getBirthDeathDate(entityID, display_age) 	 	if not details[5].content then 		details[5].content=birth 	end 	if not details[6].content then 		details[6].content= death 	end	  	local display_flag=false 	for _, value in pairs(display_flag_in_riderinfobox) do -- get data if country should be printed in this wiki 		if value == wiki then display_flag=true end 	end  	listWPlinkChrono(details, 7, entityID, {'P1532','P27'}, 'country', initialYear, display_flag)  	if not details[8].content then 		local plural 		details[8].content, plural=presentTeam(entityID) 		if plural then 			details[8].name = details[8].name_plural 		end 	end  	--speciality 	listWPlink(details, 9, entityID, 'P413',false)  	--lateralisation, for cycling not very interesting 	--listWPlink(details, 10, entityID, 'P552',false)  	--blood group, idem 	--listWPlink(details, 11, entityID, 'P1853',false)  	--height 	if not details[12].content then 		details[12].content=getHeight(entityID, display_cm)  	end  	local display_weight=true 	for _, value in pairs(display_noweight_in_riderinfobox) do -- get data if country should be printed in this wiki 		if value == wiki then display_weight=false end 	end 	--weight 	if not details[13].content and  display_weight then 		details[13].content=getWeight(entityID) 	end	  	--award, should be table 	--awards look weird 	--if not details[14].content then 	--	listWPlink(details, 14, entityID, 'P166',false) 	--end  	local amateurTeam, nonUCITeam, proTeam, UCITeam --local data 	local amateurWD=true 	local proWD=true 	local managedWD=true 	local teamAmateur,teamPro, teamMountainBike, teamCycloCross, teamTrack=listOfTeamTable(entityID, initialYear, finalYear) 	local nationalTeam, managedTeam=listOfManagedTeamTable(entityID, initialYear, finalYear) 	local managedTeam_names, managedTeam_periods, amateurTeam_names, amateurTeam_periods 	local nonUCITeam_names, nonUCITeam_periods, proTeam_names, proTeam_periods 	local nationalTeam_names, nationalTeam_periods 	local UCITeam_names, UCITeam_periods  	if teams[1].content then 		managedTeam_names=teams[1].content 		managedTeam_periods=teams[2].content 		managedWD=false 	end  	if teams[3].content then 		amateurWD=false 		amateurTeam_names=teams[3].content 		amateurTeam_periods=teams[4].content 	end 			 	if teams[5].content then  		amateurWD=false 		nonUCITeam_names=teams[5].content 		nonUCITeam_periods=teams[6].content 	end  	if teams[7].content then 		proWD=false 		proTeam_names=teams[7].content 		proTeam_periods=teams[8].content 	end 	 	if teams[9].content then 		proWD=false 		UCITeam_names=teams[9].content 		UCITeam_periods=teams[10].content 	end	 	 	if teams[11].content then 		nationalTeam_names=teams[11].content 		nationalTeam_periods=teams[12].content 		managedWD=false 	end  	--plate and grab 	tab = infoInitTab("300px", name, icon, 2) 	if subtitle[1].content then 	    tCell=tab:tag('tr'):tag('td'):attr('colspan','2') 		:cssText('solid white; text-align:center') 		:wikitext(subtitle[1].content) 	end  	infoFillOthersDetails(tab, others, details,translate("riderinfobox",55,w_race),"260px") 	if amateurWD then 		teamTable(tab, teamAmateur, translate("riderinfobox",26,w_race), translate("riderinfobox",27,w_race)) 	else 	 	localTeamTable(tab,amateurTeam_names, amateurTeam_periods, translate("riderinfobox",26,w_race), translate("riderinfobox",27,w_race)) 		localTeamTable(tab,nonUCITeam_names, nonUCITeam_periods, translate("riderinfobox",29,w_race), translate("riderinfobox",30,w_race)) 	end 	 	if proWD then 		teamTable(tab, teamPro, translate("riderinfobox",45,w_race),translate("riderinfobox",46,w_race)) 		teamTable(tab, teamMountainBike, translate("riderinfobox",39,w_race), translate("riderinfobox",40,w_race)) 		teamTable(tab, teamCycloCross, translate("riderinfobox",41,w_race), translate("riderinfobox",42,w_race)) 		teamTable(tab, teamTrack, translate("riderinfobox",43,w_race), translate("riderinfobox",44,w_race)) 	else 		localTeamTable(tab,proTeam_names, proTeam_periods,translate("riderinfobox",45,w_race), translate("riderinfobox",46,w_race)) 		localTeamTable(tab,UCITeam_names, UCITeam_periods, translate("riderinfobox",35,w_race), translate("riderinfobox",36,w_race)) 	end  	--managed teams 	if managedWD then 		teamTable(tab, nationalTeam, translate("riderinfobox",52,w_race), translate("riderinfobox",53,w_race)) 		teamTable(tab, managedTeam, translate("riderinfobox",23,w_race), translate("riderinfobox",24,w_race)) 	else 		localTeamTable(tab,managedTeam_names, managedTeam_periods,translate("riderinfobox",23,w_race), translate("riderinfobox",24,w_race)) 	end 	 	if victories[1].content then 		tab:node(addATitle(translate("riderinfobox",38,w_race)))  		tab:tag('tr'):tag('td') 		:css('vertical-align','top'):attr('colspan','2') 		:wikitext(victories[1].content) 	end 	 	if medals[1].content then 		tab:node(addATitle(translate("riderinfobox",47,w_race)))  		tab:tag('tr'):tag('td') 		:css('vertical-align','top'):attr('colspan','2') 		:wikitext(medals[1].content) 	end 	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/riderinfobox", translate("raceinfobox",26,w_race), entityID) 	return tab end  --=== P) Team infobox local function get_rider_number(entityID, details, index) 	if not details[index].content then 		local riders = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part' 		if riders > 0 then 			local stagiaire = string.gsub(getLabelFallback('Q2328847'), "%b()", "") 			local nb_stagiaires=0 			for ii, p527 in statements(entityID, 'P527') do 				local q = p527.qualifiers 				if q and q.P39 and q.P39[1] and	q.P39[1].snaktype == 'value' and 				   q.P39[1].datavalue.value=='Q2328847'then 				   nb_stagiaires=nb_stagiaires+1 				end 			end 		    if nb_stagiaires>0 then 				details[index].content = riders ..' ('.. tostring(nb_stagiaires).." "..stagiaire..')' 			else 				details[index].content = riders 			end 		end	 	end end  function p.teamseasoninfobox(frame) 	local WDlink_on = (wiki == "mk" or wiki == "ja") 	local seasonID, lf = get_and_checkID(frame) 	 	local w_race=isWomenteam(seasonID) 	local gender="m" 	if w_race then gender="f" end  	local details = { 		{ name = translate("teaminfobox",2,w_race)}, -- sport 		{ name = translate("headoftableII",3,w_race)}, -- team 		{ name = translate("teaminfobox",3,w_race), name_plural = translate("teaminfobox",4,w_race)}, -- type 	 		{ name = translate("teaminfobox",5,w_race), name_plural = translate("teaminfobox",6,w_race)}, -- UCI-cod 		{ name = translate("teaminfobox",7,w_race), name_plural = translate("teaminfobox",8,w_race)}, -- сountry 		{ name = translate("getSquadTableColumn",7,w_race)}, --team size 		{ name = translate("teaminfobox",13,w_race)}, -- official web site 		{ name = translate("teaminfobox",27,w_race), name_plural = translate("teaminfobox",28,w_race)},  --sponsor 		{ name = translate("teaminfobox",24,w_race), name_plural = translate("teaminfobox",25,w_race) }, -- bike 		{ name = translate("teaminfobox",26,w_race)}, -- budget 	}	  	local managers ={ 		{ name = translate("teaminfobox",14,w_race), name_plural = translate("teaminfobox",15,w_race)}, -- manager													--country 		{ name = translate("teaminfobox",16,w_race), name_plural = translate("teaminfobox",17,w_race)}, -- sports director 	}  	local others=get_others_dic()  	infoGetOthers(others, seasonID) 	getLocalContent(details, lf.args) 	getLocalContent(others, lf.args) 	 	local sport_id=firstValue(seasonID, 'P641', 'id') 	local icon = (sport_id == "Q3609") and -- P641 is 'sport', Q3609 is 'road bicycle racing' 		' [[File:Cycling (road) pictogram.svg|35px]]' or '' 	local name =  getLabelFallback(seasonID) or '' 	local listOfNames=getFormerNames(seasonID, 'P1448',true) 	--1st ist sport 	if not details[1].content and sport_id then 		details[1].content = WPlinkpure(sport_id) 	end 	 	local timeOfRace=getTimeOfRace(seasonID) 	local initialYear 	if timeOfRace then 		initialYear=string.sub(timeOfRace,2,5) 	else 		error("no timeOfRace found for "..seasonID) 	end     local sitelink, catID, _=getTeamLinkCat(seasonID, timeOfRace, nil, true)     --team 	if not details[2].content then  		details[2].content=sitelink 	end  	--type 	listWPlinkChrono(details, 3, seasonID, {'P2094'}, 'rider', initialYear, nil, nil, true) 	 	if not details[3].content then --fallback 	    if catID then 	    	details[3].content=getRiderLink(catID, timeOfRace) --it is not a rider, but it gives the correct result 	    end 	end	 	 	listWPlinkChrono(details, 4, seasonID, {'P1998'}, 'UCIcode', initialYear, nil, true,true)  	local display_flag=true					 	listWPlinkChrono(details, 5, seasonID, {'P1532','P17'}, 'country', initialYear, display_flag,nil,true)  	-- number of riders 	get_rider_number(seasonID, details, 6)  	-- official site 	if not details[7].content then 		details[7].content = officialSite(seasonID) 	end 	--Sponsor 	listWPlinkChrono(details, 8, seasonID, {'P859'}, 'rider', initialYear, nil, nil, true) 	 	--bike 	listWPlinkChrono(details, 9, seasonID, {'P1876'}, 'rider', initialYear, nil, nil, true)  	--budget 	if not details[10].content then 		p=firstValue(seasonID,'P2769') 		if p and p.mainsnak.snaktype == 'value' then 			local amount=p.mainsnak.datavalue.value.amount 			local unit=p.mainsnak.datavalue.value.unit 			details[10].content=dispmoney(amount, unit) 		end 	end 	 	local listofcalendar, UCIQtoYear=riderranking_sub(w_race)  	local tTable={} --no need for year, it is clear 	for _, calendar  in pairs(listofcalendar) do 		tTable[calendar]={} 	end 	--not over-writable presently 	tTable=get_teamranking(seasonID, w_race, UCIQtoYear,listofcalendar, tTable,gender)  	--Staff, there can be several 	-- manager 	listWPlinkChrono(managers, 1, seasonID, {'P505'}, 'rider', initialYear, nil, nil, true)  	-- sports director 	listWPlinkChrono(managers, 2, seasonID, {'P286'}, 'rider', initialYear, nil, nil, true) 	 	--Build the table 	tab = infoInitTab("300px", name, icon, 2) 	infoFillOthersDetails(tab, others, details, translate("teaminfobox",1,w_race)) 	 	--in case there are several names 	if listOfNames and #listOfNames>1 then --Always display a list of names 		tab:node(addATitle(translate("teaminfobox",19,w_race)))  		for _, v in pairs(listOfNames) do 			tab:node(addARow(v[2],v[3])) --period, name 		end 	end 	 	if managers[1].content or managers[2].content then 		tab:node(addATitle(translate("teaminfobox",18,w_race))) 		for _, row in ipairs(managers) do 	    	tab:node(addARow(row.name, row.content)) --node check itself if nil 		end 	end 	--Palmares 	tab:node(addATitle(translate("raceinfobox",20,w_race))) 	local wins = #wikibase.getAllStatements(seasonID, 'P2522')  	if wins then 		tab:node(addARow(translate("victories",2,w_race),tostring(wins))) 	end  	for calendar, v_calendar in pairs(tTable) do 		if v_calendar[initialYear] then 			local v=v_calendar[initialYear] 			local calendar_name=translate("riderranking",KeytoRiderRankingCode[calendar],w_race) 			if v["sitelink"] then 				tab:node(addATitle('[['..v["sitelink"]..'|'..calendar_name..']]')) 			else 				tab:node(addATitle(calendar_name)) 			end 			 			if v["teamrank"] then 				tab:node(addARow(translate("riderranking",20,w_race),v["teamrank"])) 			end 			if v["rider"] then 				tab:node(addARow(translate("riderranking",21,w_race),v["rider"])) 			end 		end 	end  -- an empty line with a title under the form in the form of an image or third-party template 	if get_arg('jersey',lf) then -- if the jersey is not specified, then the JERSEY header is not displayed  		tab:node(addATitle(translate("teaminfobox",20,w_race))) 	    local outTable = mw.html.create('tr') 		local tCell=outTable:tag('td'):attr('colspan','3'):css('text-align','center')		     		tCell:wikitext(get_arg('jersey',lf)) -- adding a form via "argument 2" by an image or an extraneous template  		tab:node(outTable) 	end		  -- adding a link to articles about the last and current seasons (the same as for the race) 	 	tab:node(getPreviousNextLine(seasonID)) 	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/raceinfobox", translate("raceinfobox",26,w_race), seasonID) 	return tab	 end  function p.teaminfobox(frame) 	-- If true, winners will have Wikidata logos with link to Wikidata 	local WDlink_on = (wiki == "mk" or wiki == "ja") 	 	local entityID, lf = get_and_checkID(frame) 	local w_race=isWomenrace(entityID) 	 	local tRace = {race={ 			raceId, 			raceDate, 			future, 			},  		  } 	 	local details = { 		{ name = translate("teaminfobox",2,w_race)}, -- sport 		{ name = translate("teaminfobox",3,w_race), name_plural = translate("teaminfobox",4,w_race)}, -- type 	 		{ name = translate("teaminfobox",5,w_race), name_plural = translate("teaminfobox",6,w_race)}, -- UCI-cod 		{ name = translate("teaminfobox",7,w_race), name_plural = translate("teaminfobox",8,w_race)}, -- сountry 		{ name = translate("teaminfobox",9,w_race)}, -- creation date 		{ name = translate("teaminfobox",10,w_race)}, -- disparition date 		{ name = translate("teaminfobox",11,w_race)}, -- number of season 		{ name = translate("teaminfobox",13,w_race)}, -- official web site 		{ name = translate("teaminfobox",27,w_race), name_plural = translate("teaminfobox",28,w_race)},  --sponsor 		{ name = translate("teaminfobox",24,w_race), name_plural = translate("teaminfobox",25,w_race) }, -- bike 		{ name = translate("teaminfobox",26,w_race)}, -- budget 	} 	 	local others=get_others_dic() 	local managers ={ 		{ name = translate("teaminfobox",14,w_race), name_plural = translate("teaminfobox",15,w_race)}, -- manager													--country 		{ name = translate("teaminfobox",16,w_race), name_plural = translate("teaminfobox",17,w_race)}, -- sports director 	} 	 	local managers_season ={ 		{ name = translate("teaminfobox",14,w_race), name_plural = translate("teaminfobox",15,w_race)}, -- manager													--country 		{ name = translate("teaminfobox",16,w_race), name_plural = translate("teaminfobox",17,w_race)}, -- sports director 	} 	 	local details_season = { 		{ name = translate("getSquadTableColumn",7,w_race)}, --team size 		{ name = translate("victories",2,w_race)} --number of victories 	}  	local name =  getLabelFallback(entityID,  lang_priority) or '' 	infoGetOthers(others, entityID)	 	 	getLocalContent(details, lf.args) 	getLocalContent(others, lf.args) 	getLocalContent(managers, lf.args) 	     local listOfNames=getFormerNames(entityID, 'P1448') 	 	local sport_id=firstValue(entityID, 'P641', 'id') 	local icon = (sport_id == "Q3609") and -- P641 is 'sport', Q3609 is 'road bicycle racing' 		' [[File:Cycling (road) pictogram.svg|35px]]' or ''  	--1st ist sport 	if not details[1].content and sport_id then 		details[1].content = WPlinkpure(sport_id) 	end 	 	local creation=firstValue(entityID, 'P571', 'time') 	local initialYear=string.sub(creation,2,5) 	 	-- type  	listWPlinkChrono(details, 2, entityID, {'P31'}, 'rider', initialYear)--it is not a rider, but we need link + official name 	 	--UCI code 	listWPlinkChrono(details, 3, entityID, {'P1998'}, 'UCIcode', initialYear, nil, true)  	-- сountry 	local display_flag=true					 	listWPlinkChrono(details, 4, entityID, {'P1532','P17'}, 'country', initialYear, display_flag)  	--creation date 	if not details[5].content and creation then 		details[5].content = funcDate(creation, "onlyyear" ) 	end  	-- disparition date 	local disparition=firstValue(entityID, 'P576', 'time') 	if not details[6].content and disparition then 		details[6].content =  funcDate(disparition,"onlyyear") 	end  	--populate tRace 	listOfWinners(entityID, tRace,true,lf) 	 	-- number of season 	if not details[7].content and tRace.numberOfEditions and tRace.lastEditionYear then 		details[7].content = tostring(tRace.numberOfEditions).." (" .. translate("teaminfobox",12,w_race) .. " "..tostring(tRace.lastEditionYear)..")" 	end  	-- official site 	if not details[8].content then 		details[8].content = officialSite(entityID) 	end 	 	--9 is sponsor 	listWPlinkChrono(details, 9, entityID, {'P859'}, 'rider', initialYear) 	 	--10 is bike  	listWPlinkChrono(details, 10, entityID, {'P1876'}, 'rider', initialYear) 	--11 budget 	listWPlinkChrono(details, 11, entityID, {'P2769'}, 'money', initialYear)  	-- manager 	listWPlinkChrono(managers, 1, entityID, {'P505'}, 'rider', initialYear)  	-- sports director 	listWPlinkChrono(managers, 2, entityID, {'P286'}, 'rider', initialYear)  	--Build the table 	tab = infoInitTab("300px", name, icon, 2) 	--former names 	wiki_listOfNamesAtBottom={'ru'} 	 	local listOfNamesAtBottom = false 	for _, value in pairs(wiki_listOfNamesAtBottom) do --  		if value == wiki then listOfNamesAtBottom = true end 	end 	--picture at the top 	infoFillOthersDetails(tab, others, details, translate("teaminfobox",1,w_race),"260px")  	if managers[1].content or managers[2].content then 		tab:node(addATitle(translate("teaminfobox",18,w_race))) 		for _, row in ipairs(managers) do 	    	tab:node(addARow(row.name, row.content)) --node check itself if nil 		end 	end 	 	if listOfNames and #listOfNames>0 then --Always display a list of names 		tab:node(addATitle(translate("teaminfobox",19,w_race)))  		for _, v in pairs(listOfNames) do 			tab:node(addARow(v[2],v[3])) --period, name 		end 	end  -- an empty line with a title under the form in the form of an image or third-party template 	if get_arg(2,lf) then -- if the jersey is not specified, then the JERSEY header is not displayed  		tab:node(addATitle(translate("teaminfobox",20,w_race))) 	    local outTable = mw.html.create('tr') 		local tCell=outTable:tag('td'):attr('colspan','3'):css('text-align','center')		     		tCell:wikitext(get_arg(2,lf)) -- adding a form via "argument 2" by an image or an extraneous template  		tab:node(outTable) 	end		  -- adding a link to articles about the last and current seasons (the same as for the race) 	 	if tRace.lastID then 		-- manager 		listWPlinkChrono(managers_season, 1, tRace.lastID, {'P505'}, 'rider', tRace.lastEditionYear, nil, nil, true) 		-- sports director 		listWPlinkChrono(managers_season, 2, tRace.lastID, {'P286'}, 'rider', tRace.lastEditionYear, nil, nil, true) 		 		get_rider_number(tRace.lastID, details_season, 1)  		local wins = #wikibase.getAllStatements(tRace.lastID, 'P2522')  		if wins then 			details_season[2].content=tostring(wins) 		end 		 		infoFillOthersDetails(tab, nil, managers_season, translate("teaminfobox",21,w_race),"260px") 		infoFillOthersDetails(tab, nil, details_season, nil,"260px") 		 		local outTable  		if tRace.lastLink then 		    outTable = mw.html.create('tr') 			local tCell=outTable:tag('td'):attr('colspan','2'):css('text-align','center') 			local lastText="[[File:Crystal Clear app kworldclock.png|left|37px]]".. 			translate("teaminfobox",22,w_race).. 			":<br>'''".. 			tRace.lastLink.."'''" 			tCell:wikitext(lastText) 			tab:node(outTable) 		end	 		 		if tRace.nextLink then 			outTable = mw.html.create('tr') 			local tCell=outTable:tag('td'):attr('colspan','2'):css('text-align','center') 		    local nextText = "[[File:Crystal Clear app kworldclock.png|left|37px]]".. 		    translate("teaminfobox",23,w_race).. 		    ":<br>'''".. 		    tRace.nextLink.."'''" 			tCell:cssText("text-align:center"):wikitext(nextText) 			tab:node(outTable) 		end 	end	  	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/raceinfobox", translate("raceinfobox",26,w_race), entityID) 	return tab end  --== teamriderCompetitionranking function p.teamriderCompetitionranking(frame) 	local tempID, lf=get_and_checkID(frame) 	local calendarID 	 	local timeOfRace=getTimeOfRace(tempID) 	local initialYear 	if timeOfRace then 		year=string.sub(timeOfRace,2,5) 	end  	local header_1_tab = {["UWT"]=13 ,["europe"]=14 ,["asia"]=15,["america"]=16 ,["africa"]=17 ,["oceania"]=18, ["WWT"]=11, ["women"]=1, ["Pro"]=22} 	local header_1_number = 12 	local key=get_arg(2,frame) 	 	if key and year then 		calendarID=data.UCIYearToQ[key][year] 		header_1_number = header_1_tab[key] 	end 	local w_race=isWomenteam(calendarID) 	if not calendarID or calendarID == "" then return "" end  	local s = { 		header_function = "calendar",  		header_1 =header_1_number,  		header_2 = {2, 3, 5, 4, 24, 23}, 		data_sort_type = {'', '','', 'unsortable', '', ''}, 		property="P1344", 		calendarID=calendarID, 		item = tempID, --should be called item for tableA 		lf=lf, 		w_race=w_race 	} 	return teamriderCompetitionranking_main(s,tableA(s))	 end  local function get_competition_bestrider(RaceID, seasonID, gender) 	local riderLink, rank, disqualified, cancelled, q  	local bold=false  	for _, p1344 in statements(seasonID, 'P1344') do  		thisCompetition = p1344.mainsnak.datavalue.value.id 		if thisCompetition and thisCompetition==RaceID then 			q = p1344.qualifiers 			if q then 				if q and q.P1352 and q.P1352[1].snaktype == 'value' then --rank 					rank= tonumber(q.P1352[1].datavalue.value.amount)  					if rank==1 then 						bold=true 					end 					rank=number(gender,rank,wiki) 				end 				--get best rider 				if q and q.P710 and q.P710[1].snaktype == 'value' then --participant 					rider = q.P710[1].datavalue.value.id 					riderLink = getRiderLink(rider, thisdate) 					countryID = getNationality(rider, thisdate) 					if countryID then 						riderLink = flag(countryID, thisdate) .. ' ' .. riderLink 					end 				end		 				_,disqualified=isdisqualified(p1344, q) 				if riderLink and disqualified==true then 					riderLink='<s>'..riderLink..'</s>' 				end 			end 		end 	end 	return riderLink, rank, bold end  function teamriderCompetitionranking_main(s, resultTable)--Display the UCI women calendar of one year 	local best_rider, rank 	local lf = s.lf 	local calendarID=s.calendarID 	local seasonID= s.item 	local t_Body ={} 	local w_race=s.w_race 	local gender="m" 	if w_race then gender="f" end  	local temp=firstValue(calendarID, s.property) 	if not temp or temp=="" then  		s.error_message = 2  		if wiki == "ar" then return "" end 	end 	local country=getCountryBool(s.no_country)  	----- Begin of the main part of the code 	local ind=0 	for _, p527 in statements(calendarID, 'P527') do 		local RaceID = p527.mainsnak.datavalue.value.id 		 		local temp=firstValue(RaceID, 'P1346','id') 		local cancelled=false 		if temp and temp=='Q30108381' then --race cancelled 			cancelled=true 		else 			ind=ind+1 		end 		if not cancelled then 			---- Create a row ---- 			local timeOfRace, date_tCell, date_sortkey = fn_date(RaceID) 			local future=compareDate(timeOfRace) 			local parentID, race_tCell, _= fn_race(RaceID,nil,false,timeOfRace,nil,country) 	 			if race_tCell~=nil then --otherwise the class is not display 				local country_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID)  				--create the table 				local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;") 				tRow:node(date_tCell) 				tRow:tag('td'):cssText("text-align:center;padding:0 0.5em"):wikitext(tostring(ind)) --correct only if the races are sorted correctly in wikidata 				tRow:node(country_tCell) 				if country then	tRow:node(race_tCell) end 	 				--logic to get the best rider||ranking 				riderLink, rank, bold=get_competition_bestrider(RaceID, seasonID, gender) 				local tCell=tRow:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.5em") 				if riderLink then 					tCell:wikitext(riderLink) 				elseif future then 					tCell:wikitext("") 				else 					tCell:wikitext(" - ") 				end 				tCell=tRow:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.5em") 				if bold then 					tCell:cssText("font-weight:bold;") 				end 				if rank then 					tCell:wikitext(rank) 				elseif future then 					tCell:wikitext("")			 				else 					tCell:wikitext(" - ") 				end 				---- Add the row to the table 				t_Body[#t_Body + 1] = {date_sortkey, tRow} 			end 		end  	end  	return sortAndConcat(t_Body, resultTable) end  --=== Z) Miscellaneous / Other / Tests  --[[ Give access to a local variable. Used by other modules. ]] function p.getLocal(name) 	if name == 'getTeamLinkCat' then return getTeamLinkCat end 	if name == 'getStatementForTime' then return getStatementForTime end end  function p.testlocal(frame) --function to test local functions 	local function_name=frame.args[1] 	local argu=frame.args 	local temp, temp2  	if function_name=='firstValue' then 		return firstValue(argu[2],argu[3],argu[4]) 	elseif function_name=='getOfficialName' then 		temp, temp2 =getOfficialName(argu[2],argu[3],argu[4]) 		return temp 	elseif function_name=='getRiderLink' then 		if argu[3]=="nil" then arg3=nil else arg3=argu[3] end 		temp=getRiderLink(argu[2],arg3) --only first arg returned 		return temp 	elseif function_name=='funcDate' then 		return funcDate(argu[2],argu[3]) 	elseif function_name=='funcDateFigure' then 		return funcDateFigure(argu[2],argu[3])		 	elseif function_name=='getStartEndTime1' then	 		temp, temp2=getStartEndTime(argu[2],argu[3],argu[4]) 		return temp 	elseif function_name=='getStartEndTime2' then	 		temp, temp2=getStartEndTime(argu[2],argu[3],argu[4]) 		return temp2 	elseif function_name=='getPeriodSub' then 		temp, temp2=getPeriodSub(argu[2],argu[3],toboolean(argu[4])) 		return temp 	elseif function_name=='getTeam' then 		temp=getTeam(argu[2],argu[3],argu[4]) 		if temp then return temp else return 'nil' end 	elseif function_name=='getStatementForTime' then 		temp=getStatementForTime(argu[2],argu[3],argu[4])	 		if temp then 			return temp.mainsnak.datavalue.value.id 		else 			return 'nil' 		end 	elseif function_name=='getTeamLinkCat' then 		temp=getTeamLinkCat(argu[2],argu[3],toboolean(argu[4]))	 		if temp then return temp else return 'nil' end 	elseif function_name=='getTeamLinkCat2' then 		temp, temp2=getTeamLinkCat(argu[2],argu[3],toboolean(argu[4]))	 		if temp2 then return temp2 else return 'nil' end 	elseif function_name=='getPlaceLink' then  		if argu[3]=="nil" then arg3=nil else arg3=argu[3] end 		return getPlaceLink(argu[2],arg3) 	elseif function_name=='getPlaceLink2' then 		 		return getPlaceLink(argu[2],argu[3],nil,true) 	elseif function_name=='seasonToTeamID' then 		if argu[2]=="nil" then arg2=nil else arg2=argu[2] end 		return tostring(seasonToTeamID(arg2)) 	elseif function_name=='translate' then 		return translate(argu[2],tonumber(argu[3]),toboolean(argu[4])) 	elseif function_name=="classLinkFn" then 		return classLinkFn(argu[2]) 	elseif function_name=='raceLink' then 		return tostring(raceLink(argu[2])) 	elseif function_name=='getMainRaceLink' then 		if argu[5]=="nil" then arg5=nil else arg5=argu[5] end 		if argu[3]=='stage' then arg3='stage' else arg3=tonumber(argu[3]) end 		return tostring(getMainRaceLink(argu[2],arg3,argu[4], arg5,argu[6])) 	elseif  function_name=='getYear' then 		return getYear(argu[2]) 	elseif function_name=='getCountryName' then 		return tostring(getCountryName(argu[2])) 	elseif function_name=='getTeamCodeCat' then 		return tostring(getTeamCodeCat(argu[2],argu[3])) 	elseif function_name=='getTeamCode' then 		return tostring(getTeamCode(argu[2],argu[3],argu[4])) 	elseif function_name=='getCountryBool' then 		return tostring(getCountryBool({argu[2],argu[3]})) 	elseif function_name=='WPlinkpure' then 		return WPlinkpure(argu[2]) 	elseif function_name=='uciCodeCountry' then 		return uciCodeCountry(argu[2]) 	elseif function_name=='isHuman' then 		return tostring(isHuman(argu[2])) 	elseif function_name=='isCountry' then 		return tostring(isCountry(argu[2])) 	elseif function_name=='isWomenrace' then 		return tostring(isWomenrace(argu[2])) 	elseif function_name=='isWomenteam' then 		return tostring(isWomenteam(argu[2]))		 	elseif function_name=='commaStage' then 		temp =commaStage(argu[2],argu[3]) 		return temp["prefix"] 	elseif function_name=='number' then 		return number(argu[2],tonumber(argu[3]), argu[4]) 	elseif function_name=='classToCircuit' then 	    return classToCircuit(argu[2], argu[3], toboolean(argu[5]), nil)  	elseif function_name=='getGenderCode' then 	    return tostring(getGenderCode(argu[2], argu[3])) 	elseif function_name=='calculateTime' then 		return calculateTime(argu[2]) 	elseif function_name=='getClass1' then 		temp, temp2 = getClass(argu[2]) 		return temp  	elseif function_name=='getClass2' then 		temp, temp2 = getClass(argu[2]) 		return temp2 	 	elseif function_name=='infoGetPlace' then 		local details = {{ name = "test", name_plural="tests"}} -- course / not used 		infoGetPlace(details,1, argu[2], argu[3], argu[4]) 		return details[1].content 	elseif function_name=='getFormerNames1' then 		temp=getFormerNames(argu[2],'P1448') 		if temp[1] then 			return temp[1][2]  --period 		else 			return "" 		end 	elseif function_name=='getFormerNames2' then 		temp=getFormerNames(argu[2],'P1448') 		if temp[1] then 			return temp[1][3]  --name 		else 			return "" 		end 	elseif function_name=='getType' then 		return getType(argu[2]) 	elseif function_name=='compareDate' then 		return tostring(compareDate(argu[2])) 	elseif function_name=='officialSite' then 		return officialSite(argu[2]) 	elseif function_name=='trans' then 		return tostring(trans(argu[2], argu[3], argu[4])) 	elseif function_name=='parseDate1' then	 		temp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text") 		return temp1 	elseif function_name=='parseDate2' then	 		temp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text") 		return temp2 	elseif function_name=='parseDate5' then			 		temp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text") 		return temp5 	elseif function_name=='findLastName' then 		return findLastName(argu[2],wiki) 	elseif function_name=='findSortKey' then 		if wiki=="ru" or wiki=="mk" then 			return findSortKey(argu[2],false, true) 		else 			return findSortKey(argu[2],true, false) 		end 	elseif function_name=='calculateAge' then 		temp1, _, _ =calculateAge(argu[2]) 		return temp1 	elseif function_name=='getBirthDeathDate1' then 	    temp1, temp2 =	getBirthDeathDate(argu[2]) 		return temp1 	elseif function_name=='getBirthDeathDate2' then 		temp1, temp2 =	getBirthDeathDate(argu[2]) 		return temp2	 	elseif function_name=='getLocalContent' then 		local details = { 	            	{ name = argu[2], name_plural= argu[3]} 	            } 		local arguments = {} 		arguments[argu[4]]="test"  		getLocalContent(details, arguments) 		return details[1].content 	elseif function_name=='plural1' then	 		_, temp1, temp2=plural(tonumber(argu[2])) 		return temp1 	elseif function_name=='plural2' then	 		_, temp1, temp2=plural(tonumber(argu[2])) 		return temp2 	elseif function_name=='getNationality' then 		return getNationality(argu[2], argu[3]) 	elseif function_name=='getCountryID' then 		return getCountryID(argu[2], argu[3]) 	elseif function_name=='get_formatted_date1' then 		if argu[3]=="nil" then arg3=nil else arg3=argu[3] end 		temp, temp2= get_formatted_date(argu[2], arg3) 		if temp then return temp end 	elseif function_name=='get_formatted_date2' then 		if argu[3]=="nil" then arg3=nil else arg3=argu[3] end 		temp, temp2= get_formatted_date(argu[2], arg3) 		if temp2 then return temp2 end 	elseif function_name=="getSpeed" then 		if argu[4]=="nil" then arg4=nil else arg4=tonumber(argu[4]) end 		return tostring(getSpeed(argu[2], toboolean(argu[3]),arg4, argu[5])) 	elseif function_name=="formatNumber" then 		return formatNumber(tonumber(argu[2]), toboolean(argu[3]),tonumber(argu[4])) 	end end  function p.test_import(frame) 	local function_name=frame.args[1] 	local argu=frame.args  	if function_name=='class_dic' then 		return tostring(data.class_dic[argu[2]]) 	elseif function_name=="class_sort" then 		return tostring(data.class_sort[argu[2]]) 	elseif function_name=='bg_color_table' then	 		local temp = data.bg_color_table[argu[2]] 		temp=string.gsub(temp,'#',"") 		return temp 	end end  return p