Módulo:Ficha de elemento químico

Este es un módulo en construcción. No debe ser usado en artículos enciclopédicos (aún).

Este módulo servirá de soporte para {{Ficha de elemento químico}}, {{Ficha de compuesto químico}} y {{Ficha de medicamento}}, ya que esas plantillas comparten un conjunto de datos en común, los que se pueden organizar en un solo módulo.

Uso: {{#invoke: Ficha de elemento químico|Función}}, donde |Función= es una de las tres funciones públicas p.FichaElementoQuimico(), p.FichaCompuestoQuimico() y p.FichaMedicamento(), las que llaman a la función privada Ficha() (la que es usualmente pública); en vez de llamar a Ficha() directamente, las llamadas a estas tres funciones llaman a Ficha() el parámetro |plantilla=, el que corresponde a las tres opciones, y en base a estas, la función Ficha() hara algunas cosas específicas de la plantilla desde la que se está llamando, especificamente, generar distintas fichas para cada una.


local p = {}
local ModuloArgumentos			= require('Módulo:Argumentos')
local ModuloFicha				= require('Módulo:Ficha')
local ModuloWikidata			= require('Módulo:Wikidata')
local elementoTabla				= require('Módulo:Tablas').elemento
local getUnit					= require('Módulo:Wikidata/unidades').main
local Datos						= mw.loadData('Módulo:Ficha de elemento químico/datos')
local argumentos
local Entidad
local InstanciaDeID

function p.FichaElementoQuimico(frame)
	return Ficha(frame, 'elementoquímico')
end

function p.FichaCompuestoQuimico(frame)
	return Ficha(frame, 'compuestoquímico')
end

function p.FichaMedicamento(frame)
	return Ficha(frame, 'medicamento')
end

function Ficha(frame, plantilla)
	-- :: Inicializador
	argumentos	= ModuloArgumentos.obtenerArgumentosConValor(frame)
	Entidad		= mw.wikibase.getEntity(argumentos.entidad) or mw.wikibase.getEntity(argumentos.id) or {}

	local InstanciaDe		= elementoTabla(Entidad, 'claims', 'P31', 1)
	if InstanciaDe then InstanciaDeID = elementoTabla(InstanciaDe, 'mainsnak', 'datavalue', 'value', 'id') end

	-- :: Información general
	local Nombre	= argumentos['nombre'] or ModuloWikidata.obtenerEtiquetaWikidata(Entidad) or ModuloPaginas.nombrePagina({desambiguar='sí'})
	local Simbolo	= propiedad('P246', argumentos['símbolo'])
	local Numero	= propiedad('P1086', argumentos['número'])
	local NM		= argumentos['nm']

	local Color	= 'CCCCCC'
	local Serie
	local Grupo
	local Periodo
	local Bloque
	local ConfElec
	local ElectNivel
	
	if plantilla == 'elementoquímico' then
		if Datos['porNumero'][Numero] then
			Color		= Datos['porNumero'][Numero][1]
			Serie		= Datos['porNumero'][Numero][2]
			Grupo		= Datos['porNumero'][Numero][3]
			Periodo		= Datos['porNumero'][Numero][4]
			Bloque		= Datos['porNumero'][Numero][5]
			ConfElec	= frame:preprocess(Datos['porNumero'][Numero][6])
			ElectNivel	= Datos['porNumero'][Numero][7]
		end
	elseif plantilla == 'compuestoquímico' then
		Color = 'DBD7D2'
	end

	local ColorEtiqueta = Color
	local res = {}
	Color:gsub('[0-9A-Fa-f][0-9A-Fa-f]',function(n)
	    n = tonumber(('0x' .. n) + 24)
	    if n > 255 then n = 255 end
	    table.insert (res, string.format("%x", n))
	    end)
	if #res > 0 then ColorEtiqueta = table.concat(res, '') end
	
	-- :: Formato
	local ClaseTitulo
	local EstiloTitulo		= 'background-color:#' .. Color .. ';'
	local EstiloEtiqueta	= 'width:50%;background-color:#' .. ColorEtiqueta .. ';'
	local EstiloDatos		= 'width:50%'
	
	-- :: Información general
	local NombreEtiqueta	= {}
	local NombreValor		= {}
	
	table.insert(NombreEtiqueta, '[[Anexo:Elementos químicos|Nombre]]')
	table.insert(NombreValor, capitalizar(Nombre))

	if Simbolo then
		NombreEtiqueta[2]	= '[[Anexo:Elementos químicos|símbolo]]'
		NombreValor[2]		= Simbolo
	end
	
	if Numero then
		table.insert(NombreEtiqueta, '[[Número atómico|número]]')
		table.insert(NombreValor, Numero)
	end
	
	NombreEtiqueta			= table.concat(NombreEtiqueta,", ")
	NombreValor				= table.concat(NombreValor,", ")
	
	if NombreEtiqueta:len() > 12 then NombreEtiqueta = '<span style="font-size:smaller">' .. NombreEtiqueta .. '</span>' end

	local GrupoEtiqueta		= {}
	local GrupoEtiquetaEnl	= {}
	local GrupoValor		= {}
	local Etiqueta

	if Grupo then
		Etiqueta = 'Grupo'
		table.insert(GrupoEtiqueta, '[[Tabla_periódica_de_los_elementos#Grupos|' .. Etiqueta .. ']]')
		table.insert(GrupoValor, Grupo)
	end
	
	if Periodo then
		Etiqueta = 'periodo'
		if not GrupoEtiqueta[1] then Etiqueta = 'Periodo' end
		table.insert(GrupoEtiqueta, '[[Tabla_periódica_de_los_elementos#Períodos|' .. Etiqueta .. ']]')
		table.insert(GrupoValor, Periodo)
	end
	
	if Bloque then
		Etiqueta = 'bloque'
		if not GrupoEtiqueta[1] then Etiqueta = 'Bloque' end
		table.insert(GrupoEtiqueta, '[[Tabla_periódica_de_los_elementos#Bloques|' .. Etiqueta .. ']]')
		table.insert(GrupoValor, Bloque)
	end

	GrupoEtiqueta			= table.concat(GrupoEtiqueta, ", ")
	GrupoValor				= table.concat(GrupoValor," , ")
	
	if GrupoEtiqueta:len() > 12 then GrupoEtiqueta = '<span style="font-size:smaller">' .. GrupoEtiqueta .. '</span>' end
	
	local Masa			= propiedad('P2067', argumentos['masa_atomica'])
	local Dureza		= propiedad('P5483') or {}
	local DurezaVickers	= argumentos['dureza_vickers'] or Dureza['Q223404']
	local DurezaBrinell = argumentos['dureza_brinell'] or Dureza['Q714750']
	local DurezaRockwell= argumentos['dureza_rockwell'] or Dureza['Q502723']
	local DurezaMohs	= argumentos['dureza'] or argumentos['dureza_mohs'] or Dureza['DurezaMohs'] or propiedad('P1088')

	--{{#ifexist:Media:Capa electrónica {{padleft:{{{número}}}|3|0}} {{Título sin coletilla}}.svg|([[:Archivo:Capa electrónica {{padleft:{{{número}}}|3|0}} {{Título sin coletilla}}.svg|imagen]])}}<!--capa electrónica fin-->

	-- :: Propiedades atómicas
	local Electronegatividad	= propiedad('P1108', argumentos['electronegatividad'])
	if Electronegatividad then Electronegatividad = Electronegatividad .. ' <span style="font-size:smaller">([[escala de Pauling]])</span>' end

	local Radio	= obtenerRadio()

	local RadioMedio						= argumentos['radio_medio'] or Radio['Q159391']
	if RadioMedio then RadioMedio			= RadioMedio .. '&nbsp;[[picómetro|pm]]' end
	
	local RadioAtomico						= argumentos['radio_atómico'] or Radio['Q483788']
	if RadioAtomico then RadioAtomico		= RadioAtomico .. '&nbsp;[[picómetro|pm]] <span style="font-size:smaller">([[radio de Bohr]])</span>' end
	
	local RadioCovalente					= argumentos['radio_covalente'] or Radio['Q485360']
	if RadioCovalente then RadioCovalente	= RadioCovalente .. '&nbsp;[[picómetro|pm]]' end
	
	local RadioIonico						= argumentos['radio_iónico'] or Radio['Q908801']
	if RadioIonico then RadioIonico 		= RadioIonico .. '&nbsp;[[picómetro|pm]]' end
	
	local RadioWaals						= argumentos['radio_van_der_waals'] or Radio['Q166879']
	if RadioWaals then RadioWaals			= RadioWaals .. '&nbsp;[[picómetro|pm]]' end

	local EstadosOxidacion					= propiedad('P1121', argumentos['estados_oxidación'])
	local Oxido								= argumentos['óxido']-- or propiedad(''}) -- Solicitar propiedad en Wikidata

	local PropiedadesAtomicasFicha = {
		tipo = 'sección',
		titulo = 'Propiedades atómicas',
		estilotitulo = EstiloTitulo,
		{'Radio medio', RadioMedio},
		{'[[Electronegatividad]]', Electronegatividad},
		{'[[Radio atómico]] <span style="font-size:100%">(calc)</span>', RadioAtomico},
		{'[[Radio iónico]]', RadioIonico},
		{'[[Radio covalente]]', RadioCovalente},
		{'<span style="font-size:smaller">[[Radio de van der Waals]]</span>', RadioWaals},
		{'<span style="font-size:smaller">[[Estado de oxidación|Estado(s) de oxidación]]</span>', EstadosOxidacion},
		{'[[Óxido]]', Oxido},
	}

	local EnergiaIonizacion		= obtenerEnergiaIonizacion() or {}
	if EnergiaIonizacion then
		for k, v in pairs(EnergiaIonizacion) do
			table.insert(PropiedadesAtomicasFicha, {'<span style="font-size:smaller">' ..  k .. 'ª&nbsp;[[Energía de ionización|energía&nbsp;de&nbsp;ionización]]</span>', v})
		end
	end

	-- :: Propiedades físicas
	local Estado				= propiedad('P515', argumentos['estado'])
	local Densidad				= propiedad('P2054', argumentos['densidad'])
	local PuntoFusion			= propiedad('P2101', argumentos['P_fusión'], 'Q11579')
	local PuntoEbullicion		= propiedad('P2102', argumentos['P_ebullición'])
	local PuntoInflamabilidad	= propiedad('P2128', argumentos['P_inflamabilidad'])
	local EntalpiaVaporizacion	= obtenerEntalpia('P2066', argumentos['E_vaporización'])
	local EntalpiaFusion		= obtenerEntalpia('P2116', argumentos['E_fusión'])
	local EntalpiaCombustion	=  obtenerEntalpia('P2117', argumentos['E_combustión'])
	local EntalpiaFormacion		=  obtenerEntalpia('P3078', argumentos['E_formación'])
	local PresionVapor			= propiedad('P2119', argumentos['presión_vapor'])

	local PresionCritica		= argumentos['P_crítica']-- or propiedad('')
	if PresionCritica then PresionCritica = PresionCritica .. '&nbsp;[[Pascal (unidad)|Pa]]' end

	local TemperaturaCritica	= argumentos['T_crítica']
	if TemperaturaCritica then TemperaturaCritica = TemperaturaCritica .. '&nbsp;[[Kelvin]]&nbsp;(' .. math.ceil(TemperaturaCritica - 273.15) .. ')' end

	local VolumenMolar			= argumentos['volumen_molar']-- or propiedad('')
	local Compresibilidad		= argumentos['compresibilidad']-- or propiedad('')

	-- Varios
	local EstCris				= propiedad('P556', argumentos['estructura_cristalina'])
	local CalorEspecifico		= propiedad('P2056', argumentos['calor_específico'], 'Q3085309')
	local CondElectrica			= propiedad('P2055', argumentos['cond_eléctrica'], 'Q20966435')
	local CondTermica			= propiedad('P2068', argumentos['cond_térmica'], 'Q1463969')
	local ResistenciaMaxima		= argumentos['limite']-- or propiedad('')
	local ModuloElastico		= argumentos['Young']-- or propiedad('')
	local ModuloCizalladura		= argumentos['cortante']-- or propiedad('')
	local Poisson				= propiedad('P5593', argumentos['Poisson'])
	local Velocidad				= propiedad('P2075', argumentos['velocidad'])
	
	-- Identificadores
	local CAS					= propiedad('P231', argumentos['CAS'])
	local EINECS				= propiedad('P232', argumentos['EINECS'])

	-- Peligrosidad
	local SGA					= p.SGA(frame)
	local NFPA704				= p.NFPA704(frame)
	local TemperaturaAutoIng	= argumentos['TAutoig']
	local FasesR				= argumentos['FrasesR']
	local FasesS				= argumentos['FrasesS']
	local FasesH				= argumentos['FrasesH']
	local FasesP				= argumentos['FrasesP']

	local LimiteExplosibilidad	= argumentos['LExplos']
	if not LimiteExplosibilidad then
		local LimitesExplosividad			= {}
		local LimiteExplosibilidadInferior	= propiedad('P2202')
		local LimiteExplosibilidadSuperor	= propiedad('P2203')

		if LimiteExplosibilidadInferior then table.insert(LimitesExplosividad, LimiteExplosibilidadInferior .. '<span style="font-size:smaller">&nbsp(límite inferior)</span>') end
		if LimiteExplosibilidadSuperor then table.insert(LimitesExplosividad,LimiteExplosibilidadSuperor .. '<span style="font-size:smaller">&nbsp(límite superior)</span>') end
		
		table.concat(LimitesExplosividad, '<br>')
	end
	
	-- Isótopos
	local Isotopos				= obtenerIsotopos()
	local IsotoposTabla 		= {}
	local IsotoposFicha

	if Isotopos and Simbolo then
		table.insert(IsotoposTabla, frame:preprocess([=[
{{{!}} width="100%"  rules="all" class="wikitable" style="margin: 0em 0em 0em 0em; text-align:center; margin-top:0; margin-bottom:0;"
{{!}}- style="background-color:#f2f2f2;"
! valign="middle" rowspan="2" {{!}} [[isótopo|iso]]
! valign="middle" rowspan="2" {{!}} [[Abundancia natural|AN]]
! valign="middle" rowspan="2" {{!}} [[Periodo de semidesintegración|Periodo]]
! valign="middle" rowspan="2" {{!}} [[Cadena de desintegración|MD]]
! [[energía de desintegración|Ed]]
! valign="middle" rowspan="2" {{!}} [[producto de desintegración|PD]]
{{!}}- style="background-color:#f2f2f2;"
! [[MeV]]
]=]))
		for _, datos in pairs(Isotopos['datos']) do
			IsotopoNM			= datos['IsotopoNM'] or ''
			IsotopoIsometria	= datos['IsotopoIsometria'] or ''
			IsotopoAbundancia	= datos['IsotopoAbundancia'] or ''
			IsotopoPS			= datos['IsotopoPS'] or ''
			IsotopoMS			= datos['IsotopoMS'] or ''
			IsotopoEnergia		= datos['IsotopoEnergia'] or ''
			IsotopoProducto		= datos['IsotopoProducto'] or ''
			IsotopoNeutrones	= datos['IsotopoNeutrones'] or ''

			table.insert(IsotoposTabla, frame:preprocess('{{!}}-'))
			table.insert(IsotoposTabla, frame:preprocess('{{!}}<sup>') .. IsotopoNM .. IsotopoIsometria .. '</sup>' .. Simbolo)
			table.insert(IsotoposTabla, frame:preprocess('{{!}}') .. IsotopoAbundancia)
			if not IsotopoPS == '' then
				table.insert(IsotoposTabla, frame:preprocess('{{!}}') .. IsotopoPS)
				table.insert(IsotoposTabla, frame:preprocess('{{!}}') .. IsotopoMS)
				table.insert(IsotoposTabla, frame:preprocess('{{!}}') .. IsotopoEnergia)
				table.insert(IsotoposTabla, frame:preprocess('{{!}}') .. IsotopoProducto)
			else
				if IsotopoNeutrones == 1 then
					table.insert(IsotoposTabla, frame:preprocess('{{!}}colspan=4{{!}}[[Isótopo estable|Estable]] con 1 [[Neutrón|' .. IsotopoNeutrones .. ']]'))
				else
					table.insert(IsotoposTabla, frame:preprocess('{{!}}colspan=4{{!}}<span style="font-size:small">[[Isótopo estable|Estable]] con ' .. IsotopoNeutrones .. ' [[Neutrón|neutrones]]'))
				end
			end
		end
	
		table.insert(IsotoposTabla, frame:preprocess('{{!}}}'))
	
		IsotoposFicha			= {
			['tipo'] = 'sección',
			['titulo'] = 'Isótopos más estables',
			['estilotitulo'] = EstiloTitulo,
			{'', 'Artículo principal: [[Anexo:Isótopos de ' .. Nombre:lower() .. '|Isótopos de ' .. Nombre:lower() .. ']]'},
			{'', frame:preprocess(table.concat(IsotoposTabla, '\n'))},
		}
	end
	
	local Sucesion	= obtenerSucecion() or {}
	local Anterior	= Sucesion[1]
	local Posterior	= Sucesion[2]
	local Sucesion	= '<div style="display:inline-block;width:50%;text-align:right;font-size:small;">' ..  Anterior .. '</div><div style="display:inline-block;width:50%;text-align:left;font-size:small;">' .. Posterior .. '</div>'
	local TablaPeriodica= obtenerTablaPeriodica(frame, Simbolo, Nombre, Numero, NM, EstCris)

	-- :: Específicos de compuestos químicos
	local FormulaMolecular = obtenerFormulaMolecular()
	
	-- :: Específicos de medicamentos
	
	-- :: Título
	local Titulo	= capitalizar(Nombre)
	local Subtitulo

	-- :: Imagen
	local Imagen		= argumentos['imagen']
	local Imagen2		= argumentos['imagen2']
	local Tamano		= argumentos['tamañoimagen'] or argumentos['tamaño de imagen']
	local Pie, Pie2

	local PieTabla

	-- :: La ficha
	local TablaFicha = {}
	if plantilla == 'elementoquímico' then
		if Estado or Densidad or PuntoFusion or PuntoEbullicion or PuntoInflamabilidad or EntalpiaVaporizacion or EntalpiaFusion or PresionVapor or TemperaturaCritica or VolumenMolar or Compresibilidad then
			PieTabla = '<span style="font-size:smaller; text-align:justify">Valores en el [[Sistema Internacional de Unidades|SI]] y [[Condiciones normalizadas de presión y temperatura]], salvo que se indique lo contrario.</span>'
		end
		
		Tamano		= Tamano or '250px'
		if Imagen then
			Pie 	= argumentos['pie']
		else
			Imagen	= ModuloWikidata.obtenerImagenWikidata(Entidad, 'P18')
		end

		TablaFicha = {
			entidad				= argumentos.id,
			titulo  			= Titulo,
			subtitulo			= Sucesion,
			subtitulo2			= TablaPeriodica,
			subtitulo3			= EnlacesTabla,
			clasetitulo			= 'física',
			estilotitulo		= EstiloTitulo,
			estiloetiqueta		= EstiloEtiqueta,
			estilodatos			= EstiloDatos,
			imagen				= Imagen,
			['tamañoimagen']	= Tamano,
			pie					= Pie,
			estilopie			= 'font-size:small',
			{tipo='sección',
				titulo = 'Información general',
				estilotitulo = EstiloTitulo,
				{NombreEtiqueta, NombreValor},
				{'[[Serie química]]', Serie},
				{GrupoEtiqueta, GrupoValor},
				{'[[Masa atómica]]', Masa},
				{'<span style="font-size:smaller">[[Configuración electrónica]]</small>', ConfElec},
				{'[[Escalas_de_dureza#Escala_de_Mohs|Dureza Mohs]]', DurezaMohs},
				{'[[Dureza Vickers]]', DurezaVickers},
				{'[[Dureza Brinell]]', DurezaBrinell},
				{'[[Electrón|Electrones]] por [[nivel de energía|nivel]]', ElectNivel},
			},
			PropiedadesAtomicasFicha,
			{tipo = 'sección',
				titulo = 'Propiedades físicas',
				estilotitulo	= EstiloTitulo,
				{'[[Estado de agregación de la materia|Estado ordinario]]', Estado},
				{'[[Densidad]]', Densidad},
				{'[[Punto de fusión]]', PuntoFusion},
				{'[[Punto de ebullición]]', PuntoEbullicion},
				{'[[Punto de inflamabilidad]]', PuntoInflamabilidad},
				{'<span style="font-size:smaller">[[Entalpía de vaporización]]</span>', EntalpiaVaporizacion},
				{'[[Entalpía de fusión]]', EntalpiaFusion},
				{'[[Presión de vapor]]', PresionVapor},
				{CriticaEtiqueta, CriticaValor},
				{'[[Volumen molar]]', VolumenMolar},
				{'[[Módulo de compresibilidad]]', Compresibilidad},
			},
			{tipo = 'sección',
				titulo = 'Varios',
				estilotitulo	= EstiloTitulo,
				{'[[Estructura cristalina]]', EstCris},
				{'[[Número CAS|N.º CAS]]', CAS},
				{'[[Número EINECS|N.º EINECS]]', EINECS},
				{'[[Calor específico]]', CalorEspecifico},
				{'<span style="font-size:smaller">[[Conductividad eléctrica]]</span>', CondElectrica},
				{'<span style="font-size:smaller">[[Conductividad térmica]]</span>', CondTermica},
				{'Resistencia máxima', ResistenciaMaxima},
				{'[[Módulo elástico]]', ModuloElastico},
				{'[[Módulo de cizalladura]]', ModuloCizalladura},
				{'<span style="font-size:smaller>[[Coeficiente de Poisson]]</span>', Poisson},
				{'[[Velocidad del sonido]]', Velocidad},
			},
			{tipo = 'sección',
				titulo = 'Peligrosidad',
				estilotitulo	= EstiloTitulo,
				{'[[Sistema globalmente armonizado de clasificación y etiquetado de productos químicos|SGA]]', SGA},
				{'[[Punto de inflamabilidad]]', PuntoInflamabilidad},
				{'[[NFPA 704]]', NFPA704},
				{'[[Temperatura de autoignición]]', TemperaturaAutoIng},
				{'[[Anexo:Frases R|Frases R]]', FasesR},
				{'[[Anexo:Frases S|Frases S]]', FasesS},
				{'[[Anexo:Frases H|Frases H]]', FasesH},
				{'[[Anexo:Frases P|Frases P]]', FasesP},
				{'[[Límites de explosividad]]', LimiteExplosibilidad},
			},
			IsotoposFicha,
			estilopiedetabla = EstiloTitulo,
			piedetabla = PieTabla,
		}
	elseif plantilla == 'compuestoquímico' then
		Tamano		= Tamano or '250px'
		Pie 		= argumentos['pie'] or 'Estructura química'
		Pie2 		= argumentos['pie2'] or 'Estructura 3D'
		Imagenes	= propiedad('P117') or {}
		Imagen		= argumentos['imagen'] or Imagenes[1]
		Imagen2		= argumentos['imagen2'] or Imagenes[2] or ModuloWikidata.obtenerImagenWikidata(Entidad, 'P18')
		if Imagen and Imagen2 then Tamano = '131px' end
		
		if Estado or Apariencia or Masa or PFK or PFC or PEK or PEC or PDK or PDC or TCK or TCC or PC or cristal or visco or IndiceRefraccion or Dielectrica then
			PieTabla = '<span style="font-size:smaller">Valores en el [[Sistema Internacional de Unidades|SI]] y en [[Condiciones estándar (química)|condiciones estándar]]<br />(25 [[Grado Celsius|℃]] y 1 [[atmósfera (unidad)|atm]]), salvo que se indique lo contrario.</span>'
		end
		
		Subtitulo = '[[Archivo:Star of life caution.svg|24px|link=]]&nbsp;[[Wikipedia:Aviso médico|Aviso médico]]'

		TablaFicha = {
			entidad				= argumentos.id,
			titulo  			= Titulo,
			subtitiulo			= Subtitulo,
			clasetitulo			= 'química',
			estilotitulo		= EstiloTitulo,
			estiloetiqueta		= EstiloEtiqueta,
			estilodatos			= EstiloDatos,
			imagenizquierda		= Imagen,
			['tamañoimagenizquierda']	= Tamano,
			pieizquierdo		= Pie,
			estiloimagenizquierda= 'vertical-align:bottom',
			imagenderecha		= Imagen2,
			['tamañoimagenderecha']	= Tamano,
			piederecho			= Pie2,
			estiloimagenderecha	= 'vertical-align:bottom',
			estilopie			= 'font-size:small;vertical-align:bottom',
			{tipo='sección',
				titulo = '[[Unión Internacional de Química Pura y Aplicada|Nombre IUPAC]]',
				estilotitulo = EstiloTitulo,
				{'', IUPAC},
			},
			{tipo='sección',
				titulo = 'Información general',
				estilotitulo = EstiloTitulo,
				{'Otros nombres', OtrosNombres},
				{'[[[Símbolo químico]]', SimboloQuimico},
				{'[[Fórmula semidesarrollada]]', FormulaSemi},
				{'[[Fórmula estructural]]', FormulaEst},
				{'[[Fórmula molecular]]', FormulaMolecular},
			},
			{tipo = 'sección',
				titulo = 'Identificadores',
				estilotitulo	= EstiloTitulo,
				{'[[Código ATC]]', ATC},
				{'[[Número CAS|N.º CAS]]', CAS},
				{'[[RTECS|Número RTECS]]', RTECS},
				{'[[ChEBI]]', CHEBI},
				{'[ChEMBL]]', CHEMBL},
				{'[[ChemSpider]]', EChemSpider},
				{'[[DrugBank]]', DrugBank},
				{'[[PubChem]]', PubChem},
				{'[[UNII]]', UNII},
				{'[[KEGG]]', KEGG},
				{'[[Módulo de compresibilidad]]', Compresibilidad},
			},
			{tipo = 'sección',
				titulo = 'Propiedades físicas',
				estilotitulo	= EstiloTitulo,
				{'', },
				{'', },
				{'', },
				{'', },
				{'', },
				{'', },
				{'', },
				{'', },
				{'', },
				{'', },
				{'', },
			},
			{tipo = 'sección',
				titulo = 'Peligrosidad',
				estilotitulo	= EstiloTitulo,
				{'[[Sistema globalmente armonizado de clasificación y etiquetado de productos químicos|SGA]]', SGA},
				{'[[Punto de inflamabilidad]]', PuntoInflamabilidad},
				{'[[NFPA 704]]', NFPA704},
				{'[[Temperatura de autoignición]]', TemperaturaAutoIng},
				{'[[Anexo:Frases R|Frases R]]', FasesR},
				{'[[Anexo:Frases S|Frases S]]', FasesS},
				{'[[Anexo:Frases H|Frases H]]', FasesH},
				{'[[Anexo:Frases P|Frases P]]', FasesP},
				{'[[Límites de explosividad]]', LimiteExplosibilidad},
			},
			{tipo = 'sección',
				titulo = 'Riesgos',
				estilotitulo	= EstiloTitulo,
				{'[[Seguridad y salud laboral|Riesgo]]s principales', Riesgo},
				{'Ingestión', Ingestion},
				{'Inhalación', Inhalacion},
				{'Piel', Piel},
				{'Ojos', Ojos},
				{'[[Dosis letal media|LD<sub>50</sub>]]', LD50},
				{'Más información', MasInfo},
			},
			{tipo = 'sección',
				titulo = 'Compuestos relacionados',
				estilotitulo	= EstiloTitulo,
				{'', Relac1n},
				{'', Relac1d},
				{'', Relac2n},
				{'', Relac2d},
				{'', Relac3n},
				{'', Relac3d},
			},
			estilopiedetabla = EstiloTitulo,
			piedetabla = PieTabla,
		}
	elseif plantilla == 'medicamento' then
		Tamano		= Tamano or '250px'
		Pie 		= argumentos['pie'] or 'Estructura química'
		Pie2 		= argumentos['pie2'] or 'Estructura 3D'
		Imagenes	= propiedad('P117') or {}
		Imagen		= argumentos['imagen'] or Imagenes[1]
		Imagen2		= argumentos['imagen2'] or Imagenes[2] or ModuloWikidata.obtenerImagenWikidata(Entidad, 'P18')
		if Imagen and Imagen2 then Tamano = '131px' end

		TablaFicha = {
			entidad				= argumentos.id,
			titulo  			= Titulo,
			subtitiulo			= Subtitulo,
			clasetitulo			= 'medicina',
			estilotitulo		= EstiloTitulo,
			estiloetiqueta		= EstiloEtiqueta,
			estilodatos			= EstiloDatos,
			imagenizquierda		= Imagen,
			['tamañoimagenizquierda']	= Tamano,
			pieizquierdo		= Pie,
			estiloimagenizquierda= 'vertical-align:bottom',
			imagenderecha		= Imagen2,
			['tamañoimagenderecha']	= Tamano,
			piederecho			= Pie2,
			estiloimagenderecha	= 'vertical-align:bottom',
			estilopie			= 'font-size:small;vertical-align:bottom',
			{tipo='sección',
				titulo = 'Información general',
				estilotitulo = EstiloTitulo,
				{'aaa', 'bbb'},
				{'', ''},
			},
		}
	end
	return ModuloFicha.infobox(TablaFicha)
end

function esUnValor(entidad, idPropiedad, idaBuscar)
	if not entidad or not idPropiedad then
		return false
	end
	
	local declaracion = elementoTabla(entidad, 'claims', idPropiedad)
	local idBuscado
	if not declaracion then
		return false
	end

	for k,v in pairs(declaracion) do
		idBuscado = elementoTabla(v,'mainsnak','datavalue','value','id')
		if idBuscado == idaBuscar then
			return true
		end
	end
	return false
end

function listaDesplegable(titulo, lista, frame)
	if not lista then
		return
	end
	return frame:preprocess('{{Lista desplegable|align=left|título='..titulo .. '|1='..lista..'}}')
end

function seccionDesplegable(titulo, lista, frame)
	if not lista then
		return
	end
	return frame:preprocess('{{Sección desplegable|align=left|título=' .. titulo .. '|datos='.. lista .. '}}')
end

function capitalizar(cad)
	return string.upper(string.sub(cad,1,1)) .. string.sub(cad,2)
end

function obtenerEnumCalculado(entidad)
	local valc
	for k,v in ipairs(clasificacionValores) do
		valc = esUnValor(entidad, v[0], v[1])
		if valc then
			return v[2]
		end
	end
end

function obtenerTablaPeriodica(frame, Simbolo, Nombre, Numero, NM, EstCris)
	if not Simbolo or not Numero or not Nombre then return false end
	if not NM then NM = '' end
	if not EstCris then EstCris = '' end

	local TablaPeriodica = frame:preprocess('{{Ficha de elemento químico/minitabla periódica|símbolo=' .. Simbolo .. '|nombre=' .. Nombre .. '|número=' .. Numero .. '|nm' .. NM .. '|estructura_cristalina=' .. EstCris .. '}}')
	local TablaPeriodicaPie = '[[Tabla periódica de los elementos|Tabla completa]] • [[Tabla periódica de los elementos ampliada|Tabla ampliada]]'
	
	return TablaPeriodica .. TablaPeriodicaPie
end

function obtenerIsotopos()
	local Isotopos				= {['ref'] = nil, ['datos'] = {}}

	for i = 1, 24, 1 do
		IsotopoNM			=  argumentos['isótopo' .. i .. '_nm']
		IsotopoIsometria	=  argumentos['isótopo' .. i .. '_isomería']
		IsotopoAbundancia	=  argumentos['isótopo' .. i .. '_abundancia']
		IsotopoPS			=  argumentos['isótopo' .. i .. '_p_semidesintegración']
		IsotopoMS			=  argumentos['isótopo' .. i .. '_modo_desintegración']
		IsotopoEnergia		=  argumentos['isótopo' .. i .. '_energía']
		IsotopoProducto		=  argumentos['isótopo' .. i .. '_producto']
		IsotopoNeutrones	=  argumentos['isótopo' .. i .. '_neutrones']

		if not IsotopoNM and not IsotopoIsometria and not IsotopoAbundancia and not IsotopoNeutrones and not IsotopoPS and not IsotopoMS and not IsotopoEnergia and not IsotopoProducto then break end
		
		table.insert(Isotopos['datos'], {
			['IsotopoNM'] = IsotopoNM,
			['IsotopoIsometria'] = IsotopoIsometria,
			['IsotopoAbundancia'] = IsotopoAbundancia,
			['IsotopoPS'] = IsotopoPS,
			['IsotopoMS'] = IsotopoMS,
			['IsotopoEnergia'] = IsotopoEnergia,
			['IsotopoProducto'] = IsotopoProducto,
			['IsotopoNeutrones'] = IsotopoNeutrones}
		)
	end
	
	if not Isotopos['datos'][1] then return false end

	Isotopos['ref'] = argumentos['isótopos_ref']

	return Isotopos
end

function obtenerEnergiaIonizacion()
	local EnergiaIonizacion

	EnergiaIonizacion		= {}
	for i = 1, 24, 1 do
		EIValor	= argumentos['E_ionización' .. i]
		if not EIValor then break end
		table.insert(EnergiaIonizacion, EIValor ..  '&nbsp;[[Kilojulio por mol|kJ/mol]]')
	end

	if #EnergiaIonizacion > 0 then return EnergiaIonizacion end

	EIObjeto = elementoTabla(Entidad, 'claims', 'P2260')

	if EIObjeto then
		for _, valor in pairs(EIObjeto) do
			EIValor = formatearValor(elementoTabla(valor, 'mainsnak', 'datavalue'))
			EIOrden = tonumber(elementoTabla(valor, 'qualifiers', 'P1545', 1, 'datavalue', 'value'))
			if EIOrden then EnergiaIonizacion[EIOrden] = EIValor end
		end
	end

	if #EnergiaIonizacion > 0 then return EnergiaIonizacion end
end

function p.NFPA704(frame)
	if argumentos['NFPA704'] then return argumentos['NFPA704'] end
	
	local NFPA704			= {}
	local NFPA704Contenido	= {}
	local NFPAValores		= propiedad('P4952') or {}

	local Inflamabilidad	= argumentos['NFPA704_inflamabilidad'] or argumentos['NFPA-F'] or NFPAValores['NFPA704_inflamabilidad'] or propiedad('P994')
	local Salud				= argumentos['NFPA704_salud'] or argumentos['NFPA-H'] or NFPAValores['NFPA704_salud'] or propiedad('P993')
	local Reactividad		= argumentos['NFPA704_reactividad'] or argumentos['NFPA-R'] or NFPAValores['NFPA704_reactividad'] or propiedad('P995')
	local Otro				= argumentos['NFPA704_especial'] or argumentos['NFPA-S'] or NFPAValores['NFPA704_otro'] or propiedad('P877')
	if Otro == 'W' then Otro = '<s>W</s>' end
	
	if Inflamabilidad then return Inflamabilidad end
	
	if Datos['NFPA704']['inflamabilidad'][Inflamabilidad] then table.concat(NFPA704Contenido, '<div class="NFPA704_inflababilidad" title="Inflamabilidad:&nbsp;' ..NFPA704Datos['inflamabilidad'][Inflamabilidad] .. '>' .. Inflamabilidad .. '</div>') end
	if Datos['NFPA704']['salud'][Salud] then table.concat(NFPA704Contenido, '<div class="NFPA704_salud" title="Salud:&nbsp;' ..NFPA704Datos['salud'][Salud] .. '>' .. Salud .. '</div>') end
	if Datos['NFPA704']['reactividad'][Reactividad] then table.concat(NFPA704Contenido, '<div class="NFPA704_reactividad" title="Reactividad:&nbsp;' ..NFPA704Datos['reactividad'][Reactividad] .. '>' .. Reactividad .. '</div>') end
	if Datos['NFPA704']['otro'][Otro] then table.concat(NFPA704Contenido, '<div class="NFPA704_otro" title="Otros peligros:&nbsp;' ..NFPA704Datos['otro'][Otro] .. '>' .. Otro .. '</div>') end

	if #NFPA704Contenido > 0 then
		NFPA704Contenido = table.concat(NFPA704Contenido, '\n')
		table.insert(NFPA704, [=[
<div style="position: relative; height: 85px; width: 75px;">
<div style="position: absolute; height: 75px; width: 75px;">
[[Archivo:NFPA 704.svg|75px|enlace=]]
</div>
]=])
		table.insert(NFPA704, table.concat(NFPA704Contenido, '\n'))
		table.insert(NFPA704, '</div>')
		
		return table.concat(NFPA704, '\n')
	end
end

function p.SGA(frame)
	if argumentos['SGA'] then return argumentos['SGA'] end
end

function obtenerFormulaMolecular()
	local FormulaQuimica	= propiedad('P274')
	local res = {}
	if FormulaQuimica then
		FormulaQuimica = FormulaQuimica:gsub('[A-Z][a-z]*[₁₂₃₄₅₆₇₈₉₁₂₃₄₅₆₇₈₉]*',function(n)table.insert(res, elementoQuimicoAEnlace(n))end)
	end
	
	return table.concat(res, '')
end

function elementoQuimicoAEnlace(elemento)
	local Valor = {}
	local Elemento	= elemento:match('[A-Z][a-z]?')
	local Numero	= elemento:match('[1-9₁₂₃₄₅₆₇₈₉]+')

	if Datos['porAbreviatura'][Elemento] then
		table.insert(Valor, Datos['porAbreviatura'][Elemento])
		if Numero then table.insert(Valor, Datos['aSubíndice'][Numero]) end
	end
	return table.concat(Valor, '')
end

function obtenerEntalpia(propiedad,entidad)
	if not entidad then entidad = Entidad end

	local Elemento	= elementoTabla(entidad, 'claims', propiedad, 1)
	if Elemento then
		Valor		= string.sub(elementoTabla(Elemento, 'mainsnak', 'datavalue', 'value', 'amount'), 2)
		Unidad		= elementoTabla(EnElemento, 'mainsnak', 'datavalue', 'value', 'unit')
		if Unidad then
			if Unidad:sub(32) == 'Q13035094' then
				return tonumber(Valor/1000)
			elseif Unidad:sub(32) == 'Q752197' then
				return tonumber(Valor)
			end
		end
	end
end

function obtenerRadio(entidad)
	if not entidad then entidad = Entidad end

	local Radio			= elementoTabla(entidad, 'claims', 'P2120')
	local RadioValores	= {}
	if Radio then
		for _,prop in pairs(Radio) do
			Valor			= string.sub(elementoTabla(prop, 'mainsnak', 'datavalue', 'value', 'amount'), 2)
			Unidad			= elementoTabla(prop, 'mainsnak', 'datavalue', 'value', 'unit')
			ParteImplicada	= elementoTabla(prop, 'qualifiers', 'P518', 1, 'datavalue', 'value', 'id')
			if Unidad then
				UnidadID	= Unidad:sub('32')
				UnidadValor	= getUnit(Unidad)
				if UnidadID == 'Q192274' then
					if ParteImplicada then
						RadioValores[ParteImplicada] = Valor
					end
				end
			end
		end
		
		if RadioValores['Q483788'] and RadioValores['Q652571'] then RadioValores['Q483788'] = RadioValores['Q483788'] .. '&nbsp;(' .. RadioValores['Q652571'] .. ')' end
	end
	
	return RadioValores
end

function obtenerSucecion()
	local Anterior	= propiedad('P155', argumentos['anterior'])
	local Posterior	= propiedad('P156', argumentos['posterior'])
	local instanciaDe = elementoTabla(Entidad, 'claims', 'P31', 1)
	
	if not Anterior then
		AN	= mw.wikibase.getEntity(elementoTabla(instanciaDe, 'qualifiers', 'P155', 1, 'datavalue', 'value', 'id'))
		if AN then Anterior = ModuloWikidata.obtenerEtiquetaWikidata(AN) end
	end
	
	if not Posterior then
		POS	= mw.wikibase.getEntity(elementoTabla(instanciaDe, 'qualifiers', 'P156', 1, 'datavalue', 'value', 'id'))
		if POS then Posterior = ModuloWikidata.obtenerEtiquetaWikidata(POS) end
	end

	if Anterior then
		Anterior = '[[' .. capitalizar(Anterior:gsub('[%[%]]+','')) .. ']] ← '
	else
		Anterior = ''
	end

	if Posterior then
		Posterior = ' → [[' .. capitalizar(Posterior:gsub('[%[%]]+','')) .. ']]'
	else
		Posterior = ''
	end
	
	return {Anterior, Posterior}
end

--- La función propiedad(), modificada para aceptar calificadores y formatear numeros con unidad
-- @idPropiedad: el identificador de la propiedad de Wikidata
-- @valor: Valor por defecto (usualmente el valor pasado localmente)
-- @unidad: unidad por defecto, de haberla
-- return: Mixed (string o table, dependiendo de la función invocada)
function propiedad(idPropiedad, Valor, Unidad)
	if Valor then
	if Unidad then
			local sep = ' '
			if Unidad:match('^Q[0-9]+$') then
				if Unidad == 'Q25267' or Unidad == 'Q42289' then sep = '' end
				local unit = getUnit('http://www.wikidata.org/entity/Q192274' .. Unidad)
				if unit then
					Valor = Valor .. sep .. unit
				end
			else
				Valor = Valor .. sep .. Unidad
			end
		end
		return Valor
	end

	local Propiedad		= elementoTabla(Entidad, 'claims', idPropiedad)
	
	if Propiedad then
		local ValorFinal
		local Valores		= {}
		for k, propiedad in pairs(Propiedad) do
			Valor			= formatearValor(elementoTabla(propiedad, 'mainsnak', 'datavalue'))
			Calificadores	= elementoTabla(propiedad, 'qualifiers') or {}
			if Valor then table.insert(Valores, {Valor, Calificadores}) end
		end

		-- Si la tabla Valores no está vacía
		if #Valores > 0 then
			-- :: Manejos especializados
			local ValorFinal = {}

			-- Dureza
			if idPropiedad == 'P5483' then
				for k,valor in pairs(Valores) do
					ValorConcatenado= {}
					Valor			= valor[1]
					Calificadores	= valor[2]
					
					if not Valor and not Calificadores then break end
					
					table.insert(ValorConcatenado, Valor)
					
					if Calificadores then
						Metodo		= elementoTabla(Calificadores['P459'], 1, 'datavalue', 'value', 'id')
						if not Metodo then break end
						
						Temperatura	= formatearValor(elementoTabla(Calificadores['P2076'], 1, 'datavalue'))
						Presion		= formatearValor(elementoTabla(Calificadores['P2077'], 1, 'datavalue'))

						if Temperatura then table.insert(ValorConcatenado, Temperatura) end --Temperatura
						if Presion then table.insert(ValorConcatenado, Presion) end --Presión
						
						if #ValorConcatenado > 1 then
							ValorConcatenado[2] = '<span style="font-size:smaller">&nbsp;@&nbsp;' .. ValorConcatenado[2]
							if #ValorConcatenado > 2 then
								ValorConcatenado[3] = '&nbsp;y&nbsp;' .. ValorConcatenado[3]
							end
							ValorConcatenado[#ValorConcatenado] = ValorConcatenado[#ValorConcatenado] .. '</span>'
						end

						ValorFinal[Metodo] = table.concat(ValorConcatenado)
					end
				end
				return ValorFinal

			-- Dureza de Mohs, punto y entalpía
			elseif idPropiedad == 'P1088' or idPropiedad == 'P2128' or idPropiedad == 'P2102' or idPropiedad == 'P2101' or idPropiedad == 'P3078' or idPropiedad == 'P2116' or idPropiedad == 'P2117' or idPropiedad == 'P2066' or idPropiedad == 'P5593' then
				for k,valor in pairs(Valores) do
					ValorConcatenado= {}
					Valor			= valor[1]
					Calificadores	= valor[2]
					table.insert(ValorConcatenado, Valor)

					if Calificadores then
						Temperatura	= formatearValor(elementoTabla(Calificadores['P2076'], 1, 'datavalue'))
						Presion		= formatearValor(elementoTabla(Calificadores['P2077'], 1, 'datavalue'))
						
						if Temperatura then table.insert(ValorConcatenado, Temperatura) end
						if Presion then table.insert(ValorConcatenado, Presion) end

						if #ValorConcatenado > 1 then
							ValorConcatenado[2] = '<span style="font-size:smaller">&nbsp;@&nbsp;' .. ValorConcatenado[2]
							if #ValorConcatenado > 2 then
								ValorConcatenado[#ValorConcatenado] = '&nbsp;y&nbsp;' .. ValorConcatenado[#ValorConcatenado]
							end
							ValorConcatenado[#ValorConcatenado] = ValorConcatenado[#ValorConcatenado] .. '</span>'
						end
					end
					table.insert(ValorFinal, table.concat(ValorConcatenado))
				end
				return table.concat(ValorFinal, '<br>')
				
			-- :: Etiquetado de seguridad (para usar junto con p.NFPA704)
			elseif  idPropiedad == 'P4952' then
				for k,valor in pairs(Valores) do
					Etiquetado		= {}
					Valor			= valor[1]
					Calificadores	= valor[2]
					if Calificadores then
						Etiquetado['NFPA704_inflamabilidad']	= elementoTabla(Calificadores['P994'], 1, 'datavalue', 'value')
						Etiquetado['NFPA704_salud']				= elementoTabla(Calificadores['P993'], 1, 'datavalue', 'value')
						Etiquetado['NFPA704_reactividad']		= elementoTabla(Calificadores['P995'], 1, 'datavalue', 'value')
						Etiquetado['NFPA704_otro']				= elementoTabla(Calificadores['P877'], 1, 'datavalue', 'value')
					end
				end
				return Etiquetado

			-- Sistema cristalino
			elseif idPropiedad == 'P556' then
				Valor = ModuloWikidata.obtenerEtiquetaWikidata(mw.wikibase.getEntity(Valores[1][1]))
				if Valor then
					ValorSimple = Valor:match("%s(%S+)$")
					if ValorSimple:sub(-1) == 'o' then ValorSimple = ValorSimple:sub(1, ValorSimple:len()-1) .. 'a' end
					return '[[' .. Valor .. '|' .. ValorSimple .. ']]'
				end
				
			elseif idPropiedad == 'P117' then
				local Imagenes = {}
				for k,valor in pairs(Valores) do
					table.insert(Imagenes, valor[1])
				end
				
				if #Imagenes > 0 then return Imagenes end

			-- :: Manejos generales sin calificadores
			elseif idPropiedad == 'P2055' or idPropiedad == 'P2056' or idPropiedad == 'P2067' or idPropiedad == 'P2068' or idPropiedad == 'P2075' then
				for k,valor in pairs(Valores) do
					ValorConcatenado= {}
					Valor			= valor[1]
					table.insert(ValorConcatenado, Valor)
				end
				return table.concat(ValorConcatenado)
			end
		end
	end

	-- Si todo falla, retornar la función ModuloWikidata.propiedad()
	return ModuloWikidata.propiedad(Entidad, idPropiedad, {['linkback'] = 'no'})
end

-- Función para formatear un valor, en base al tipo
-- @param objeto El objeto datavalue
function formatearValor(objeto)
	if elementoTabla(objeto, 'type') == 'quantity' then
		Valor	= elementoTabla(objeto, 'value', 'amount'):gsub('+','')
		Unidad	= elementoTabla(objeto, 'value', 'unit')
		if Unidad then
			-- Los grados se formatean como Kelvin (°C)
			local UnidadID = Unidad:sub('32')
			if UnidadID then
				if UnidadID == 'Q11579' then
					return formatoNumero(Valor) .. ' [[Kelvin]] (' .. formatoNumero(math.ceil(Valor - 273.15)) .. '[[Grado celsius|°C]])'
				elseif UnidadID == 'Q25267' then
					return formatoNumero(math.ceil(Valor + 273.15)) .. ' [[Kelvin]] (' .. formatoNumero(Valor) .. '[[Grado celsius|°C]])'
				elseif not getUnit(Unidad) == '' then
					return formatoNumero(Valor) .. '&nbsp;' .. getUnit(Unidad)
				elseif UnidadID == 'Q42289' then -- No devolver valores en Farenheight
					return false
				else
					return formatoNumero(Valor)
				end
			end
		end
	elseif elementoTabla(objeto, 'type') == 'wikibase-entityid' then
		return elementoTabla(objeto, 'value', 'id')
	else
	return elementoTabla(objeto, 'value')
	end
end

-- Función para agregar puntos y comas a un número
function formatoNumero(n)
	local left,num,right = string.match(tostring(n):gsub('%.', ','),'^([^%d]*%d)(%d*)(.-)$')
	return left..(num:reverse():gsub('(%d%d%d)','%1.'):reverse())..right
end

return p