پرش به محتوا

ماژول:Wikidata2/نسخه

ویکی‌پدیا، آزادِ دانشنومه، جه

توضیحات این پودمان می‌تواند در ماژول:Wikidata2/نسخه/توضیحات قرار گیرد.

local p = {}
local help_functions = require("Module:Wikidata2/functions")
local filterclaims = require("Module:Wikidata2/filter_claims")
local ill_wd2 = require("Module:Wikidata2/Ill-WD2")

local formatera
local Modulecite
local ModuleGlobes

local citetitle = "ماژول:Cite/نسخه"
local sortingproperties = { "P585", "P571", "P580", "P569", "P582", "P570" }

local sorting_methods = {
	["chronological"] = "chronological",
	["صعودی"] = "chronological",
	["asc"] = "chronological",
	["inverted"] = "inverted",
	["نزولی"] = "inverted",
	["desc"] = "inverted"
}

local function isvalid(x)
	if x and x ~= "" then return x end
	return nil
end

function isntvalid(x)
	if not x or x == "" or x == nil then return true end
	return lse
end

function get_entityId(options)
	local id = options.entityId or options.entityid or options.id or options.qid
	if isntvalid(id) then
		if isvalid(options.page) then
			id = mw.wikibase.getEntityIdForTitle(options.page)
		end
	end
	--mw.log("id :" .. id)
	return id or ""
end

function addTrackingCategory(options)
	return ""
end

function catewikidatainfo(options)
	return ''
end

function getDateArb(claim, sorting_properties)
	local sortingproperty = sorting_properties
	if claim.mainsnak.snaktype == "value" then
		local item = claim.mainsnak.datavalue.value["numeric-id"]
		if claim.mainsnak.datavalue.value["entity-type"] == "item" then
			item = "Q" .. item
		elseif claim.mainsnak.datavalue.value["entity-type"] == "property" then
			item = "P" .. item
		end
		for k, prop in pairs(sortingproperty) do
			local date = formatStatements({
				property = prop,
				entityId = item,
				firstvalue = "t",
				noref = "t",
				modifytime = "q"
			})
			if isvalid(date) then
				--mw.log("item:" .. item .. ", prop:" .. prop .. ", date:" .. date)
				return date
			end
		end
	end
end

function formatError(key)
	return help_functions.i18n.errors[key]
end

function Labelfunction(entityId, label, labeloption, options) -- label with no arwiki sitelink
    local jlabel = label                           --help_functions.formatcharacters(label, options) -- The label
    local mzn = help_functions.labelIn("mzn", entityId) -- هرجا falabel بود فقط اسمش اینه در عمل مازنی است
    --mw.log('mzn'..mzn)
    local falabel = mzn                             --help_functions.formatcharacters(mzn, options)
    
    if isvalid(labeloption) then
        jlabel = labeloption

    elseif isvalid(options.illwd2) and isntvalid(options.nolink) then
        jlabel = ill_wd2.Ill_WD2_label(entityId, falabel, options)

    elseif isvalid(options.enlabelcate) then
        if isntvalid(falabel) then
            jlabel = label --help_functions.formatcharacters(label, options)
            if isvalid(jlabel) then
                jlabel = jlabel --.. " [[" .. help_functions.i18n.nofarsilabel .. "|" .. entityId .. "]]"
            end
        end
    else --if isvalid(options.justfarsi) then
        if isvalid(falabel) then
            jlabel = falabel
        else
            jlabel = nil
        end
    end

    if isvalid(jlabel) then
        --mw.log('jlabel' .. jlabel )
        return jlabel .. catewikidatainfo(options)
    end
end

function formatOneStatement(statement, ref, options)
	local vava = nil
	local stat = formatStatement(statement, options)
	if stat == nil then
		return { v = vava, raw = stat }
	end

	if not stat.qualifiers then
		stat.qualifiers = {}
	end

	local s = stat.value
	local P585 = stat.P585
	local tf = stat.tifr
	local awardqual = stat.foto
	local ro = stat.ro
	local qp1a = stat.qp1a
	local onlyqualifier = stat.onlyqualifier
	local qp1 = stat.qp1
	local qp2 = stat.qp2
	local qp3 = stat.qp3
	local qp4 = stat.qp4
	local qp5 = stat.qp5
	local reff = stat.reff
	local QPrefix
	local QSuffix
	if isntvalid(s) then s = nil end
	if s then
		if reff and isvalid(options.reff) then
			s = s .. reff
		end
		if isvalid(options.template) then
			s =
				mw.getCurrentFrame():expandTemplate {
					title = options.template,
					args = {
						stat.QQ1,
						s,
						stat.QQ2,
						stat.QQ3,
						stat.QQ4,
						stat.QQ5,
						stat.QQ6,
						stat.QQ7,
						stat.QQ8,
						stat.QQ9,
						stat.QQ10,
						entityId = options.entityId,
						v1 = options.v1,
						id = stat.ID
					}
				}
		end
		if isvalid(options.football) then
			s =
				mw.getCurrentFrame():expandTemplate {
					title = "صندوق معلومات سيرة كرة قدم/سطر فريق",
					args = {
						stat.qualifiers.P580 or "",
						stat.qualifiers.P582 or "",
						s,
						stat.amatch,
						stat.goal
					}
				}
		end

		if isvalid(options.office) then
			s =
				mw.getCurrentFrame():expandTemplate {
					title = "معلومات صاحب منصب/منصب ويكي بيانات/نواة",
					args = {
						office = s,
						termstart = stat.qualifiers.P580 or "",
						termend = stat.qualifiers.P582 or "",
						constituency = stat.qualifiers.P768 or "",
						predecessor = stat.qualifiers.P1365 or "",
						successor = stat.qualifiers.P1366 or "",
						series = stat.qualifiers.P1545 or "",
						of = stat.qualifiers.P642 or "",
						electedin = stat.qualifiers.P2715 or "",
						jurisdiction = stat.qualifiers.P1001 or "",
						employer = stat.qualifiers.P108 or "",
						entityId = options.entityId
					}
				}
		end

		if isvalid(options.office2) then
			s =
				mw.getCurrentFrame():expandTemplate {
					title = "معلومات صاحب منصب/منصب ويكي بيانات2",
					args = {
						office = s,
						termstart = stat.qualifiers.P580 or "",
						termend = stat.qualifiers.P582 or "",
						constituency = stat.qualifiers.P768 or "",
						predecessor = stat.qualifiers.P1365 or "",
						successor = stat.qualifiers.P1366 or "",
						series = stat.qualifiers.P1545 or "",
						P642 = stat.pp642
					}
				}
		end

		function qoo(Prefix, qualpref, p, Suffix)
			if isvalid(p) then
				stri = Prefix .. (qualpref or "") .. " " .. p .. Suffix
				return stri
			end
		end

		QPrefix = options.qualifierprefix or ""
		QSuffix = options.qualifiersuffix or ""
		--///////////////////

		if qp1 and options.qual1 and options.qual1 and qp1a and isvalid(options.qual1a) then
			s =
				s ..
				"، " ..
				qoo("", options.qual1pref, qp1, (options.qual1suff or "")) ..
				"، " .. qoo("", options.qp1apref, qp1a, (options.qp1asuff or ""))
		elseif qp1 and isvalid(options.qual1) then
			s = s .. "، " .. (options.qual1pref or "") .. qp1 .. (options.qual1suff or "")
		elseif qp1a and isvalid(options.qual1a) then
			s = s .. "، " .. (options.qp1apref or "") .. qp1a
		end

		if qp2 and isvalid(options.qual2) then
			q2 = qoo(QPrefix, (options.qual2pref or ""), qp2, QSuffix .. (options.qual2suff or ""))
			if options.qual2pref == "**" then
				q2 = "\n** " .. qoo(QPrefix, "", qp2, QSuffix .. (options.qual2suff or ""))
			end
			s = s .. q2
		end

		if qp3 and isvalid(options.qual3) then
			s = s .. qoo(QPrefix, options.qual3pref, qp3, QSuffix)
		end
		if qp4 and isvalid(options.qual4) then
			s = s .. qoo(QPrefix, options.qual4pref, qp4, QSuffix)
		end
		if qp5 and isvalid(options.qual5) then
			s = s .. qoo(QPrefix, options.qual5pref, qp5, QSuffix)
		end
		if isvalid(options.justthisqual) then
			if onlyqualifier then
				s = (options.qualifierprefix or "") .. onlyqualifier
			else
				s = nil -- We need only the qualifier
			end
		end
		if isvalid(ro) and isvalid(options.withro) then
			s = s .. qoo(QPrefix, "", ro, QSuffix)
		end
		if P585 and isvalid(options.withdate) then
			if options.withdate == "y" then
				s = s .. " (سال " .. P585 .. ")"
			elseif options.withdate == "در" then
				s = s .. " در " .. P585
			else
				s = s .. QPrefix .. P585 .. QSuffix
			end
		end
		if awardqual and isvalid(options.awardqua) then
			s = s .. qoo(QPrefix, "", awardqual, QSuffix)
		end
		local bothdates = options.bothdates
		if tf and isvalid(bothdates) then
			if bothdates == "line" then
				s = s .. mw.text.tag("br") .. qoo(QPrefix, "", tf, QSuffix)
			elseif bothdates == "before" then
				s = "(" .. tf .. ") " .. s
			else
				s = s .. qoo(QPrefix, "", tf, QSuffix)
			end
		end

		if type(ref) == 'table' or (isvalid(options.noref)) or
			(isvalid(options.justthisqual))
		then
			vava = s
		else
			local t = formatReferences(statement, options)
			stat.ref = t
			if isvalid(options.justref) then
				vava = t
			elseif isvalid(options.onlyvaluewithref) then
				if isvalid(t) then
					vava = s .. t
				end
			else
				vava = s .. t
			end
		end
	end

	return { v = vava, raw = stat }
end

--[[

  sort claims functions

]]

function comparedates(a, b) -- returns true if a is earlier than B or if a has a date but not b
	local a = tonumber(a) or a
	local b = tonumber(b) or b
	if a and b then
		return a > b
	elseif a then
		return true
	end
end

function get_sorting_properties(options)
	if type(options.sortingproperty) == "table" then
		return options.sortingproperty
	elseif type(options.sortingproperty) == "string" and options.sortingproperty ~= "" then
		return mw.text.split(options.sortingproperty, ",")
	else
		return sortingproperties
	end
end

function getqualifierbysortingproperty(claim, sortingproperty)
	for k, v in pairs(sortingproperty) do
		if claim.qualifiers and claim.qualifiers[v] and claim.qualifiers[v][1].snaktype == "value" then
			vali = claim.qualifiers[v][1].datavalue.value.time or claim.qualifiers[v][1].datavalue.value.amount
			if vali:sub(1, 1) == "+" then
				vali = vali:sub(2)
			end
			--mw.log(vali)
			return vali
		end
	end
	return nil
end

function sortbyqualifier(claims, sorting_properties, options)
	if not sorting_properties or #sorting_properties == 0 then
		sorting_properties = get_sorting_properties(options)
	end
	local sortbytime = sorting_methods[options.sortbytime] or options.sortbytime
	table.sort(
		claims,
		function(a, b)
			local timeA = getqualifierbysortingproperty(a, sorting_properties)
			local timeB = getqualifierbysortingproperty(b, sorting_properties)
			if sortbytime == "inverted" then
				return comparedates(timeB, timeA)
			else
				return comparedates(timeA, timeB)
			end
		end
	)
	return claims
end

function sortbyqualifiernumber(claims, sorting_properties, options)
	if not sorting_properties or #sorting_properties == 0 then
		sorting_properties = get_sorting_properties(options)
	end
	local sortbynumber = sorting_methods[options.sortbynumber] or options.sortbynumber
	table.sort(
		claims,
		function(a, b)
			local timeA = getqualifierbysortingproperty(a, sorting_properties)
			local timeB = getqualifierbysortingproperty(b, sorting_properties)
			if sortbynumber == "inverted" then
				return comparedates(timeB, timeA)
			else
				return comparedates(timeA, timeB)
			end
		end
	)
	return claims
end

function sortbyarb(claims, sorting_properties, options)
	if not sorting_properties or #sorting_properties == 0 then
		sorting_properties = get_sorting_properties(options)
	end
	local sortingmethod = options.sortbyarbitrary or options.sortingmethod
	sortingmethod = sorting_methods[sortingmethod] or sortingmethod
	--mw.log("sortbyarb: " .. sortingmethod)

	table.sort(
		claims,
		function(a, b)
			local timeA = getDateArb(a, sorting_properties)
			local timeB = getDateArb(b, sorting_properties)
			if sortingmethod == "inverted" then
				return comparedates(timeB, timeA)
			else
				return comparedates(timeA, timeB)
			end
		end
	)
	return claims
end

function sort_claims(claims, options)
	local sortingmethod = options.sortbyarbitrary or options.sortingmethod
	local sorting_properties = get_sorting_properties(options)

	if isvalid(options.sortbytime) and sorting_methods[options.sortbytime] then
		claims = sortbyqualifier(claims, sorting_properties, options)
		--
	elseif isvalid(options.sortbynumber) and sorting_methods[options.sortbynumber] then
		claims = sortbyqualifiernumber(claims, sorting_properties, options)
		--
	elseif isvalid(sortingmethod) and sorting_methods[sortingmethod] then
		claims = sortbyarb(claims, sorting_properties, options)
	end
	return claims
end

function filter_claims(claims, options)
	local claims = claims
	--===========
	claims = filterclaims.filter_claims(claims, options)
	--===========
	return claims
end

function formatStatements(options, ref)
	local valuetable = {} -- formattedStatements
	local claims = {}

	if isntvalid(options.property) and isvalid(options.pid) then
		options.property = options.pid
	end

	if isntvalid(options.property) and isntvalid(options.pid) then
		return formatError("property-param-not-provided")
	end
	local option1 = options.option1
	if option1 and options.option1value then
		options[option1] = options.option1value
		options['"' .. option1 .. '"'] = options.option1value
	end
	if type(ref) == "table" then
		claims = ref[options.property] or {}
		mw.log("claims = ref[options.property]")
	else
		--===========
		--Get entity
		local qid = get_entityId(options)
		if isvalid(qid) then
			local check = mw.ustring.match(qid, "Q%d+") or mw.ustring.match(qid, "P%d+")
			if check == nil then
				mw.addWarning(qid .. " ونه ویکی دیتای شناسه معتبر نی‌یه")
				return ""
			else
				options.entityId = qid
				options.qid = qid
			end
		else
			mw.addWarning("entityId غير معرف")
			return ""
		end
		local entity = nil
		if options.entity and type(options.entity) == "table" then
			entity = options.entity
		else
			entity = mw.wikibase.getEntityObject(qid)
		end
		--local property=mw.wikibase.resolvePropertyId(options.property:upper())
		local property = options.property:upper()

		if not entity then
			return ""
		end
		if not entity.claims or not entity.claims[property] then
			if isvalid(options.otherproperty) then
				options.property = options.otherproperty
				property = options.otherproperty:upper()
			end
		end
		if not property then
			return ""
		end
		if not entity.claims or not entity.claims[property] then
			return ""
		end
		--===========
		--Format statement and concat them cleanly
		if options.rank == "best" or not options.rank then
			--claims = entity:getAllStatements( property )
			claims = entity:getBestStatements(property)
		elseif options.rank == "valid" then
			for i, statement in pairs(entity.claims[property]) do
				if statement.rank == "preferred" or statement.rank == "normal" then
					table.insert(claims, statement)
				end
			end
		elseif options.rank == "all" then
			for i, statement in pairs(entity.claims[property]) do
				table.insert(claims, statement)
			end
		else
			for i, statement in pairs(entity.claims[property]) do
				if statement.rank == options.rank then
					table.insert(claims, statement)
				end
			end
		end
	end
	--===%%##$$====
	claims = filter_claims(claims, options)

	claims = sort_claims(claims, options)

	local statementsraw = {}
	local All_claims = claims
	if claims then
		--==========================================
		if options["property-module"] or options["property-function"] then
			if not options["property-module"] or not options["property-function"] then
				return formatError("unknown-property-module")
			end
			local formatter = require("Module:" .. options["property-module"])
			if not formatter then
				return formatError("property-module-not-found")
			end
			local fun = formatter[options["property-function"]]
			if not fun then
				return formatError("property-function-not-found")
			end

			mw.log("work with property-module: " .. options["property-module"] .. "|" .. options["property-function"])
			return fun(claims, options)
		else
			--==========================================
			local numval1
			if isvalid(options.numval1) and type(options.numval1) ~= "number" then
				numval1 = tonumber(options.numval1)
			end
			for i, statement in pairs(claims) do
				options.num = i
				local va = formatOneStatement(statement, ref, options)
				if va.v then
					if numval1 then
						if numval1 > #valuetable then
							table.insert(valuetable, va.v)
						end
					else
						table.insert(valuetable, va.v)
					end
				end
				table.insert(statementsraw, va.raw)
			end
		end
	end
	local priff = ""
	local sep = "، و "
	if options.separator and options.separator == "" and options.conjunction and options.conjunction == "" then
		sep = ""
	elseif isvalid(options.separator) == "br" or isvalid(options.conjunction) == "br" then
		sep = "\n"
	elseif isvalid(options.separator) == "*" or isvalid(options.conjunction) == "*" or isvalid(options.sep) == "*" then
		priff = "\n*"
		sep = "\n*"
	elseif isvalid(options.separator) == "#" or isvalid(options.conjunction) == "#" or isvalid(options.sep) == "#" then
		priff = "\n#"
		sep = "\n#"
	elseif isvalid(options.separator) then
		sep = options.separator
	elseif isvalid(options.conjunction) then
		sep = options.conjunction
	end
	if isvalid(options.justref) then sep = "" end

	local tot = mw.text.listToText(valuetable, sep, sep)
	if #valuetable > 1 then tot = priff .. tot end

	if isntvalid(tot) then tot = nil end
	if isvalid(options.raw) then
		if isvalid(options.rawtolua) then
			return mw.getCurrentFrame():extensionTag("source", mw.dumpObject(statementsraw), { lang = "lua" })
		end
		return statementsraw
	end
	if isvalid(options.returnnumberofvalues) or options.returnnumberofvalues == true then
		return tot, #valuetable
	end
	if isvalid(options.numberofclaims) then
		return #All_claims
	end
	return tot
end

function formatReferences(statement, options)
	local reference = {}
	if statement.references then
		if Modulecite == nil then
			Modulecite = require(citetitle)
		end
		for i, ref in pairs(statement.references) do
			local s = nil
			if ref.snaks then
				s = Modulecite.citeitem(ref.snaks, ref.hash, options)
			end
			table.insert(reference, s)
		end
	end
	return table.concat(reference)
end

function formatqualifiers(statement, s, options)
	s.qualifiers = {}
	function qua(p, firstvalue, modifytime, Formatting)
		if isvalid(p) then
			vvv = formatStatements({
				property = p,
				enlabelcate = "t",
				illwd2 = options.illwd2,
				firstvalue = (firstvalue or ""),
				modifytime = (modifytime or "longdate"),
				formatting = Formatting or "",
				noref = "t",
				formatcharacters = options.formatcharacters
			}, statement.qualifiers) or ""
			s.qualifiers[p] = vvv
			return vvv
		end
	end

	s.ID = ""
	if statement.mainsnak.datavalue then
		s.ID = help_functions.getEntityIdFromValue(statement.mainsnak.datavalue.value)
	end

	if isvalid(options.template) then
		s.QQ1 = qua(options.Q1, "", "", options.Q1formatting)
		s.QQ2 = qua(options.Q2, "", "", options.Q2formatting)
		s.QQ3 = qua(options.Q3, "", "", options.Q3formatting)
		s.QQ4 = qua(options.Q4, "", "", options.Q4formatting)
		s.QQ5 = qua(options.Q5, "", "", options.Q5formatting)
		s.QQ6 = qua(options.Q6, "", "", options.Q6formatting)
		s.QQ7 = qua(options.Q7, "", "", options.Q7formatting)
		s.QQ8 = qua(options.Q8, "", "", options.Q8formatting)
		s.QQ9 = qua(options.Q9, "", "", options.Q9formatting)
		s.QQ10 = qua(options.Q10, "", "", options.Q10formatting)
	end

	if isvalid(options.football) then
		if statement.qualifiers.P1350 or statement.qualifiers.P1351 then
			s.amatch = qua("P1350", "true")
			s.goal = qua("P1351", "true")
		end
	end

	if (isvalid(options.football)) or (isvalid(options.office)) then
		s.start1 = qua("P580", "true")

		s.finish1 = qua("P582", "true")
	end

	if isvalid(options.office) then
		if
			statement.qualifiers.P580 or statement.qualifiers.P582 or statement.qualifiers.P1365 or
			statement.qualifiers.P1366
		then
			s.before1 = qua("P1365", "true")
			s.after1 = qua("P1366", "true")
			s.constituency1 = qua("P768")
			s.series1 = qua("P1545")
			s.electedin1 = qua("P2715", "")
			s.pp1001 = qua("P1001")
			s.pp108 = qua("P108")
			s.pp642 = qua("P642")
		end
	end

	if statement.qualifiers.P585 then
		s.P585 = qua("P585", "true", options.modifyqualifiertime)
	end

	local qwe = options.qwer
	if statement.qualifiers.qwe then
		s.ro = qua(qwe, "true")
	end
	local bothdates_option = options.bothdates
	if isvalid(bothdates_option) then
		if statement.qualifiers.P580 or statement.qualifiers.P582 then
			local f = qua("P580", "true", options.modifyqualifiertime)
			if statement.qualifiers.P582 then
				local t = qua("P582", "true", options.modifyqualifiertime)
				s.tifr = f .. "–" .. t
				if not statement.qualifiers.P580 then
					s.tifr = "حتى " .. t
				end
			else
				s.tifr = "منذ " .. f
			end
		end
	end

	if isvalid(options.awardqua) then
		if statement.qualifiers.P585 or statement.qualifiers.P1346 then
			local fo = qua("P585", "true", options.modifyqualifiertime)
			local to = qua("P1346", "true")
			s.foto = fo .. " " .. mw.text.tag("span", {}, " " .. to .. "")
		end
	end

	function quaaal(opti, options)
		if isvalid(opti) and statement.qualifiers[opti] then
			kkk = formatStatements({
				property = opti,
				noref = "t",
				separator = options.qualifierseparator,
				conjunction = options.qualifierconjunction,
				size = options.size,
				formatting = options.qualformatting,
				image = options.image,
				modifytime = options.modifyqualifiertime,
				enlabelcate = "t",
				langpref = options.langpref,
				showlang = options.showlang,
				illwd2 = "t",
				formatcharacters = options.formatcharacters
			}, statement.qualifiers) or ""

			s.qualifiers[opti] = kkk
			return kkk
		end
	end

	if s then
		if isvalid(options.justthisqual) and statement.qualifiers[options.justthisqual] then
			s.onlyqualifier = quaaal(options.justthisqual, options)
		end
		if isvalid(options.qual1) and statement.qualifiers[options.qual1] then -- عرض تصفيات لبنود الخاصية
			s.qp1 = quaaal(options.qual1, options)
			if isntvalid(s.qp1) and options.qualformatting == "sitelink" then
				return nil
			end
		end
		if isvalid(options.qual1a) and statement.qualifiers[options.qual1a] then
			s.qp1a = quaaal(options.qual1a, options)
		end
		if isvalid(options.qual2) and statement.qualifiers[options.qual2] then
			s.qp2 = quaaal(options.qual2, options)
			if isntvalid(s.qp2) and options.qualformatting == "sitelink" then
				return nil
			end
		end

		if isvalid(options.qual3) and statement.qualifiers[options.qual3] then
			s.qp3 = quaaal(options.qual3, options)
			if isntvalid(s.qp3) and options.qualformatting == "sitelink" then
				return nil
			end
		end
		if isvalid(options.qual4) and statement.qualifiers[options.qual4] then
			s.qp4 = quaaal(options.qual4, options)
		end
		if isvalid(options.qual5) and statement.qualifiers[options.qual5] then
			s.qp5 = quaaal(options.qual5, options)
		end
	end
	return s
end

function formatStatement(statement, options)
	if options["claim-module"] or options["claim-function"] then
		if not options["claim-module"] or not options["claim-function"] then
			return { value = formatError("unknown-claim-module") }
		end
		local formatter = require("Module:" .. options["claim-module"])
		if not formatter then
			return { value = formatError("claim-module-not-found") }
		end
		local fun = formatter[options["claim-function"]]
		if not fun then
			return { value = formatError("claim-function-not-found") }
		end
		return { value = fun(statement, options) }
	elseif statement.type == "statement" then
		local s = formatSnak(statement.mainsnak, options)
		if isvalid(s) then
			if statement.qualifiers then
				s = formatqualifiers(statement, s, options)
				-- if isvalid(qualu) then table.insert(qualu) end
			end
			if statement.references then
				if isvalid(options.reff) then
					s.reff = formatReferences(statement, options)
				end
			end
		end
		return s
	elseif not statement.type then
		return formatSnak(statement, options)
	end
	return { value = formatError("unknown-claim-type") }
end

function formatSnak(snak, options)
	if snak.snaktype == "somevalue" then
		if options.somevalue then
			if isntvalid(options.somevalue) then
				return nil
			else
				return { value = options.somevalue }
			end
		end
		return { value = help_functions.i18n["somevalue"] }
	elseif snak.snaktype == "novalue" then
		if options.novalue then
			if isntvalid(options.novalue) then
				return nil
			else
				return { value = options.novalue }
			end
		end
		return { value = help_functions.i18n["novalue"] }
	elseif snak.snaktype == "value" then
		local s = formatDatavalue(snak.datavalue, snak.datatype, options)
		if s and s.value and isvalid(s.value) and isvalid(options.prefix) then
			s.value = options.prefix .. " " .. s.value
		end
		if s and s.value and isvalid(s.value) and isvalid(options.suffix) then
			s.value = s.value .. " " .. options.suffix
		end
		return s
	else
		return { value = formatError("unknown-snak-type") }
	end
end

function get_property1(options, item)
	--[[ function to get countries flags without reload large countries items ]]
	local property1 = options.property1
	local caca = formatStatements({
		property = options.property1,
		otherproperty = options.otherproperty1,
		entityId = item,
		noref = options.noref,
		rank = options.property1rank,
		pattern = options.property1pattern,
		formatting = options.property1formatting,
		size = options.size,
		image = options.image,
		firstvalue = "t"
	})
	return caca
end

function formatwikibaseitem(datavalue, datatype, options)
	--[[ datatype	wikibase-item  ]]
	local item = help_functions.getEntityIdFromValue(datavalue.value)
	local itemValue = formatEntityId(item, options).value
	local Format = options.formatting
	local Skipped = help_functions.skiip[options.property] or {}
	for k, v in pairs(Skipped) do
		if datavalue.value.id == v then
			return { value = "" }
		end
	end
	if isvalid(Format) then
		if Format == "raw" then
			--mw.log("raw: " .. item )
			return { value = item }
		elseif Format == "rawtotemplate" then
			--mw.log("options")
			--mw.log(options)
			if isvalid(options.rawtotemplate) then
				return {
					value = mw.getCurrentFrame():expandTemplate {
						title = options.rawtotemplate,
						args = {
							q = item,
							no1 = options.no1 or "",
							no2 = options.no2 or ""
						}
					} .. "\n"
				}
			end
		elseif Format == "fu" then
			fu_temp = "Cycling race/stageclassification2"
			return { value = mw.getCurrentFrame():expandTemplate { title = fu_temp, args = { item, type = "2" } } }
		elseif Format == "sitelink" then -- for Wikidata property giving Wikimedia list
			return { value = formatsitelink(datavalue.value.id, options) }
		elseif Format == "sitelink1" then
			return { value = formatsitelink1(datavalue.value.id, options) }
		else
			return {
				value = help_functions.formatFromPattern(help_functions.formatcharacters(datavalue.value, options),
					options)
			}
		end
	elseif isvalid(options.property1) and options.property1:upper():sub(1, 1) == "P" then
		for i, statement in pairs(datavalue) do
			caca = get_property1(options, item)
			if isvalid(itemValue) then
				if isvalid(caca) then
					cooooca = (options.property1pref or "") .. "" .. caca .. "" .. (options.property1suff or "")
					if isvalid(options.property1after) then
						return { value = itemValue .. cooooca }
					else
						return { value = cooooca .. " " .. itemValue }
					end
				else
					return { value = itemValue }
				end
			end
		end
	elseif isvalid(options.propertyimage) then
		------------------------------
		mw.log("propertyimage")
		local p_f = options.propertyimageformatting or options.formattingpropertyimage
		for i, statement in pairs(datavalue) do
			local vas = formatStatements({
				property = options.propertyimage,
				formatting = p_f,
				entityId = item,
				noref = options.noref,
				rank = options.rank,
				pattern = options.pattern,
				size = options.size,
				image = options.image,
				avoidvalue = options.avoidvaluepropertyimage,
				firstvalue = "t",
				nolink = options.nolink
			})
			if isvalid(vas) then
				return { value = vas }
			end
		end
	elseif isvalid(options.property2) then
		------------------------------
		for i, statement in pairs(datavalue) do
			local caca = formatStatements({
				property = options.property2,
				entityId = item,
				noref = options.noref,
				rank = options.rank,
				pattern = options.property2pattern,
				size = options.size,
				image = options.image,
				propertyimage = options.property3,
				firstvalue = "t"
			})
			if isvalid(itemValue) then
				if isvalid(caca) then
					return { value = caca .. " " .. itemValue }
				else
					return { value = itemValue }
				end
			end
		end
	elseif isvalid(options.cateforjop) then
		------------------------------
		for i, statement in pairs(datavalue) do
			local caca = formatStatements({
				property = options.cateforjop,
				entityId = item,
				noref = "t",
				rank = options.rank,
				pattern = options.pattern,
				size = options.size,
				image = options.image,
				propertyimage = options.cateforjop1,
				firstvalue = "t",
				formattingpropertyimage = options.formattingcateforjop,
				nolink = options.nolink
			})
			if isvalid(caca) then
				return { value = caca }
			else
			end
		end
	else
		return { value = formatEntityId(item, options).value, item = item }
	end
end

function formatwikibaseproperty(datavalue, datatype, options)
	--[[ datatype	wikibase-property	]]
	if isvalid(options.formatting) then
		if options.formatting == "raw" then
			tid = help_functions.getEntityIdFromValue(datavalue.value)
		else
		end
	else
		tid = formatEntityId(help_functions.getEntityIdFromValue(datavalue.value), options).value
	end
	return { value = tid }
end

function formatcommonsMedia(datavalue, datatype, options)
	--[[  commonsMedia ]]
	local border = "border"
	if isvalid(options.center) then
		border = "center"
	end
	if isvalid(options.image) then
		tid = "[[file:" .. datavalue.value .. "|" .. (options.size or "120") .. "px|" .. border .. "]]"
	else
		tid = help_functions.formatcharacters(datavalue.value, options)
	end
	return { value = tid }
end

function formatexternalid(datavalue, datatype, options)
	local result = help_functions.formatcharacters(datavalue.value, options)
	if isntvalid(options.pattern) then
		return { value = result } --just return value
	end
	local par = options.pattern
	local patter = formatStatements({
		property = "P1630",
		entityId = options.property,
		firstvalue = "true",
		noref =
		"true",
		rank = "all"
	}) -- get formatter URL
	local po = help_functions.formatFromPattern(datavalue.value, { pattern = patter })
	local plabel = mw.wikibase.label(options.property) or po
	local ppp = mw.ustring.gsub(po, " ", "_")
	local tid = help_functions.formatFromPattern(result, options)

	local results = {
		["autourl"]  = ppp,                                   -- like http://example.com/$1.html
		["autourl2"] = "[" .. ppp .. " " .. datavalue.value .. "]", -- like [http://example.com/$1.html $1]
		["autourl3"] = "[" .. ppp .. " " .. ppp .. "]",       -- like [http://example.com/$1.html http://example.com/$1.html]
		["autourl4"] = "[" .. ppp .. " " .. plabel .. "]",
	}
	if isvalid(patter) then -- if P1630 are there
		if results[par] then
			tid = results[par]
		end
	else        --	 P1630 are not there
		if par == "autourl" or par == "autourl2" or par == "autourl3" or par == "autourl4" then
			tid = result --just return value
		end
	end
	return { value = tid }
end

function formatcoordinate(datavalue, datatype, options)
	--[[ datatype  globe-coordinate]]
	local coord = datavalue.value
	local globe = datavalue.value.globe
	if ModuleGlobes == nil then
		ModuleGlobes = require("Module:Wikidata2/Globes")
	end
	local globe2 = ModuleGlobes[globe] or ""

	local results = {
		["latitude"]  = coord.latitude,
		["longitude"] = coord.longitude,
		["dimension"] = coord.dimension,
		["precision"] = coord.precision,
		["globe"]     = globe:match("Q%d+"),
		["globe2"]    = globe2,
	}
	local pro = ""
	if isvalid(options.formatting) then
		pro = results[options.formatting]
	else
		pro = mw.getCurrentFrame():expandTemplate {
			title = "coord", args = { coord.latitude, coord.longitude, display = inline }
		} .. catewikidatainfo(options)
	end
	return { value = pro }
end

function formatquantity(datavalue, datatype, options)
	--[[ datatype quantity]]
	local amount = datavalue.value.amount
	local unit = datavalue.value.unit
	local cat
	amount = mw.ustring.gsub(amount, "+", "")
	if unit then
		unit = unit:match("Q%d+")
	end
	if formatera == nil then
		formatera = require("Module:Wikidata2/Math")
	end
	local number = formatera.newFromWikidataValue(datavalue.value)

	local unitraw = unit
	if unit then
		-- يتحقق اذا كان هناك اي اختصار لوحدة القياس
		local unitlab = isvalid(options.label) or
			formatStatements({ property = "P5061", entityId = unit, numval1 = "1", noref = "t", langpref = "" })
			or ""

		if isvalid(unitlab) and isntvalid(options.nounitshort) then
			mw.addWarning("unitlab:" .. unitlab .. ", for unit: " .. unit)
			local s = formatEntityId(unit, { label = unitlab, nolink = (options.nounitlink or options.nolink) })
			unit = s.value
			cat = s.cat
		else
			local s = formatEntityId(unit, { nolink = options.nounitlink })
			unit = s.value
			cat = s.cat
		end
	end
	if options.formatcharacters and options.formatcharacters == "formatnum" then
		amount = help_functions.make_format_num(amount)
	end
	local Value = amount .. " " .. (unit or "")
	if isvalid(options.nounit) then
		Value = amount
	end
	return { value = Value, amount = amount, unit = unit, unitraw = unitraw, cat = cat }
end

function formaturl(datavalue, datatype, options)
	--[[ datatype	url ]]
	local label = options.label
	if isvalid(options.urllabel) then
		label = options.urllabel
	end
	va = mw.ustring.gsub(datavalue.value, " ", "_")
	if isvalid(label) then
		pro = "[" .. va .. " " .. label .. "]"
	else
		pro = va
	end
	return { value = pro }
end

function formatmonolingualtext(datavalue, datatype, options)
	--[[ datatype	 monolingualtext ]]
	local langcode = datavalue.value.language
	local lang = mw.language.fetchLanguageName(langcode, "mzn")
	local text = datavalue.value.text
	if isvalid(options.showlang) then
		text = text .. " (" .. lang .. ")"
	end
	local val = text
	if isvalid(options.langpref) then
		if options.langpref == "justlang" then
			val = lang
		elseif options.langpref == "langcode" then
			val = langcode
		elseif options.langpref == datavalue.value.language then
			val = text
		else
			val = ""
		end
	end
	return { value = val }
end

function formatDatavalue(datavalue, datatype, options)
	--Use the customize handler if provided
	if options["value-module"] or options["value-function"] then
		if not options["value-module"] or not options["value-function"] then
			return { value = formatError("unknown-value-module") }
		end
		local formatter = require("Module:" .. options["value-module"])
		if not formatter then
			return { value = formatError("value-module-not-found") }
		end
		local fun = formatter[options["value-function"]]
		if not fun then
			return { value = formatError("value-function-not-found") }
		end
		return { value = fun(datavalue, datatype, options) }
	end

	--Default dataformatters
	local dataformatters = {
		['wikibase-item']     = formatwikibaseitem,
		['wikibase-property'] = formatwikibaseproperty,
		['commonsMedia']      = formatcommonsMedia,
		['external-id']       = formatexternalid,
		['globe-coordinate']  = formatcoordinate,
		['quantity']          = formatquantity,
		['url']               = formaturl,
		['monolingualtext']   = formatmonolingualtext,

		['time']              = help_functions.formattime,
		['tabular-data']      = help_functions.formattabulardata,
		['geo-shape']         = help_functions.formatgeoshape,
		['math']              = help_functions.formatmath,
		['string']            = help_functions.formatstring,
	}

	local dataformatter = dataformatters[datatype]
	if not dataformatter then
		return { value = formatError('unknown-data-type') }
	end
	return dataformatter(datavalue, datatype, options)
end

function formatEntityId(entityId, options)
	local catinfo = catewikidatainfo(options)
	local label = options.label or mw.wikibase.label(entityId)
	if isntvalid(label) then
		label = mw.wikibase.label(entityId) or nil
	end
	local label_chart = help_functions.formatcharacters(label, options)

	local link = mw.wikibase.sitelink(entityId)

	local tab = {}
	tab.value = ""
	tab.label = label

	if isvalid(link) and isntvalid(options.nolink) then
		local link_chart = help_functions.formatcharacters(link, options)
		if isvalid(label) then
			tab.value = "[[" .. link .. "|" .. label_chart .. "]]" .. catinfo
			if link == label_chart then
				tab.value = "[[" .. link .. "]]" .. catinfo
			end
		else
			tab.label = link
			tab.value = "[[" .. link .. "|" .. link_chart .. "]]" .. catinfo
			if link == link_chart then
				tab.value = "[[" .. link .. "]]" .. catinfo
			end
		end
	else
		if isvalid(label) then
			local label3 = Labelfunction(entityId, label, options.label, options)
			tab.value = label3
		end
	end
	return tab
end

function formatEntityId2(entityId, options)
	local catinfo = catewikidatainfo(options)
	local label = options.label or mw.wikibase.label(entityId)
	if isntvalid(label) then
		label = mw.wikibase.label(entityId) or nil
	end
	local label_chart = help_functions.formatcharacters(label, options)

	local link = mw.wikibase.sitelink(entityId)
	local link_chart = help_functions.formatcharacters(link, options)
	local tab = {}
	tab.value = ""
	tab.label = ""
	if isvalid(link) and isntvalid(options.nolink) then
		if isvalid(label) then
			tab.value = "[[" .. link .. "|" .. label_chart .. "]]" .. catinfo
		else
			tab.value = "[[" .. link_chart .. "]]" .. catinfo
			tab.label = link
		end
	else
		if label then
			tab.value = label_chart
			tab.label = label
		end
	end
	return tab
end

function sitelink(id, wikisite)
	--[[ function to get any link from any sister project]]
	local site = wikisite or "mznwiki"
	local link = mw.wikibase.sitelink(id, site) or ""
	--mw.log("mw.wikibase.sitelink,site: " .. site .. ",link:" .. link)
	return link
end

function formatsitelink(entityId, options)
	--[[ function to get only the value with link]]
	local label = help_functions.labelIn("mzn", entityId)
	if isvalid(options.label) then
		label = options.label
	end
	local link = mw.wikibase.sitelink(entityId)
	if isvalid(link) then
		if isvalid(label) then
			return "[[" .. link .. "|" .. label .. "]]"
		else
			return "[[" .. link .. "]]"
		end
	end
end

function p.getEntity(id)
	if type(id) == "table" then
		return id
	end
	return help_functions.getEntityFromId(id)
end

function formatsitelink1(entityId, options)
	local link = mw.wikibase.sitelink(entityId)
	if isvalid(link) then
		if isvalid(options.nolink) then
			return link
		else
			return "[[" .. link .. "]]"
		end
	end
end

function p.isSubclass(frame)
	return help_functions.Subclass(frame.args)
end

function p.formatSnak(snak, options)
	return formatSnak(snak, options)
end

function p.formatEntityId(entityId, options)
	return formatEntityId(entityId, (options or {}))
end

function p.formatEntityId2(entityId, options)
	return formatEntityId2(entityId, (options or {}))
end

function p.formatStatements(frame, key)
	--[[ The main function	]]
	local args = frame.args
	--If a value if already set, use it
	if isvalid(args.value) then
		return args.value
	end
	if isntvalid(args.property) and isvalid(args.pid) then
		args.property = args.pid
	end
	local valuesnumb = 0
	if isvalid(args.returnnumberofvalues) then
		mw.log("valuesnumb: " .. valuesnumb)
		s, valuesnumb = formatStatements(args, key)
		return s, valuesnumb
	end

	local prop = formatStatements(args, key)
	if isvalid(prop) then
		if isvalid(args.mainprefix) then -- mainprefix
			prop = args.mainprefix .. " " .. prop
		end
		if isvalid(args.mainsuffix) then -- mainsuffix
			prop = prop .. " " .. args.mainsuffix
		end
		if isvalid(args.mainsuffixAfterIcon) then -- another suffix but after wikidata icon
			prop = prop .. args.mainsuffixAfterIcon
		end
	else
		if isvalid(args.NoPropValue) then -- value if no local value and no wikidata value
			prop = args.NoPropValue
		end
	end
	return prop
end

function p.fs(frame, key)
	return p.formatStatements(frame, key)
end

function p.formatStatementsFromLua(options, key)         --	 main function but to use from lua module
	if isvalid(options.value) then return options.value end --If a value if already set, use it

	if isntvalid(options.property) and isvalid(options.pid) then
		options.property = options.pid
	end

	local s = formatStatements(options, key)
	if options.returnnumberofvalues == true or isvalid(options.returnnumberofvalues) then
		s, valuesnumb = formatStatements(options, key)
	end
	if s == "" then s = nil end
	if isvalid(s) then
		if isvalid(options.mainprefix) then s = options.mainprefix .. s end -- mainprefix
		if isvalid(options.mainsuffix) then s = s .. options.mainsuffix end -- mainsuffix
	else
		s = nil
	end
	if options.returnnumberofvalues == true or isvalid(options.returnnumberofvalues) then
		return s, valuesnumb
	end
	return s
end

-- Return the site link for a given data item and a given site (the current site by default)

function p.getSiteLink(frame)
	local site = frame.args[2] or frame.args.site
	local id = frame.args[1] or frame.args.id
	local count = frame.args.countsitelinks
	if isntvalid(id) then
		if isvalid(frame.args.page) then
			id = mw.wikibase.getEntityIdForTitle(frame.args.page)
		end
	end
	if isvalid(count) then
		return help_functions.count_Site_Links(id)
	end
	local link = sitelink(id, site)
	if isvalid(link) then
		return link
	end
end

-- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata
function p.pageId(frame)
	return mw.wikibase.getEntityIdForCurrentPage()
end

function p.descriptionIn(frame)
	local langcode = frame.args[1] or frame.args["lang"]
	local id = frame.args[2] or frame.args["id"]
	return help_functions.descriptionIn(langcode, id)
end

function p.labelIn(frame)
	local langcode = frame.args[1] or frame.args["lang"]
	local id = frame.args[2] or frame.args["id"]
	return help_functions.labelIn(langcode, id)
end

function p.getLabel(entity, lang)
	return help_functions.labelIn(lang, entity)
end

function p.ViewSomething(frame) -- from en:Module:Wikidata
	return help_functions.ViewSomething(frame)
end

function p.Dump(frame)
	return help_functions.Dump(frame)
end

function p.countSiteLinks(id)
	return help_functions.count_Site_Links(id)
end

function p.EntityIdForTitle(frame)
	local title = frame.args[1]
	local str = mw.wikibase.getEntityIdForTitle(title)
	--mw.log(str)
	return str
end

return p