--[[

Link of copy of main module used (Module:Wikidata2/functions):
https://ar.wikipedia.org/w/index.php?title=وحدة:Wikidata2/ملعب&oldid=58189763

]]

local help_functions = {}
local ModuleTime = require "Module:wikidata2/time"
help_functions.Frame_args = {} 
help_functions.i18n = {
	["errors"] = {
		["property-param-not-provided"] = "وسيط property غير متوفر.",
		["entity-not-found"] = "الكيان غير موجود.",
		["unknown-claim-type"] = "نوع claim غير معروف.",
		["unknown-snak-type"] = "نوع snak غير معروف.",
		["unknown-datatype"] = "نوع data غير معروف.",
		["unknown-entity-type"] = "نوع entity غير معروف.",
		["unknown-value-module"] = "يجب عليك تعيين كل من  value-module و value-function.",
		["unknown-claim-module"] = "يجب عليك تعيين كل من claim-module و claim-function.",
		["unknown-property-module"] = "يجب عليك تعيين كل من property-module و property-function.",
		["property-module-not-found"] = "الوحدة المستخدمة في وسيط property-module غير موجودة.",
		["property-function-not-found"] = "الوظيفة المستخدمة في وسيط property-function غير موجودة.",
		["value-module-not-found"] = "الوحدة المستخدمة في وسيط value-module غير موجودة.",
		["value-function-not-found"] = "الوظيفة المستخدمة في وسيط value-function غير موجودة.",
		["claim-module-not-found"] = "الوحدة المستخدمة في وسيط claim-module غير موجودة.",
		["claim-function-not-found"] = "الوظيفة المستخدمة في وسيط claim-function غير موجودة."
	},
	["noarabiclabel"] = "تصنيف:صفحات_ويكي_بيانات_بحاجة_لتسمية_عربية",
	["warnDump"] = "[[Category:Called function 'Dump' from module Wikidata]]",
	["somevalue"] = "",	--''غير محدد''
	["novalue"] = "", 	--قيمة مجهولة
	["cateref"] = "[[" .. "تصنيف:صفحات بها مراجع ويكي بيانات" .. "]]",
	["to translate"] = "صفحات تستعمل معطيات من ويكي بيانات بحاجة لترجمة",
	["trackingcat"] = "صفحات تستخدم خاصية $1",
	["see-wikidata-value"] = "الاطلاع ومراجعة البيانات على ويكي داتا",
	["see-wikidata"] = "راجع العنصر من ويكي بيانات المقابل",
	["see-another-project"] = "مقالة على $1",
	["see-another-language"] = "مقالة على ويكيبيديا $1"
}
help_functions.sortingproperties = {"P585", "P571", "P580", "P569", "P582", "P570"}
help_functions.sorting_methods = {
	["chronological"] = "chronological",
	["تصاعدي"] = "chronological",
	["asc"] = "chronological",
	["inverted"] = "inverted",
	["تنازلي"] = "inverted",
	["desc"] = "inverted"
}

help_functions.skiip = {
	["P106"] = {
		"Q42857", -- prophet
		"Q14886050", -- terrorist
		"Q2159907" -- criminal
	}
}

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

function help_functions.formatFromPattern(str, options)
	-- [[	function to replace $1 with string	]]
	local str = string.gsub(str, "%%", "%%%%")
	if options.pattern and options.pattern ~= "" then
		str = mw.ustring.gsub(options.pattern, "$1", str) --الحصول على اول نتيجة للدالة
	end
	return str
end

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

function help_functions.count_Site_Links(id)
	numb = 0
	Table = {}
	local entity = mw.wikibase.getEntityObject(id)
	if entity and entity.sitelinks then
		for i, v in pairs(entity.sitelinks) do
			Table[v.site] = v.title
			numb = numb + 1
		end
	--return Frame:extensionTag("source", mw.dumpObject( Table ),{ lang= 'lua'})
	end
	return numb
end

function help_functions.make_format_num(String)
	local line = String
	line = mw.getCurrentFrame():preprocess("{{ {{{|safesubst:}}}formatnum: " .. String .. " }}")
	line = mw.ustring.gsub(line, "٫", ".")
	line = mw.ustring.gsub(line, "٬", ",")
	return line
end

function help_functions.formatcharacters(label, options)
	local formatcharacters = options.formatcharacters
	--if options.FormatfirstCharacter and options.num == 1 then
	--formatcharacters = options.FormatfirstCharacter
	--end
	if not label then return label end
	local String2 = mw.ustring.gsub(label, "–", "-")
	local march_y = mw.ustring.match(String2, "%d%d%d%d%-%d%d%d%d", 1) or 
		mw.ustring.match(String2, "%d%d%-%d%d%d%d", 1) or 
		mw.ustring.match(String2, "%d%d%d%d", 1) or 
		mw.ustring.match(String2, "%d%d%d%d%-%d%d", 1) or
		mw.ustring.match(String2, "%d%d%d%d", 1)
		
	if options.illwd2y and options.illwd2y ~= "" then
		ca = march_y or label
		return ca
	end
	if options.illwd2noy and options.illwd2noy ~= "" and march_y then
		label = mw.ustring.gsub(label, march_y, "")
		return label
	end
	if not formatcharacters or formatcharacters == "" then
		return label
	end
	function preproces(Type, label)
		return mw.getCurrentFrame():preprocess("{{ {{{|safesubst:}}}" .. Type .. ":" .. label .. " }}")
	end
	if formatcharacters == "lcfirst" then
		return preproces("lcfirst", label)
	elseif formatcharacters == "ucfirst" then
		return mw.language.getContentLanguage():ucfirst(label)
	elseif formatcharacters == "lc" then
		return preproces("lc", label)
	elseif formatcharacters == "uc" then
		return preproces("uc", label)
	elseif formatcharacters == "formatnum" then
		return help_functions.make_format_num(label)
	end
	return label
end

function help_functions.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 help_functions.get_entityId(options)
	local id = options.entityId or options.entityid or options.id or options.qid
	if isvalid(id) == nil then
		if isvalid(options.page) then
			id = mw.wikibase.getEntityIdForTitle( options.page )
		end
	end
	--mw.log("id :" .. id)
	return id or ""
end

function help_functions.descriptionIn(langcode, id) -- returns item description for a given language
	local lan = langcode
	if not lan or lan == "" then
		lan = "ar"
	end

	if lan == "ar" then
		local description, lange = mw.wikibase.getDescriptionWithLang(id)
		if lange == lan then
			return description
		else
			return nil
		end
	else
		local entity = help_functions.getEntityFromId(id)
		if entity and entity.descriptions then
			local description = entity.descriptions[lan]
			if description and description.value then
				if description["language"] == lan then
					return description.value
				else
					return nil
				end
			end
		end
	end
end

function help_functions.labelIn(langcode, id) -- returns item label for a given language
	local lang = langcode
	if not langcode or langcode == "" then
		lang = "ar"
	end
	if type(id) ~= "string" then
		id = tostring(id)
	end
	local label = mw.wikibase.getLabelByLang(id, lang) or nil
	return label
end

function help_functions.get_snak_id(snak)
	if
		snak and snak.type and snak.type == "statement" and snak.mainsnak and snak.mainsnak.snaktype and
			snak.mainsnak.snaktype == "value" and
			snak.mainsnak.datavalue and
			snak.mainsnak.datavalue.type and
			snak.mainsnak.datavalue.type == "wikibase-entityid" and
			snak.mainsnak.datavalue.value and
			snak.mainsnak.datavalue.value.id
	 then
		--ID = 'Q' .. snak.datavalue.value['numeric-id']
		ID = snak.mainsnak.datavalue.value.id
		return ID
	end
end

function help_functions.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 help_functions.getEntityIdFromValue(value)
	if value then
		if value["entity-type"] == "item" then
			return "Q" .. value["numeric-id"]
		elseif value["entity-type"] == "property" then
			return "P" .. value["numeric-id"]
		end
	end
	return help_functions.formatError("unknown-entity-type")
end

function help_functions.getEntityFromId(id)
	if id and id ~= "" then
		--	if not(mw.wikibase.isValidEntityId(id)) or not(mw.wikibase.entityExists(id)) then
		--	return false
		--end
		return mw.wikibase.getEntityObject(id)
	else
		return mw.wikibase.getEntityObject()
	end
end

function help_functions.claimindex(claims, options)
	local claims2 = {}
	for j, index in pairs(mw.text.split(options.claimindex, ",")) do
		if tonumber(index) and #claims >= tonumber(index) then
			table.insert(claims2, claims[tonumber(index)])
		end
	end
	return claims2
end

function help_functions.avoidvalue(claims, options)
	-- options.avoidvalue
	-- to avoid values
	local claims4 = {}
	local vaild
	local toavoid
	if (type(options.avoidvalue) == "string") then
		toavoid = mw.text.split(options.avoidvalue, ",")
	elseif (type(options.avoidvalue) == "table") then
		toavoid = options.avoidvalue
	else
		return claims
	end
	for i, j in pairs(claims) do
		ID = help_functions.get_snak_id(j)
		vaild = true
		if ID then
			for k, t in pairs(toavoid) do
				--mw.log("t: " .. t)
				if ID == t then
					vaild = false
					break
				end
			end
			if vaild then
				table.insert(claims4, j)
			end
		end
	end
	return claims4
end

function help_functions.prefervalue(claims, options)
	local claims4 = {}
	local prefervalues
	if (type(options.prefervalue) == "string") then
		prefervalues = mw.text.split(options.prefervalue, ",")
	elseif (type(options.prefervalue) == "table") then
		prefervalues = options.prefervalue
	else
		return claims
	end
	for i, j in pairs(claims) do
		ID = help_functions.get_snak_id(j)
		vaild = false
		if ID then
			for k, t in pairs(prefervalues) do
				if ID == t then
					table.insert(claims4, j)
					break
				end
			end
		end
	end
	return claims4
end

function help_functions.avoidqualifier(claims, options)
	-- options.avoidqualifier
	-- options.avoidqualifiervalue
	if not options.avoidqualifier or options.avoidqualifier == "" then
		return claims
	end
	local av = options.avoidqualifier:upper()
	local claims2 = {}
	for i, statement in pairs(claims) do
		if not statement.qualifiers or not statement.qualifiers[options.avoidqualifier:upper()] then
			table.insert(claims2, statement)
		elseif statement.qualifiers and statement.qualifiers[av] then
			if options.avoidqualifiervalue and options.avoidqualifiervalue ~= "" then
				list = {}
				if (type(options.avoidqualifiervalue) == "string") then
					list = mw.text.split(options.avoidqualifiervalue, ",")
				elseif (type(options.avoidqualifiervalue) == "table") then
					list = options.avoidqualifiervalue
				end
				local active = true
				for k, t in pairs(list) do
					for ii, quall in pairs(statement.qualifiers[av]) do
						if
							quall.snaktype == "value" and quall.datavalue and quall.datavalue.value and
								quall.datavalue.value["id"]
						 then
							if quall.datavalue.value["id"] == t then
								active = false
							end
						end
					end
				end
				if active then
					table.insert(claims2, statement)
				end
			end
		end
	end
	return claims2
end

function help_functions.preferqualifier(claims, options)
	-- options.preferqualifier
	-- options.preferqualifiervalue
	mw.log("preferqualifier: " .. options.preferqualifier)
	local preferqualifiers = options.preferqualifier:upper()

	local claims2 = {}
	for i, statement in pairs(claims) do --
		if statement.qualifiers and statement.qualifiers[preferqualifiers] then
			if options.preferqualifiervalue and options.preferqualifiervalue ~= "" then
				for k, t in pairs(mw.text.split(options.preferqualifiervalue, ",")) do
					for ii, quall in pairs(statement.qualifiers[preferqualifiers]) do
						--mw.log( "value " .. value )
						snaktype = quall.snaktype
						if snaktype == "value" then
							ty = quall.datavalue.value["id"]
							if ty and ty == t then
								table.insert(claims2, statement)
								break
							end
						end
					end
				end
			else
				table.insert(claims2, statement)
			end
		end
	end
	return claims2
end

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

function help_functions.sortbyqualifiernumber(claims, options, sorting_properties)
	if not sorting_properties then
		if (type(options.sortingproperty) == "table") then
			sorting_properties = options.sortingproperty
		elseif (type(options.sortingproperty) == "string") and options.sortingproperty ~= "" then
			sorting_properties = mw.text.split(options.sortingproperty, ",")
		else
			sorting_properties = help_functions.sortingproperties
		end
	end
	local sortbynumber = help_functions.sorting_methods[options.sortbynumber] or options.sortbynumber
	table.sort(
		claims,
		function(a, b)
			local timeA = help_functions.getqualifierbysortingproperty(a, sorting_properties)
			local timeB = help_functions.getqualifierbysortingproperty(b, sorting_properties)
			if sortbynumber == "inverted" then
				return help_functions.comparedates(timeB, timeA)
			else
				return help_functions.comparedates(timeA, timeB)
			end
		end
	)
	return claims
end

function help_functions.sortbyarb(claims, sorting_properties, options)
	local sortingmethod = options.sortbyarbitrary or options.sortingmethod
	sortingmethod = help_functions.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 help_functions.comparedates(timeB, timeA)
			else
				return help_functions.comparedates(timeA, timeB)
			end
		end
	)
	return claims
end

function help_functions.claims_limit(claims, limit)
	local newclaims = {}
	local ic = 0
	if #claims > limit then -- limit is not 0
		for i = 1, #claims do
			if i <= limit then
				newclaims[ic] = claims[i]
				ic = ic + 1
			end
		end
	end
	return newclaims
end

function help_functions.claims_offset(claims, offset)
	local offsetclaims = {}
	local ic = 1
	if #claims > offset then -- offset is not 0
		for i = 1, #claims do
			if i > offset then
				offsetclaims[#offsetclaims + 1] = claims[i]
			end
		end
	end
	return offsetclaims
end

function help_functions.filter_claims(claims, options)
	local claims = claims
	--===========
	local offset = options.offset
	if offset and offset ~= "" and type(offset) ~= "number" then
		offset = tonumber(offset)
		claims = help_functions.claims_offset(claims, offset)
	end
	--===========
	local limit = options.limit
	if limit and limit ~= "" and type(limit) ~= "number" then
		limit = tonumber(limit)
		claims = help_functions.claims_limit(claims, limit)
	end
	--===========
	if options.avoidqualifier and options.avoidqualifier ~= "" then -- to avoid value with a given qualifier
		claims = help_functions.avoidqualifier(claims, options)
	end
	--===========
	if options.preferqualifier and options.preferqualifier ~= "" then
		claims = help_functions.preferqualifier(claims, options)
	end
	--===========
	-- options.avoidvalue
	if options.avoidvalue and options.avoidvalue ~= "" then
		claims = help_functions.avoidvalue(claims, options)
	end
	--===========
	-- options.prefervalue
	if options.prefervalue and options.prefervalue ~= "" then
		claims = help_functions.prefervalue(claims, options)
	end
	--===========
	if not options.langpref or options.langpref == "" then
		local claims7 = {}
		for i, statement in pairs(claims) do
			if statement.qualifiers and statement.qualifiers.P407 then
				for k, v in pairs(statement.qualifiers.P407) do
					if v.snaktype == "value" and v.datavalue.value["numeric-id"] == 13955 then -- Q13955 = 'العربية'
						table.insert(claims7, statement)
					end
				end
			elseif statement.qualifiers and statement.qualifiers.P282 then
				for k, v in pairs(statement.qualifiers.P282) do
					if v.snaktype == "value" and v.datavalue.value["numeric-id"] == 8196 then -- Q8196 = 'أبجدية عربية'
						table.insert(claims7, statement)
					end
				end
			end
		end
		if #claims7 > 0 then
			claims = claims7
		end
	end
	--===========
	local sortingmethod = options.sortbyarbitrary or options.sortingmethod
	local sorting_properties = {}

	if (type(options.sortingproperty) == "table") then
		sorting_properties = options.sortingproperty
	elseif (type(options.sortingproperty) == "string") and options.sortingproperty ~= "" then
		sorting_properties = mw.text.split(options.sortingproperty, ",")
	end

	if isvalid(options.sortbytime) then
		if #sorting_properties == 0 then
			sorting_properties = help_functions.sortingproperties
		end
		claims = help_functions.sortbyqualifier(claims, sorting_properties, options)

	elseif isvalid(options.sortbynumber) then
		claims = help_functions.sortbyqualifiernumber(claims, options, sorting_properties)

	elseif isvalid(sortingmethod) then
		claims = help_functions.sortbyarb(claims, sorting_properties, options)
	end
	--===========
	local firstvalue = options.enbarten or options.firstvalue
	if firstvalue and firstvalue ~= "" and #claims > 1 then
		if firstvalue == "2" then
			claims = {claims[2]}
		elseif firstvalue == "3" and #claims > 2 then
			claims = {claims[3]}
		elseif firstvalue == "4" and #claims > 3 then
			claims = {claims[4]}
		elseif firstvalue == "5" and #claims > 4 then
			claims = {claims[5]}
		elseif firstvalue == "6" and #claims > 5 then
			claims = {claims[6]}
		elseif firstvalue == "7" and #claims > 6 then
			claims = {claims[7]}
		elseif firstvalue == "8" and #claims > 7 then
			claims = {claims[8]}
		elseif firstvalue == "9" and #claims > 8 then
			claims = {claims[9]}
		else
			claims = {claims[1]}
		end
	end
	--===========
	local numval = options.numval
	if numval and type(numval) ~= "number" then
		numval = tonumber(numval)
	end
	if numval and type(numval) == "number" and #claims > 1 and #claims > numval then
		local claimsnumval = {}
		local ic = 1
		while (numval >= ic) and (#claims >= ic) do
			table.insert(claimsnumval, claims[ic])
			ic = ic + 1
		end
		claims = claimsnumval
	end
	--===========
	return claims
end

function help_functions.formattabulardata(datavalue, datatype, options)
	--[[ tabular-data]]
	data = "[[commons:" .. datavalue.value .. "|" .. datavalue.value .. "]]"
	return {value = data}
end

function help_functions.formatgeoshape(datavalue, datatype, options)
	--[[ geo-shape ]]
	shape = "[[commons:" .. datavalue.value .. "|" .. datavalue.value .. "]]"
	return {value = shape}
end

function help_functions.formatmath(datavalue, datatype, options)
	--[[ datatype math ]]
	--return	{value = mw.text.tag('math', {}, ''.. datavalue.value..'') } -- that doesn't work well
	return {value = mw.getCurrentFrame():callParserFunction("#tag:math", "" .. datavalue.value .. "")}
end

function help_functions.formatstring(datavalue, datatype, options)
	--[[ datatype	string	-  external-id ]]
	local par = options.pattern
	if options.stringpattern and options.stringpattern ~= "" then
		--mw.log(options.stringpattern)
		tid = mw.ustring.gsub(options.stringpattern, "$1", datavalue.value)
	elseif par and par ~= "" then
		if par == "autourl" or par == "autourl2" or par == "autourl3" or par == "autourl4" then
			tid = help_functions.formatcharacters(datavalue.value, options)
		else
			tid = help_functions.formatFromPattern(help_functions.formatcharacters(datavalue.value, options), options)
		end
	else
		tid = help_functions.formatcharacters(datavalue.value, options)
	end
	return {value = tid}
end

function help_functions.formattime(datavalue, datatype, options)
	--[[  datatype	 time  ]]
	local timen = datavalue.value
	local modifytime = (options.modifytime or "")
	local tid = ModuleTime.getdate(timen, options)
	-- local tid =	mw.getCurrentFrame():preprocess(mall)
	if options.modifytime and options.modifytime ~= "" then
		if options.modifytime == "q" then
			local mall = datavalue.value.time
			tid = mw.getCurrentFrame():preprocess(mall)
		elseif options.modifytime == "precision" then
			local mall = datavalue.value.precision
			tid = mw.getCurrentFrame():preprocess(mall)
		end
	end
	return {value = tid}
end

function help_functions.get_site_link(id, wikisite)
	local site = wikisite or "arwiki"
	--local link = mw.wikibase.getSitelink( id , site ) or ""
	--return link

	local entity = mw.wikibase.getEntityObject(id)
	if
		entity and entity.sitelinks and entity.sitelinks["" .. site .. ""] and entity.sitelinks["" .. site .. ""].site and
			entity.sitelinks["" .. site .. ""].title
	 then
		if entity.sitelinks["" .. site .. ""].site == site then
			return entity.sitelinks["" .. site .. ""].title
		else
			return ""
		end
	end
end

function help_functions.getId(snak)
	if (snak.snaktype == "value") then
		if snak.datavalue.type == "wikibase-entityid" then
			return "Q" .. snak.datavalue.value["numeric-id"]
		end
	end
end

function help_functions.addLinkBack(str, id, property)
	if not id then
		id = help_functions.getEntity()
	end
	if not id then
		return str
	end
	if type(property) == "table" then
		property = property[1]
	end
	if type(id) == "table" then
		id = id.id
	end
	local class = ""
	if property then
		class = "wd_" .. string.lower(property)
	end
	local icon = "[[File:Blue pencil.svg|%s|10px|baseline|class=noviewer|link=%s]]"
	local title = help_functions.i18n["see-wikidata-value"]
	local url = mw.uri.fullUrl("d:" .. id, "uselang=ar")
	url.fragment = property
	url = tostring(url)
	local v =
		mw.html.create("span"):addClass(class):wikitext(str):tag("span"):addClass("noprint wikidata-linkback"):css(
		"padding-left",
		"0.5em"
	):wikitext(icon:format(title, url)):allDone()
	return tostring(v)
end

function help_functions.Subclass(options)
	if options then help_functions.Frame_args = options end
	local parent = options.parent or ""
	local id = isvalid(options.id) or isvalid(options.qid) or ""
	local Entity = help_functions.getEntityFromId(id)
	if Entity then
		id = Entity.id
	end
	local property = isvalid(options.property) or isvalid(options.pid) or "P31"
	if parent == "" or id == "" or property == "" then
		return false
	end
	local tab = mw.text.split(options.parent, ",")
	local result = mw.wikibase.getReferencedEntityId(id, property, tab) -- { 'Q5', 'Q2095' } )
	if not result and property == "P31" then
		result = mw.wikibase.getReferencedEntityId(id, "P279", tab)
	end
	if result then
		return true
	end
end

function help_functions.ViewSomething(frame) -- from en:Module:Wikidata
	if frame.args then help_functions.Frame_args = frame.args end

	local f = (frame.args[1] or frame.args.id) and frame or frame:getParent()
	if f.args.id and f.args.id ~= "" then
		aa = f.args.id
	end
	local data = mw.wikibase.getEntityObject(aa)
	if not data then
		return nil
	end
	local i = 1
	while true do
		local index = f.args[i]
		if not index then
			if type(data) == "table" then
				return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY)
			else
				return tostring(data)
			end
		end
		data = data[index] or data[tonumber(index)]
		if not data then
			return
		end
		i = i + 1
	end
end

function help_functions.Dump(frame)
	if frame.args then Frame_args = frame.args end

	local f = (frame.args[1] or frame.args.id) and frame or frame:getParent()
	if f.args.id and f.args.id ~= "" then
		aa = f.args.id
	end
	local data = mw.wikibase.getEntityObject(aa)
	if not data then
		return help_functions.i18n.warnDump
	end
	local i = 1
	while true do
		local index = f.args[i]
		if not index then
			return frame:extensionTag("source", mw.dumpObject(data), {lang = "lua"}) .. help_functions.i18n.warnDump
		end
		data = data[index] or data[tonumber(index)]
		if not data then
			return help_functions.i18n.warnDump
		end
		i = i + 1
	end
end

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

	mw.log("work with property-module: " .. options["property-module"] .. "|" .. options["property-function"])
	
	return fun(claims, options)
end

return help_functions