Для документации этого модуля может быть создана страница Модуль:Infobox gene/doc

local p = { }

-- local navbar = require('Module:Navbar')._navbar
--local infobox = require('Module:Infobox3cols').infobox
--local infoboxImage = require('Module:InfoboxImage').InfoboxImage



--on a page {{#invoke:Sandbox/genewiki/alllua|getTemplateData|QID=Q14865053}}
--in debug window 
--frame = mw.getCurrentFrame()
--frame.args = {QID="Q14865053"} Q18031325
--print(p.getTemplateData(frame))
p.getTemplateData = function(frame)

	--make some guesses about whether the provided QID is a good one
	--could expand here if we had some kind of error handling framework
	--did we get it from the page
	local root_qid = mw.text.trim(frame.args['QID']  or "") --try to get it from the args
	local mm_qid = ""
	--pull all the entity objects that we will need
	local	entity = {} 
	local	entity_protein = {}
	local	entity_mouse = {}
	local	entity_mouse_protein = {}
	local	checkOrtholog = "" --flag used to see if mouse data avaliable
	
	local mouse_propertyID = "P684"
	local protein_propertyID = "P688" 

	--get root gene entity
	if root_qid == "" then
		entity = mw.wikibase.getEntityObject()
		if entity then root_qid = entity.id else root_qid = "" end
			
	else
		--assuming we think its good make one call to retrieve and store its wikidata representation
		entity = mw.wikibase.getEntity(root_qid)
	end
	
  	--need to figure out if it is protein or gene here
	local subclass = p.getValue(entity, "P279") or ""
	if string.find(subclass, 'protein') then --if protein switch entity to gene
		if entity.claims then
	 		claims = entity.claims["P702"] --encoded by
	 	end
		if claims then
			--go through each index and reassign entity
			entity = {}
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do --this would be problematic if multiple genes for the protein
					local itemID = "Q" .. claims[#entity + 1].mainsnak.datavalue.value["numeric-id"]
					entity[#entity + 1] = mw.wikibase.getEntity(itemID)
					root_qid = itemID
				end
				
			end --will return nothing if no claims are found
		end
		 entity = mw.wikibase.getEntity(root_qid) 	
	 end
	
	
	--get the other related entities
	if entity then
		local claims = ""
	 	--get protein entity object
	 	if entity.claims then
	 		claims = entity.claims[protein_propertyID]
	 	end
		if claims then
			--go through each index and then make entity_protein indexed
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do
					local protein_itemID = "Q" .. claims[#entity_protein + 1].mainsnak.datavalue.value["numeric-id"]
					entity_protein[#entity_protein + 1] = mw.wikibase.getEntity(protein_itemID)
				end
				
			end --will return nothing if no claims are found
		end
	
	 	--get mouse entity object
	 	if entity.claims then
			claims = entity.claims[mouse_propertyID]
		end
		if claims then
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				local mouse_itemID = "Q" .. claims[1].mainsnak.datavalue.value["numeric-id"]
				mm_qid = mouse_itemID 
				entity_mouse = mw.wikibase.getEntity(mouse_itemID)
				checkOrtholog = 1 
			end --will return nothing if no claims are found
		else
			checkOrtholog = 0
		end
	
	 	--get mouse protein entity object
	 	if entity_mouse and entity_mouse.claims then
			claims = entity_mouse.claims[protein_propertyID]
		end
	 	if claims then
	 		if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do
					local protein_itemID = "Q" .. claims[#entity_mouse_protein + 1].mainsnak.datavalue.value["numeric-id"]
					entity_mouse_protein[#entity_mouse_protein + 1] = mw.wikibase.getEntity(protein_itemID)
				end
			end --will return nothing if no claims are found
	 	end	
	
	end
	
	
	if entity then --only require the main gene entity
		--a list variables of all the data in the info box
		local name = p.getLabel(entity)
		local entrez_gene = p.getValue(entity, "P351")
		local entrez_gene_mm = p.getValue(entity_mouse, "P351", "n/a")
		local image = p.getImage(entity, "P18", " ", "250px") --need to set size
		local uniprotID_hs = p.getValueProtein(entity_protein, "P352", "n/a")
	    local uniprotID_mm = p.getValueProtein(entity_mouse_protein, "P352", "n/a")
	    local pdbIDs = p.getPDB(entity_protein) --makes a list with links to RCSB
	    local aliases = p.getAliases(entity)
	    local gene_symbol = p.getValue(entity, "P353")
	    local hgnc_id = p.getValue(entity, "P354")
	    local homologene_id = p.getValue(entity, "P593")
	    local omim_id = p.getValue(entity, "P492")
	    local mgi_id = p.getValue(entity_mouse, "P671")
	    local ChEMBL_id = p.getValue(entity_protein, "P592") 
	    local IUPHAR_id = p.getValue(entity_protein, "P595")
	    local ec_no = p.getValueProtein(entity_protein, "P591")
	    local mol_funct = p.getGO(entity_protein, "P680")
	    local cell_comp = p.getGO(entity_protein, "P681")
	    local bio_process = p.getGO(entity_protein, "P682")
	    local expression_images = p.getImage(entity,"P692","<br><br>","250px")
	    local ensembl = p.getValue(entity, "P594", "n/a")
	    local ensembl_mm = p.getValue(entity_mouse, "P594", "n/a")
	    local refseq_mRNA = p.getRefseq_mRNA(entity, "P639", "n/a")
	    local refseq_mRNA_mm = p.getRefseq_mRNA(entity_mouse, "P639", "n/a")
	    local refseq_prot = p.getRefseq_protein(entity_protein, "P637", "n/a")
	    local refseq_prot_mm = p.getRefseq_protein(entity_mouse_protein, "P637", "n/a")
		local gstart = p.getChromosomeLoc(entity, "P644", "hg")
		local gend = p.getChromosomeLoc(entity, "P645", "hg")
		local chr = p.trimChromosome(entity) 
		local db = p.getAliasFromGenomeAssembly(entity,"hg")
		local gstart_mm = p.getChromosomeLoc(entity_mouse, "P644", "mm")
		local gend_mm = p.getChromosomeLoc(entity_mouse, "P645", "mm") 
		local db_mm = p.getAliasFromGenomeAssembly(entity_mouse,"mm")
		local chr_mm = p.trimChromosome(entity_mouse)
		local disease, dis_ref = p.getDisease(entity, "P2293")
		local drug = p.getDrug(entity_protein, "P129")
		
		--define Global Color Scheme
		rowBGcolor = '#eee'
		titleBGcolor = '#ddd'
		sideTitleBGcolor = '#c3fdb8'

		p.createTable()
    	p.renderUpperTitle(name)
    	--p.renderCaption()
    	p.renderImage(image)
    	p.renderAvailableStructures(uniprotID_hs, uniprotID_mm, checkOrtholog, pdbIDs) --PDB info
		p.renderIdentifiers(aliases, hgnc_id, gene_symbol, homologene_id, omim_id, mgi_id, ChEMBL_id, IUPHAR_id, ec_no, entrez_gene)
		if (disease ~= "" and dis_ref ~= "") then --removes section from those items without disease info
			p.renderDiseases(disease, dis_ref)
		end
        
		if (drug ~= "" ) then --removes section from those items without drug info
			p.renderDrug(drug)
		end
		
		if (mol_funct ~= "" and cell_comp ~= "" and bio_process ~= "") then
			p.renderGeneOntology(mol_funct, cell_comp, bio_process, uniprotID_hs)
		end
		if expression_images ~= ""  then
			p.renderRNAexpression(expression_images, entrez_gene)
		end
		p.renderOrthologs(entrez_gene, entrez_gene_mm, ensembl, ensembl_mm, uniprotID_hs, uniprotID_mm, refseq_mRNA, refseq_mRNA_mm, refseq_prot, refseq_prot_mm, db, chr, gstart, gend, db_mm, chr_mm, gstart_mm, gend_mm)
		p.renderFooter(root_qid, mm_qid)        
   		
		return tostring(root)


	else return "An Error has occurred retrieving Wikidata item for infobox"
	end	
end

p.createTable = function(subbox)

    if subbox == 'sub' then --doesn't work 
    	 root
        	:tag('table') 
            :css('padding', '0')
            :css('border', 'none')
            :css('margin', '0')
            :css('width', 'auto')
            :css('min-width', '100%')
            :css('font-size', '100%')
            :css('clear', 'none')
            :css('float', 'none')
            :css('background-color', 'transparent')
           
    else
    	root = mw.html.create('table')
    	root
    		:addClass('infobox')
        	:css('width', '26.4em')
        	 :newline()
    end

end

--Title above image
p.renderUpperTitle = function(name)
	local title = name
    if not title then return "error: failed to get label"; end
    
    root
        :tag('tr')
            :tag('th')
                :attr('colspan', 4)
                :css('text-align', 'center')
                :css('font-size', '125%')
                :css('font-weight', 'bold')
                :wikitext(title)
                :newline()
end

--This is a place holder for the image caption, which is stored in wikicommons comments unsure how to access 
p.renderCaption = function(entity)
	--caption
end

--gets default image
p.renderImage = function(image)

	root
			:tag('tr')
        	:tag('td')
   				:attr('colspan', 4)
            	:css('text-align', 'center')
            	:wikitext(image)
         		:done()
         		 :newline()
end



p.renderAvailableStructures = function(uniprotID_hs, uniprotID_mm, checkOrtholog, pdbIDs)

    local title = 'Доступные структуры'
    local pdb_link = "[[Protein_Data_Bank|PDB]]"
    local searchTitle = "" 
    local listTitle = "Список идентификаторов PDB"
    local PDBe_base = 'http://www.ebi.ac.uk/pdbe/searchResults.html?display=both&amp;term='
    local RCSB_base = 'http://www.rcsb.org/pdb/search/smartSubquery.do?smartSearchSubtype=UpAccessionIdQuery&amp;accessionIdList='
    local url_uniprot = " " 
    
    
    if checkOrtholog == 1 and uniprotID_mm ~= 'n/a' then
    	searchTitle = 'Поиск ортологов: '
    	url_uniprot = uniprotID_mm
    else
    	searchTitle = 'Human UniProt search: '
    	url_uniprot = uniprotID_hs
    end
    local PDBe_list = " " --create a list with " or " if there is more than one uniprot
    --get first uniprot in a list
	if url_uniprot:match("([^,]+),") then--first check if there is a list if not just assume one value
		PDBe_list = string.gsub(url_uniprot, ",", "%%20or%%20") --add or's inststead of commas
	else
		PDBe_list = url_uniprot
	end
    
    local PDBe = "["..PDBe_base..PDBe_list.." PDBe] "
    local RCSB = "["..RCSB_base..url_uniprot.." RCSB] "
    
    if string.match(pdbIDs, '%w+') then --if there aren't any PDB_ID don't display this part of the infobox
    	--p.formatRow(title)---how to not close the tags is a mystery and I could condense code once I figure out
    	root
	 		:tag('tr')
        	:tag('td')
   				:attr('colspan', 4)
            	:css('text-align', 'center')
            	:css('background-color', rowBGcolor)
            	:newline()
            	--p.createTable('sub')
            	:tag('table') 
            		:css('padding', '0')
            		:css('border', 'none')
            		:css('margin', '0')
            		:css('width', '100%')
            		:css('text-align', 'left')
            		:newline()

            		:tag('tr')    --create title header
            			:tag('th')
            			:attr('colspan', '2')
            			:css('text-align', 'center')
            			:css('background-color',titleBGcolor)
            			:wikitext(title)
            			:done()
            			:newline()
            		
    			--p.rowLabel(pdb_link) 
    			:tag('tr')
        		:tag('th')
        			:attr('rowspan', '2')
        			:css('background-color', sideTitleBGcolor)
        			:css('width', '43px')
         			:wikitext(pdb_link)
        			:done()
        			
            			:tag('td')
            				:css('background-color', rowBGcolor)
            				:wikitext(searchTitle)
            				:tag('span')
            					:attr('class', 'plainlinks')
            					:wikitext(PDBe)
            					:wikitext(RCSB)
            					:done()
            				:done()
            		:done() --this may not be needed
            		:newline()
            		--new row for collapsible list of PDB codes
            		:tag('tr')
            			:tag('td')
            			:tag('table')
            			:attr('class', 'collapsible collapsed')
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'left')
            			:newline()
            			:tag('tr')
            				:css('background-color',titleBGcolor)
            				:css('text-align', 'center')
            				:newline()
            				:tag('th')
            					:wikitext(listTitle)
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:css('background-color', rowBGcolor)
            			:newline()
            			:tag('p')
            				:tag('span')
            					:attr('class', 'plainlinks')
            					:wikitext(pdbIDs)
            					:done()
            				 :newline()
    else
    	return ""
	end

end

p.renderIdentifiers = function(aliases, hgnc_id, gene_symbol, homologene_id, omim_id, mgi_id, ChEMBL_id, IUPHAR_id, ec_no, entrez_gene)
	local title = "Идентификаторы"
	local label_aliases = "[[Международная организация по изучению генома человека|Символы]]"
	local symbol_url 
	if gene_symbol == "" or gene_symbol == nil  then
		symbol_url = ""
	else
		if hgnc_id == "" or hgnc_id == nil  then
			symbol_url = gene_symbol
			
		else
			symbol_url = "[http://www.genenames.org/cgi-bin/gene_symbol_report?hgnc_id="..hgnc_id.." "..gene_symbol.."]"
		end
	end

	aliases = string.gsub(aliases, ', '..gene_symbol..'$', '') --get rid of gene name if last in alias list
	aliases = string.gsub(aliases, gene_symbol..', ', '') --get rid of gene name if first in aliases list
	aliases = string.gsub(aliases, ', '..gene_symbol..',', ',') --get rid of gene name if in aliases list
	aliases = string.gsub(aliases, ", ,", ",") --remove comma from middle
	aliases = string.gsub(aliases, ", $", "") --remove comma from end
	local label_ext_id = "Внешние IDs"
	
	omim_id = string.gsub(omim_id, "%s", "")
	local omim_list = mw.text.split(omim_id, ",")
	local omim = ""
	if (omim_id ~= nil and omim_id ~= "") then
		omim = "[[Mendelian_Inheritance_in_Man|OMIM:]]".." "
	end
	for i, v in ipairs(omim_list) do
		if string.match(v, '%w+') then
			omim = omim.."[https://omim.org/entry/"..v.." "..v.."], "
		end
	end
	omim = string.gsub(omim, ", $"," ")	--remove comma from end
	
	homologene_id = string.gsub(homologene_id, "%s", "")
	local homolo_list = mw.text.split(homologene_id, ",")
	local homolo =""
	if (homologene_id ~= nil and homologene_id ~= "") then
		homolo = "[[HomoloGene|HomoloGene:]]".." "
	end
	for i, v in ipairs(homolo_list) do
		if string.match(v, '%w+') then
			homolo = homolo.."[http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=homologene&dopt=HomoloGene&list_uids="..v.." "..v.."] "
		end
	end
	homolo = string.gsub(homolo, ", $"," ")	--remove comma from end

	entrez_gene = string.gsub(entrez_gene, "%s", "")
	local entrez_list = mw.text.split(entrez_gene, ",")
	local genecards = "" 
	if (entrez_list ~= nil and entrez_list ~= "") then
		genecards = "[[GeneCards|GeneCards:]]".." "
	end
	for i, v in ipairs(entrez_list) do
		if string.match(v, '%w+') then
			genecards = genecards.."[http://www.genecards.org/cgi-bin/carddisp.pl?id_type=entrezgene&id="..v.." "..v.."] "
		end
	end
	genecards = string.gsub(genecards, ", $"," ")	--remove comma from end

	
	mgi_id = string.gsub(mgi_id, "%s", "")
	local mgi_list = mw.text.split(mgi_id, ",")
	local mgi = "" 
	if (mgi_id ~= nil and mgi_id ~= "") then
		mgi = "[[Mouse_Genome_Informatics|MGI:]]".." "
	end
	for i, v in ipairs(mgi_list) do
		if string.match(v, '%w+') then
			local mgi_number = string.sub(mgi_id, 5)
			mgi = mgi.."[http://www.informatics.jax.org/marker/"..mgi_id.." "..mgi_number.."] "
		end
	end
	mgi = string.gsub(mgi, ", $"," ")--remove comma from end

	local ChEMBL = ""
	if string.match(ChEMBL_id, '%w+') then
		ChEMBL = "[[ChEMBL|ChEMBL:]]".." ".."[https://www.ebi.ac.uk/chembldb/index.php/target/inspect/CHEMBL"..ChEMBL_id.." "..ChEMBL_id.."] "
	end
	local IUPHAR = ""
	if string.match(IUPHAR_id, '%w+') then 
		IUPHAR = "[[International_Union_of_Basic_and_Clinical_Pharmacology|IUPHAR:]]".." ".."[http://www.guidetopharmacology.org/GRAC/ObjectDisplayForward?objectId="..IUPHAR_id.." "..IUPHAR_id.."] "
	end
	local label_EC = "[[Enzyme_Commission_number|EC number]]"
	ec_no = string.gsub(ec_no, "%d%.%d+%.%d+%.%-,", "")--remove those with"-" in list
	ec_no = string.gsub(ec_no, "%d%.%d+%.%d+%.%-", "")--remove those with"-" not in list
	local link_ec_no = string.gsub(ec_no, "," ,"+") --create format for link

	local EC = "[http://www.genome.jp/dbget-bin/www_bget?enzyme+" .. link_ec_no .. " " .. ec_no .. "]"
	
	root
		:tag('tr')
        	:tag('th')
        		:attr('colspan', '4')
        		:css('text-align', 'center')
        		:css('background-color', titleBGcolor)
         		:wikitext(title)
        		:newline()

        	:tag('tr')
        		:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:tag('span')
            		:attr('class', 'plainlinks')
        			:wikitext(label_aliases)
        			:done()
        			:newline()
        		:tag('td')
        			:attr('colspan','3')
        			:css('background', rowBGcolor)
        			:tag('span')
            		 	:attr('class', 'plainlinks')
        			 	:wikitext(symbol_url)
        				:done()
        			:wikitext(aliases)
        		:done()
         :newline()
         
         :tag('tr')
         	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
         		:wikitext(label_ext_id)
        		:done()
        		:newline()
        	:tag('td')
        		:attr('colspan', '3')
        		:css('background-color', rowBGcolor)
        		:tag('span')
            		:attr('class', 'plainlinks')
        			:wikitext(omim)
        			:wikitext(mgi)
        			:wikitext(homolo)
        			:wikitext(ChEMBL)
        			:wikitext(IUPHAR)
        			:wikitext(genecards)
        			:done()
        		 	:newline()
        		 :done()
	if ec_no ~= ""  then
	  root
         :tag('tr')
         	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
         		:wikitext(label_EC)
        		:done()
        		:newline()
        	:tag('td')
        		:attr('colspan', '3')
        		:css('background-color', rowBGcolor)
        		:tag('span')
            		:attr('class', 'plainlinks')
        			:wikitext(EC)
        			:done()
        		 	:newline()
        		 :done()
    end
end

p.renderDiseases = function(disease, dis_ref) 
	local title = "Связанные наследственные заболевания"
	local disease_title = "Название болезнии"
	local source_title = "'''Ссылки'''"

	
	--check first to see if any of the diseases have references
	local ref_flag = {} --check each disease for a reference
	local ref_flag_all = "" --check if any disease have references if not then don't render the headers
	for index,value in ipairs(disease) do
		if (dis_ref[index] ~= nil and dis_ref[index] ~= '') then	
			ref_flag[index] = "true"
			ref_flag_all = "true"
		end		
	end
    if ref_flag_all == "true" then
    	root
		:tag('tr')
			:tag('td')
   				:attr('colspan', 4)
            	:css('text-align', 'center')
            	:css('background-color', rowBGcolor)
            	:newline()
		
		:tag('tr') --create title bar
			:tag('th')
			:attr('colspan', '3')
			:css('text-align', 'center')
			:css('background-color', titleBGcolor)
			:wikitext(title)
			:done()
			:newline()
		:tag('tr')
			:tag('th')
				:css('background-color', sideTitleBGcolor)
				:attr('colspan', '2')
				:wikitext(disease_title)
				:done()
				:newline()
			:tag('td')
				:css('background-color', sideTitleBGcolor)
				:attr('colspan', '2')
				:wikitext(source_title)
				:done()
				:newline()
				:done()
	end
			for index,value in ipairs(disease) do 
				local i = 0
				local ref_collapse = ""
				local ref_default = ""
				local ref_link = ""
				local ref_link_list = ""
				if ref_flag[index] == "true" then 
					if (dis_ref[index] ~= nil or dis_ref[index] ~= '') then
						ref_link_list =	mw.text.split(dis_ref[index], ",")
					end
					

					--if less than 4 don't create collapsible list
					if  table.getn(ref_link_list) < 5 then
						ref_collapse = "none"
					else	
						ref_collapse = "collapsible collapsed"
						for i =1, 5 do --get at most 4 elements to display
		     				ref_default = ref_default..table.remove(ref_link_list, 1) .. ' '
						end
						local br_count = 0
						for i =1, table.getn(ref_link_list) do --get at most 4 elements to display
		     				ref_link = ref_link..table.remove(ref_link_list, 1) .. ' '
		     
		     				if br_count < 5 then
		     					br_count = br_count + 1
		     				else
		     					br_count = 0
		     					ref_link = ref_link ..'<br>'
		     				end
						end
					end
	
					if ref_link_list[#ref_link_list] then
						ref_link = table.concat(ref_link_list, " ")
					end
			  	root
			    	:tag('tr')
   					:attr('colspan', 4)
            		:css('text-align', 'center')
            		:css('background-color', rowBGcolor)
            		:newline()
            	
					:tag('th')
							:css('background-color', rowBGcolor)
								:attr('scope', 'row')
								:attr('colspan', '2')
								:wikitext(value)
								:done()
								:newline()
					:tag('td')
						:tag('span')
						:attr('colspan', '2')
					
        				:tag('table')
            				:attr('class', ref_collapse)
            				:css('padding', '0')
            				:css('border', 'none')
            				:css('margin', '0')
            				:css('width', '100%')
            				:css('text-align', 'right')
            				:tag('tr')
            					:newline()
            					:tag('th')
            						:attr('colspan', '1')
            						:tag('span')
            							:attr('class', 'plainlinks')
            							:wikitext(ref_default)
            						:done()
            					:done()
            					:newline()
            				:done()
            				:tag('tr')
            				:tag('td')
            					:attr('colspan', '1')
            				:newline()
            				:tag('p')
            					:attr('class', 'plainlinks')
            					:wikitext(ref_link)
            				 	:newline()
            					:done()
            				:done()
            			:done()
            		:done()
        			:newline()
    			end	
    	end
    
end

--p.renderDrug = function(drug, drug_ref) 
p.renderDrug = function(drug) 
	local title = "Targeted by Drug"
    local drug_title = "Drug Name"
	local source_title = "'''References'''"

	
	--check first to see if any of the drugs have references
	--local ref_flag = {} --check each drug for a reference
	local ref_flag_all = "" --check if any drugs have references if not then don't render the headers

	for k,v in pairs(drug) do
		ref_flag_all = "true"
	end
    if ref_flag_all == "true" then
    	root
		:tag('tr')
			:tag('td')
   				:attr('colspan', 4)
            	:css('text-align', 'center')
            	:css('background-color', rowBGcolor)
            	:newline()
		
		:tag('tr') --create title bar
			:tag('th')
			:attr('colspan', '3')
			:css('text-align', 'center')
			:css('background-color', titleBGcolor)
			:wikitext(title)
			:done()
			:newline()
		:tag('tr')
			:tag('th')
				:css('background-color', sideTitleBGcolor)
				:attr('colspan', '2')
				:wikitext(drug_title)
				:done()
				:newline()
			:tag('td')
				:css('background-color', sideTitleBGcolor)
				:attr('colspan', '2')
				:wikitext(source_title)
				:done()
				:newline()
				:done()
	end
			for key,value in pairs(drug) do 
				local i = 0
				local ref_collapse = ""
				local ref_default = ""
				local ref_link = ""
				local ref_link_list = {}

				local ref_split =	mw.text.split(value, ",")
				local hash = {} --storage to look for duplicated values in case
				for k,v in ipairs(ref_split) do 
					if not hash[v] then --only add if not found previously
						ref_link_list[#ref_link_list+1] = v
						hash[v] = true
					end
				end
					
					

					--if less than 4 don't create collapsible list
					if  table.getn(ref_link_list) < 5 then
						ref_collapse = "none"
					else	
						ref_collapse = "collapsible collapsed"
						for i =1, 5 do --get at most 4 elements to display
		     				ref_default = ref_default..table.remove(ref_link_list, 1) .. ' '
						end
						local br_count = 0
						for i =1, table.getn(ref_link_list) do --get at most 4 elements to display
		     				ref_link = ref_link..table.remove(ref_link_list, 1) .. ' '
		     
		     				if br_count < 5 then
		     					br_count = br_count + 1
		     				else
		     					br_count = 0
		     					ref_link = ref_link ..'<br>'
		     				end
						end
					end
	
					if ref_link_list[#ref_link_list] then
						ref_link = table.concat(ref_link_list, " ")
					end
			  	root
			    	:tag('tr')
   					:attr('colspan', 4)
            		:css('text-align', 'center')
            		:css('background-color', rowBGcolor)
            		:newline()
            	
					:tag('th')
							:css('background-color', rowBGcolor)
								:attr('scope', 'row')
								:attr('colspan', '2')
								--:wikitext(value)
								:wikitext(key)
								:done()
								:newline()
					:tag('td')
						:tag('span')
						:attr('colspan', '2')
					
        				:tag('table')
            				:attr('class', ref_collapse)
            				:css('padding', '0')
            				:css('border', 'none')
            				:css('margin', '0')
            				:css('width', '100%')
            				:css('text-align', 'right')
            				:tag('tr')
            					:newline()
            					:tag('th')
            						:attr('colspan', '1')
            						:tag('span')
            							:attr('class', 'plainlinks')
            							:wikitext(ref_default)
            						:done()
            					:done()
            					:newline()
            				:done()
            				:tag('tr')
            				:tag('td')
            					:attr('colspan', '1')
            				:newline()
            				:tag('p')
            					:attr('class', 'plainlinks')
            					:wikitext(ref_link)
            				 	:newline()
            					:done()
            				:done()
            			:done()
            		:done()
        			:newline()
    	end
    
end

p.renderGeneOntology = function(mol_funct, cell_comp, bio_process, uniprotID)
	local title = "[[Генная онтология|Генная онтология]]"
	local mol_funct_title = "Функции"
	local cell_comp_title = "Компонент клетки"
	local bio_process_title = "Биологический процесс"
	local amigo_link = "[http://amigo.geneontology.org/" .. " Amigo]"
	local quickGO_link = "[http://www.ebi.ac.uk/QuickGO/" .. " QuickGO]"


	root
		:tag('tr')
        	:tag('td')
   				:attr('colspan', 4)
            	:css('text-align', 'center')
            	:css('background-color', rowBGcolor)
            	:newline()
            	--p.createTable('sub')
            	:tag('table')
            		:attr('class', 'collapsible collapsed')
            		:css('padding', '0')
            		:css('border', 'none')
            		:css('margin', '0')
            		:css('width', '100%')
            		:css('text-align', 'left')
            		:newline()
            		            		
            		:tag('tr') --create title bar
        				:tag('th')
        				:attr('colspan', '2')
        				:css('text-align', 'center')
        				:css('background-color', titleBGcolor)
         				:wikitext(title)
        				:done()
        				:newline()
            :tag('tr')
            	:tag('th')
            		:css('background-color', sideTitleBGcolor)
            		:wikitext(mol_funct_title)
            		:done()
            	:tag('td')
            		:css('background-color', rowBGcolor)
            		:newline()
            		:tag('span')
            			:attr('class', 'plainlinks')
            			:wikitext(mol_funct)
            		:done()
            		:newline()
            	:done()
            :tag('tr')
            	:tag('th')
            		:css('background-color', sideTitleBGcolor)
            		:wikitext(cell_comp_title)
            		:done()
            	:tag('td')
            		:css('background-color', rowBGcolor)
            		:newline()
            		:tag('span')
            			:attr('class', 'plainlinks')
            			:wikitext(cell_comp)
            		:done()
            		:newline()
            	:done()
              :tag('tr')
            	:tag('th')
            		:css('background-color', sideTitleBGcolor)
            		:wikitext(bio_process_title)
            		:done()
            	:tag('td')
            		:css('background-color', rowBGcolor)
            		:newline()
            		:tag('span')
            			:attr('class', 'plainlinks')
            			:wikitext(bio_process)
            		:done()
            		:newline()
            	:done()
            	:tag('tr')
            		:tag('td')
            			:css('background-color', rowBGcolor)
            			:css('text-align', 'center')
            			:attr('colspan', '2')
            			:wikitext("Источники:")
            			:wikitext(amigo_link)
            			:wikitext(" / ")
            			:wikitext(quickGO_link)
            		:done()
            :done()
					
end 

p.renderRNAexpression = function(expression_images, entrez_gene)
	local title = "Профиль экспрессии РНК"
	local biogps_link = "[http://biogps.org/gene/"..entrez_gene.."/ Больше информации]"
	root
		:tag('tr')
        	:tag('th')
        		:attr('colspan', '4')
        		:css('text-align', 'center')
        		:css('background-color', titleBGcolor)
         		:wikitext(title)
        		:done()
        		:newline()
        :tag('tr')
        	:tag('td')
        		:attr('colspan', '4')
        		:css('text-align', 'center')
        		:css('background-color', rowBGcolor)
        		:wikitext(expression_images)
        		:done()
        		:newline()
        :tag('tr')
        	:tag('td')
        		:attr('colspan', '4')
        		:css('text-align', 'center')
        		:css('background-color', rowBGcolor)
        		:tag('span')
            		:attr('class', 'plainlinks')
        			:wikitext(biogps_link)
        		:done()
        		:newline()
end

p.renderOrthologs = function(entrez_gene, entrez_gene_mm, ensembl, ensembl_mm, uniprot, uniprot_mm, refseq_mRNA, refseq_mRNA_mm, refseq_prot, refseq_prot_mm, db, chr, gstart, gend,  db_mm, chr_mm,gstart_mm, gend_mm) 
	local title = "Ортологи"
	--to do make the list creation a function
	--create list for entrez ids
	local category_chromosome = ''
	if chr == "X" or chr == "Y" then
		category_chromosome = '[[Категория:Гены '..chr..'-хромосомы]]'
	else
		category_chromosome = '[[Категория:Гены '..chr..'-й хромосомы]]'
	end
	local entrezTitle = "[[Entrez|Entrez]]"
	entrez_gene = string.gsub(entrez_gene, "%s", "")
	local entrez_link = "n/a"
	local entrez_collapse 
	local entrez_default = ""
	local split_entrez = mw.text.split(entrez_gene, ",")
	local entrez_link_list = {}
	for k,v in ipairs(split_entrez) do 
		if string.match(v, '%w+') and v ~= "n/a" then
			entrez_link_list[#entrez_link_list+1] = "[http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&amp;cmd=retrieve&amp;dopt=default&amp;list_uids="..entrez_gene.."&amp;rn=1 "..entrez_gene.."]"
		end
	end
	--if less than 5 don't create collapsible list
	if  table.getn(entrez_link_list) < 5 then
		entrez_collapse = "none"
		if entrez_default == nil and table.getn(entrez_link_list) == 0 then entrez_link = "n/a" end
	else	
		entrez_collapse = "collapsible collapsed"
		entrez_default = table.remove(entrez_link_list, 1) .. '<br>' .. table.remove(entrez_link_list, 1) .. '<br>' ..table.remove(entrez_link_list, 1) .. '<br>' .. table.remove(entrez_link_list, 1) .. '<br>' .. table.remove(entrez_link_list, 1) .. '<br>'--get first 5 elements in table and use for display
	end
	if entrez_link_list[#entrez_link_list] then
		entrez_link = table.concat(entrez_link_list, "<br>")
	end
	
	--create list for mouse Entrez id
	entrez_gene_mm = string.gsub(entrez_gene_mm, "%s", "")
	local entrez_mm_link = "n/a"
	local entrez_mm_collapse 
	local entrez_mm_default = ""
	local split_entrez_mm = mw.text.split(entrez_gene_mm, ",")
	local entrez_mm_link_list = {}
	for k,v in ipairs(split_entrez_mm) do 
		if string.match(v, '%w+') and v ~= "n/a" then
			entrez_mm_link_list[#entrez_mm_link_list+1] = "[http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&amp;cmd=retrieve&amp;dopt=default&amp;list_uids="..v.."&amp;rn=1 "..v.."]"
		end
	end
	--if less than 5 don't create collapsible list
	if  table.getn(entrez_mm_link_list) < 5 then
		entrez_mm_collapse = "none"
		if entrez_mm_default == nil and table.getn(entrez_mm_link_list) == 0 then entrez_mm_link = "n/a" end
	else	
		entrez_mm_collapse = "collapsible collapsed"
		entrez_mm_default = table.remove(entrez_mm_link_list, 1) .. '<br>' .. table.remove(entrez_mm_link_list, 1) .. '<br>' ..table.remove(entrez_mm_link_list, 1) .. '<br>' .. table.remove(entrez_mm_link_list, 1) .. '<br>' .. table.remove(entrez_mm_link_list, 1) .. '<br>'--get first 5 elements in table and use for display
	end
	if entrez_mm_link_list[#entrez_mm_link_list] then
		entrez_mm_link = table.concat(entrez_mm_link_list, "<br>")
	end
	
	--create list of ensembl id
	local ensemblTitle = "[[Ensembl|Ensembl]]"
	ensembl = string.gsub(ensembl, "%s", "")
	local ensembl_link = "n/a"
	local ensembl_collapse 
	local ensembl_default = ""
	local split_ensembl = mw.text.split(ensembl, ",")
	local ensembl_link_list = {}
	for k,v in ipairs(split_ensembl) do 
		if string.match(v, '%w+') and v ~= "n/a" then
			ensembl_link_list[#ensembl_link_list+1] = "[http://www.ensembl.org/Homo_sapiens/geneview?gene="..v..";db=core".." "..v.."]"
		end
	end
	--if less than 5 don't create collapsible list
	if  table.getn(ensembl_link_list) < 5 then
		ensembl_collapse = "none"
		if ensembl_default == nil and table.getn(ensembl_link_list) == 0 then ensembl_link = "n/a" end
	else	
		ensembl_collapse = "collapsible collapsed"
		ensembl_default = table.remove(ensembl_link_list, 1) .. '<br>' .. table.remove(ensembl_link_list, 1) .. '<br>' ..table.remove(ensembl_link_list, 1) .. '<br>' .. table.remove(ensembl_link_list, 1) .. '<br>' .. table.remove(ensembl_link_list, 1) .. '<br>'--get first 5 elements in table and use for display
	end
	if ensembl_link_list[#ensembl_link_list] then
		ensembl_link = table.concat(ensembl_link_list, "<br>")
	end
	
	--create list of mouse ensembl id
	local ensemblTitle = "[[Ensembl|Ensembl]]"
	ensembl_mm = string.gsub(ensembl_mm, "%s", "")
	local ensembl_mm_link = "n/a"
	local ensembl_mm_collapse 
	local ensembl_mm_default = ""
	local split_ensembl_mm = mw.text.split(ensembl_mm, ",")
	local ensembl_mm_link_list = {}
	for k,v in ipairs(split_ensembl_mm) do 
		if string.match(v, '%w+') and v ~= "n/a" then
			ensembl_mm_link_list[#ensembl_mm_link_list+1] = "[http://www.ensembl.org/Homo_sapiens/geneview?gene="..v..";db=core".." "..v.."]"
		end
	end
	--if less than 5 don't create collapsible list
	if  table.getn(ensembl_mm_link_list) < 5 then
		ensembl_mm_collapse = "none"
		if ensembl_mm_default == nil and table.getn(ensembl_mm_link_list) == 0 then ensembl_mm_link = "n/a" end
	else	
		ensembl_mm_collapse = "collapsible collapsed"
		ensembl_mm_default = table.remove(ensembl_mm_link_list, 1) .. '<br>' .. table.remove(ensembl_mm_link_list, 1) .. '<br>' ..table.remove(ensembl_mm_link_list, 1) .. '<br>' .. table.remove(ensembl_mm_link_list, 1) .. '<br>' .. table.remove(ensembl_mm_link_list, 1) .. '<br>'--get first 5 elements in table and use for display
	end
	if ensembl_mm_link_list[#ensembl_mm_link_list] then
		ensembl_mm_link = table.concat(ensembl_mm_link_list, "<br>")
	end


	--create lists of uniprot ID
	local uniprotTitle = "[[UniProt|UniProt]]"
	local uniprot_url = "http://www.uniprot.org/uniprot/"
	
	local uniprot_link = "n/a"
	local uniprot_collapse
	local uniprot_default = ""
	--split string and loop through concatenate by <br>
	local split_uniprot = mw.text.split(uniprot, ",")
	local uniprot_link_list = {}
	local uniprot_first = {} --preferred values only display [O,P,Q] prefixed entries if they exist
	local uniprot_alternate = {} --[A-N,R-Z] entries
	local hash = {} --storage to look for duplicated values 
	for k,v in ipairs(split_uniprot) do 
		if not hash[v] then --only add if not found previously..some encodes uniprotID dup in different encodes
			local label = mw.text.trim(v)
			local concat_uniprot_link = uniprot_url .. label
			if string.match(v, '%w+') and v ~= "n/a" then
				if string.match(v, '^O') or string.match(v,'^P') or string.match(v, '^Q') then
				    uniprot_first[#uniprot_first+1] = "[" .. concat_uniprot_link .. " " ..label .. "]"
				else
					uniprot_alternate[#uniprot_alternate+1] = "[" .. concat_uniprot_link .. " " ..label .. "]"
				end
			end
			hash[v] = true
		end
	end
    if table.getn(uniprot_first)>0 then --if there is something in the preferred values display else display anything else
		uniprot_link_list  = uniprot_first
	else
		uniprot_link_list  = uniprot_alternate
	end
	
	--if less than 5 don't create collapsible list
	if  table.getn(uniprot_link_list) < 5 then
		uniprot_collapse = "none"
		if uniprot_default == nil and table.getn(uniprot_link_list) == 0 then uniprot_link = "n/a" end
	else	
		uniprot_collapse = "collapsible collapsed"
		uniprot_default = table.remove(uniprot_link_list, 1) .. '<br>' .. table.remove(uniprot_link_list, 1) .. '<br>' ..table.remove(uniprot_link_list, 1) .. '<br>' .. table.remove(uniprot_link_list, 1) .. '<br>' .. table.remove(uniprot_link_list, 1) .. '<br>'--get first 5 elements in table and use for display
	end
	
	if uniprot_link_list[#uniprot_link_list] then
		uniprot_link = table.concat(uniprot_link_list, "<br>")
	end
	
    --mouse uniprot lists
	local uniprot_mm_link = "n/a"
	local uniprot_mm_collapse
	local uniprot_mm_default = ""
	--split string and loop through concatenate by <br>
	local split_uniprot_mm = mw.text.split(uniprot_mm, ",")
    local uniprot_mm_link_list = {}	
    local uniprot_mm_first = {} --preferred values only display [O,P,Q] prefixed entries if they exist
    local uniprot_mm_alternate = {} --[A-N,R-Z] entries
    local hash = {} --storage to look for duplicated values
	for k,v in ipairs(split_uniprot_mm) do 
	    if not hash[v] then --only add if not found previously..some encodes uniprotID dup in different encodes
		    local label = mw.text.trim(v)
		    local concat_uniprot_link = uniprot_url .. label
		    if string.match(v, '%w+') and v ~= "n/a" then
			    if string.match(v, '^O') or string.match(v,'^P') or string.match(v, '^Q') then 
					uniprot_mm_first[#uniprot_mm_first+1] = "[" .. concat_uniprot_link .. " " ..label .. "]"
				else
					uniprot_mm_alternate[#uniprot_mm_alternate+1] = "[" .. concat_uniprot_link .. " " ..label .. "]"
				end
		    end
			hash[v] = true
		end
	end
	if table.getn(uniprot_mm_first)>0 then --if there is something in the preferred values display else display anything else
		uniprot_mm_link_list  = uniprot_mm_first
	else
		uniprot_mm_link_list  = uniprot_mm_alternate
	end

	--if less than 5 don't create collapsible list
	if  table.getn(uniprot_mm_link_list) < 5 then
		uniprot__mm_collapse = "none"
		if uniprot_mm_default == nil and table.getn(uniprot_mm_link_list) == 0 then uniprot_mm_link = "n/a" end
	else	
		uniprot_mm_collapse = "collapsible collapsed"
		uniprot_mm_default = table.remove(uniprot_mm_link_list, 1) .. '<br>' .. table.remove(uniprot_mm_link_list, 1) .. '<br>' ..table.remove(uniprot_mm_link_list, 1) .. '<br>' .. table.remove(uniprot_mm_link_list, 1) .. '<br>' .. table.remove(uniprot_mm_link_list, 1) .. '<br>'--get first 5 elements in table and use for display
	end
	
	if uniprot_mm_link_list[#uniprot_mm_link_list] then
		uniprot_mm_link = table.concat(uniprot_mm_link_list, "<br>")
	end
	
	
	
	local ncbi_link = "http://www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?val="
	local refseq_mRNATitle = "RefSeq (мРНК)"
	
	--create list of links for refSeq mRNA
	local refseq_mRNA_link = "n/a"
	local refseq_mRNA_collapse
	local refseq_mRNA_default = ""
	--split string and loop through concatenate by <br>
	local split_refseq_mRNA = mw.text.split(refseq_mRNA, ",")
	local link_list_first = {} --hold those the have NM or NP values
	local link_list_alternate = {} --hold those that are XM or XP values
	local link_list = {} --if NM,NP display if not display XM, XP values 
	for k,v in ipairs(split_refseq_mRNA) do
		local label = mw.text.trim(v)
		local concat_ncbi_link = ncbi_link .. label
		if string.match(v, '%w+') and v ~= "n/a" then
			if string.match(v, 'NM') or string.match(v, 'NP') then
			    link_list_first[#link_list_first+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
			elseif string.match(v, 'XM') or string.match(v, 'XP') then
				link_list_alternate[#link_list_alternate+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
			end
		end
   end
   	if table.getn(link_list_first)>0 then
		link_list = link_list_first
	else
		link_list = link_list_alternate
	end
	
	--if less than 5 don't create collapsible list
	if  table.getn(link_list) < 6 then
		refseq_mRNA_collapse = "none"
		if refseq_mRNA_default == nil and table.getn(link_list) == 0 then refseq_mRNA_link = "n/a" end
	else	
		refseq_mRNA_collapse = "collapsible collapsed"
		refseq_mRNA_default  = table.remove(link_list, 1) .. '<br>' .. table.remove(link_list, 1) .. '<br>' ..table.remove(link_list, 1) .. '<br>' .. table.remove(link_list, 1) .. '<br>' .. table.remove(link_list, 1) .. '<br>'--get first 5 elements in table and use for display
	end
	
	if link_list[#link_list] then
		refseq_mRNA_link = table.concat(link_list, "<br>")
	end
	
	
	--create list of links for refSeq mRNA for mouse
	local refseq_mRNA_mm_link = "n/a"
	local refseq_mRNA_mm_collapse
	local refseq_mRNA_mm_default = ""
	local split_refseq_mRNA_mm = mw.text.split(refseq_mRNA_mm, ",")
	local link_list_mm = {} --if NM,NP display if not display XM, XP values
	local link_list_first = {} --hold those the have NM or NP values
	local link_list_alternate = {} --hold those that are XM or XP values
  
	for k,v in ipairs(split_refseq_mRNA_mm) do
		local label = mw.text.trim(v)
		local concat_ncbi_link = ncbi_link .. label
		if string.match(v, '%w+') and v ~= "n/a" then
			if string.match(v, 'NM') or string.match(v, 'NP') then
			    link_list_first[#link_list_first+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
			elseif string.match(v, 'XM') or string.match(v, 'XP') then
				link_list_alternate[#link_list_alternate+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
			end
		end
    end
	if table.getn(link_list_first)>0 then
		link_list_mm = link_list_first
	else
		link_list_mm = link_list_alternate
	end
	--if less than 5 don't create collapsible list
	if  table.getn(link_list_mm) < 6 then
		refseq_mRNA_mm_collapse = "none"
		if refseq_mRNA_mm_default == nil and table.getn(link_list_mm) == 0 then refseq_mRNA_mm_link = "n/a" end
	else	
		refseq_mRNA_mm_collapse = "collapsible collapsed"
		refseq_mRNA_mm_default = table.remove(link_list_mm, 1) .. '<br>' .. table.remove(link_list_mm, 1) .. '<br>' ..table.remove(link_list_mm, 1) .. '<br>' .. table.remove(link_list_mm, 1) .. '<br>' .. table.remove(link_list_mm, 1) .. '<br>'--get first 5 elements in table and use for display
	end

	if link_list_mm[#link_list_mm] then
		refseq_mRNA_mm_link = table.concat(link_list_mm, "<br>")
	end
	



	local refseq_protTitle = "RefSeq (белок)"
	--create list of links for human refseq protein
	local refseq_prot_link = "n/a"
	local refseq_prot_collapse 
	local refseq_prot_default = ""
	local split_refseq_prot = mw.text.split(refseq_prot, ",")
	local link_list_prot = {}
    local link_list_first = {} --hold those the have NM or NP values
	local link_list_alternate = {} --hold those that are XM or XP values
  
	for k,v in ipairs(split_refseq_prot) do
		local label = mw.text.trim(v)
		local concat_ncbi_link = ncbi_link .. label
		if string.match(v, '%w+') and v ~= "n/a" then
			if string.match(v, 'NM') or string.match(v, 'NP') then
			    link_list_first[#link_list_first+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
			elseif string.match(v, 'XM') or string.match(v, 'XP') then
				link_list_alternate[#link_list_alternate+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
			end
		end
	end
	if table.getn(link_list_first)>0 then
		link_list_prot  = link_list_first
	else
		link_list_prot  = link_list_alternate
	end
	--if less than 5 don't create collapsible list
	if  table.getn(link_list_prot) < 6 then
		refseq_prot_collapse  = "none"
		if refseq_prot_default == nil and table.getn(link_list_prot) == 0 then refseq_prot_link = "n/a" end
	else	
		refseq_prot_collapse = "collapsible collapsed"
		refseq_prot_default = table.remove(link_list_prot, 1) .. '<br>' .. table.remove(link_list_prot, 1) .. '<br>' ..table.remove(link_list_prot, 1) .. '<br>' .. table.remove(link_list_prot, 1) .. '<br>' .. table.remove(link_list_prot, 1) .. '<br>'--get first 5 elements in table and use for display
	end

   
	if link_list_prot[#link_list_prot] then
		refseq_prot_link = table.concat(link_list_prot, "<br>")
	end
	
	
	--create list of links for mouse refseq protein
	local refseq_prot_mm_link = "n/a"
	local refseq_prot_mm_collapse
	local refseq_prot_mm_default = ""
	local split_refseq_prot_mm = mw.text.split(refseq_prot_mm, ",")
	local link_list_prot_mm = {}
	local link_list_first = {} --hold those the have NM or NP values
	local link_list_alternate = {} --hold those that are XM or XP values
  
	for k,v in ipairs(split_refseq_prot_mm) do
		local label = mw.text.trim(v)
		local concat_ncbi_link = ncbi_link .. label
		if string.match(v, '%w+') and v ~= "n/a" then
			if string.match(v, 'NM') or string.match(v, 'NP') then
			    link_list_first[#link_list_first+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
			elseif string.match(v, 'XM') or string.match(v, 'XP') then
				link_list_alternate[#link_list_alternate+1] = "[" .. concat_ncbi_link .. " " ..label .. "]"
			end
		end
	end
	if table.getn(link_list_first)>0 then
		link_list_prot_mm  = link_list_first
	else
		link_list_prot_mm  = link_list_alternate
	end
	--if less than 5 don't create collapsible list
	if  table.getn(link_list_prot_mm) < 6 then
		refseq_prot_mm_collapse  = "none"
		if refseq_prot_mm_default == nil and table.getn(link_list_prot_mm) == 0 then refseq_prot_mm_link = "n/a" end
	else	
		refseq_prot_mm_collapse = "collapsible collapsed"
		refseq_prot_mm_default = table.remove(link_list_prot_mm, 1) .. '<br>' .. table.remove(link_list_prot_mm, 1) .. '<br>' ..table.remove(link_list_prot_mm, 1) .. '<br>' .. table.remove(link_list_prot_mm, 1) .. '<br>' .. table.remove(link_list_prot_mm, 1) .. '<br>'--get first 5 elements in table and use for display
	end
	if link_list_prot_mm[#link_list_prot_mm] then
		refseq_prot_mm_link = table.concat(link_list_prot_mm, "<br>")
	end
	

	local locTitle = "Локус (UCSC)"
	local gstart_mb = p.locToMb(gstart, 2)
	local gend_mb = p.locToMb(gend, 2)
	local chr_loc_link =  ""
	if (string.match(db, '%w+') and string.match(chr, '%w+') and string.match(gstart, '%w+') and string.match(gend, '%w+') )then
		chr_loc_link = "[http://genome.ucsc.edu/cgi-bin/hgTracks?org=Human&db="..db.."&position=chr"..chr..":"..gstart.."-"..gend.." ".."Chr "..chr..": "..gstart_mb.." – "..gend_mb.." Mb]" 
	else
		chr_loc_link = "n/a"	
	end
	local gstart_mm_mb = p.locToMb(gstart_mm, 2)
	local gend_mm_mb = p.locToMb(gend_mm, 2)
	local chr_loc_mm_link = ""
	if (string.match(db_mm, '%w+') and string.match(chr_mm, '%w+') and string.match(gstart_mm, '%w+') and string.match(gend_mm, '%w+') )then
	 chr_loc_mm_link =  "[http://genome.ucsc.edu/cgi-bin/hgTracks?org=Human&db="..db_mm.."&position=chr"..chr_mm..":"..gstart_mm.."-"..gend_mm.." ".."Chr "..chr_mm..": "..gstart_mm_mb.." – "..gend_mm_mb.." Mb]"
	else
	 chr_loc_mm_link = "n/a"	
	end

	local pubmedTitle = "Поиск [[PubMed|PubMed]]"
	local pubmed_link = entrez_gene
	if string.match(entrez_gene, '%w+') and entrez_gene ~= "n/a" then
		pubmed_link = "[http://www.ncbi.nlm.nih.gov/sites/entrez?db=gene&cmd=Link&LinkName=gene_pubmed&from_uid="..entrez_gene.."]"
	end
	local pubmed_mm_link = entrez_gene_mm
	if string.match(entrez_gene_mm, '%w+') and entrez_gene_mm ~= "n/a" then
		pubmed_mm_link = "[http://www.ncbi.nlm.nih.gov/sites/entrez?db=gene&cmd=Link&LinkName=gene_pubmed&from_uid="..entrez_gene_mm.."]"
	end
	
	root
		:tag('tr')
        	:tag('th')
        		:attr('colspan', '4')
        		:css('text-align', 'center')
        		:css('background-color', titleBGcolor)
         		:wikitext(title)
        		:done()
        		:newline()
        :tag('tr')
        	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:wikitext("Виды")
        		:done()
        		:newline()
        	:tag('td')
        		:wikitext("'''Человек'''")
        		:done()
        		:newline()
        	:tag('td')
        		:wikitext("'''Мышь'''")
        		:done()
        		:newline()
        	:done()
        	---this section would be nice to do in a loop if the tag closures were figured out
        :tag('tr')
        	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:wikitext(entrezTitle)
        		:done()
        		:newline()
        	:tag('td')
        			:tag('table')
            			:attr('class', entrez_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:tag('span')
            						:attr('class', 'plainlinks')
            						:wikitext(entrez_default)
            					:done()
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:attr('class', 'plainlinks')
            				:wikitext(entrez_link)
            				 :newline()
            				:done()
            			:done()
            		:done()
            	:done()
        		:newline()
        	    :tag('td')
        			:tag('table')
            			:attr('class', entrez_mm_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:tag('span')
            						:attr('class', 'plainlinks')
            						:wikitext(entrez_mm_default)
            					:done()
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:attr('class', 'plainlinks')
            				:wikitext(entrez_mm_link)
            				 :newline()
            				:done()
            			:done()
            		:done()
            	:done()
        		:newline()	
        :tag('tr')
        	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:wikitext(ensemblTitle)
        		:done()
        		:newline()
        	:tag('td')
        			:tag('table')
            			:attr('class', ensembl_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:tag('span')
            						:attr('class', 'plainlinks')
            						:wikitext(ensembl_default)
            					:done()
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:attr('class', 'plainlinks')
            				:wikitext(ensembl_link)
            				 :newline()
            				:done()
            			:done()
            		:done()
            	:done()
        		:newline()
        	    :tag('td')
        			:tag('table')
            			:attr('class', ensembl_mm_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:tag('span')
            						:attr('class', 'plainlinks')
            						:wikitext(ensembl_mm_default)
            					:done()
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:attr('class', 'plainlinks')
            				:wikitext(ensembl_mm_link)
            				 :newline()
            				:done()
            			:done()
            		:done()
            	:done()
        		:newline()
        :tag('tr')
        	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:wikitext(uniprotTitle)
        		:done()
        		:newline()
        	:tag('td')
        			:tag('table')
            			:attr('class', uniprot_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:tag('span')
            						:attr('class', 'plainlinks')
            						:wikitext(uniprot_default)
            					:done()
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:attr('class', 'plainlinks')
            				:wikitext(uniprot_link)
            				 :newline()
            				:done()
            			:done()
            		:done()
            	:done()
        		:newline()
        	    :tag('td')
        			:tag('table')
            			:attr('class', uniprot_mm_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:tag('span')
            						:attr('class', 'plainlinks')
            						:wikitext(uniprot_mm_default)
            					:done()
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:attr('class', 'plainlinks')
            				:wikitext(uniprot_mm_link)
            				 :newline()
            				:done()
            			:done()
            		:done()
            	:done()
        		:newline()
        :tag('tr')
        	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:wikitext(refseq_mRNATitle)
        		:done()
        		:newline()
        	:tag('td') --RNASeq mRNA collapsible table 
        		:tag('table')
            			:attr('class', refseq_mRNA_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:attr('class', 'plainlinks')
            					:wikitext(refseq_mRNA_default)
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:tag('span')
            					:attr('class', 'plainlinks')
            					:wikitext(refseq_mRNA_link)
            					:done()
            				 :newline()
            				:done()
            			:done()
            		:done()
            :done()	
        	:tag('td') --RNASeq mRNA collapsible table for mouse 
        		:tag('table')
            			:attr('class', refseq_mRNA_mm_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:attr('class', 'plainlinks')
            					:wikitext(refseq_mRNA_mm_default)
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:tag('span')
            					:attr('class', 'plainlinks')
            					:wikitext(refseq_mRNA_mm_link)
            					:done()
            				 :newline()
            				:done()
            			:done()
            		:done()
            :done()	
        		
        :tag('tr')
        	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:wikitext(refseq_protTitle)
        		:done()
        		:newline()
        	:tag('td') --RNASeq protein collapsible table 
        		:tag('table')
            			:attr('class', refseq_prot_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:attr('class', 'plainlinks')
            					:wikitext(refseq_prot_default)
            				:done()
            				:newline()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:tag('span')
            					:attr('class', 'plainlinks')
            					:wikitext(refseq_prot_link)
            					:done()
            				 :newline()
            				:done()
            			:done()
            		:done()
            :done()	
			
			:tag('td') --RNASeq protein collapsible table for mouse
        		:tag('table')
            			:attr('class', refseq_prot_mm_collapse)
            			:css('padding', '0')
            			:css('border', 'none')
            			:css('margin', '0')
            			:css('width', '100%')
            			:css('text-align', 'right')
            			:tag('tr')
            				:newline()
            				:tag('th')
            					:attr('colspan', '1')
            					:attr('class', 'plainlinks')
            					:wikitext(refseq_prot_mm_default)
            				:done()
            			:done()
            			:tag('tr')
            			:tag('td')
            				:attr('colspan', '1')
            			:newline()
            			:tag('p')
            				:tag('span')
            					:attr('class', 'plainlinks')
            					:wikitext(refseq_prot_mm_link)
            					:done()
            				 :newline()
            				:done()
            			:done()
            		:done()
            :done()
    
        :tag('tr')
        	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:wikitext(locTitle)
        		:done()
        		:newline()
        	:tag('td')
        		:tag('span')
            		:attr('class', 'plainlinks')
        			:wikitext(chr_loc_link)
        		:done()
        		:newline()
        	:tag('td')
        		:tag('span')
            		:attr('class', 'plainlinks')
        			:wikitext(chr_loc_mm_link)
        		:done()
        		:newline()
        :tag('tr')
        	:tag('th')
        		:attr('scope', 'row')
        		:css('background-color', sideTitleBGcolor)
        		:wikitext(pubmedTitle)
        		:done()
        		:newline()
        	:tag('td')
        		:tag('span')
            		:attr('class', 'plainlinks')
        			:wikitext(pubmed_link)
        		:done()
        		:newline()
        	:tag('td')
        		:tag('span')
            		:attr('class', 'plainlinks')
        			:wikitext(pubmed_mm_link)
        		:done()
        		:newline()
        		:wikitext(category_chromosome)
end

p.formatRow = function(title)
	 root
	 		:tag('tr')
        	:tag('td')
   				:attr('colspan', '4')
            	:css('text-align', 'center')
            	:css('background-color', rowBGcolor)
            	:newline()
            	--p.createTable('sub')
            	:tag('table') 
            		:css('padding', '0')
            		:css('border', 'none')
            		:css('margin', '0')
            		:css('width', '100%')
            		:css('text-align', 'left')
            		:newline()
            		:tag('tr')    --create title header
            			:css('background-color',titleBGcolor)
            			:css('text-align', 'center')
            			:tag('th')
            				:attr('colspan',"2")
            				:wikitext(title)
            				:done()
            		:done()
            		:newline()
end

p.renderFooter = function(Qid, Qid_mm)
 local text = "[[Wikidata|Викиданные]]"
 local hs_link = "[[d:"..Qid.."|Просмотр/Править (Человек)]]"
 local mm_link = ""
 local link_no_hs
 local link_no_mm
 
 if Qid_mm == "" then
 	link_no_mm = 0
 	link_no_hs = 4
 else 
 	link_no_mm = 2
 	link_no_hs = 2
 	mm_link = "[[d:"..Qid_mm.."|Просмотр/Править (Мышь)]]"
 end
 
 root
 	:tag('tr')
 		:tag('td')
 		:attr('colspan', '4')
 		:css('text-align', 'center')
 		:css('font-size','x-small')
 		:css('background-color', rowBGcolor)
 		:wikitext(text)
 		:done()
 		:newline()

 	:tag('tr')
 		:tag('td')
 		:attr('colspan', link_no_hs)
 		:css('background-color', rowBGcolor)
 		:css('text-align', 'center')
		:css('font-size','x-small')
		:wikitext(hs_link)
		:done()
		
		:tag('td')
 		:attr('colspan', link_no_mm)
 		:css('background-color', rowBGcolor)
 		:css('text-align', 'center')
		:css('font-size','x-small')
		:wikitext(mm_link)
		:done()
		:newline()
		
	:done()

end

--this code isn't used was hoping could do some generalization of rows
p.rowLabel=function(label)
	root
	    :tag('tr')
        :tag('th')
        	:attr('rowspan', '2')
        	:css('background-color', sideTitleBGcolor)
        	:css('width', '43px')
         	:wikitext(label)
        	--:done()
end

-- look into entity object
p.getLabel = function(entity)
	local data = entity

	local f = {'labels','ru','value'}

	local i = 1
	while true do
		local index = f[i]
		if not index then
			if type(data) == "table" then
				return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY)
			else
				return tostring(data)
			end
		end
		
		data = data[index] or data[tonumber(index)]
		if not data then
			return
		end
		
		i = i + 1
	end
end



--general function to get value given an entity and property
p.getValue = function(entity, propertyID, return_val)

	local claims
	if return_val == nil then return_val = "" end
    local sep = " " --could ad as input parameter if need be
	if entity and entity.claims then
		claims = entity.claims[propertyID]
	end
	if claims then
		-- if wiki-linked value output as link if possible
		if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
			local out = {}
			for k, v in pairs(claims) do
				local datav = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
				if datav == nil then datav = " " end 
				out[#out + 1] = datav			
			end
			return table.concat(out, sep)
		else
		-- just return best values
			return entity:formatPropertyValues(propertyID).value
		end
	else
		return return_val
	end
end

p.getValueProtein = function(protein_entities, propertyID, return_val)
	if return_val == nil then return_val = "" end
	local sep = ","
    local overall_results = {} --should return empty if nothing assigned
	for key, val in pairs(protein_entities) do --in cases where there are multiple encodes we loop through each and return concatenated data as a whole
		local claims
		local entity = val --each protein in encodes
		if entity and entity.claims then
			claims = entity.claims[propertyID]
		end
		if claims then
			local results
			-- if wiki-linked value output as link if possible
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				local out = {}
				for k, v in pairs(claims) do
					local datav = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
					if datav == nil then datav = " " end 
					out[#out + 1] = datav			
				end
				results = table.concat(out, sep)
			else
				results = entity:formatPropertyValues(propertyID).value
			end
			overall_results[#overall_results+1] = results --individual propertyID value stored in this index	
		end
	end

	local str_overall_results = table.concat(overall_results, sep) --weirdness happens when add a sep = " " otherwise each value represented one time
	if string.match(str_overall_results, '%w+') then
		return str_overall_results 
	else
		return return_val
	end
end


--general function to get value given an entity and property
p.getQid = function(entity)
	local Qid
	if entity and entity.id then
		Qid = entity.id
		return Qid
	else
		return ""
	end
end

--get random value that is preferred ranked 
p.getRefseq_mRNA = function(entity, propertyID, return_val)
	if return_val == nil then return_val = "" end
	local input_rank = "RANK_PREFERRED" ---this is mostly like won't do anything because ranking isn't maintained in wikidata 
	local claims
	
	if entity.claims then
		claims = entity.claims[propertyID]
	end
	if claims then
		-- if wiki-linked value output as link if possible
		if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid" ) then
			local out = {}
			for k, v in pairs(claims) do
				local sitelink = mw.wikibase.sitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"])
				local label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
				if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end
							
				if sitelink then
					out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]"
				else
					out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]"
				end
			end
			return table.concat(out, ", ")
		else
			local results = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value 
			
			--loop through results until get a NP or NM or just return whatever is in first element
			--[[local results_split = mw.text.split(results, ",")
			
			local preffered_results = " "
			if results_split[1] then
				preferred_result = mw.text.trim(results_split[1]) --return first element if desired prefix not found and remove whitespace
			end
			local id --refseq id in question
			for i, id in ipairs(results_split) do
				local trim_id = mw.text.trim(id)
  				if string.match( trim_id, '^NM_%d+') then 
  					preferred_result = trim_id --overwrite each time found only need one to display
  				end
			end
			if preferred_result then
				return preferred_result --return a id starting with NP or NM
			else
				return return_val --return first element because desired prefix not found and remove whitespaces
			end
			--]]
			return results
		end
	else
		return return_val
	end
end

p.getRefseq_protein = function(protein_entities, propertyID, return_val)
local sep = ","
local overall_results = {} --should return empty if nothing assigned

	for key, val in pairs(protein_entities) do --in cases where there are multiple encodes we loop through each and return concatenated data as a whole
	
		local claims
		local entity = val --each protein in encodes
		if entity.claims then
			claims = entity.claims["P637"]
		end
		if claims then
			local results
			-- if wiki-linked value output as link if possible
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid" ) then
				local out = {}
				for k, v in pairs(claims) do
					local datav = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
					if datav == nil then datav = " " end 
					out[#out + 1] = datav			
				end
				results = table.concat(out, sep)
			else
				results = entity:formatPropertyValues("P637", mw.wikibase.entity.claimRanks).value 
			end
			overall_results[#overall_results+1] = results --a list is in each index 
		end	
		
	end
	--why are there duplicate results here
	local str_overall_results = table.concat(overall_results, sep)
	return str_overall_results

end
	--[[
	local results_split = mw.text.split(str_overall_results, sep) --split complete list so can loop through..probably a more direct way to do this
				--loop through results until get a NP or NM or just return whatever is in first element
	

	local preffered_result = results_split[1] or ""

	for i, id in ipairs(results_split) do
		local trim_id = mw.text.trim(id)
		--check of id starts with NP or NM
		if string.match( trim_id, '^NP_%d+') then 
			preferred_result = trim_id --overwrite each time found only need one to display
		end
	end
	--check if something in preffered_result if not get first element in result_split
	if p.isempty(preffered_result) then
		return return_val
	else
		return preferred_result --return a id starting with NP or NM
	end

end --]]

--gets an image
p.getImage = function(entity, propertyID, sep, imgsize)
  
 	local claims
  
 	if entity and entity.claims then  
 		claims = entity.claims[propertyID]  
 	end
  
 	if claims then
 		if (claims[1] and claims[1].mainsnak.datatype == "commonsMedia") then  
 			local out = {}  
 			for k, v in pairs(claims) do  
 				local filename = v.mainsnak.datavalue.value  
 				out[#out + 1] = "[[File:" .. filename .. "|" .. imgsize .. "]]" 
 			end   
 				return table.concat(out, sep)   
 		else   
 			return ""   
 		end   
	else   
 		return ""   
 	end   
end

p.getPDB = function(protein_entities)
	local pdb_propertyID = "P638"
	local overall_results = {}
	for key, val in pairs(protein_entities) do --in cases where there are multiple encodes we loop through each and return concatenated data as a whole
		local claims
		local entity = val
		if entity and entity.claims then
			claims = entity.claims[pdb_propertyID]
		end
		local sitelink = "http://www.rcsb.org/pdb/explore/explore.do?pdbId="
		if claims then
			local results
			if (claims[1] and claims[1].mainsnak.snaktype == "value") then
			
			
				local out = {}
				for k, v in pairs(claims) do
					local label = mw.wikibase.label(v.mainsnak.datavalue.value)
					if label == nil then label = v.mainsnak.datavalue.value end
				
					if sitelink then
						out[#out + 1] = "[" .. sitelink .. label .. " " ..label .. "]"
					else
						out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value .. "|" .. label .. "]]"
					end
				end
				results = table.concat(out, ", ")
			else
				results = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
			end
			overall_results[#overall_results+1] = results --individual propertyID values stored in this index
		end
	end
	return table.concat(overall_results, ",%%s")
end

function p.getAliases(entity)
	a = ''
	if entity['aliases'] ~= nil then
        local test = entity['aliases']['en']
        if test then
			for key, value in ipairs(test) do
				a = a .. ', ' ..  value['value']
			end
			return a
		else
			return ""
		end
	else
		return ""
	end
	
end


--get a geneome start P644 or end P645
p.getChromosomeLoc = function(entity, propertyID, prefix)
	-- will contain the numeric value for the requested coordinate
	local output = ""
	local sep = " "
	-- can only be P644 (genomic start) or P645 (genomic end) for this to work
	-- should probably try to catch that.  Might also increase legibility to use specific variable names when possible
--	local propertyID = mw.text.trim(frame.args[1] or "") 
	-- this can really only be P659 right now.  I'm not sure of the value of including it as a parameter as other values will likely break this function
	local qualifierID = "P659" --mw.text.trim(frame.args[2] or "")
	-- Why do we include this here?  What should happen if FETCH_WIKIDATA is not included? 
	--local input_parm = mw.text.trim(frame.args[3] or "")
	-- this can needs to be fed to the function either by a call to {{#invoke:Wikidata|pageId}} or by setting it directly (e.g. if the function was applied on a page other than the targeted gene)
	--alert if this id is not a valid thing in wikidata, a Lua error will occur that says
	--The ID entered is unknown to the system. Please use a valid entity ID.
	--local itemID = mw.text.trim(frame.args[4] or "")
	-- will track the different builds pulled from the qualifiers
	local newest_build = "0"
	-- starts the process
	--local entity = mw.wikibase.getEntityObject(itemID)
	local claims
	--gets a table of claims on the (genomic start or end) property Q19847637
	if entity and entity.claims then
		claims = entity.claims[propertyID]
	end
	--will return nothing if no claims are found
	if claims then
		--checking to be sure claims is populated, not sure it its needed
		if (claims[1] ) then
			--useful for debugging
			--local out = {}
			--pulls the genome location from the claim
			for k, v in pairs(claims) do
				local location = v.mainsnak.datavalue.value
				--debugging
				--out[#out + 1] = k.." location:" .. location.. " || " 
				--gets the qualifiers linked to the current claim
				local quals 
				if v.qualifiers then
					quals = v.qualifiers.P659
				end
				--if there are any
				if quals then
					for qk, qv in pairs(quals) do
						local qual_obj_id = "Q"..qv.datavalue.value["numeric-id"]
						--get to the entity targeted by the qualifier property.  Genome builds are Items in wikidata
						local qual_obj = mw.wikibase.getEntityObject(qual_obj_id)
						local alias = ""
						--this uses the aliases to pull out version numbers
						--seems like there ought to be a better way to do this, but likely would need to change the data added by the bot
						if qual_obj["aliases"] ~= nil then
							local test = qual_obj["aliases"]["en"]
							for key, value in ipairs(test) do
								if string.match(value['value'], prefix) then
									alias = value['value']
									local build_no = alias:gsub(prefix,"")
									--report only the most location associated with the most recent build
									--if there is more than one location per build, just give one back as that is not our problem right now.
									if build_no > newest_build then
										output = location
										newest_build = build_no
									end
								end
							end
						end
					end
				--in case there are no qualifiers, but there is a location, might as well return it
				else output = location 
				end
			end
				return output
		else
			return ""
		end
	else
		return ""
		--debug
		--"no claims for "..itemID.." prop "..propertyID
	end
end

p.getAliasFromGenomeAssembly = function(entity, prefix)
	-- will contain the numeric value for the requested coordinate
	local output = ""
	local sep = " "
	local propertyID = "P644" --genomic start used 
	local qualifierID = "P659"

	local newest_build = "0"
	local claims
	if entity.claims then
	 claims = entity.claims[propertyID]
	end
	--will return nothing if no claims are found
	if claims then
		--checking to be sure claims is populated, not sure it its needed
		if (claims[1] ) then
			--useful for debugging
			--local out = {}
			--pulls the genome location from the claim
			for k, v in pairs(claims) do
				local quals
				if v.qualifiers then
					quals = v.qualifiers.P659
				end
				--if there are any
				if quals then
					for qk, qv in pairs(quals) do
						local qual_obj_id = "Q"..qv.datavalue.value["numeric-id"]
						--get to the entity targeted by the qualifier property.  Genome builds are Items in wikidata
						local qual_obj = mw.wikibase.getEntityObject(qual_obj_id)
						local alias = ""
						--this uses the aliases to pull out version numbers
						--seems like there ought to be a better way to do this, but likely would need to change the data added by the bot
						if qual_obj["aliases"] ~= nil then
							local test = qual_obj["aliases"]["en"]
							for key, value in ipairs(test) do
								if string.match(value['value'], prefix) then
									alias = value['value']
									local build_no = alias:gsub(prefix,"")
									--report only the most location associated with the most recent build
									--if there is more than one location per build, just give one back as that is not our problem right now.
									if build_no > newest_build then
										newest_build = build_no
									end
								end
							end
						end
					end
				--in case there are no qualifiers, but there is a location, might as well return it
				else output = location 
				end
			end
				return prefix..newest_build
		else
			return ""
		end
	else
		return ""
	end
end

p.trimChromosome = function(entity)
	local string_to_trim = p.getValue(entity, "P1057")
	local out = ''
	if string.find(string_to_trim, 'хромосома') then
		out = string.match(string_to_trim, "%d+")--extract number from string
		if out == nil then
			out = string.match(string_to_trim, "X") or string.match(string_to_trim, "Y")
		end
	end
	if string.find(string_to_trim, 'митохондр') then
		out = "M"
	end
	return out
end

p.locToMb = function(num, idp)
  num = tonumber(num)
  if num == nil then 
  	return ""
  else
  	local mb = num/1000000
  	local mult = 10^(idp or 0)
  	return math.floor(mb * mult + 0.5) / mult
  end
end

p.isempty = function(s)
  	return s == nil or s == ''
end


p.getGO = function(protein_entities, propertyID)
	--propertyID ie molecular, cellular, function
	
	local overall_results = {}
	local results = "" --string to return
	
	for key, val in pairs(protein_entities) do
	
		local claims
		local entity = val
		if entity.claims then
			claims = entity.claims[propertyID] -- ie molecular, cellular, function
		end
		local propertyID_child = "P686" -- Gene Ontology ID
		
		if claims then
			
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				--local out = {}
				for k, v in pairs(claims) do
					local itemID_child = "Q" .. v.mainsnak.datavalue.value["numeric-id"] --get Qid of property item so can get the GOid
					local entity = mw.wikibase.getEntityObject(itemID_child)
					local claims
					local result_GOID = ''
					if entity and entity.claims then claims = entity.claims[propertyID_child] end
					if claims then
						result_GOID = entity:formatPropertyValues(propertyID_child, mw.wikibase.entity.claimRanks).value
					else
						result_GOID = nil --no GO ID
					end
					local sitelink = "http://amigo.geneontology.org/amigo/term/"
					local label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
					if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end
					local wiki_link	= ""
					if sitelink and result_GOID ~= nil then
						wiki_link = "<big>•</big> [" .. sitelink .. result_GOID .. " " .. label .."]<br>"
					else
						wiki_link = "<big>•</big> [[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]<br>"
					end
					overall_results[#overall_results+1] = wiki_link
				end
				
			else
				results = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
			end
			
		end
		--overall_results[#overall_results+1] = results --each protein GO terms stored in this index, so table contains all the GO terms with duplicates 
	end

	local hash = {} --temp check
	local res = {} --no dups

	for _,v in ipairs(overall_results) do
   		if (not hash[v]) then
       		res[#res+1] = v 
       		hash[v] = true
   		end
	end
	return table.concat(res, "")
end

local function getReference(qID, index, entity, property_id, ref_index)
	local f = {"claims",property_id,index,"references",ref_index,"snaks","P854",1,"datavalue","value"} 
	local id = qID
	--if id and (#id == 0) then
	--	id = nil
	--end
	local data = entity
	if not data then
		return nil
	end
	
    
	local i = 1
	while true do
		local index = f[i]
		if not index then
			if type(data) == "table" then
				return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY)
			else
				return tostring(data)
			end
		end
		
		data = data[index] or data[tonumber(index)]
		if not data then
			return ""
		end
		i = i + 1
	end
end

p.getDisease= function(entity, propertyID)
    local claims
	if return_val == nil then return_val = "" end
	if entity and entity.claims then
		claims = entity.claims[propertyID]
	end
	if claims then
		-- if wiki-linked value output as link if possible
		
		if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then

			local out = {}
			local datasource = {}
			--{{#invoke:Wikidata |ViewSomething |id=Q18023174 |claims|P2293|1|references|1|snaks|P854|1|datavalue|value}}
			--maybe there is a more direct way to find this than looping through the json object
			
			for k, v in pairs(claims) do
				local datav = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
				
				if datav == nil then datav = " " end 
			   
				local id = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
				local linkTarget = mw.wikibase.sitelink(id)
				local refLink = ""
				local i 
				for i=1,100 do --limits to 100 references displayed
				  local ref = ""
				  ref = getReference("", k, entity, "P2293", i)
				  if (ref ~= nil and ref ~= '') then
				     refLink = refLink..",["..ref.."]"
				  end
				end
                --if refLink = "" then --skip if there isn't a reference found
				datasource[#out + 1] = refLink
				if linkTarget then
					out[#out + 1] = "[["..datav.."|"..datav.."]]"
				else
					out[#out + 1] = "[[:d:" .. id .. "|" .. datav .. "]]"
				end
				--end				
			end
			return out, datasource
		else
		-- just return best values
			--return entity:formatPropertyValues(propertyID).value
			return return_val, return_val
		end
	else
		return return_val
	end	
   return return_val
end

p.getDrug= function(protein_entities, propertyID)
    local out = {}
	local datasource = {}

	for key, val in pairs(protein_entities) do
		local claims
		local entity = val
		if entity.claims then
			claims = entity.claims[propertyID] -- ie physically interacts with
		end
		local protein_id
		if entity then protein_id = entity.id else protein_id = "" end
		if claims then
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				for k, v in pairs(claims) do
					local datav = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
				
					if datav == nil then datav = "" end
					local id = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
					local linkTarget = mw.wikibase.sitelink(id)
					local refLink = ""
					local i
					for i=1,100 do --limits to 100 references displayed
						local ref = ""
						ref = getReference(protein_id, k, entity, "P129", i)
						if (ref ~= nil and ref ~= '') then
							refLink = refLink..",["..ref.."]"
						end
					end
					
					local wikiLink = "[["..datav.."|"..datav.."]]"
					local wikidataLink = "[[:d:" .. id .. "|" .. datav .. "]]"
					if (refLink ~= nil and refLink ~= '') then
						if linkTarget then
							if out[wikiLink] then
								out[wikiLink] = out[wikiLink]..","..refLink
							else
								out[wikiLink] = refLink
							end
						else
							if out[wikidataLink] then
								out[wikidataLink] = out[wikidataLink]..","..refLink
							else
								out[wikidataLink] = refLink
							end
						end--end if linkTarget
					end -- end  if refLink
				end --end k,v claims loop
			end --end claims[1]
		end --if claims
    end -- end protein_entities loop
	return out
end

return p