Jump to content

Module:Global infobox tools

Ón Vicipéid, an chiclipéid shaor.

Documentation for this module may be created at Module:Global infobox tools/doc

local p = {}
--Version 2020-07-30

local SA		= require "Module:SimpleArgs"
local SD		= require "Module:SimpleDebug"
local WD		= require "Module:Wikidades"
local MLMT		= require "Module:Multilang module tools"
local Infobox	= require "Module:Infobox"
local II		= require 'Module:InfoboxImage'
local GIBTi		= require "Module:Global infobox tools/items"
local GIBTi18n	= require (SA.I18nName ("Global infobox tools"))

--INITIALIZATION---
local ModuleAbbrev = 'GIBT'
local ModuleName = 'Global infobox tools'
SA.AcceptNone = true 
MLMT.with_pos_col = true
MLMT.with_arg_prop = true
MLMT.uses_QP_for_labels = true
p.UsualListOpt = {
	MLMT.LOpt.list,
	MLMT.LOpt.params,
	MLMT.LOpt.template,
	MLMT.LOpt.labels,
}
----------------------------------------
-- Color functions --
----------------------------------------
local function CheckColorTab ()
	for k, cc in pairs(GIBTi18n.colors) do
		if (type(cc) ~= 'table') or (#cc ~= 2) or (type(cc[1]) ~= 'string') or (type(cc[2]) ~= 'string') then
			SD.vtos (cc)
			error ('In "'..k..'" of color table: '..SD.s..' is not a table with two colors, where two colors are strings',0)
		end	
	end	
end	--CheckColorTab
CheckColorTab ()

function p._GetInfoboxColor (grp_color_key, n)
	-- MLMT.ChkFunc ("GetInfoboxColor", {{"grp_color_key",grp_color_key,"xr"},{"n",n,"xi"},})
	for _, v in pairs(GIBTi18n.lcol) do
		if grp_color_key == v then
			return GIBTi18n.colors[grp_color_key][n]
		end	
	end	
	error ('Invalid color class ('..v..')',0) --Don't require translation
end --GetInfoboxColor

function p.GetInfoboxColor (frame)
	local args = SA.GetArgs (frame)
	return p._GetInfoboxColor (SA.RStr_Par (args, 1), SA.RPosInt_Par (args, 2, 1, 2))
end --DefaultColor

function p.DisplayTitleColors ()
	-- It shows a table with all color pairs used in Catalan WP infoboxes
	local res = '<table class="wikitable sortable">'
	res = res..'<tr><th>Header</th><th>RGB</th><th>Subheader</th><th>RGB</th></tr>'
	function AddColor (c, n)
		return '<td><span style="background-color:'..GIBTi18n.colors[c][n]..'">&nbsp;'..c..'&nbsp;</td><td>'..GIBTi18n.colors[c][n]..'</td>'
	end	
	for _,c in ipairs(GIBTi18n.col_idx) do
		res = res..'<tr>'..AddColor(c,1)..AddColor(c,2)..'</tr>'
	end	
	res = res..'</table>'
	return res
end	--DisplayTitleColors

----------------------------------------
-- Icon functions --
----------------------------------------
local function CheckIconTab ()
	for k, v in pairs(GIBTi18n.icons) do
		if type(v) ~= 'string' then
			SD.vtos (v)
			error ('In "'..k..'" of icon table: '..SD.s..' is not a string',0)
		end	
	end	
end --CheckIconTab	
CheckIconTab ()

function p._GetIcon (icon_key)
	local found = false
	for _, v in pairs(GIBTi18n.licon) do
		if icon_key == v then
			return GIBTi18n.icons[icon_key]
		end	
	end	
	error ('Invalid icon key ('..v..')',0) --Don't require translation
end --_GetIcon

function p.GetIcon (frame)
	local args = SA.GetArgs (frame)
	local name = SA.RStr_Par (args, 1)
	return p._GetIcon (name)
end --GetIcon

function p.DisplayTitleIcons (frame)
	-- It shows a table with all icons used in Catalan WP infoboxes
	local args = SA.GetArgs (frame)
	local with_lnk = SA.Bool_Par (args, 1)
	local res = '<table class="wikitable sortable">'
	res = res..'<th>Key</th><th>Icon name</th><th>Icon</th>'
	for _,i in ipairs(GIBTi18n.icon_idx) do
		local h = GIBTi18n.icons_headers[i]
		if h ~= nil then
			res = res..'<tr><td colspan="3"><b>'..h..'</b></td></tr>'
		end	
		local iconf = GIBTi18n.icons[i]
		local lnk = i
		if with_lnk then
			if string.sub (lnk,1,1) ~= '_' then
				if lnk ~= GIBTi18n.licon.Taxobox then
					lnk = 'Infobox '..lnk
				end	
				lnk = '[[:en:Template:'..lnk..'|'..i..']]'
			end
		end	
		res = res..'<tr><td>'..lnk..'</td><td>[[:commons:File:'..iconf..'|'..iconf..']]</td><td>[[File:'..iconf..'|20px|'..i..']]</td></tr>'
	end	
	return res..'</table>'
end	--DisplayTitleIcons

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

function p.tableMerge (ModuleName, tab_main, tab_lang)
	-- It returns tab_main table with the new items from tab_lang (located in i18n)
	MLMT.ChkFunc ("tableMerge", {{"ModuleName",ModuleName,"xr"},{"tab_main",tab_main,"tr"},
		{"tab_lang",tab_lang,"tr"},})
	if tab_main[MLMT.k.Args][GIBTi.rk.name] == nil then
		error ('"'..GIBTi.rk.name..'" not found in "'..MLMT.k.Args..'" of the table items of '..MLMT.MN(ModuleName), 0)	
	end	
	return MLMT.tableMerge (ModuleName, tab_main, tab_lang, true)
end --tableMerge

local function ErrorCheck (ModuleName, what, S)
	error ('"'..SD.s..'" (for "'..S..'") is not a '..what..' (from '..ModuleName..')', 0) -- Translation not required
end	
local function CheckIsStr (ModuleName, v, S)
	-- returns a required "v" string for S, otherwise return error
	if type(v) == "string" then
		return v
	else	
		SD.vtos (v)
		ErrorCheck (ModuleName, 'string', S)
	end	
end --CheckIsStr

local function CheckIsBool (ModuleName, v, S)
	-- returns a required "v" boolean for S, otherwise return error
	if type(v) == "boolean" then
		return v
	else	
		SD.vtos (v)
		ErrorCheck (ModuleName, 'boolean', S)
	end	
end --CheckIsBool
	
local function CheckIsInt (ModuleName, v, S, LimInf, LimSup)
	-- returns a required "v" boolean for S, otherwise return error
	if type(v) == "number" then
		SA.CheckNumIsInt (v, S, LimInf, LimSup)
		return v
	else	
		SD.vtos (v)
		ErrorCheck (ModuleName, 'positive integer', S)
	end	
end --CheckIsBool
	
function title_without_disambig ()
	-- returns the current page name without text between "()"
	local s = mw.title.getCurrentTitle().baseText
	s, c = mw.ustring.gsub(s,'%s%(.*%)','')
	return s
end	

local function CheckIsStrRs (key)
	return CheckIsStr (MLMT.MNi18n(ModuleName), GIBTi18n.rs_val[key], key)
end	

local function CheckIsBoolRs (key)
	return CheckIsBool (MLMT.MNi18n(ModuleName), GIBTi18n.rs_val[key], key)
end	

local function CheckIsIntRs (key, LimInf, LimSup)
	return CheckIsInt (MLMT.MNi18n(ModuleName), GIBTi18n.rs_val[key], key, LimInf, LimSup)
end	

p.rs = { --Values for reserved keys
	--default colors
	[GIBTi.rk.rs_colorbox] 			= "",
	[GIBTi.rk.rs_color_tit_cllps] 	= "",
	--styles
	[GIBTi.rk.rs_bodystyle] 		= CheckIsStrRs (GIBTi.rk.rs_bodystyle),
	[GIBTi.rk.rs_titlestyle] 		= CheckIsStrRs (GIBTi.rk.rs_titlestyle),
	[GIBTi.rk.rs_headerstyle] 		= CheckIsStrRs (GIBTi.rk.rs_headerstyle),
	[GIBTi.rk.rs_subheaderstyle] 	= CheckIsStrRs (GIBTi.rk.rs_subheaderstyle),
	[GIBTi.rk.rs_imagestyle] 		= CheckIsStrRs (GIBTi.rk.rs_imagestyle),
	[GIBTi.rk.rs_captionstyle] 		= CheckIsStrRs (GIBTi.rk.rs_captionstyle),
	[GIBTi.rk.rs_labelstyle] 		= CheckIsStrRs (GIBTi.rk.rs_labelstyle),
	[GIBTi.rk.rs_datastyle]			= CheckIsStrRs (GIBTi.rk.rs_datastyle),
	[GIBTi.rk.rs_belowstyle]		= CheckIsStrRs (GIBTi.rk.rs_belowstyle),
	--icon & default name
	[GIBTi.rk.rs_icon]				= "", --p.used_icon ~= SA.None
	[GIBTi.rk.rs_icon_at_begin]		= CheckIsBoolRs (GIBTi.rk.rs_icon_at_begin),
	[GIBTi.rk.rs_icon_hint]			= "", 
	[GIBTi.rk.rs_def_name]			= title_without_disambig(), 
	--image
	[GIBTi.rk.rs_image_max_num]		= CheckIsIntRs (GIBTi.rk.rs_image_max_num, 1, 2),
	[GIBTi.rk.rs_def_image_size]	= CheckIsStrRs (GIBTi.rk.rs_def_image_size),
	[GIBTi.rk.rs_send_img_preinfobox]= CheckIsBoolRs (GIBTi.rk.rs_send_img_preinfobox),
	--referred to label/data content
	[GIBTi.rk.rs_changeable_lbls]	= CheckIsBoolRs (GIBTi.rk.rs_changeable_lbls),
	[GIBTi.rk.rs_param_prefix_lbl]	= CheckIsStrRs (GIBTi.rk.rs_param_prefix_lbl),
	[GIBTi.rk.rs_def_charnum_cllps]	= CheckIsIntRs (GIBTi.rk.rs_def_charnum_cllps, 1, 1000),
	[GIBTi.rk.rs_error]				= "_Q29485",
	[GIBTi.rk.rs_below]				= "",
}
local rs_wd_t = {
	--[rs_key] = {value, argtype_displayed}
}
local rs_idx = { --index for reserved keys 
	--default colors
	GIBTi.rk.rs_colorbox,
	GIBTi.rk.rs_color_tit_cllps,
	--styles
    GIBTi.rk.rs_bodystyle,
    GIBTi.rk.rs_titlestyle,
    GIBTi.rk.rs_headerstyle,
    GIBTi.rk.rs_subheaderstyle,
    GIBTi.rk.rs_imagestyle,
    GIBTi.rk.rs_captionstyle,
    GIBTi.rk.rs_labelstyle,
    GIBTi.rk.rs_datastyle,
	GIBTi.rk.rs_belowstyle,
	--icon
	GIBTi.rk.rs_icon,
	GIBTi.rk.rs_icon_at_begin,
    GIBTi.rk.rs_icon_hint,
    GIBTi.rk.rs_def_name,
	--image
	GIBTi.rk.rs_image_max_num,
	GIBTi.rk.rs_def_image_size,
	GIBTi.rk.rs_send_img_preinfobox,
	--referred to label/data content
	GIBTi.rk.rs_changeable_lbls,
	GIBTi.rk.rs_param_prefix_lbl,
    GIBTi.rk.rs_def_charnum_cllps,
	GIBTi.rk.rs_error,
	GIBTi.rk.rs_below,
}

local cat = { --category keys
	[GIBTi.rk.rs_cat_arg_dupli]		= "_Q89919289",
	[GIBTi.rk.rs_cat_arg_error]		= "",
	[GIBTi.rk.rs_cat_wds_untranslat]	= "",
	[GIBTi.rk.rs_cat_no_image]		= "",
}	
local cat_idx = { --index for category keys 
	GIBTi.rk.rs_cat_arg_error,
	GIBTi.rk.rs_cat_arg_dupli,
	GIBTi.rk.rs_cat_wds_untranslat,
	GIBTi.rk.rs_cat_no_image,
}
local rs_icon_where	= 'left' --icon position related to title
function GetWhereIcon ()
	rs_icon_where = ''
	if ((not LangIsRTL) and p.rs[GIBTi.rk.rs_icon_at_begin]) or (LangIsRTL and (not p.rs[GIBTi.rk.rs_icon_at_begin])) then
		rs_icon_where = 'left'
	else
		rs_icon_where = 'right'
	end	
	return rs_icon_where
end	--GetWhereIcon

p.rss = { --reserved keys from specific toolbox
}
-- (not index is required, thus are none or few items


local function IsQuali (ModuleName, key, s)
	--returns if s is a Wikidata qualifier or property for WD. All qualifiers or properties must be as Qnnn or Pnnn.
	local Is = string.sub (s, 1, 1) == '_'
	if Is then
		local Ch = string.sub (s, 2, 2)
		if (string.len(s) < 3) or ((Ch ~= 'P') and (Ch ~= 'Q')) or (not tonumber(string.sub (s,3,3))) then --Checks only first number
			error ('For the key "'..key..'" (from '..ModuleName..'), "'..string.sub (s,2)..'" is invalid qualifier or property for WD', 0)
		end
	end	
	return Is
end	--IsQuali

local function LabelFromWD (s)
	s = string.sub (s, 2)
	return WD.getLabel({s,['lang']=MLMT.lang})
end	
local function perhaps (key, wd, typ)
	if rs_wd_t[key] == nil then
		rs_wd_t[key] = {wd, MLMT.item_type_req_vals_prep(typ)}
	end
end	
local function SetDef (ModuleName, tab)
	function GetStyleBg (key, color)
		if tab[key] == nil then
			p.rs[key] = 'background-color:'..color..';'..p.rs[key]
		else	
			if tab[key] ~= "" then
				local val = CheckIsStr (ModuleName, tab[key], key)
				p.rs[key] = val
			end
		end
		perhaps (key, '', MLMT.IT.s)	
	end --GetStyleBg
	function GetStr (key, def)
		local val
		local wd
		if (p.rs[key] ~= nil) and IsQuali (ModuleName, key, p.rs[key]) then
			wd = p.rs[key]
			p.rs[key] = LabelFromWD (p.rs[key])
			perhaps (key, wd, MLMT.IT.s)	
		end	
		if tab[key] ~= nil then
			if tab[key] ~= "" then
				val = CheckIsStr (ModuleName, tab[key], key)
			elseif p.rs[key] == "" then
				val = def
			end	
		end
		if val ~= nil then
			if IsQuali (ModuleName, key, val) then
				wd = val
				val = LabelFromWD (val)
			else
				wd = ''
			end	
			p.rs[key] = val
			perhaps (key, wd, MLMT.IT.s)	
		end	
	end --GetStr
	function GetColor (key, def)
		if SA.HasValue(tab[key]) then
			local s = CheckIsStr (ModuleName, tab[key], key)
			if s ~= '' then
				SA.CheckSIsColor (s, 1)
			end	
			p.rs[key] = s
		elseif (def ~= nil) and (not SA.HasValue(p.rs[key])) then
			p.rs[key] = def
		end	
		perhaps (key, p.rs[key], MLMT.IT.s)
	end	--GetColor
	function GetInt (key, Lims, def)
		if tab[key] ~= nil then
			p.rs[key] = CheckIsInt (ModuleName, tab[key], key, Lims[1], Lims[2])
		elseif def ~= nil then
			p.rs[key] = def
		end	
		perhaps (key, '', {MLMT.IT.i,Lims})
	end --GetInt 
	function GetBool (key, def)
		if tab[key] ~= nil then
			p.rs[key] = CheckIsBool (ModuleName, tab[key], key)
		elseif def ~= nil then
			p.rs[key] = def
		end	
		perhaps (key, '', MLMT.IT.b)	
	end --GetBool 
	--BEGIN--
	--default colors
	GetColor	(GIBTi.rk.rs_colorbox)
	GetColor	(GIBTi.rk.rs_color_tit_cllps,	p.rs[GIBTi.rk.rs_colorbox])
	--styles
	GetStr		(GIBTi.rk.rs_bodystyle)
	GetStyleBg	(GIBTi.rk.rs_titlestyle,		p.rs[GIBTi.rk.rs_colorbox])
	GetStyleBg	(GIBTi.rk.rs_headerstyle,		p.rs[GIBTi.rk.rs_colorbox])
	GetStyleBg	(GIBTi.rk.rs_subheaderstyle,	p.rs[GIBTi.rk.rs_color_tit_cllps])
	GetStr		(GIBTi.rk.rs_imagestyle)
	GetStr		(GIBTi.rk.rs_captionstyle)
	GetStr		(GIBTi.rk.rs_labelstyle)
	GetStr		(GIBTi.rk.rs_datastyle)
	GetStr		(GIBTi.rk.rs_belowstyle) 
	--icon
	GetStr		(GIBTi.rk.rs_icon)
	GetBool		(GIBTi.rk.rs_icon_at_begin)
	GetStr		(GIBTi.rk.rs_icon_hint)
	GetStr		(GIBTi.rk.rs_def_name)
	--image
	GetInt		(GIBTi.rk.rs_image_max_num, 	{0,2})
	GetStr		(GIBTi.rk.rs_def_image_size)
	GetBool		(GIBTi.rk.rs_send_img_preinfobox)
	--referred to label/data content
	GetBool		(GIBTi.rk.rs_changeable_lbls)
	GetStr		(GIBTi.rk.rs_param_prefix_lbl)
	GetInt		(GIBTi.rk.rs_def_charnum_cllps,	{1,1000})
	GetStr		(GIBTi.rk.rs_error)
	GetStr		(GIBTi.rk.rs_below)
end	--SetDef

local function SetRsv_ToArgs (ModuleName, frame, rs_main, rsi18n, cat_list, rss_main, rssi18n, tab_lims)
	function SetRsv (tab, key)
		function GetStr (key)
			local val
			local wd
			if tab[key] ~= nil then
				if tab[key] ~= "" then
					val = CheckIsStr (ModuleName, tab[key], key)
				end	
			end
			if val ~= nil then
				if IsQuali (ModuleName, key, val) then
					wd = val
					val = LabelFromWD (val)
				else
					wd = ''
				end	
				p.rss[key] = val
				perhaps (key, wd, MLMT.IT.s)	
			end	
		end --GetStr
		function GetInt (key, Lims)
			if tab[key] ~= nil then
				SA.CheckSIsInt (tab[key], key, Lims[1], Lims[2])
				p.rss[key] = tab[key]
			end	
			perhaps (key, '', {MLMT.IT.i,Lims})
		end --GetInt 
		function GetPosInt (key)
			if tab[key] ~= nil then
				SA.CheckSIsPosInt (tab[key], key) 
			end	
			perhaps (key, '', MLMT.IT.ipos)
		end	--GetPosInt
		function GetNum (key, Lims)
			if tab[key] ~= nil then
				SA.CheckSIsNum (tab[key], key, Lims[1], Lims[2])
				p.rss[key] = tab[key]
			end	
			perhaps (key, '', {MLMT.IT.i,Lims})
		end --GetNum 
		function GetBool (key)
			if tab[key] ~= nil then
				p.rss[key] = CheckIsBool (ModuleName, tab[key], key)
			end	
			perhaps (key, '', MLMT.IT.b)	
		end --GetBool 
		function Not_supported (key, typ)
			error ('Parameter type ('..typ..') not allowed for key "'..key..'"')
		end	
		--BEGIN--
		local arg_type, params
		arg_type, required, params = MLMT.split_item_type_req_vals2 (tab_lims, key)
		if required then
			error ('Required values for reserved keys are not available, for "'..key..'"')
		end	
		if (arg_type == MLMT.IT.s) or (arg_type == MLMT.IT.d) then	
			GetStr (key)
		elseif arg_type == MLMT.IT.i then
			if params == nil then
				GetInt (key)
			else
				GetInt (key, params[1], params[2])
			end	
		elseif arg_type == MLMT.IT.ipos then
			GetPosInt (key)
		elseif arg_type == MLMT.IT.n then
			if params == nil then
				GetNum (key)
			else
				GetNum (key, params[1], params[2])
			end	
		elseif arg_type == MLMT.IT.npos then
			Not_supported (key, MLMT.IT.npos)
		elseif arg_type == MLMT.IT.b then	
			GetBool (key)
		elseif arg_type == MLMT.IT.sz then	
			Not_supported (key, MLMT.IT.sz)
		elseif arg_type == MLMT.IT.a then	
			Not_supported (key, MLMT.IT.a)
		end
	end --SetRsv
	-- rss_main, rssi18n, tab_lims are optionals, 
	-- tab lims can content limits for specific reserved keys
	function OkTable (tab, name)
		if tab ~= nil then
			if #tab > 0 then
				error ('Not numeric parameters are allowed for '..name)
			else
				for key, val in pairs(tab) do
					if type(val) == table then
						error ('The value of the key "'..key..'" is a table, for '..name)
					end
				end
			end
		end
	end --OkTable
	function SetCatInLang (key, val)
		if not string.find (val, '<sup>') then
			cat[key] = val
		end	
	end	--SetCatInLang
	function SetIniCat ()
		function GetCateg (key, val)
			if cat[key] == nil then
				error ('Unknown key name for tracking category ("'..key..'")')
			elseif IsQuali (ModuleName, key, val) then
				local wd = val
				val = LabelFromWD (wd)
				perhaps (key, wd, MLMT.IT.s)	
			end
			SetCatInLang (key, val) 
		end	--GetCateg
		for key, val in pairs (cat) do
			if IsQuali (ModuleName, key, val) then
				local wd = val
				val = LabelFromWD (wd)
				perhaps (key, wd, MLMT.IT.s)
				SetCatInLang (key, val) 
			end	
		end	
		if cat_list ~= nil then --only in demo cat_list == nil
			for key, val in pairs (cat_list) do
				GetCateg (key, val)
			end
		end	
	end	--SetIniCat
	--BEGIN--
	OkTable (rs_main,	'rs table of '..MLMT.MN(ModuleName))
	OkTable (rsi18n,	'rs_val table of '..MLMT.MNi18n(ModuleName))
	OkTable (cat_list,	'cat table of '..MLMT.MN(ModuleName))
	OkTable (rss_main,	'rss table of '..MLMT.MN(ModuleName))
	OkTable (rssi18n,	'rss_val table of '..MLMT.MN(ModuleName))
	SetDef (MLMT.MN(ModuleName), rs_main)
	SetDef (MLMT.MNi18n(ModuleName), rsi18n)
	if SA.HasValue (rsi18n[GIBTi.rk.rs_colorbox]) then
		function SetC (key)
			p.rs[key] = p.rs[key]..';background-color:'..rsi18n[GIBTi.rk.rs_colorbox]
		end	
		if not SA.HasValue (rsi18n[GIBTi.rk.rs_titlestyle]) then
			SetC (GIBTi.rk.rs_titlestyle)
		end	
		if not SA.HasValue (rsi18n[GIBTi.rk.rs_headerstyle]) then
			SetC (GIBTi.rk.rs_headerstyle)
		end	
		if not SA.HasValue (rsi18n[GIBTi.rk.rs_color_tit_cllps]) then
			SetC (GIBTi.rk.rs_subheaderstyle)
		end	
	end	
	local has_rss = (rss_main ~= nil) and (SA.TableSize(rss_main) > 0)
	if has_rss then
		for key, val in pairs(rss_main) do
			if tab_lims[key] == nil then
				p.rss[key] = val
			else
				SetRsv (rss_main, key)
			end	
		end
	end
	local has_rssi18n = (rss_main ~= nil) and (SA.TableSize(rss_main) > 0)
	if (not has_rss) and has_rssi18n then
		error ('Undefined rss table in '..MLMT.MN(ModuleName)..', when rss is defined in '..MLMT.MNi18n(ModuleName), 0)
	elseif has_rss and has_rssi18n then	
		for key, val in pairs(rssi18n) do
			if p.rss[key] == nil then
				error ('Unknown key ('..key..') in rss_val of '..MLMT.MN(ModuleName)..', key found in rss of '..MLMT.MNi18n(ModuleName), 0)
			else
				if tab_lims[key] == nil then
					p.rss[key] = val
				else
					SetRsv (rssi18n, key)
				end	
			end
		end
	end
	SetIniCat ()
	if p.rs[GIBTi.rk.rs_icon_hint] == '' then
		p.rs[GIBTi.rk.rs_icon_hint] = frame:getParent():getTitle()
	end
end --SetRsv_ToArgs

local function SplitRsFromNsArgs (args)
	new_args = {}
	new_config = {}
	for key, val in pairs(args) do
		if MLMT.IsReserv (key) then
			new_config[key] = val
		else	
			new_args[key] = val
		end	
	end
	return new_args, new_config
end --SplitRsFromNsArgs

function p.SetRsv_1ToArgs (ModuleName, frame, args, rs_main, rsi18n, cat_list, rss_main, rssi18n, tab_lims)
	MLMT.ChkFunc ("SetRsv_1ToArgs", {{"ModuleName",ModuleName,"xr"},{"frame",frame,"tr"},
		{"args",args,"tr"},{"rs_main",rs_main,"tr"},{"rsi18n",rsi18n,"tr"},{"cat_list",cat_list,"t"},
		{"rss_main",rss_main,"t"},{"rssi18n",rssi18n,"t"},{"tab_lims",tab_lims,"t"},})
	SetRsv_ToArgs (ModuleName, frame, rs_main, rsi18n, cat_list, rss_main, rssi18n, tab_lims)	
	-- when the config arguments are modified from a template
	local new_args, new_config = SplitRsFromNsArgs (args)
	SetDef ('Parameters', new_config)
	return new_args
end --SetRsv_1ToArgs

function p.SetRsv_2ToArgs (ModuleName, frame, pargs, args, rs_main, rsi18n, cat_list, rss_main, rssi18n, tab_lims)
	MLMT.ChkFunc ("SetRsv_2ToArgs", {{"ModuleName",ModuleName,"xr"},{"frame",frame,"tr"},
		{"pargs",pargs,"tr"},{"args",args,"tr"},{"rs_main",rs_main,"tr"},{"rsi18n",rsi18n,"tr"},
		{"cat_list",cat_list,"t"},{"rss_main",rss_main,"t"},{"rssi18n",rssi18n,"t"},
		{"tab_lims",tab_lims,"t"},})
	SetRsv_ToArgs (ModuleName, frame, rs_main, rsi18n, cat_list, rss_main, rssi18n, tab_lims)	
	-- when the config arguments are modified from a template
	local new_args1, new_config1 = SplitRsFromNsArgs (pargs)
	SetDef ('Template', new_config1)
	local new_args2, new_config2 = SplitRsFromNsArgs (args)
	SetDef ('Parameters', new_config2)
	for key, val in pairs (new_args1) do
		new_args2[key] = val
	end
	return new_args2
end	--SetRsv_2ToArgs

p.id = nil
p.demo = false -- if true, the argument name is set.

local function isSet(var)
	return not ((var == nil) or (var == ''))
end
local function Init0 (args)
	-- Get identification and demo	
	p.id = args.item
	if not isSet(p.id) then
		p.id = mw.wikibase.getEntityIdForCurrentPage()
	end
	p.demo = SA.Bool_Par (args, MLMT.arg.demo)
end --Init0

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

function p.CollapsibleText (S, MaxLength)
	MLMT.ChkFunc ("CollapsibleText", {{"S",S,"sr"},{"MaxLength",MaxLength,"ir"},})
	local Collapsed = ''
	if SD._plain_len(S) > MaxLength then
		Collapsed = '<div class="NavFrame collapsed" style="border:none; padding: 0;">'
	end	
	return
		Collapsed..
		'<div class="NavHead" style="width:100%; background:transparent" align="left">'..
		'</div>'..
		'<div class="NavContent" style="text-align:left;">'..S..'</div></div>'
end --CollapsibleText

function _TitCollapsibleText (args)
	local S = args[1]
	local max_num = SA.PosInt_Par (args, 2, 40)
	local expand = SA.Bool_Par (args, 'expand')
	local framestyle = args['framestyle']
	local titlestyle = args['titlestyle']
	local titlecolor = args['titlecolor']
	local title = args['title']
	local liststyle = args['liststyle']
	local listcolor = args['listcolor']
	local res = ''   
	if S ~= nil then
		if expand == nil then
			expand = SD._plain_len(S) > max_num
		end 
		res= '<div class="mw-collapsible '
		if expand then
			res = res..'mw-collapsed' 
		end	
		res = res..'" style="'
		if framestyle ~= nil then
			res = res..framestyle
		else
			res = res..'border:none; padding: 0;'
		end
		res = res.. '">'
		res = res.. '<div style="'
		if titlestyle ~= nil then
			res = res..titlestyle
		else
			if titlecolor == nil then
				titlecolor = 'transparent'
			end	
			res = res..'width:100%; background:'..titlecolor..'" align="left'
		end
		res = res..'">'
		if title ~= nil then
			res = res..title
		else 
			res = res..WD.getLabel ({'Q27948'})
		end
		res = res..'</div>'
		res = res..'<div class="mw-collapsible-content" style="'
		if liststyle ~= nil then
			res = res..liststyle
		else
			if listcolor == nil then
				listcolor = 'transparent'
			end	
			res = res..'background:'..listcolor..';text-align:left;'
		end
		res = res..'">'..S..'</div></div>'
	end
	return res
end --_TitCollapsibleText

function p.TitCollapsibleText (frame)
	args = SA.GetArgs (frame)
	return _TitCollapsibleText (args)
end

local function ToRed (s)
	return '<span style="color:red"><b>'..s..'</b></span>'
end	

local function CheckByItemA (ModuleName, tab, name)
	-- It checks a item table
	for key, val in pairs(tab[MLMT.k.Args]) do
		function error_h ()
			error ('Expected a string or string table (from '..MLMT.MNi18n(ModuleName)') in '..name..', for "'..key..'"', 0)
		end	
		if type(val) == 'string' then
		elseif type(val) == 'table' then
			for _,s in ipairs(val) do
				if type(s) ~= 'string' then
					error_h ()
				end	
			end	
		else
			error_h ()
		end	
	end	
end --CheckByItemA

local function CheckByItem (ModuleName, name, tab, what, n)
	-- It checks a item table
	if tab[what] == nil then return end
	ModuleName = ModuleName..name
	for key, val in pairs(tab[what]) do
		function msg (s)
			error ('Expected '..s..' as value for "'..key..'" for "'..what..'" in the table of '..MLMT.MN(ModuleName), 0) --Don't translate, for debug
		end	
		if ((type(val) ~= 'table') and (n == 2)) or ((type(val) == 'table') and (#val < 2)) then
			msg ('table (with 2 or more items)') --Don't translate, for debug
		elseif n == 2 then
			if (type(val[1]) ~= 'string') and (type(val[1]) ~= 'table') then
				msg ('1st item of the table a string or table with strings')
			elseif type(val[1]) == 'table' then
				local isOk = true
				for _, s in ipairs(val[1]) do
					if type(s) ~= 'string' then
						isOk = false
						break
					end
				end	
				if not isOk then
					msg ('the table of the 1st item of the table with non-string items')
				end	
			end	
			if type(val[2]) == 'string' then
				IsQuali (ModuleName, key, val[2])
			end	
		elseif n == 1 then
			if type(val) == 'string' then
				IsQuali (ModuleName, key, val)
			else
				msg ('string')
			end	
		end	
	end	
end --CheckByItem

local ArgNames = {} -- it will contain all parameter names, to check duplicate names
local function AddNames (tab, is_main)
	-- It adds each possible parameter name assigned to previous "ArgNames", 
	--   and if a name exists make an error message.
	if tab == nil then return end
	for key, val in pairs(tab) do
		local names = val
		if is_main then
			names = val[1]
		end	
		function CheckSet (S)
			if S == '' then return end
			if ArgNames[S] == nil then
				ArgNames[S] = key
			elseif ArgNames[S] ~= key then
				error ('Duplicate parameter name, thus "'..S..'" exists with the keys: "'..key..'" and "'..ArgNames[S]..'"', 0)
			end	
		end	
		if type(names) == 'string' then
			CheckSet (names)
		else 
			for _, name in ipairs(names) do
				CheckSet (name)
			end	
		end	
	end	
end	--AddNames

function p.CheckArgLab (ModuleName, tab_main, tab_i18n, omit_params, preset_params)
	-- It checks the standard tables ("tab_main", "tab_i18n"; and, in lua, custom new items)
	-- It checks "omit_params" and "preset_params"
	-- Also deletes the items according to the content of the table "omit_params"
	MLMT.ChkFunc ("CheckArgLab", {{"ModuleName",ModuleName,"xr"},{"tab_main",tab_main,"tr"},
		{"tab_i18n",tab_i18n,"tr"},{"omit_params",omit_params,"t"},{"preset_params",preset_params,"t"}})
	CheckByItem (ModuleName, '', tab_main, MLMT.k.Args, 	2)
	CheckByItem (ModuleName, '', tab_main, MLMT.k.Labels,	1)
	CheckByItemA (ModuleName, tab_i18n,	'i18n')
	CheckByItem (ModuleName, '/i18n', tab_i18n, MLMT.k.Labels,	1)
	if omit_params ~= nil then
		for key, val in ipairs(omit_params) do
			if tab_main[MLMT.k.Args][val] == nil then
				error ('Not found "'..val..'" in omit_params from '..MLMT.MNi18n(ModuleName), 0)
			else	
				tab_main[MLMT.k.Args][val] = nil
				tab_i18n[MLMT.k.Args][val] = nil
				if tab_main[MLMT.k.Labels] ~= nil then
					tab_main[MLMT.k.Labels][val] = nil
				end	
				if tab_i18n[MLMT.k.Labels] ~= nil then
					tab_i18n[MLMT.k.Labels][val] = nil
				end	
			end	
		end
	end
	AddNames (tab_main[MLMT.k.Args], true)
	AddNames (tab_i18n[MLMT.k.Args], false)
	if preset_params ~= nil then
		for key, val in pairs(preset_params) do
			if tab_main[MLMT.k.Args][key] == nil then
				error ('Not found "'..key..'" in preset_params of '..MLMT.MNi18n(ModuleName), 0)
			else	
				if type(val) ~= 'number' then
					SD.vtos (val)
					error ('Invalid value assignment for "'..key..'" in preset_params (of '..MLMT.MNi18n(ModuleName)'): '..SD.s, 0)
				end	
			end	
		end
	end	
	return tab_main, tab_i18n
end --CheckArgLab	

function p.CheckArgLabLua (ModuleName, tab_main, tab_i18n, tab_i18n_new, omit_params, preset_params)
	MLMT.ChkFunc ("CheckArgLabLua", {{"ModuleName",ModuleName,"xr"},{"tab_main",tab_main,"tr"},
		{"tab_i18n",tab_i18n,"tr"},{"tab_i18n_new",tab_i18n_new,"t"},{"omit_params",omit_params,"t"},
		{"preset_params",preset_params,"t"},})
	function CheckByItemNew (tab, what, n) --used by lua
		if (tab == nil) or (tab[what] == nil) then return end
		CheckByItem (ModuleName, '/i18n', tab, what, n)
		for key, i in pairs(tab[what]) do
			if tab_main[what][key] ~= nil then
				error ('The new key "'..key..'" (from '..MLMT.MNi18n(ModuleName)..') already exists in '..MLMT.MN(ModuleName)..' and "'..what..'"', 0)
			end	
		end
	end --CheckByItemNew
	tab_main, tab_i18n = p.CheckArgLab (ModuleName, tab_main, tab_i18n, omit_params, preset_params)
	CheckByItemNew (tab_i18n_new, MLMT.k.Args,	 2) --used by lua
	CheckByItemNew (tab_i18n_new, MLMT.k.Labels, 1) --used by lua
	if tab_i18n_new ~= nil then
		AddNames (tab_i18n_new[MLMT.k.Args], true)
	end	
	return tab_main, tab_i18n
end --CheckArgLabLua

p.arglab_t = {
	'al',
	'L',
	'l',
	'a',
	'-',
	'cl',
}
function p.CheckIdx_arglab (ModuleName, idx, omit_params, for_lua)
	-- It checks index "idx" where each item must content a type and a key i.g. {'al',p.k.name}
	-- Also deletes from "idx" the keys contained in "omit_params"
	MLMT.ChkFunc ("CheckIdx_arglab", {{"ModuleName",ModuleName,"xr"},{"idx",idx,"tr"},
		{"omit_params",omit_params,"t"},{"for_lua",for_lua,"b"},})
	local s = #idx
	local pos = 0
	local prior_key = ''
	for _, key in ipairs(idx) do
		pos = pos + 1
		if (type(key) ~= 'table') or (#key ~= 2) then
			SD.vtos (idx)
			SD.vtos (key)
			error ('Expected index table in '..ModuleName..' with {type,key} in position '..pos..' (after "'..prior_key..'"). Now: '..SD.s, 0) --Don't translate, for debug
		else
			prior_key = key[2]
		end	
	end
	local pos = 0
	local old_val = "" 
	for _, key in ipairs(idx) do
		pos = pos + 1
		old_val = key[2]
	end
	ModuleName = '(from '..ModuleName..')'
	if pos ~= #idx then
		error ('Index table '..ModuleName..' error in the key after key "'..old_val..'"', 0) --Don't translate, for debug
	end	
	for _, key in ipairs(idx) do
		local z = 1
		if for_lua then
			z = 0
		end	
		local found = false
		for i = 1, #p.arglab_t-z do
			if key[1] == p.arglab_t[i] then
				found = true
				break
			end
		end
		if not found then
			local list = ''
			for i = 1, #p.arglab_t-z do
				list = list..'"'..p.arglab_t[i]..'", '
			end
			error ('In index table '..ModuleName..' : Invalid type for key "'..key[2]..'" ("'..key[1]..'"). Type must be a value of {'..list..'}', 0)
		end	
	end
	if omit_params ~= nil then
		local idx2 = {}
		for _, key2 in ipairs(idx) do
			local found = false
			for _, key in ipairs(omit_params) do
				if key2[2] == key then
					found = true
					break
				end	
			end
			if not found then
				table.insert (idx2, key2)
			end	
		end
		idx = idx2
	end	
	return idx
end --CheckIdx_arglab

function p.CheckIdx_arglabLua (ModuleName, idx, new_idx)
	-- It checks index "idx" where each item must content a type and a key i.g. {'al',p.k.name}
	-- Also, it checks "new_idx" if exists, and then replace "idx".
	MLMT.ChkFunc ("CheckIdx_arglabLua", {{"ModuleName",ModuleName,"xr"},{"idx",idx,"tr"},
		{"new_idx",new_idx,"t"},})
	p.CheckIdx_arglab (MLMT.MNi(ModuleName), idx, nil, true)
	if new_idx == nil then
		return idx
	else	
		p.CheckIdx_arglab (MLMT.MNi18n(ModuleName), new_idx, nil, true)
		return new_idx
	end
end	-- CheckIdx_arglabLua

----------------------------------------
--Functions for read (from argument) or load (from Wikidata) and write as label or data 
----------------------------------------

local infotable_pos = 1 --pos or label or data. I.e. if N = 3 then assign values in label3 and data3 

function p.GetInfotablePos()
	return infotable_pos
end	

----------------------------------------
-- DEMO FUNCTIONS --
----------------------------------------

local function ArgNameForDemo0 (tab, key)
	res = tab[MLMT.k.Args][key]
	if res == nil  then
		error ('Not set value in table for "'..key..'"')
	else	
		local arg = res[1]
		if type(arg) == 'table' then
			arg = arg[1]
		end
		return res, arg
	end
end	--ArgNameForDemo0

local nopropcolor = 'maroon'
function p.ArgNameForDemo (tab, key)
	MLMT.ChkFunc ("ArgNameForDemo", {{"tab",tab,"tr"},{"key",key,"k"},})
	local res, arg = ArgNameForDemo0 (tab, key)
	local color
	if res[2] == '' then
		color = nopropcolor
	else
		color = 'blue'
	end	
	res = '<span style="color:'..color..'">'..arg..'</span>'
	return res
end	--ArgNameForDemo

-----------------------------------------
-- Image parameters and functions
-----------------------------------------

local i_items1 = {
	[MLMT.k.Args] = {
		[GIBTi.ik.image]		= {{"image","Image"},		"_P18"},
		[GIBTi.ik.image_idx]	= {"image_idx",				""},
		[GIBTi.ik.alt]			= {"alt",					""},
		[GIBTi.ik.size]			= {{"size","width"},		""},
		[GIBTi.ik.caption]		= {{"caption","Caption"},	"_P18,P2096"},
	},	
}
local i_items2 = {
	[MLMT.k.Args] = {
		[GIBTi.ik.image1]		= {{"image","Image",
								"image1","Image1",},		"_P18"},
		[GIBTi.ik.image_idx1]	= {"image_idx1",			""},
		[GIBTi.ik.alt1]			= {{"alt","alt1"},			""},
		[GIBTi.ik.size1]		= {{"size","width",
								"size1","width1"},			""},
		[GIBTi.ik.caption1]		= {{"caption","Caption",
								"caption1","Caption1"},		"_P18,P2096"},
		[GIBTi.ik.image2]		= {{"image2","Image2"},		""},
		[GIBTi.ik.image_idx2]	= {"image_idx2",			""},
		[GIBTi.ik.alt2]			= {"alt2",					""},
		[GIBTi.ik.size2]		= {{"size2","width2"},		""},
		[GIBTi.ik.caption2]		= {{"caption2","Caption2"},	""},
	},	
}
p.i_itemsM = {}
local i_with2 = false
local i_has_capt = -1

function p.i_LoadI18n ()
	if p.rs[GIBTi.rk.rs_image_max_num] == 1 then
		CheckByItemA (ModuleName, GIBTi18n.i_items1, 'i_items1')
		MLMT.CheckLims (ModuleName, GIBTi.i_arg_lims1, true)
		p.i_itemsM = MLMT.tableMerge (ModuleName, i_items1, GIBTi18n.i_items1, true)
	else
		i_with2 = true
		CheckByItemA (ModuleName, GIBTi18n.i_items2, 'i_items2')
		MLMT.CheckLims (ModuleName, GIBTi.i_arg_lims2, true)
		p.i_itemsM = MLMT.tableMerge (ModuleName, i_items2, GIBTi18n.i_items2, true)
	end
	MLMT.add_mod_used (ModuleAbbrev, ModuleName)
end --i_LoadI18n

local function i_arg_items (option)
	if i_with2 then
		for _, i in ipairs(GIBTi.i_idx2) do 
			i = i[2] --since only exists args
			MLMT.add_arg_item (option, ModuleAbbrev, i, i_items2, GIBTi18n.i_items2, GIBTi.i_arg_lims2)
		end	
	else
		for _, i in ipairs(GIBTi.i_idx1) do 
			i = i[2] --since only exists args
			MLMT.add_arg_item (option, ModuleAbbrev, i, i_items1, GIBTi18n.i_items1, GIBTi.i_arg_lims1)
		end	
	end	
end --i_arg_items

local function i_arglab_items ()
	if i_with2 then
		for _, i in ipairs(GIBTi.i_idx2) do 
			i = i[2] --since only exists args
			p.add_arglab_item (ModuleAbbrev, i, i_items2, GIBTi18n.i_items2, GIBTi.i_arg_lims2)
		end	
	else
		for _, i in ipairs(GIBTi.i_idx1) do 
			i = i[2] --since only exists args
			p.add_arglab_item (ModuleAbbrev, i, i_items1, GIBTi18n.i_items1, GIBTi.i_arg_lims1)
		end	
	end	
end --i_arglab_items

local i_tab = {}
local i_used_hand = 0	--number of used images entered manually
local i_used_WD = 0		--number of used images from WD
local i_caption = 0		--number of captions (to detect images without captions)
function p.i_main (frame, args)
	MLMT.ChkFunc ("i_main", {{"frame",frame,"tr"},{"args",args,"tr"},})
	function clean_img (img)
		local brd = string.find (img, '<span data')
	    if brd ~= nil then
	    	img = string.sub (img, 1, brd-1)
	    end	
	    return img
	end
    local imgWD
    local captionWD = {'', ''}
	local img_fromWD = {false, false}
    function readWD (ini_num)
        local sep = '==='
        imgWD = WD.claim ({
            item=p.id, 
            property='P18',
            qualifier='P2096',
            lang=MLMT.lang,
            formatting = 'table', 
            list='true',
            separator = sep,
            rowformat='$0<br/>$1',
            editicon='false',
        })
        if imgWD ~= nil then
	        imgWD = mw.text.split(imgWD, sep)
	        imgWD[#imgWD] = clean_img(imgWD[#imgWD])
	        for i = 1, #imgWD do
				local j = imgWD[i]
	            local p = string.find (j, '<br/>')
	            imgWD[i] = string.sub (j, 1, p-1)
	            img_fromWD[i] = true
	            captionWD[i] = mw.text.trim(string.sub (j, p+5))
	        end
		end
    end --readWD
    function  fromWD (idx)
    	if imgWD == nil then
    		return nil, ''
		else
	        if idx > #imgWD then
	            error ('invalid "image_idx", bigger than '..#imgWD)
	        else
	            return imgWD[idx], captionWD[idx]
	        end
        end
    end --fromWD
    local pencil_added = false
    function pencil (i)
    	if img_fromWD[i] then
    		pencil_added = true
			return ' <span data-bridge-edit-flow="overwrite">'
				.. "[[File:Arbcom ru editing.svg|10px|baseline|"
				.. mw.message.new('Editlink'):inLanguage(SA.lang_to_use):plain()
				.. "|link=https://www.wikidata.org/wiki/" .. p.id .. "?uselang=" .. SA.lang_to_use .. "#P18]]"
				.. "</span>"
		else
			return ''
		end	
    end	--pencil
	local DIS = p.rs[GIBTi.rk.rs_def_image_size]
	local hide = false
	if i_with2 then
		local img = {nil, nil}
		local img_idx = {-1, -1}
		local altfnd = {'', ''}
		local size = {DIS, DIS}
		local caption = {'', ''}
		local first2 = 2
		if p.demo then
			for i = 1, 2 do
				img[i]		= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.image..i)
				altfnd[i]	= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.alt..i)
				caption[i]	= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.caption..i)
			end	
		else
			local read_wd_req = false
			for i = 1, 2 do
				img[i] = SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.image..i][1])
				if img[i] == SA.None then
					if i == 1 then
						hide = true
						break
					end
				else
					img_idx[i]	= SA.Int_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.image_idx..i][1], -1)
					if (img[i] == nil) and (img_idx[i] ~= 0) then
						read_wd_req = true
					end
					altfnd[i]	= SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.alt..i][1], '')
					size[i]		= SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.size..i][1], size[i])
					caption[i]	= SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.caption..i][1], '')
				end	
			end
			if read_wd_req and (not hide) then
				readWD ()
				if img[1] ~= nil then
					first2 = 1
				end	
			end
		end
		if not hide then 
			local img1 = img[1]
			local caption1 = caption[1]
			local same_img = false
			for i = 1, 2 do
				if img[i] ~= nil then
					if img[i] ~= SA.None then
						img[i] = II.InfoboxImage ({args={["image"]=img[i], ["size"]=size[i], ["alt"]=altfnd[i]}})
						i_used_hand = i_used_hand + 1
					end	
				elseif imgWD ~= nil then
					if (((i == 1) and (imgWD[1] ~= nil)) or ((i == 2) and (imgWD[first2] ~= nil))) and (img_idx[i] ~= 0) then
						local imgX, captX
						local ii = img_idx[i]
						if img_idx[i] == -1 then
							if i == 2 then
								ii = first2
							else
								ii = i
							end	
						end
						imgX, captX = fromWD (ii)
						same_img = imgX == img1
						if (i == 2) and (
							(same_img and (captX == '')) or 
							-- two images are equals and not legend in WD
							((img1 ~= '') and (caption1 ~= '') and (img_idx[2] < 1) and (captX == '')) 
							-- the infobox has been edited manually adding one image with complete information, but new image don't has caption
							)
						then 						
							-- WD image is not used -> not second image is added
						else
							img[i] = imgX
							if img[i] ~= nil then
								img[i] = '[[File:'..img[i]..'|'..size[i]..'px|alt='..altfnd[i]..']]'
								i_used_WD = i_used_WD + 1
							end
							if captX ~= '' then
								caption[i] = captX
							end
						end
					end
				end	
			end
			if same_img and (caption[1] == '') and (caption[2] ~= '') then --exists a explanation in second same img, usually from WD
				img[2] = nil
				caption[1] = caption[2]
			elseif (caption[1] == '') and (caption[2] ~= '') then
				local img2 = img[2]
				local caption2 = caption[2]
				img[2] = img[1]
				caption[2] = caption[1]
				img[1] = img2
				caption[1] = caption2
			end	
			for i = 2, 1, -1 do
				if img[i] ~= nil then
					pencil_added = false
					if caption[i] == '' then
						img[i] = img[i]..pencil (i)
						i_has_capt = -1
					elseif caption[i] ~= nil then
						caption[i] = caption[i]..pencil (i)
						i_has_capt = i
						i_caption = i_caption + 1
					end
					if pencil_added then
						break
					end	
				end	
			end
			for i = 1, 2 do
				if img[i] == nil then
					break
				else
					i_tab["image"..i] = img[i]
					if caption[i] ~= nil then
						i_tab["caption"..i] = caption[i]
					end	
				end
			end
		end
	else
		local img = nil
        local img_idx = -1
		local altfnd = ''
		local size = DIS
		local caption = ''
		if p.demo then
			img = p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.image)
			altfnd = p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.alt)
			caption = p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.caption)
		else	
			img = SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.image][1])
			if img == SA.None then
				hide = true
			else	
				img_idx = SA.Int_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.image_idx][1]) or -1
				if p.i_itemsM[MLMT.k.Args][GIBTi.ik.alt] ~= nil then
					altfnd = SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.alt][1]) or ''
				end	
				size = SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.size][1], size)
			end	
		end	
		if not hide then 
			if img ~= nil then
				if not p.demo then
					altfnd = SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.alt][1], '')
					caption = SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.caption][1])
				end	
				img = II.InfoboxImage ({args={["image"]=img, ["size"]=size, ["alt"]=altfnd}})
				i_used_hand = i_used_hand + 1
			else
				local captX
				if img_idx == -1 then
					readWD ()
					if imgWD ~= nil then 
						img, captX = fromWD (1)
					end	
				elseif img_idx > 0 then
					readWD ()
					if imgWD ~= nil then 
						img, captX = fromWD (img_idx)
					end    
				end
				if img ~= nil then
					img = '[[File:'..img..'|'..size..'px|alt='..altfnd..']]'
					i_used_WD = i_used_WD + 1
					if (caption == nil) and (captX == '') then
						img = img..pencil (1)
					elseif SA.HasValue (caption) then
						caption = caption..pencil (1)
						i_caption = 1
					elseif captX ~= '' then
						caption = captX..pencil (1)
						i_caption = 1
					end
				end
			end	
			if img ~= nil then
				if SA.HasValue (caption) then
					i_has_capt = 0
					i_tab["caption"] = caption
				else
					img = img..pencil (1)   
				end	
				i_tab["image"] = img
			end	
		end	
	end	
	for k, v in pairs (i_tab) do  --used in only-lua infoboxes
		p.tab[k] = v
	end	
	return i_has_capt
end --i_main

----------------------------------------
-- LIST (& TemplateData) FUNCTIONS --
----------------------------------------

local function add_arglab_item (mod_abbrev, key, wd_lang_l, lnk, wd_main_a, wd_lang_a, prop, item_type_req)
	MLMT.add_mod_used_in_class (mod_abbrev)
	local row = ''
	row = MLMT.add_pos (row)
	
	--labels
	row = row..'<td>'..MLMT.PerhapsDsplKeyMode(key)..'</td>'
	row = MLMT.append_mod_item (mod_abbrev, row)
	if lnk ~= '' then
		local lnk1 = lnk
		if string.sub (lnk,1,1) == 'P' then
			lnk1 = 'Property:'..lnk1
		end
		row = row..'<td>[[:wikidata:'..lnk1..'|'..lnk..']]</td><td>'..WD.getLabel({lnk, ['lang']=MLMT.lang})..'</td>'
	else	
		row = row..'<td></td><td></td>'
	end	
	row = row..'<td>'..wd_lang_l..'</td>'
	
	--arguments
	local item_type, required, values = MLMT.split_item_type_req_vals_forList (item_type_req)	
	function concat_wd (A)
		if type(A) == 'table' then
			for i, j in pairs(A) do
				if type(j) == 'table' then
					SD.vtos (j)
					error ('Error in table design and key = "'..key..'":'..SD.s..' must be a string') --for debug
				end	
			end	
			A = table.concat (A, ', ')
		end	
		if A == nil then
			error ('Not set variable for key = "'..key..'"') --for debug
		end	
		return A
	end
	wd_main_a = concat_wd(wd_main_a) 
	wd_lang_a = concat_wd(wd_lang_a)
	row = row..'<td>'..wd_main_a..'</td><td>'..wd_lang_a..'</td>'
	if SA.HasValue (prop) then 
		if prop == true then
			row = row..'<td>true</td><td></td>'
		elseif prop == false then	
			row = row..'<td>false</td><td></td>'
		elseif type(prop) == 'table' then
			local props = prop["property"]
			if props == nil then
				--Prop contains a pattern to format a manual value
				row = row..'<td></td><td></td>'
			else	
				local sep = ''
				if string.find(props, ' OR ') then
					sep = ' OR '
					props = mw.text.split (props,sep)
					sep = '<small>'..sep..'</small>'
				elseif string.find(props, '/') then	
					sep = '/'
					props = mw.text.split (props,sep)
				end	
				if type(props) == 'table' then
					local trans = {}
					for k, w in ipairs(props) do
						props[k] = '[[:wikidata:Property:'..w..'|'..w..']]'
						local wd = WD.getLabel({w, ['lang']=MLMT.lang})
						if wd ~= nil then
							table.insert (trans, wd)
						end	
					end	
					row = row..'<td><span style="font-size:50%">WD </span>'..table.concat(props,sep)..'</td><td>'..table.concat(trans,',&#10;')..'</td>'
				else
					local wd = WD.getLabel({props, ['lang']=MLMT.lang})
					row = row..'<td><span style="font-size:50%">WD </span>'..props..'</td><td>'..wd..'</td>'
				end	
			end	
		elseif string.sub (prop,1,1) == '_' then
			local props = mw.text.split(string.sub (prop,2), '-')
			local trans = {}
			for k, w in ipairs(props) do
				if string.sub (w,1,1) == 'Q' then 
					props[k] = '[[:wikidata:'..w..'|'..w..']]'
				else
					props[k] = '[[:wikidata:Property:'..w..'|'..w..']]'
				end	
				local wd = WD.getLabel({w, ['lang']=MLMT.lang})
				if wd ~= nil then
					table.insert (trans, wd)
				end	
			end	
			row = row..'<td><span style="font-size:50%">WD </span>'..table.concat(props,',')..'</td><td>'..table.concat(trans,',&#10;')..'</td>'
		elseif string.sub (prop,1,5) == 'Color:' then
			local color = string.sub (prop,6)
			row = row..'<td><span style="background-color:'..color..'">'..color..'</span></td><td></td>'
		else	
			row = row..'<td>'..prop..'</td><td></td>'
		end
	else
		row = row..'<td></td><td></td>'
	end		
	if wd_main_a == '' then
		item_type = ''
	elseif item_type == nil then
		item_type = 's'
	end
	MLMT.add_arg_types_used (item_type)
	item_type = MLMT.IT_required_vals (item_type, required, values)
	MLMT.ins_tab_row (row..'<td>'..item_type..'</td>')
end	--add_arglab_item

local function blank (val)
	if val == nil then 
		return ''
	else
		return val
	end	
end	--blank

function p.add_arglab_item (mod_abbrev, key, tab_main, tab_lang, lims)
	MLMT.ChkFunc ("add_arglab_item", {{"mod_abbrev",mod_abbrev,"xr"},{"key",key,"k"},
		{"tab_main",tab_main,"tr"},{"tab_lang",tab_lang,"tr"},{"lims",lims,"t"},})
	local wd_main_l, wd_lang_l, lnk
	if tab_main[MLMT.k.Labels] == nil then --only exists arguments
		lnk = ''
		wd_lang_l = ''
	else	
		wd_main_l = tab_main[MLMT.k.Labels][key]
		if wd_main_l == nil then
			lnk = ''
		else	
			wd_main_l, lnk = MLMT.GetLabelL2 (wd_main_l, key)
		end
		wd_lang_l = blank (tab_lang[MLMT.k.Labels][key])
	end	
	local wd_main_a = tab_main[MLMT.k.Args][key] 
	local prop = nil
	local item_type_req = ''
	if wd_main_a == nil then
		wd_main_a = ''
	else	
		prop = wd_main_a[2]
		item_type_req = MLMT.GetITRFromLims (lims, key)
		wd_main_a = wd_main_a[1]
	end	
	wd_lang_a = tab_lang[MLMT.k.Args][key]
	if wd_lang_a == nil then
		wd_lang_a = ''
	end	
	add_arglab_item (mod_abbrev, key, wd_lang_l, lnk, wd_main_a, wd_lang_a, prop, item_type_req)
end --add_arglab_item

function p.add_arglab_item_grp (mod_abbrev, grp, key, tab_main, tab_lang, lims)
	MLMT.ChkFunc ("add_arglab_item_grp", {{"mod_abbrev",mod_abbrev,"xr"},{"grp",grp,"xr"},{"key",key,"k"},
		{"tab_main",tab_main,"tr"},{"tab_lang",tab_lang,"tr"},{"lims",lims,"t"},})
	local wd_main_l, wd_lang_l, lnk
	if (tab_main[MLMT.k.Labels] == nil) or (tab_main[MLMT.k.Labels][grp] == nil) then --only exists arguments
		wd_main_l = ''
		lnk = ''
	else	
		wd_main_l = tab_main[MLMT.k.Labels][grp][key]
		if wd_main_l == nil then
			lnk = ''
		else	
			wd_main_l, lnk = MLMT.GetLabelL2 (wd_main_l, key)
		end
		wd_lang_l = blank (tab_lang[MLMT.k.Labels][grp][key])
	end	
	local wd_main_a = tab_main[MLMT.k.Args][grp][key] 
	local prop = nil
	local item_type_req = ''
	if wd_main_a == nil then
		wd_main_a = ''
	else
		item_type_req = MLMT.GetITRFromLimsGr (lims, grp, key)
		prop = wd_main_a[2]
		wd_main_a = wd_main_a[1]
	end	
	wd_lang_a = tab_lang[MLMT.k.Args][grp][key]
	if wd_lang_a == nil then
		wd_lang_a = ''
	end	
	add_arglab_item (mod_abbrev, grMLMT..'.'..key, wd_lang_l, lnk, wd_main_a, wd_lang_a, prop, item_type_req)
end --add_arglab_item_grp

local function show_arglab_items (idx, func, tab_modname_func)
	local row = ''
	local pos = 1
	table.insert (MLMT.tab_items, '<table class="wikitable sortable">')
	MLMT.ins_tab_row ('<th>P.</th><th>Key</th><th>Value</th><th>WD</th><th>T.</th>')
	local wd = ''
	local typ = ''
	function wd_type (i)
		if rs_wd_t[i] ~= nil then
			wd = rs_wd_t[i][1]
			typ = rs_wd_t[i][2]
			if string.sub (wd,1,1) == '_' then
				wd = string.sub (wd,2)
				if string.sub (wd,1,1) == 'Q' then 
					wd = '[[:wikidata:'..wd..'|'..wd..']]'
				else
					wd = '[[:wikidata:Property:'..wd..'|'..wd..']]'
				end	
			end	
		else
			wd = ''
			typ = MLMT.IT.s
		end
		return wd, typ
	end	--wd_type
	for _, key in ipairs (rs_idx) do
		wd, typ = wd_type (key)
		row = '<td>'..pos..'</td><td>'..key..'</td><td>'..tostring(p.rs[key])..'</td><td>'..wd..'</td><td>'..typ..'</td>'
		MLMT.ins_tab_row (row)
		pos = pos + 1
	end
	for _, key in ipairs (cat_idx) do
		if cat[key] ~= nil then
			wd = wd_type (key)
			row = '<td>'..pos..'</td><td>'..key..'</td><td>'..cat[key]..'</td><td>'..wd..'</td><td>s</td>'
			MLMT.ins_tab_row (row)
			pos = pos + 1
		end
	end
	for key, val in pairs (p.rss) do
		wd, typ = wd_type (key)
		row = '<td>'..pos..'</td><td>'..key..'</td><td>'..tostring(val)..'</td><td>'..wd..'</td><td>'..typ..'</td>'
		MLMT.ins_tab_row (row)
		pos = pos + 1
	end
    table.insert (MLMT.tab_items, '</table>')

	table.insert (MLMT.tab_items, '<table class="wikitable sortable">')
	row = ''
	--begin & labels
	row = MLMT.begin_headers()..row
	row = row.. '<th>WD</th><th>WD content ('..SA.lang_to_use..')</th>'..
				'<th>Localization (i18n)</th>'
	--arguments
	row = row.. '<th>Default names</th><th>Localized names (i18n)</th>'..
				'<th>Values</th><th>WD content ('..SA.lang_to_use..')</th>'..
				'<th>T.</th>'
	local row0 = ''
	if #MLMT.mod_used > 1 then
		row0 = row0..'<th></th>'
	end	
	row0 = row0..'<th></th>'
	MLMT.ins_tab_row (row0..'<th></th><th colspan="3">Labels</th><th colspan="5">Arguments</th>')
	MLMT.ins_tab_row (row)
	MLMT.CheckIdx (idx)
	if idx[SA.HasChild] == nil then
		for _, key in ipairs(idx) do
			if key[1] == '-' then
				key = key[2]
				for _, j in ipairs (tab_modname_func) do
					if (j[1] == "") or (j[1] == key) then
						j[2](key)
						break
					end	
				end	
			else
				local mod_abbrev, key, tab_main, tab_lang, lims = func (key[2])
				p.add_arglab_item (mod_abbrev, key, tab_main, tab_lang, lims)
			end
		end
	else
		for _, grp in ipairs(idx[SA.HasChild]) do
			for _, key in ipairs(idx[grp]) do
				if key[1] == '-' then
					key = key[2]
					for _, j in ipairs (tab_modname_func) do
						if (j[1] == "") or (j[1] == key) then
							j[2](grp, key)
							break
						end	
					end	
				else
					local mod_abbrev, key, tab_main, tab_lang, lims = func (grp, key[2])
					p.add_arglab_item_grp (mod_abbrev, grp, key, tab_main, tab_lang, lims)
				end	
			end
		end
	end
	return MLMT.foot_for_args ()
end --show_arglab_items	

function p.CheckFuncs (funcs)
	--Checks function local_func of i18n
	local_func_name = '"function local_func"'
	if funcs == nil then
	elseif type(funcs) ~= 'table' then
		error (local_func_name..' must return a table, perhaps you are deleted "vals = {}" or "return vals"') --don't translate
	else
		for h, i in ipairs(funcs) do
			if (type(i) ~= 'table') or (#i ~= 2) then
				error ('The item '..h..' returned from '..local_func_name..' is not a table with two items: the target parameter and its value') --don't translate
			elseif i[1] == nil then
				error ('The item '..h..' returned from '..local_func_name..' has not a valid target param, check its name') --don't translate
			end
		end	
	end
end -- CheckFuncs  

----------------------------------------
-- SHARED PREINFOBOX AND ONLY-LUA INFOBOX
----------------------------------------

function p.SetColorsAndIcon (ModuleName, color_gr, icon_key)
	MLMT.ChkFunc ("SetColorsAndIcon", {{"ModuleName",ModuleName,"xr"},{"color_gr",color_gr,"xr"},{"icon_key",icon_key,"x"},})
	--Set values to usual reserved variables: colors and icon
	p.rs[GIBTi.rk.rs_colorbox]			= p._GetInfoboxColor (CheckIsStr(ModuleName,color_gr,GIBTi.rk.rs_colorbox), 1)
	p.rs[GIBTi.rk.rs_color_tit_cllps]	= p._GetInfoboxColor (color_gr, 2)
	if icon_key ~= nil then -- only in demos icon_key == nil (not used)
		p.rs[GIBTi.rk.rs_icon]			= p._GetIcon (CheckIsStr(ModuleName,icon_key,GIBTi.rk.rs_icon))
	end	
end --SetColorsAndIcon

function p.CheckLims (ModuleName, tab)
	MLMT.ChkFunc ("CheckLims", {{"ModuleName",ModuleName,"xr"},{"tab",tab,"tr"},})
	MLMT.CheckLims0 (ModuleName, tab)
end 

function p.Checki18nLims (ModuleName, tab)
	MLMT.ChkFunc ("CheckLims", {{"ModuleName",ModuleName,"xr"},{"tab",tab,"tr"},})
	MLMT.CheckLims0 (ModuleName..'/i18n', tab)
end 

local OtherArgs = {'lang','item','name','demo','proof_params'}

--Uses ruby for infobox labels
p.w_hint_txt = true

--Suffix for hint text, using ruby, at end of the argument name.
p.arg_suffix_equal = '=...'

local function Arg1NameOfKey (tab, key, with_error)
	local ArgOrArgs = tab[MLMT.k.Args][key]
	if (ArgOrArgs == nil) and with_error then
		error ('Not found parameter name/s for "'..key..'"')
	elseif ArgOrArgs == nil  then
	else	
		ArgOrArgs = ArgOrArgs[1]
		if type(ArgOrArgs) == 'table' then
			ArgOrArgs = ArgOrArgs[1]
		end
		return ArgOrArgs
	end
end --Arg1NameOfKey

function p.label_of_key_w_hint_txt (args, tab, key, lab_no_ruby)
	--A text label with its key (with "lbl_"). The text label contains a hint text if its key is not in table of "lab_no_ruby".
	--The text label is a preset label or a customized label for an article using "l_" as prefix for argument.
	MLMT.ChkFunc ("label_of_key_w_hint_txt", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},
		{"lab_no_ruby",lab_no_ruby,"t"},})
	local k = tab[MLMT.k.Args][key]
	local z
	if k ~= nil then
		if type (k[1]) == 'table' then
			local tab2 = {}
			for _, j in ipairs(k[1]) do
				z = p.rs[GIBTi.rk.rs_param_prefix_lbl]..j
				table.insert (tab2, z)
				table.insert (OtherArgs, z)
			end
			k = tab2
		else
			k = p.rs[GIBTi.rk.rs_param_prefix_lbl]..k[1]
			table.insert (OtherArgs, k)
		end	
		k = SA.Str_Par (args, k)
	else
		z = p.rs[GIBTi.rk.rs_param_prefix_lbl]..key
		table.insert (OtherArgs, z)
		k = SA.Str_Par (args, z)
	end	
	if k == nil then
		local l = MLMT.GetLabel (tab, key)
		if (l ~= nil) and string.find (l, 'File:') then
			return l
		elseif p.w_hint_txt then
			local ruby = true
			if lab_no_ruby ~= nil then
				for _, i in ipairs (lab_no_ruby) do
					if i == key then
						ruby = false
						break
					end	
				end	
			end	
			if ruby then
				local lnk_arg_name = Arg1NameOfKey (tab,key,false)
				local param_n = ''
				if lnk_arg_name == nil then
					param_n = p.rs[GIBTi.rk.rs_param_prefix_lbl]..key..'='..l
				else
					param_n = p.rs[GIBTi.rk.rs_param_prefix_lbl]..lnk_arg_name..'='..l..'&#10;'..lnk_arg_name..p.arg_suffix_equal
				end
				return '<ruby title="'..param_n..'">'..l..'</ruby>'
			 else
			 	return l
			 end	
		else	
			return l
		end	
	else
		return k
	end	
end --label_of_key_w_hint_txt
	
function p.label_of_key_w_hint_txts (args, tab, key, keys)
	MLMT.ChkFunc ("label_of_key_w_hint_txts", {{"args",args,"tr"},{"tab",tab,"tr"},
		{"key",key,"k"},{"keys",keys,"ar"}})
	local custom_lab_name = p.rs[GIBTi.rk.rs_param_prefix_lbl]..key
	table.insert (OtherArgs, custom_lab_name)
	local custom_lab = SA.Str_Par (args, custom_lab_name)
	if custom_lab == nil then
		local l = MLMT.GetLabel (tab, key)
		if type (keys) == 'table' then
			for i, j in ipairs(keys) do
				keys[i] = Arg1NameOfKey (tab,j,true)..p.arg_suffix_equal
			end
			keys = table.concat (keys, ', ')
		else
			keys = Arg1NameOfKey (tab,keys,true)..p.arg_suffix_equal
		end
		return '<ruby title="'..custom_lab_name..'='..l..'&#10;'..keys..'">'..l..'</ruby>'
	else
		return custom_lab
	end
end --label_of_key_w_hint_txts
	
p.images = 'images' -- also used as index item
function p.ItemList_or_TempData (args, 
	ModuleAbbrev, -- Abbreviation for ModuleName  
	ModuleName,   -- Main module name
	tab_main,	-- parameter and label table (i18n) from main module
	tab_lang,	-- parameter and label table (i18n) from main module/i18n
	idx,		-- item index table  
	lims,		-- restriction table for a main module parameters
	other_arglab, other_arg, other_lab -- optional tables (to hook parameters and/or labels from other shared modules) 
	  -- with 1 {{name,function}} or 2 items {{name1,function1},{name2,function2}}
	) 
	-- Returns 
	-- * item list or TemplateData code according to |list=p.UsualListOpt, or 
	-- * nothing, if |list= is not set
	MLMT.ChkFunc ("ItemList_or_TempData", {{"args",args,"tr"},{"ModuleAbbrev",ModuleAbbrev,"xr"},
		{"ModuleName",ModuleName,"xr"},{"tab_main",tab_main,"tr"},{"tab_lang",tab_lang,"tr"},
		{"idx",	idx,"tr"},{"lims",lims,"t"},
		{"other_arglab",other_arglab,"t"},{"other_arg",other_arg,"t"},{"other_lab",other_lab,"t"},})
	function Check (tab, what) 
		--Checks that other_arglab and other_arg are correct	
		--Don't translate the messages, are for debug
		for _, j in ipairs(tab) do
			if type(j) == 'table' then
				function typer_error (w_type)
					error ('The item n. '..i..' of '..what..' must be a '..w_type)
				end	
				if type(j[1]) ~= 'string' then
					typer_error ('string')
				end	
				if type(j[2]) ~= 'function' then
					typer_error ('function')
				end	
			else
				SD.vtos (tab)
				SD.vtos (j)
				error ('In "'..what..'", '..SD.s..' must be a table') 
			end	
		end	
	end	--Check
	function arg_label_from_key (key)
		return ModuleAbbrev, key, tab_main, tab_lang, lims
	end	
	function label_from_key (key)
		return MLMT.GetLabelX (ModuleAbbrev, key, tab_main, tab_lang)
	end
	function f_arg_names_types_from_keys (key)
		return ModuleAbbrev, tab_main, tab_lang, lims
	end
	function ArgImg (option)
		return i_arg_items (option)
	end	
	local option = MLMT.all_items_opt (args, p.UsualListOpt)
	local res = nil
	if option ~= nil then
		MLMT.add_mod_used (ModuleAbbrev, ModuleName)
		if option == MLMT.LOpt.list then
			local tabs = {{p.images, i_arglab_items}}
			if other_arglab ~= nil then
				Check (other_arglab, 'other_arglab')
				for _, tab in ipairs (other_arglab) do
					table.insert (tabs, tab)
				end	
			end	
			res = show_arglab_items (idx, arg_label_from_key, tabs)
		elseif (option == MLMT.LOpt.params) or (option == MLMT.LOpt.template) then
			local tabs = {{p.images, ArgImg}}
			if other_arg ~= nil then
				Check (other_arg, 'other_arg')
				for _, tab in ipairs (other_arg) do
					table.insert (tabs, tab)
				end	
			end	
			res = MLMT.show_arg_items (option, idx, f_arg_names_types_from_keys, tabs)
		elseif option == MLMT.LOpt.labels then
			if other_lab == nil then
				res = MLMT.show_lab_items (idx, label_from_key)
			else
				Check (other_lab, 'other_lab')
				res = MLMT.show_lab_items (idx, label_from_key, other_lab)
			end	
		end	
	end	
	return res
end --ItemList_or_TempData

----------------------------------------
-- LUA-INFOBOX FUNCTIONS --
----------------------------------------

p.tab = {}

--each item contains, e.g. ['name_1'] = {2, 'data for name 1'}.
-- where 2 is the position in infobox.data2 = 'data for name 1'
local values = {}

--ordered according to items displayed in infobox, each item contains e.g. 
--  {'name_1', ''} for a normal item and 
--  {'header_1', 'h'} for a header
local keys = {}

local untrans_arg = false

local BeginLangStr = ''

local function DoneLang ()
	if MLMT.LangsDifWriteDirect () then
		return '</div>'
	else
		return ''
	end	
end	--DoneLang

function p.IniLua (args, tab)
	MLMT.ChkFunc ("IniLua", {{"args",args,"tr"},{"tab",tab,"tr"},})
	if MLMT.LangsDifWriteDirect () then
		BeginLangStr = '<div lang="'..MLMT.lang..'" dir="'..MLMT.WriteDirect()..'">'
	end	
	Init0 (args)
	---
	p.tab["bodystyle"]		= p.rs[GIBTi.rk.rs_bodystyle]
	p.tab["titlestyle"]		= p.rs[GIBTi.rk.rs_titlestyle]
	p.tab["headerstyle"]	= p.rs[GIBTi.rk.rs_headerstyle]
	p.tab["subheaderstyle"]	= p.rs[GIBTi.rk.rs_subheaderstyle]
	p.tab["imagestyle"]		= p.rs[GIBTi.rk.rs_imagestyle]
	p.tab["captionstyle"]	= p.rs[GIBTi.rk.rs_captionstyle]
	p.tab["labelstyle"]		= p.rs[GIBTi.rk.rs_labelstyle]
	p.tab["datastyle"]		= p.rs[GIBTi.rk.rs_datastyle]
	p.tab["belowstyle"]		= p.rs[GIBTi.rk.rs_belowstyle]
	
	local Name = SA.Str_Par (args, tab[MLMT.k.Args][GIBTi.rk.name][1])
	if not isSet(Name) then
		if isSet(p.id) then
			Name = WD.getLabel({p.id,['lang']=MLMT.lang})
		end	
		if not isSet(Name) then
			Name = p.rs[GIBTi.rk.rs_def_name]
		end	
	end	
	if (p.rs[GIBTi.rk.rs_icon] == '') or (p.rs[GIBTi.rk.rs_icon] == SA.None) then
		p.tab["title"] = Name
	else
		p.tab["title"] = '<span style="float:'..GetWhereIcon()..';margin:1.5px">[[File:'..p.rs[GIBTi.rk.rs_icon]..'|'..p.rs[GIBTi.rk.rs_icon_hint]..'|22px]]</span>'..Name
	end		
end --IniLua

function p.AddLocalAdminItems (tab_main, tab_i18n_new)
	MLMT.ChkFunc ("AddLocalAdminItems", {{"tab_main",tab_main,"tr"},{"tab_i18n_new",tab_i18n_new,"tr"},})
	function Add (what)
		for key, i in pairs(tab_i18n_new[what]) do
			tab_main[what][key] = i
		end
	end --Add
	Add (MLMT.k.Args)
	Add (MLMT.k.Labels)
	return tab_main
end	--AddLocalAdminItems

function p.CheckAddLocalAdminLims (ModuleName, main, new)
	MLMT.ChkFunc ("CheckAddLocalAdminLims", {{"ModuleName",ModuleName,"xr"},{"main",main,"tr"},
		{"new",new,"t"},})
	p.CheckLims (ModuleName, main)
	if new ~= nil then
		p.Checki18nLims (ModuleName, new)
		for key, j in pairs(new) do 
			if main[key] ~= nil then
				local i = main[key]
				if (type (j) == 'table') and (j[1] == MLMT.IT.a) then 
					--sometimes the array limits are updated in i18n due to translation 
					if (type (i) == 'table') and (i[1] == MLMT.IT.a) then
					else
						error ('Incompatible parameter types for the key "'..j[1]..'" (probably the new limit in i18n)')
					end	
				else	
					error ('The limit (probably the new limit in i18n) for the key "'..j[1]..'" already exists"')
				end
			end	
			main[key] = j
		end
	end
	return main
end	--CheckAddLocalAdminLims

function p.load_key (args, tab, key, lims, untrans_arg_list)
	-- It read the preset values (in demo mode) or the values entered manually or read from WD, as appropriate.
	-- and return the found or set value
	MLMT.ChkFunc ("load_key", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},{"lims",lims,"t"},
		{"untrans_arg_list",untrans_arg_list,"t"},})
	if tab[MLMT.k.Args][key] == nil then
		error ('Not found "'..key..'" in "'..MLMT.k.Args..'"')
	end	
	local Prop = tab[MLMT.k.Args][key][2]
	function GetValNoProp (val)
		if Prop["formatting"] == nil then
			error ('When a value is not called from WD but a second value is defined in a table, the "formatting" is required, in key "'..key..'"') --Don't translate, for debug
		else
			val, n = mw.ustring.gsub (Prop["formatting"], '$1', {['$1'] = val})
		end	
		return val
	end	--GetValNoProp
	local val, untranslated
	if p.demo then
		if (Prop ~= nil) and (type(Prop) == "table") and (Prop["property"] == nil) then
			--Prop contains a pattern to format value
			local res, arg = ArgNameForDemo0 (tab, key)
			val = '<span style="color:'..nopropcolor..'">'..GetValNoProp (arg)..'</span>'
		else	
			val = p.ArgNameForDemo (tab, key)
		end
		return val, true
	else
		if type(Prop) ~= "table" then 
			if string.sub (Prop,1,1) == '_' then
				Prop = string.sub (Prop,2)
			else
				Prop = nil
			end	
		end
		local arg_type, required, params = MLMT.split_item_type_req_vals2 (lims, key)
		local ParId = tab[MLMT.k.Args][key][1]
		if (ParId == nil) or (ParId == '') then
			-- the value is only read from WD and never manually
		else
			val = MLMT.ParamVal (args, ParId, arg_type, required, nil, params)
		end	
		if val == SA.None then
			val = nil
		elseif (val == nil) and (Prop ~= nil) then
			for i = 2, #tab[MLMT.k.Args][key] do
				Prop = tab[MLMT.k.Args][key][i]
				if type(Prop) == "table" then
					Prop["item"] = p.id
					Prop["lang"] = MLMT.lang
					Prop["query"] = 'untranslated'
					val, untranslated = WD.claim (Prop)
				else
					val, untranslated = WD.claim ({item=p.id, lang=MLMT.lang, property=Prop, query='untranslated'})
				end	
				if val ~= nil then
					function found_in_list ()
						for _, i in ipairs(untrans_arg_list) do
							if i == key then
								return true
							end	
						end
						return false
					end
					if untranslated and (untrans_arg_list ~= nil) and found_in_list() then
						untrans_arg = true
					end
					break
				end	
			end	
		elseif (val ~= nil) and (Prop ~= nil) then
			if (Prop["formatting"] ~= nil) and (string.find(Prop["formatting"],'$2') == nil) and 
				(string.find(val,'<span') == nil) and (string.find(val,'%[') == nil)
			then
				val,n = string.gsub (Prop["formatting"], '$1', val)
			elseif (type(Prop) == "table") and (Prop["property"] == nil) then
				--Prop contains a pattern to format a manual value
				val = GetValNoProp (val)
			end	
		end
	end	
	return val, val ~= nil
end --load_key	

local function DataToStr (data)
	if type(data) == 'number' then
		return tostring (data)
	elseif type(data) == 'string' then
		return data
	else
		SD.vtos (data)
		error ('Invalid data type to convert to string, found: '..SD.s)
	end	
end	--DataToStr

local function SetData (key, val)
	p.tab['data'..infotable_pos] = DataToStr (val)
end

local function GetLabelLua (args, tab, key)
	if p.rs[GIBTi.rk.rs_changeable_lbls] then
		return p.label_of_key_w_hint_txt (args, tab, key)
	else	
		return MLMT.GetLabel (tab, key)
	end	
end --GetLabelLua

local function set_val (key, val)
	values[key] = {infotable_pos, val}
	table.insert (keys, {key,''})
	infotable_pos = infotable_pos + 1
end --set_val

function p.show (args, tab, key, val)
	-- It adds to the infobox the the label and/or value (from the value val) for a key
	MLMT.ChkFunc ("show", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},})
	if val ~= nil then
		p.tab['label'..infotable_pos] = GetLabelLua (args, tab, key)
		SetData (key, val)
	end
	set_val (key, val) 
	return val ~= nil
end --show

local function show_direct (key, label, val)
	p.tab['label'..infotable_pos] = label
	SetData (key, val)
	set_val (key, val) 
end	

function p.load_show_key (args, tab, key, lims, untrans_arg_list)
	-- It adds to the infobox the the label and/or value for a key
	-- taking the values, as appropriate, from:
	--   the preset values (in demo mode) or entered manually or read from WD.
	MLMT.ChkFunc ("load_show_key", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},
		{"lims",lims,"t"},{"untrans_arg_list",untrans_arg_list,"t"},})
	val = p.load_key (args, tab, key, lims, untrans_arg_list)
	return p.show (args, tab, key, val)
end --load_show_key	

local function AddTitCollapsibleText (args, tab, key, val, where, color)
	local res =
		p.TitCollapsibleText ({val, p.rs[GIBTi.rk.rs_def_charnum_cllps], 
			title = "&nbsp;<b>"..GetLabelLua (args,tab,key).."</b>",
			titlecolor = color,})
	p.tab['data'..where] = res		
	infotable_pos = infotable_pos + 1
end --AddTitCollapsibleText

function p.AddTitCollapsibleText (args, tab, key, val)
	-- It adds a subheader with collapsible text
	if val ~= nil then
		MLMT.ChkFunc ("AddTitCollapsibleText", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},
			{"val",val,"ar"},})
		val = DataToStr (val)	
		AddTitCollapsibleText (args, tab, key, val, infotable_pos, p.rs[GIBTi.rk.rs_color_tit_cllps])
	end	
	set_val (key, val) 
	return val ~= nil
end --AddTitCollapsibleText

function p.AddHeader (args, tab, key)
	-- It adds a simple header
	MLMT.ChkFunc ("AddHeader", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},})
	local label = GetLabelLua (args, tab, key)
	values[key] = {infotable_pos, label}
	p.tab['header'..infotable_pos] = label
	table.insert (keys, {key,'h'})
	infotable_pos = infotable_pos + 1 
end	--AddHeader

function p.AddHeaderArg (args, tab, key, val, collapsible)
	-- It adds a header with associated val
	MLMT.ChkFunc ("AddHeaderArg", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},
		{"val",val,"a"},{"collapsible",collapsible,"br"},})
	val = DataToStr (val)
	if collapsible then
		AddTitCollapsibleText (args, tab, key, val, p.rs[GIBTi.rk.rs_colorbox])
	else
		p.AddHeader (args, tab, key)
		p.tab['data'..infotable_pos] = val
		infotable_pos = infotable_pos + 1
	end	
end	--AddHeaderArg

function p.ExecFuncs_SetHeaders (frame, tab, local_func, n_last_capt)
	MLMT.ChkFunc ("ExecFuncs_SetHeaders", {{"frame",frame,"tr"},{"tab",tab,"tr"},
		{"local_func",local_func,"f"},{"n_last_capt",n_last_capt,"ir"},})
	-- 1. Execute the functions send from "local_func"
	if local_func ~= nil then 
		function args_f (key)
			local found = false
			for k, j in pairs(tab[MLMT.k.Args]) do
				if k == key then
					found = true
					break
				end
			end	
			if not found then
				error ('Invalid key from local_func: "'..key..'"')
			end
			return values[key][2] or ''
		end	--args_f
		local funcs = local_func (frame, args_f)
		p.CheckFuncs (funcs)
		if funcs ~= nil then
			for h, i in ipairs(funcs) do
				local val = i[2]
				val = DataToStr (val)
				val = mw.text.trim (val)
				if (val ~= '') and (values[key] ~= nil) then
					local key = i[1]
					p.tab['data'..values[key][1]] = val
				end	
			end
		end
	end

	-- 2. Set group headers if they contain any item in the group
	local has_items = false
	for h = #keys, 1, -1 do
		if keys[h][2] == 'h' then
			if has_items then
				has_items = false
			else
				p.tab['header'..values[keys[h][1]][1]] = nil
			end	
		else
			if values[keys[h][1]][2] ~= nil then
				has_items = true
			end	
		end	
	end	
	if has_items and (n_last_capt > -1) then
		if n_last_capt == 0 then
			n_last_capt = ''
		end	
		-- Now it displays the last caption followed by a bar if there are elements of 
		---  1. a first group without a header. 
		---  2. any element if no groups exist.
		-- The color of the bar is less apparent than the color corresponding to a heading
		p.tab[GIBTi.ik.caption..n_last_capt] = p.tab[GIBTi.ik.caption..n_last_capt]..
		'<span style="display:inline-block;width:100%;height:1.0em;background:'..p.rs[GIBTi.rk.rs_color_tit_cllps]..';position:relative;top:0.4em;"></span>'
	end	
end --ExecFuncs_SetHeaders

function p.HasAnyValue (keys)
	-- Used i.g. for change the header group caption if exists any items of a subgroup defined in "keys"
	MLMT.ChkFunc ("HasAnyValue", {{"keys",keys,"tr"},})
	for _, i in ipairs(keys) do
		if (values[i] ~= nil) and (values[i][2] ~= nil) then
			return true
		end	
	end	
	return false
end	--HasAnyValue

function p.HasNValues (keys)
	-- It returns the item number of the subgroup "keys" that have a value
	MLMT.ChkFunc ("HasNValues", {{"keys",keys,"tr"},})
	local count = 0
	for _, i in ipairs(keys) do
		if (values[i] ~= nil) and (values[i][2] ~= nil) then
			count = count + 1
		end	
	end	
	return count
end	--HasNValues

function p.HasAllValues (keys)
	-- It returns true if all items of the subgroup "keys" have a value
	MLMT.ChkFunc ("HasAllValues", {{"keys",keys,"tr"},})
	for _, i in ipairs(keys) do
		if (values[i] == nil) or (values[i][2] == nil) then
			return false
		end	
	end	
	return true
end	--HasAllValues

function p.SetOtherHeader (target_key, label)
	-- To change a header tag
	MLMT.ChkFunc ("SetOtherHeader", {{"target_key",target_key,"k"},{"label",label,"xr"},})
	p.tab['header'..values[target_key][1]] = label
end	

function p.SetOtherLabel (target_key, label)
	-- To change a label text
	MLMT.ChkFunc ("SetOtherLabel", {{"target_key",target_key,"k"},{"label",label,"xr"},})
	p.tab['label'..values[target_key][1]] = label
end	

function p.SetOtherData (target_key, val)
	-- To change a val content
	MLMT.ChkFunc ("SetOtherData", {{"target_key",target_key,"k"},{"val",val,"ar"},})
	p.tab['data'..values[target_key][1]] = DataToStr (val)
end

function p.GetData (key)
	-- It returns the value of a key
	MLMT.ChkFunc ("GetData", {{"key",key,"k"},})
	return p.tab['data'..values[key][1]] or ''
end

function p.CheckShowParams (frame, args, ArgsPoss)
	--Check that all parameters are valid
	MLMT.ChkFunc ("CheckShowParams", {{"frame",frame,"tr"},{"args",args,"tr"},{"ArgsPoss",ArgsPoss,"tr"},})
	MLMT.CheckParams (args, ArgsPoss, OtherArgs, true, true)
	local res, has_error, has_dupli = MLMT.ErrorMsgs (frame, args, tab)
	local cat = ''
	if res ~= nil then
		local key = ArgsPoss[1]
		show_direct (key, ToRed (p.rs[GIBTi.rk.rs_error]), ToRed (res)) 
	end	
	if has_error and (cat_arg_error ~= nil) then
		cat = ' [['..cat_arg_error..']]'
	end
	if has_dupli and (cat_arg_dupli ~= nil) then
		cat = cat..' [['..cat_arg_dupli..']]'
	end
	if untrans_arg and (cat_wds_untranslat ~= nil) then
		cat = cat..' [['..cat_wds_untranslat..']]'
	end
	return cat
end	--CheckShowParams

function p.InfoboxWithItsValues ()
	--Main return of only-lua infobox 
	return BeginLangStr..Infobox.infobox (p.tab)..DoneLang()
end	

----------------------------------------
-- PREINFOBOX FUNCTIONS --
----------------------------------------
--Variables--

--Prefix for value name to send to template
p.arg_prefix_val = 'val_'

--Prefix for label name to send to template
p.lbl_prefix = 'lbl_'

--table with the parameters (arguments and labels) to send to template.
local args_t = {}

function p.GetParamNFromT (ModuleName, i18nM, i18n, idx, new_args, new_pos)
--[[
	Used in preinfoboxes, 
	it adds non-standard items (and returned in "i18nM" and "i18n"), after checking them.
	  Non-standard items are defined in "new_args" 
	  "new_args" is a table with i.g. ["name_1"] = {"name_1","Name_1"}, ...  and 
	their optional position ("new_pos") in standard table, are returned in "idx".
	  "new_pos" is a table with i.g. {"new_1", "prior_standard_item_name"}, ...
--]]
	MLMT.ChkFunc ("GetParamNFromT", {{"ModuleName",ModuleName,"xr"},{"i18nM",i18nM,"tr"},
		{"i18n",i18n,"tr"},{"idx",idx,"tr"},{"new_args",new_args,"t"},{"new_pos",new_pos,"t"},})
    if new_args == nil then
    else
    	function in_new_args ()
    		return ', in new_args (from '..MLMT.MNi18n(ModuleName)..')'
    	end
        for k, j in pairs(new_args) do
        	if i18nM[MLMT.k.Args][k] ~= nil then
        		error ('The key "'..k..'" already exists, you try to add it as a new parameter'..in_new_args(), 0)
        	end	
        	if (type(j) ~= 'string') and (type(j) ~= 'table') then
        		error ('The value for a new key "'..k..'" must be a string or string table'..in_new_args(), 0)
        	end	
        	if type (j) == 'table' then
        		for _, item in ipairs(j) do
        			if type (item) ~= 'string' then
        				error ('All values for the new key "'..k..'" must be a string'..in_new_args(), 0)
        			end		
        		end	
        	end	
            i18nM[MLMT.k.Args][k] = {j, ''}
            i18n[MLMT.k.Args][k] = {j, ''}
        end
        if (new_pos == nil) or (#new_pos == 0) then
 	        for k, j in pairs(new_args) do
	        	table.insert (idx, {'a',k})
			end
		else
			function in_new_pos ()
				return 'new_pos (of '..MLMT.MNi18n(ModuleName)..')'
			end	
	        for i, kk in ipairs(new_pos) do
	        	if type(kk) ~= 'table' then
	        		SD.vtos (kk)
	        		error ('The item '..i..' from '..in_new_pos()..' does not contain a table. Now: '..SD.s, 0)
	        	elseif (#kk ~= 2) or (type(kk[1]) ~= 'string') or (type(kk[2]) ~= 'string') then
	        		SD.vtos (kk)
	        		error ('The item '..i..' from '..in_new_pos()..' must contains a table with two keys. Now: '..SD.s, 0)
	        	else	
	        		local found = false
	        		for k, j in pairs(new_args) do
	        			if k == kk[1] then
		        			found = true
		        			break
		        		end	
	        		end	
	        		if not found then
	        			error ('Not found "'..kk[1]..'"'..in_new_args(), 0)	
	        		end	
	        		found = false
	        		for where, k in ipairs(idx) do
	        			if k[2] == kk[2] then
	        				table.insert (idx, where+1, {'a',kk[1]})
		        			found = true
		        			break
		        		end
	        		end	
	        		if not found then
	        			error ('Not found "'..kk[2]..'" from '..in_new_pos()..' in idx of '..MLMT.MNi(ModuleName), 0)		
	        		end	
	        	end	
			end	
		end	
    end 
    AddNames (new_args, false)
    return i18nM, i18n, idx
end --GetParamNFromT

--Functions for send arguments and labels to template infotable--

function p.val_of_key (key, val)
	MLMT.ChkFunc ("val_of_key", {{"key",key,"k"},{"val",val,"a"},})
	if val ~= nil then
		args_t[key] = val
	end	
end --val_of_key
function p.valval_of_key (key, val)
	MLMT.ChkFunc ("valval_of_key", {{"key",key,"k"},{"val",val,"a"},})
	if val ~= nil then
		args_t[p.arg_prefix_val..key] = val
	end	
end --valval_of_key
function p.rsval_of_key (key, val) --for reserved arguments, ie rs_colorbox
	MLMT.ChkFunc ("rsval_of_key", {{"key",key,"k"},{"val",val,"a"},})
	if val ~= nil then
		args_t[key] = val
	end	
end --rsval_of_key

function p.lbl_of_key (key, val)
	MLMT.ChkFunc ("lbl_of_key", {{"key",key,"k"},{"val",val,"xr"},})
	args_t[p.lbl_prefix..key] = val
end

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

-- proof params is a list of parameter keys to use as example for test the infobox
local use_proof_params = false
local proof_params = {}

function p.arg_of_key (args, tab, key, lims, DefVal)
	-- Send a string value of a normal argument with its key (with "val_" prefix). 
	-- In demo mode send the preferred name for the key. Accept "NONE" value.
	MLMT.ChkFunc ("arg_of_key", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},
		{"lims",lims,"t"},{"DefVal",DefVal,"a"},})
	if tab[MLMT.k.Args][key] == nil then --added new key, incompletly
		error ('Undefined key ('..key..') in [MLMT.k.Args] of parent module')
	end	
	local res = nil
	local Args = tab[MLMT.k.Args][key][1] 
	if use_proof_params then --only used in demo
		for _, i in ipairs(proof_params) do
			if i == key then
				return 
			end	
		end
		if tab[MLMT.k.Args][key][3] ~= '' then
			args_t[p.arg_prefix_val..key] = SA.None
		end	
		return nil
	end	
	if Args == SA.None then
		res = SA.None
	elseif p.demo then
		res = p.ArgNameForDemo (tab, key)
	else
		local arg_type, required, params = MLMT.split_item_type_req_vals2 (lims, key)
		res = MLMT.ParamVal (args, Args, arg_type, required, DefVal, params)
	end
	if res ~= nil then
		p.valval_of_key (key, res)
		return res
	end	
end	--arg_of_key

function p.lcfirst (S) 
	--returns lowercase first character
	MLMT.ChkFunc ("lcfirst", {{"S",S,"s"},})
	if (S == nil) or (S == '') then
		return nil
	elseif string.len(S) == 1 then
		return string.lower(S)
	else	
		return string.lower(string.sub(S,1,1))..string.sub(S,2)
	end	
end --lcfirst

function p.arg_label_of_key (args, tab, key, lims, DefVal) --Usual
	-- It adds to the table args_t the the label and/or value for a key
	-- taking the values entered manually or read from WD, as appropriate.
	MLMT.ChkFunc ("arg_label_of_key", {{"args",args,"tr"},{"tab",tab,"tr"},{"key",key,"k"},
		{"lims",lims,"t"},{"DefVal",DefVal,"a"},})
	p.lbl_of_key (key, p.label_of_key_w_hint_txt (args, tab, key))
	return p.arg_of_key (args, tab, key, lims, DefVal)
end	

function p.std_lab_arg_to_tab (frame, args, tab, idx, lims, local_func, lab_no_ruby, omit_params)
	-- It adds to the table args_t the label and/or value for each item according to the index
	-- taking the values as test, entered manually or read from WD, as appropriate.
	function i_second ()
		function ReadPar (key, def)
			args_t[p.arg_prefix_val..key] = SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][key][1], def)
		end
		function ReadParI (key, i, def)
			args_t[p.arg_prefix_val..key..i] = SA.Str_Par (args, p.i_itemsM[MLMT.k.Args][key..i][1], def)
		end
		local DIS = p.rs[GIBTi.rk.rs_def_image_size]
		if i_with2 then
			if p.demo then
				for i = 1, 2 do
					args_t[p.arg_prefix_val..GIBTi.ik.image..i]		= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.image..i)
					args_t[p.arg_prefix_val..GIBTi.ik.alt..i]		= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.alt..i)
					args_t[p.arg_prefix_val..GIBTi.ik.caption..i]	= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.caption..i)
				end	
			else
				for i = 1, 2 do
					ReadParI (GIBTi.ik.image, i)
					args_t[p.arg_prefix_val..GIBTi.ik.image_idx..i] = SA.Int_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.image_idx..i][1], -1)
					ReadParI (GIBTi.ik.alt, i)
					ReadParI (GIBTi.ik.size, i, DIS)
					ReadParI (GIBTi.ik.caption, i)
				end
			end
		else
			if p.demo then
				args_t[p.arg_prefix_val..GIBTi.ik.image]	= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.image)
				args_t[p.arg_prefix_val..GIBTi.ik.alt]		= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.alt)
				args_t[p.arg_prefix_val..GIBTi.ik.caption]	= p.ArgNameForDemo (p.i_itemsM, GIBTi.ik.caption)
			else	
				ReadPar (GIBTi.ik.image)
				args_t[p.arg_prefix_val..GIBTi.ik.image_idx] = SA.Int_Par (args, p.i_itemsM[MLMT.k.Args][GIBTi.ik.image_idx][1], -1)
				ReadPar (GIBTi.ik.alt)
				ReadPar (GIBTi.ik.size, DIS)
				ReadPar (GIBTi.ik.caption)
			end	
		end	
	end -- i_second
	--Inizialization--
	MLMT.ChkFunc ("std_lab_arg_to_tab", {{"frame",frame,"tr"},{"args",args,"tr"},{"tab",tab,"tr"},
		{"idx",idx,"tr"},{"lims",lims,"t"},{"local_func",local_func,"fr"},
		{"lab_no_ruby",lab_no_ruby,"t"},{"omit_params",omit_params,"t"},})
	--Functions--
	function label_of_key_w_hint_txt (key)
		--A text label with its key (with "lbl_"). The text label contains a hint text if its key is not in table of "lab_no_ruby".
		--The text label is a preset label or a customized label for an article using "l_" as prefix for argument.
		return p.label_of_key_w_hint_txt (args, tab, key, lab_no_ruby) 
	end	
	function label_of_key (key) --Usual
		--Send a text label, the normal use.
		p.lbl_of_key (key, label_of_key_w_hint_txt (key))
	end	
	function label_lc_of_key (key) --lc = lowercase first character
		--Send a text label, but if its value is read from Wikidata the first character is lowercase (lc).
		p.lbl_of_key (key, p.lcfirst (label_of_key_w_hint_txt (key)))
	end
	function arg_label_of_key (key) --Usual
		label_of_key (key)
		return p.arg_of_key (args, tab, key, lims)
	end	
	--begin--
	argsC = {}
	if p.rs[GIBTi.rk.rs_send_img_preinfobox] then 
		p.i_main (frame, args)
		for k, v in pairs (i_tab) do 
			args_t[p.arg_prefix_val..k] = v
		end
		args_t[p.arg_prefix_val..GIBTi.ik.rs_img_used_hand] = i_used_hand
		args_t[p.arg_prefix_val..GIBTi.ik.rs_img_used_WD] = i_used_WD
		args_t[p.arg_prefix_val..GIBTi.ik.rs_img_caption] = i_caption
	else	
		i_second ()
	end	
	for i, k in ipairs(idx) do
		local res = nil
		if k[1] == 'a' then
			res = p.arg_of_key (args, tab, k[2], lims)
		elseif k[1] == 'L' then
			label_of_key (k[2])
		elseif k[1]	== 'al' then
			res = arg_label_of_key (k[2])
		elseif k[1] == 'l' then
			label_lc_of_key (k[2])
		end	
		if res ~= nil then
			argsC[k[2]] = res
		end	
	end
	if omit_params ~= nil then
		for _, key in ipairs(omit_params) do
			args_t[p.arg_prefix_val..key] = SA.None
		end
	end	
	function args_f (key)
		local found = false
		for k, j in pairs(tab[MLMT.k.Args]) do
			if k == key then
				found = true
				break
			end
		end	
		if not found then
			error ('Invalid key from local_func: "'..key..'"')
		end	
		return argsC[key] or ''
	end	--args_f
	funcs = local_func (frame, args_f)
	p.CheckFuncs (funcs)
	if funcs ~= nil then
		for h, i in ipairs(funcs) do
			local val = mw.text.trim (i[2])
			if val ~= '' then
				args_t[p.arg_prefix_val..i[1]] = val
			end	
		end
	end
	MLMT.CheckParams (args, {tab, p.i_itemsM}, OtherArgs, true, true)
end --std_lab_arg_to_tab	

----------

function p.arg_of_str (args, key)
	-- Send a string value of a special argument with its key (without "val_" prefix). I.e. used for lang or item
	MLMT.ChkFunc ("arg_of_str", {{"args",args,"tr"},{"key",key,"k"},})
	p.val_of_key (key, SA.Str_Par (args, key))
end
function p.arg_of_rskey (args, key)
	-- Send a string value of a reserved (rs) argument with its key (without its "rs_" prefix and with "val_" prefix)
	MLMT.ChkFunc ("arg_of_rskey", {{"args",args,"tr"},{"key",key,"k"},})
	p.rsval_of_key (key, SA.Str_Par (args, key, p.rs[key]))
end	
function p.arg_of_rsbool (args, key)
	-- Send a boolean value of a reserved (rs) argument with its key (without its "rs_" prefix and with "val_" prefix)
	MLMT.ChkFunc ("arg_of_rsbool", {{"args",args,"tr"},{"key",key,"k"},})
	p.rsval_of_key (key, SA.Bool_Par (args, key, p.rs[key]))
end
function p.IniPreinfo (args, tab, preset_params)
	--Prepare the values to send to template: 
	--* if exist: lang, item, proof_params, preset_params
	--* reserved words, 
	--* tracking categories 
	MLMT.ChkFunc ("IniPreinfo", {{"args",args,"tr"},{"tab",tab,"tr"},{"preset_params",preset_params,"t"},})
	Init0 (args)
	p.arg_of_str (args, MLMT.arg.lang)
	p.arg_of_str (args, MLMT.arg.item)
	local p_f = args[GIBTi.rk.rs_proof_params]
	if p_f ~= nil then
		use_proof_params = true
		local p_f = mw.text.split(p_f,',')
		for i, j in ipairs(p_f) do
			p_f[i] = mw.text.trim (j)
			found = false
			for key, k in pairs(tab[MLMT.k.Args]) do
				if type(k[1]) == 'table' then
					for _, W in ipairs(k[1]) do
						if W == p_f[i] then
							found = true
							break
						end
					end
				else	
					if k == p_f[i] then
						found = true
					end	
				end
				if found then
					table.insert (proof_params, key)
					break
				end	
			end	
			if not found then
				error ('Invalid parameter key to proof the infobox, (with the name: '..p_f[i]..'), passed with "'..GIBTi.rk.rs_proof_params..'"', 0)
			end	
		end
	end
	local rs_idx = { --index for reserved keys 
		--default colors
		GIBTi.rk.rs_colorbox,
		GIBTi.rk.rs_color_tit_cllps,
		--styles
		GIBTi.rk.rs_bodystyle,
		GIBTi.rk.rs_titlestyle,
		GIBTi.rk.rs_headerstyle,
		GIBTi.rk.rs_subheaderstyle,
		GIBTi.rk.rs_imagestyle,
		GIBTi.rk.rs_captionstyle,
		GIBTi.rk.rs_labelstyle,
		GIBTi.rk.rs_datastyle,
		GIBTi.rk.rs_belowstyle,
		--icon & default name
		GIBTi.rk.rs_icon,
		GIBTi.rk.rs_icon_at_begin,
		GIBTi.rk.rs_icon_hint,
		GIBTi.rk.rs_def_name,
		--image
		--GIBTi.rk.rs_image_max_num,
		--GIBTi.rk.rs_def_image_size,
		--referred to label/data content
		--GIBTi.rk.rs_changeable_lbls,
		--GIBTi.rk.rs_param_prefix_lbl,
		--GIBTi.rk.rs_def_charnum_cllps,
		GIBTi.rk.rs_error,
		GIBTi.rk.rs_below,
	}
	for _, key in ipairs(rs_idx) do
		p.rsval_of_key (key, p.rs[key])
	end
	local cat_idx = { --index for category keys 
		GIBTi.rk.rs_cat_arg_error,
		GIBTi.rk.rs_cat_arg_dupli,
		--GIBTi.rk.rs_cat_wds_untranslat,
		GIBTi.rk.rs_cat_no_image,
	}
	for _, key in ipairs (cat_idx) do
		p.rsval_of_key (key, cat[key])
	end
	for key, val in pairs (p.rss) do
		p.rsval_of_key (key, val)
	end
	if preset_params ~= nil then
		for key, val in pairs(preset_params) do
			args_t[p.arg_prefix_val..key] = val
		end
	end
end --IniPreinfo

function p.SendToTemplate (frame, args, tab, TemplateN)
	-- Send to TemplateN all contained values in the table args_t,
	-- having previously added the found errors made by editor
	MLMT.ChkFunc ("SendToTemplate", {{"frame",frame,"tr"},{"args",args,"tr"},{"tab",tab,"tr"},
		{"TemplateN",TemplateN,"xr"},})
	--if use_proof_params then
	local res, has_error, has_dupli = MLMT.ErrorMsgs (frame, args, tab)
	local cat = ''
	if (p.rs[GIBTi.rk.rs_icon] ~= '') and (p.rs[GIBTi.rk.rs_icon] ~= SA.None) then
		args_t['rs_icon_where'] = GetWhereIcon ()
	end	
	if res ~= nil then
		args_t['rs_error'] = ToRed (p.rs[GIBTi.rk.rs_error])
		args_t['val_errors'] = ToRed (res)
	end	
	if has_error and (cat_arg_error ~= nil) then
		cat = ' [['..cat_arg_error..']]'
	end
	if has_dupli and (cat_arg_dupli ~= nil) then
		cat = cat..' [['..cat_arg_dupli..']]'
	end
	return frame:expandTemplate {
		title = TemplateN,
		args = args_t,}..cat
end	--SendToTemplate

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

return p