Vés al contingut

Mòdul:Global infobox tools

De la Viquipèdia, l'enciclopèdia lliure
Aquesta és una versió anterior d'aquesta pàgina, de data 22:00, 19 set 2024 amb l'última edició de Jmarchn (discussió | contribucions). Pot tenir inexactituds o contingut no apropiat no present en la versió actual.
(dif.) ←la pròxima versió més antiga | vegeu la versió actual (dif.) | Versió més nova → (dif.)
Icona de documentació de mòdul Documentació del mòdul [ mostra ] [ modifica el codi ] [ mostra l'historial ] [ refresca ]

Mòdul Global infobox tools (codi · ús · discussió · proves · tests · casos prova | subpàgines · enllaços)

A continuació es mostra la documentació transclosa de la subpàgina /ús. [salta a la caixa de codi]


Mòdul per facilitar la creació de mòduls d'infotaules multilingües (o, dit d'altra forma, permeten la fàcil localització d'aquestes); i així adequar-se a qualsevol Viquipèdia.

Aquest mòdul utilitza, principalment, el Module:Multilang module tools, mòdul del qual hereta moltes propietats i funcions. "Multilang module tools" és de creació de plantilles multilingües; així aquest mòdul és una adequació a les infotaules.

Òbviament, aquest mòdul no presenta (per ell mateix) cap infotaula. Són els mòduls que l'utilitzen els que presenten (directa o indirectament) la infotaula.

Mireu AQUÍ per a més explicacions sobre el mòdul.

Per a proves utilitzeu Mòdul:Global infobox tools/prova.

En profunditat

[modifica]

Variables

[modifica]

Que podrien ser modificades des del mòdul principal, però llavors amb el canvi de l'abreviatura p -> MLITT.

variable Valor per defecte Significat
p.w_hint_txt true Uses ruby for infobox labels
p.arg_prefix_l 'l_' Prefix for label keys, since the label text can be modified.
p.arg_suffix_equal '=...' Suffix for hint text, using ruby, at end of the nom del paràmetre.
p.arg_prefix_val 'val_' Prefix for value name to send to template
p.lbl_prefix 'lbl_' Prefix for label name to send to template




Module to facilitate the creation of multilingual infobox modules (or, in other words, allow easy its localization); and so adapt to any Wikipedia.

This module mainly uses the Module:Multilang module tools, from which it inherits many properties and functions. "Multilang module tools" is the creation of multilingual templates; thus this module is an adaptation to infoboxes.

Obviously, this module does not (by itself) present any infoboxe. These are the modules that are used by those who present (directly or indirectly) the infobox. So the explanations that follow extend to these modules that use it.

Look at here for more explanations on the module.

In depth

[modifica]

Variables

[modifica]

They could be modified from the main module, but then with the change of the abbreviation p -> MLITT.

variable Valor per defecte Significat
p.w_hint_txt true Uses ruby for infobox labels
p.arg_prefix_l 'l_' Prefix for label keys, since the label text can be modified.
p.arg_suffix_equal '=...' Suffix for hint text, using ruby, at end of the nom del paràmetre.
p.arg_prefix_val 'val_' Prefix for value name to send to template
p.lbl_prefix 'lbl_' Prefix for label name to send to template

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>'
	local 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
	
local function title_without_disambig ()
	-- returns the current page name without text between "()"
	local s = mw.title.getCurrentTitle().baseText
	s = 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
local function GetWhereIcon ()
	rs_icon_where = ''
	local LangIsRTL = false -- TODO: currently not provided
	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)
	local 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
	local 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
	local 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
	local 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 
	local 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)
	local function SetRsv (tab, key)
		local 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
		local 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 
		local function GetPosInt (key)
			if tab[key] ~= nil then
				SA.CheckSIsPosInt (tab[key], key) 
			end	
			perhaps (key, '', MLMT.IT.ipos)
		end	--GetPosInt
		local 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 
		local function GetBool (key)
			if tab[key] ~= nil then
				p.rss[key] = CheckIsBool (ModuleName, tab[key], key)
			end	
			perhaps (key, '', MLMT.IT.b)	
		end --GetBool 
		local 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
	local 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
	local function SetCatInLang (key, val)
		if not string.find (val, '<sup>') then
			cat[key] = val
		end	
	end	--SetCatInLang
	local function SetIniCat ()
		local 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
		local 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)
	local new_args = {}
	local 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

local 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
		local 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
		local 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	
		local 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"},})
	local 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"},})
	local 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}
    local 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
    local 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
    local 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]..'px', ["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)	
	local 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 = ''
	local 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 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"},})
	local 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
				local 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
	local function arg_label_from_key (key)
		return ModuleAbbrev, key, tab_main, tab_lang, lims
	end	
	local function label_from_key (key)
		return MLMT.GetLabelX (ModuleAbbrev, key, tab_main, tab_lang)
	end
	local function f_arg_names_types_from_keys (key)
		return ModuleAbbrev, tab_main, tab_lang, lims
	end
	local 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"},})
	local 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]
	local 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
					local 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 = 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"},})
	local 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 
		local 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)
				local key = i[1]
				if (val ~= '') and (values[key] ~= nil) then
					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) -- TODO: it was MLMT.ErrorMsgs(frame, args, tab), apparently tab is not needed
	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[GIBTi.rk.rs_cat_arg_error] ~= nil) then
		cat = ' [['..cat[GIBTi.rk.rs_cat_arg_error]..']]'
	end
	if has_dupli and (cat[GIBTi.rk.rs_cat_arg_dupli] ~= nil) then
		cat = cat..' [['..cat[GIBTi.rk.rs_cat_arg_dupli]..']]'
	end
	if untrans_arg and (cat[GIBTi.rk.rs_cat_wds_untranslat] ~= nil) then
		cat = cat..' [['..cat[GIBTi.rk.rs_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
    	local 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
			local 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.
	local function i_second ()
		local 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
		local 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--
	local 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	
	local 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	
	local 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
	local 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	
	local 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