Jump to content

Module:Sandbox/Matroc

From Wikivoyage

-- This test module has been cleaned up - most functions removed due to lack of interest
-- or collaboration to create viable modules for wikivoyage use.
-- Left a few functions as they are used on another article page. Module will remain and
-- probably will be used for testing other functions... Matroc
-- Note: may wish to change some code to do "if not " (boolean) ???? testing for nil

local p = {}



local function loadwikinames()
    local wikinames = {}	
	wikinames[1] = "wikisource"
	wikinames[2] = "wikibooks"
	wikinames[3] = "wikinews"
	wikinames[4] = "wikiquote"
	wikinames[5] = "wikivoyage"
	wikinames[6] = "wiki"
	return wikinames
end  

function p.date(frame)
	
return os.date("%m%d%Y -- %I:%M:%S")

end

-- Load a page and scan it for listing templates and find duplicate parameters


-- The next five functions though not used may be useful for someone else to use in the future
-- in building circles for OpenStreetMaps -- see p.circle function below

local function isINF(value)
        return value == math.huge or value == -math.huge
end

local function degrees2meterslat(lat)
        x = math.log(math.tan((90 + lat) * math.pi / 360)) / (math.pi / 180)
        x = x * 20037508.34 / 180
        return x
end

local function degrees2meterslong(long)
        y = long * 20037508.34 / 180    --- longitude to meters
        return y
end

local function meters2degreeslat(y)
        lat = math.atan(math.exp(y * math.pi / 20037508.34)) * 90 / math.pi - 90
        return lat
end

local function meters2degreeslong(y)
        long = y *  180 / 20037508.34
        return long
end

-- Rough calculation of distance between 2 coordinates in miles and kilometres

local function distance(lat1,long1,lat2,long2) -- in Progress
    lat1 = math.rad(lat1)
    lat2 = math.rad(lat2)
	long1 = math.rad(long1)
	long2 = math.rad(long2)
    local longd = long2 - long1
    local latd = lat2 - lat1
    local x = (math.sin(latd/2))^2 + math.cos(lat1) * math.cos(lat2) * (math.sin(longd/2))^2
    local y = 2 * math.atan2( math.sqrt(x), math.sqrt(1-x) )
    local distance1 = 3861 * y  -- miles
    local distance2 = 6373 * y  -- kilometers
    return "Approximate distance in '''miles''': " .. distance1 .. " Approximate distance in '''kilometers''': " .. distance2
end
function p.distance(frame,lat1,long1,lat2,long2) -- in Progress
	local lat1 = frame.args['lat1']	
    lat1 = math.rad(lat1)
local lat2 = frame.args['lat2']	    
    lat2 = math.rad(lat2)
local long1 = frame.args['long1']	      
	long1 = math.rad(long1)
local long2 = frame.args['long2']	
	long2 = math.rad(long2)
    local longd = long2 - long1
    local latd = lat2 - lat1
    local x = (math.sin(latd/2))^2 + math.cos(lat1) * math.cos(lat2) * (math.sin(longd/2))^2
    local y = 2 * math.atan2( math.sqrt(x), math.sqrt(1-x) )
    local distance1 = 3861 * y  -- miles
    local distance2 = 6373 * y  -- kilometers
distance1 = string.format("%.6f",distance1)
distance2 = string.format("%.6f",distance2)
    return "Approximate distance in '''miles''': " .. distance1 .. " Approximate distance in '''kilometers''': " .. distance2
end


-- load a table for tblukup
local function load_t1(t1,table2load)
	if pcall(function()t1 = mw.loadData(table2load) end) then
		return t1
	else
		error ("Unable to load table!")
	end
end

 -- FROM WIKIBASE
 -- Returns the most updated info from a series of statements - called by some of the other functions

local function updated(item,prop,frame)
    if item~=nil then
        local claims = item.claims
        if claims~=nil and claims[prop]~=nil then
            for index,claim in pairs(claims[prop]) do
                local qual = claim.qualifiers
                if qual==nil or qual.P582==nil then
                    -- p582 è la data di fine, significa che non è il valore attuale
                    local val = claim.mainsnak.datavalue.value
                    if val['numeric-id']~=nil then
                        local id = 'Q'..val['numeric-id']
                        local sl = mw.wikibase.sitelink(id)
                        local lb = mw.wikibase.label(id)
                        if sl~=nil and sl~='' then
                            return frame:preprocess('[['..sl..'|'..lb..']]')
                        end
                        return lb
                    end
                    return val
                end
            end
        end
    end
    return ''
end 

function p.libya(frame)
	local linkTarget = mw.wikibase.sitelink("Q1016")
	local linkName = mw.wikibase.label("Q1016")
	
	return "LinkTarget: " .. linkTarget .. " LinkName: " .. linkName
	
end


-- GET LATITUDE -- P625

function p.latitude(frame)
--    if frame.args[1]~=nil and frame.args[1]~='' then
--        return frame.args[1]
--    end
	local latitude = ""
	local arg1 = frame.args[1]
    local entity = mw.wikibase.getEntityObject(arg1)	
--	local entity = mw.wikibase.getEntityObject()
	if entity == nil then return latitude end    		
	local claims = entity.claims
	if claims == nil then
		return latitude
	end	
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		return latitude
	end
	return latitude
end

--  GET LONGITUDE -- P625

function p.longitude(frame)
--    if frame.args[1]~=nil and frame.args[1]~='' then
--        return frame.args[1]
--    end
	local longitude = ""
	local arg1 = frame.args[1]
    local entity = mw.wikibase.getEntityObject(arg1)	
--	local entity = mw.wikibase.getEntityObject()
	if entity == nil then return longitude end    		
	local claims = entity.claims
	if claims == nil then
		return longitude
	end	
	if claims.P625 ~= nil then
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		return longitude
	end
	return longitude
end

-- GET URL -- P856
function p.url(frame)
--    if frame.args[1]~=nil and frame.args[1]~='' then
--        return frame.args[1]
--    end
	local url = ""
	local arg1 = frame.args[1]
	local entity = mw.wikibase.getEntityObject(arg1)
	if entity == nil then return url end	
	local claims = entity.claims
	if claims == nil then
		return
		end
	if claims.P856 ~= nil then
		url = entity.claims.P856[1].mainsnak.datavalue.value
		url = string.gsub(url,"%,.*","") -- KEEP ONLY ONE
		return url
	end
return url
end

-- make a completed mapframe template from data from Wikidata with zoom of 13 {{mapframe|||}}

function p.makemapframe(frame)
	local output = ""
	local latitude = ""
	local longitude = ""
	local arg1 = frame.args[1]
	local entity = mw.wikibase.getEntityObject(arg1)
	if entity == nil then return end
	local claims = entity.claims
	if claims == nil then return end
	if claims.P625 == nil then return end
-- pcall is actually used as a test mechanism - bit more complicated in use than regular tests
	if pcall(function () t = claims.P625 end) then

		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
			latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
			end
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			
			longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
			end	

		if latitude ~= "" and latitude ~= nil and longitude ~= "" and longitude ~= nil then
			latitude = string.format("%.6f",latitude) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000
			longitude = string.format("%.6f",longitude) -- format number to 6 decimal places see above
			latitude = string.gsub(latitude,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1.
			longitude = string.gsub(longitude,"0+$","") -- string any number of ending zeroes - see above
			latitude = string.gsub(latitude,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1
			longitude = string.gsub(longitude,"%.$","") -- strip an ending period
			output = output .. "{{mapframe|" .. latitude .. "|" .. longitude  .. "|zoom=8}}\n"
			end
	end
	if output ~=nil and output ~= "" then
		return output
	end
	
end

-- make a completed geo template from data from Wikidata {{geo||}}

function p.makegeo(frame)
	local output = ""
	local latitude = ""
	local longitude = ""
	local arg1 = frame.args[1]
	local entity = mw.wikibase.getEntityObject(arg1)
	if entity == nil then return end
	local claims = entity.claims
	if claims == nil then return end
	if claims.P625 == nil then return end
-- pcall is actually used as a test mechanism - bit more complicated in use than regular tests
	if pcall(function () t = claims.P625 end) then

		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
			latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
			end
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			
			longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
			end	

		if latitude ~= "" and latitude ~= nil and longitude ~= "" and longitude ~= nil then
--			latitude = string.format("%.4f",latitude) -- format number to 4 decimal places	-- keeping now as 4 decimal places		
--			longitude = string.format("%.4f",longitude) -- format number to 4 decimal places			
			latitude = string.format("%.6f",latitude) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000
			longitude = string.format("%.6f",longitude) -- format number to 6 decimal places see above
			latitude = string.gsub(latitude,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1.
			longitude = string.gsub(longitude,"0+$","") -- string any number of ending zeroes - see above
			latitude = string.gsub(latitude,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1
			longitude = string.gsub(longitude,"%.$","") -- strip an ending period
-- if zoom parameter is desired this can be done fairly easily
--			output = output .. "{{geo|" .. latitude .. "|" .. longitude  .. "| zoom=13}}\n"
			output = output .. "{{geo|" .. latitude .. "|" .. longitude  .. "}}\n"
			end
	end
	if output ~=nil and output ~= "" then
		output = string.gsub(output,'}}','|zoom=13}}')
		return output
	end
	
end

-- TBLUKUP - loads a table and does a lookup for table
-- Table to load is required to be on a Module: page by itself

function p.tblukup(frame)
	local table2load = frame.args[1] or ""
	local lookup = frame.args[2] or ""
	local bywhat = "key" --- lookup to be performed on the key - can add args[3] as key or str in future
	if table2load == "" or table2load == nil then return end
	table2load = "Module:" .. table2load -- table is to be found on a Module: page
	if lookup == "" or lookup == nil then return end
	local t1 = {}
	t1 = load_t1(t1,table2load)
	if bywhat == "key" then
-- Shorter version possible rather than cycling through all 
	if t1[lookup] then return t1[lookup] end		
--		for key,value in pairs(t1) do
--			if key == lookup then
--				return value
--				end
--		end

	end
--	if bywhat == "str" then
--		for key,value in pairs(t1) do
--			if value == lookup then
--				return key
--				end
--		end
--	end
	return lookup
end

-- Purpose: Create a basic simple map template in an article based on Qnn for future editorial purposes
-- What is produced is actual code for extension Kartographer - this is very verbose and probably not
-- for the faint at heart
-- programming is being done to translate listings directly in maps 
-- One general argument is this function is at cross purposes to normal see, buy listings etc. and probably not
-- desired however it appears that just a little bit more can be accomplished in the image field
-- than the image field in a listing.
-- Whereas there is no place for other pieces of information as found in a see listing.
-- arg1 would be the overall location of the Qnn passed to get the latitude and longitude for the overall marker
-- arg2 would be multiple Qnnn,Qnnn - separated by a comma
-- and build each feature from data garnered from Wikidata - (latitude, longitude, image etc.)
-- error could possibly arise if the Qnnn in not in Wikidata
-- arguments that can be passed as well have been added for this function are:
-- zoom -- group -- show -- color -- symbol
-- Possible issue to check - the name in Wikidata may not be name in wikivoyage -- may have to do a check there as well
-- safesubst to be used so you can see what you get and once saved can be edited manually
-- Is there room for both forms - I do not know. There should be at least some discussion about this....

function p.amapframe(frame)
	local arg1 = frame.args[1] or ""
	if string.match(arg1,"^[Qq]%d+$") == nil then return "" end  -- arg1 should be in a specific format 'Qnnnn' testing 
	local arg2 = frame.args['list'] or ""
	if arg2 ~= nil and arg2 ~= "" then
		arg2 = string.gsub(arg2,"%s","")
	end
	local group = frame.args['group'] or "city"
	local show = frame.args['show'] or "city"
	local zoom = frame.args['zoom'] or "4"
	local markercolor = frame.args['color'] or "#33a2ff"  -- prep for color argument -- change the concatenation of text
	if markercolor == nil or markercolor == "" then markercolor = "#33a2ff" end
	local markersymbol = frame.args['symbol'] or "city"   -- prep for symbol argument
	if markersymbol == nil or markersymbol == "" then markersymbol = "city" end
    local markercolor = '"marker-color": "' .. markercolor .. '"'
    local markersymbol = '"marker-symbol": "' .. markersymbol .. '",' -- use these items for concatenation below
	local latitude = ""
	local longitude = ""
	local separator = ","
	local output = ""
	local feature = ""
	local entity = mw.wikibase.getEntityObject(arg1)
	if entity == nil then return end
	local claims = entity.claims
	if claims == nil then return end
	if claims.P625 == nil then return end
-- pcall is actually used as a test mechanism - bit more complicated in use than regular tests
	if pcall(function () t = claims.P625 end) then
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
			latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
			end
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			
			longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		end	
end
	if latitude ~= "" and latitude ~= nil and longitude ~= "" and longitude ~= nil then
			latitude = string.format("%.6f",latitude) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000
			longitude = string.format("%.6f",longitude) -- format number to 6 decimal places see above
			latitude = string.gsub(latitude,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1.
			longitude = string.gsub(longitude,"0+$","") -- string any number of ending zeroes - see above
			latitude = string.gsub(latitude,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1
			longitude = string.gsub(longitude,"%.$","") -- strip an ending period
			local part1 = '\n'   -- not going to output div box
--   	local part1 = '\n<div style="border-style:solid; border-width:2px; width:412px; \
--    	height:412px; padding:12px 12px 2px 2px; float:right;">\n'
    	local part2 = '\n<mapframe latitude=' .. latitude .. ' longitude=' .. longitude .. ' zoom=' .. zoom .. ' width="400" height="400" group="' .. group .. '" show="' .. show .. '">\n'
		local part3 = '\n' .. '{' .. '\n\t' .. '"type": "FeatureCollection",' .. '\n\t' ..  '"features": [' .. '\n'

-- count up others to put on map - using Qnnnn and add basic type feature
-- module to get each name, latitude and longitude using split arg2 would be Qnnn,Qnnn,Qnnn
-- can get label --  get latitude longitude and basic description and image if possible
-- Need to eliminate duplicates - perhaps put Qnns in an array and scan each and eliminate duplicates

---- TEST OF REMOVING DUPLICATES FROM LIST OF Qnn
 local index = 1
 local items = {}
 local flags = {}

 for str in string.gmatch(arg2,"([^"..separator.."]+)") do
	items[index] = str
	index = index + 1
	end
 for i=1,#items do
	if not flags[items[i]] then
		flags[items[i]] = true
 feature = feature .. p.feature(items[i],markercolor,markersymbol) -- extra arguments ??
		end
	end
---- END TEST OF REMOVING DUPLICATES FROM LIST OF Qnnn

---- OLD CODE KEEP --
---- for str in string.gmatch(arg2,"([^"..separator.."]+)") do --
---- feature = feature .. p.feature(str,markercolor,markersymbol) --
---- feature = feature .. p.feature(str) --	
--	end --
----OLD CODE KEEP --

		feature = string.gsub(feature,",$","")
	    local part4 = '\n\t' .. ']' .. '\n' .. '}</mapframe>' .. '\n' -- not outputting div 
--	    local part4 = '\n\t' .. ']' .. '\n' .. '}</mapframe>' .. '\n' .. '</div>' .. '\n'
		output = part1 .. part2 .. part3 .. feature .. part4
	end
	return output
end
-----------function p.feature(str)
function p.feature(str,markercolor,markersymbol)
	local text = ""
	local lat = ""
	local long = ""
	local name = ""
	local image = ""
	local voysitename = ""
	local voysitename2 = ""
	local wiki = ""
	local xtraname = ""
	local part1 = ""
	local part2 = ""
	local part3 = ""
	local part4 = ""
	local part5 = ""
	local part6 = ""
	local part7 = ""
	local part8 = ""
	 -- Do check on str to insure its correct format and check to see if we get object or maybe do a test
	 -- using pcall
	 if string.match(str,"^[Qq]%d+$") == nil then return "" end -- str should be in a specific format 'Qnnn'

--	 if pcall(function () t = mw.wikibase.getEntityObject(str) end ) then
--	 local entity = mw.wikibase.getEntityObject(str)
--	 else return end

   	local entity = mw.wikibase.getEntityObject(str)

	if entity == nil then return "" end    		
	local claims = entity.claims
	if claims == nil then
		return ""
	end	
	if pcall(function () t = claims.P625 end) then
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
			lat = entity.claims.P625[1].mainsnak.datavalue.value.latitude
			end
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			
			long = entity.claims.P625[1].mainsnak.datavalue.value.longitude
			end	
		end
	if pcall(function () t = claims.P18 end) then
		if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then		
			image = entity.claims.P18[1].mainsnak.datavalue.value
			end
	end
	if lat == "" or long == "" then return "" end
			lat = string.format("%.6f",lat) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000
			long = string.format("%.6f",long) -- format number to 6 decimal places see above
			lat = string.gsub(lat,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1.
			long = string.gsub(long,"0+$","") -- string any number of ending zeroes - see above
			lat = string.gsub(lat,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1
			long = string.gsub(long,"%.$","") -- strip an ending period
	if image ~= "" then	
		image = str.gsub(image,'%"','\\"') -- Believe it or not there are image names with quotes
		                                -- this can be picked up as a redlinked image
		image = '[[File:' .. image .. '|280px|link=]]'		
--		image = '"[[File:' .. image .. '|280px|link=]]"'
	else
		if pcall(function () t = claims.P948 end) then
			if pcall(function () t = entity.claims.P948[1].mainsnak.datavalue.value end ) then		
				image = entity.claims.P948[1].mainsnak.datavalue.value
				image = '[[File:' .. image .. '|280px|link=]]'				
			end
		end
	end
	if image == "" then
		image = '[[File:Wikivoyage-Logo-v3-small-en.png|Wikivoyage|80px|link=]]<br>' -- [[File:WV-logo-artmap.jpg|120px]]
	end
	name = mw.wikibase.sitelink(str)
	if name == "" or name == nil then
		name = mw.wikibase.label(str) or ""
	end

	voysitename = ""
	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then
		voysitename = entity:getSitelink("enwikivoyage") or ""
		if voysitename ~= nil and voysitename ~= "" then
			name = "[[" .. voysitename  .."]]"
		end
	end

-- testing an idea can be removed if not wanted
	wiki = "enwiki"
	xtraname = ""
	xtraname = entity:getSitelink(wiki) or ""			-- If blank as is in many cases skip adding link to description

	description = mw.wikibase.description(entity.id)
	if description == "" or description == nil then
		description = ""
	end

if str.len(xtraname .. description) <= 15 then   -- arbitrary bending of the rules to make images in box nicer
	description = description .. ' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
end

	part1 = '\n\t' .. '{' .. '\n\t' .. '"type": "Feature",' .. '\n\t\t' .. '"properties": {'
if xtraname ~= "" then
    part2 = '\n\t\t\t' .. '"description": "'.. image .. ' ' .. name .. ' &mdash; (w:[[:w:' .. xtraname .. '|' .. xtraname .. ']])' .. ' ' .. description .. '",'
else
    part2 = '\n\t\t\t' .. '"description": "'.. image .. ' ' .. name .. ' &mdash;' .. ' ' .. description .. '",'
end

    part3 = '\n\t\t\t' .. '"title": "' .. name .. '",'
	part4 = '\n\t\t\t' .. markersymbol
    part5 = '\n\t\t\t' .. '"marker-size": "medium",'
    part6 = '\n\t\t\t' .. markercolor
    part7 = '\n\t\t' .. '},' .. '\n\t\t' .. '"geometry": {' .. '\n\t\t\t' .. '"type": "Point",' .. '\n\t\t\t' .. '"coordinates": ['
    part8 = '\n\t\t\t' .. long .. ',' .. '\n\t\t\t' .. lat .. '\n\t\t\t' .. ']' .. '\n\t\t'.. '}' .. '\n\t' .. '},'
    text = part1 .. part2 .. part3 .. part4 .. part5 .. part6 .. part7 .. part8
	return text
end
-- END Function

-- Make a marker --

function p.initmarker(frame)
--    if frame.args[1]~=nil and frame.args[1]~='' then
--        return frame.args[1]
--    end
	local arg1 = frame.args[1] or ''
	local arg2 = frame.args[2] or 'red'
    local entity = mw.wikibase.getEntityObject(arg1)
    if entity == nil then return end
	local claims = entity.claims
	if claims == nil then
		return
		end
	local listing = ""
	local type = arg2
	local name = ""
	local url = ""
	local latitude = ""
	local longitude = ""
	local image = ""
	local description = ""
	-- name
	name = mw.wikibase.sitelink(arg1)
	if name == "" or name == nil then
		name = mw.wikibase.label(arg1)
	end
	-- url
	if claims.P856 ~= nil then
		url = entity.claims.P856[1].mainsnak.datavalue.value
		url = string.gsub(url,"%,.*","") -- KEEP ONLY ONE
		if url == nil or url == "" then
			url = ""
		end
	end
	-- coordinates
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		if latitude == nil or latitude == "" then
			latitude = ""
			end
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		if longitude == nil or longitude == "" then
			longitude = ""
			end
	end
	-- image
	if claims.P18 ~= nil then
		image = entity.claims.P18[1].mainsnak.datavalue.value
		if image == nil then
			image = ""
			end
	end
	-- description
	description = mw.wikibase.description(entity.id)
	if description == "" or description == nil then
		description = ""
	end	

	marker = "{{marker\n| type=" .. type .. "\n| zoom=13\n| wikidata=" .. arg1 .. "\n| name=" .. name .. "\n| url=" .. url .. "\n| lat=" .. latitude .. "\n| long=" .. longitude.. "\n| image=" .. image .. "}} &mdash; " .. description	
	
	return marker

end

function p.initlisting(frame)
--    if frame.args[1]~=nil and frame.args[1]~='' then
--        return frame.args[1]
--    end
	local arg1 = frame.args[1] or ''
	local arg2 = frame.args[2] or 'see'
    local entity = mw.wikibase.getEntityObject(arg1)
    if entity == nil then return end
	local claims = entity.claims
	if claims == nil then
		return
		end
	local listing = ""
	local type = arg2
	local name = ""
	local alt = ""
	local url = ""
	local email =  ""
	local wiki = ""
	local name = ""
	local wikidata = arg1
	local wikiname = ""
	local address = ""
	local directions = ""
	local phone = ""
	local tollfree = ""
	local fax = ""
	local hours = ""
	local price = ""
	local checkin = ""
	local checkout = ""
	local latitude = ""
	local longitude = ""
	local image = ""
	local description = ""
	local lastedit = ""
	
	
	-- get wikipedia name
	lang = mw.language.getContentLanguage(arg1).code	
	wiki = lang .. "wiki"
	wikiname = entity:getSitelink(wiki) or ""
	-- name
	name = mw.wikibase.sitelink(arg1)
	if name == "" or name == nil then
		name = mw.wikibase.label(arg1)
	end
	-- url
	if claims.P856 ~= nil then
		url = entity.claims.P856[1].mainsnak.datavalue.value
		url = string.gsub(url,"%,.*","") -- KEEP ONLY ONE
		if url == nil or url == "" then
			url = ""
		end
	end
	-- coordinates
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		if latitude == nil or latitude == "" then
			latitude = ""
			end
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		if longitude == nil or longitude == "" then
			longitude = ""
			end
	end
	-- image
	if claims.P18 ~= nil then
		image = entity.claims.P18[1].mainsnak.datavalue.value
		if image == nil then
			image = ""
			end
	end
	-- description
	description = mw.wikibase.description(entity.id)
	if description == "" or description == nil then
		description = ""
	end	

	local part1 = "{{" .. type .. "\n| name=" .. name .. " | alt= " .. alt .. "| wikidata=" .. wikidata .. "| wikipedia=" .. wikiname
	local part2 = "\n| email=" .. email .. " | address=" .. address .. " | directions=" .. directions
	local part3 = "\n| phone=" .. phone .. " | tollfree=" .. tollfree .. " | fax=" .. fax
	local part4 = "\n| hours=" .. hours .. " | price=" .. price .. " | checkin=" .. checkin .. " | checkout=" .. checkout
	local part5 ="\n| url=" .. url .. "\n| lat=" .. latitude .. "\n| long=" .. longitude
	local part6 ="\n| image=" .. image .. "| content=" .. description .. "}}\n"
	
	listing = part1 .. part2 .. part3 .. part4 .. part5 .. part6

	return listing

end

function p.getwiki(frame)
	local wikip = ""
	local asitelink = ""
	local lang = ""
	local commons = ""
	local quotelink = ""
	local output = ""
	local arg1 = frame.args[1] or ""
	if arg1 == nil or arg1 == "" then return end
	local item = mw.wikibase.getEntityObject(arg1)
	if item == nil or item == "" then return end
	lang = mw.language.getContentLanguage(arg1).code
	if lang ~= nil and lang ~= "" then
		asitelink = lang .. "wiki"
		asitelink = item:getSitelink(asitelink)
		if asitelink ~= nil and asitelink ~= "" then
			asitelink = "[[w:" .. lang .. ":" .. asitelink .. "|W]] "
		end
		quotelink = lang .. "wikiquote"
		quotelink = item:getSitelink(quotelink)
		if quotelink ~= nil and quotelink ~= "" then
			quotelink = "[[q:" .. lang .. ":" .. quotelink .. "|Q]] "
		end
	end
	local claims = item.claims
	if claims ~= nil and claims ~= "" then
		commons = item.claims.P373[1].mainsnak.datavalue.value
		if commons ~= nil and commons ~= "" then
			commons = "[[c:" .. commons .. "|C]] "
			end
		end
	output = asitelink .. commons .. quotelink
	output = string.gsub(output,"%s+","")		-- just for cleaning up since outputting 3 variables as one
	output = string.gsub(output," $","")		-- getting rid of ending space
	return output
end


function p.tocheaders3(frame)
	
		local page = frame.args[1]

        local title = mw.title.new(page)
        if title == nil then return end

        if title.id == 0 then
            return "Page does not exist!"
        end

        local data = title:getContent()
if data == nil or data == "" then
	return
end


data = string.gsub(data,"\n","@@@@@")
data = string.gsub(data,"@@@@@@@@@@","@@@@@")
	local tt = {}
	local count = 0
	local output = "\n: [[" .. page .. "]]\n"

	local separator = "@@@@@"
	for str in string.gmatch(data,"([^"..separator.."]+)") do
		if str ~= nil and str ~= "" then
			 if string.find(str, '^%=') == 1 then			-- not just an ='s sign but one at beginning of line
				count = count + 1
				tt[count] = str
			end
		end
	end

	local part1 = ""
	local part2 = ""
	local part2a = ""

	for key,value in pairs(tt) do
		value = mw.text.unstrip(value)
		value = string.gsub(value,"%[","")
		value = string.gsub(value,"%]","")
		value = string.gsub(value,"^%s+","")   -- remove lead spaces
		value = string.gsub(value,"%=%s","%=")
		value = string.gsub(value,"%s+$"," ")  -- change multiple spaces to " "
		value = string.gsub(value,"%=+$","")   -- remove trailing =
		value = string.gsub(value,"%+$","")   -- remove trailing spaces
		value = string.gsub(value,"^%=%=%=%=%=%=","::::::")  -- change leading = to :
		value = string.gsub(value,"^%=%=%=%=%=",":::::")  -- change leading = to :
		value = string.gsub(value,"^%=%=%=%=","::::")  -- change leading = to :
		value = string.gsub(value,"^%=%=%=",":::")  -- change leading = to :
		value = string.gsub(value,"^%=%=","::")  -- change leading = to :
		value = string.gsub(value,"^%=",":")  -- change leading = to :
		part1 = string.gsub(value,"^(%:+)(.*)","%1")
		part2 = string.gsub(value,"^(%:+)(.*)","%2")
		if value ~= nil and value ~= "" then
			part2a = string.gsub(part2," ","_")
--			output = output .. part1 .. "[http://localhost/wiki/index.php/" .. page .. "#" .. part2a .. " " .. part2 .. "]\n"
			output = output .. part1 .. "[[" .. page .. "#" .. part2 .. "|" .. part2 .. "]]" .. "\n"
		end
	end
	return output
end

-- Load a page and scan it for images and produce a gallery

function p.getsomeimages(frame)
		local page = frame.args[1] or "Main Page"
		local flags = frame.args['flags'] or "n"
		if flags ~= "y" then flags = "n" end       -- Images from {{flag|name}} as in embassies -- y or n
        local title = mw.title.new(page)
        if title == nil then return end

        if title.id == 0 then
            return "Page does not exist!"
        end

        local data = title:getContent()
		
		if data == nil or data == "" then
			return
		end

		local tt = {}
		local count = 0
		local output = ""
		local separator = "@@@@@"
		local newstr = ""		
		
		local imagechecklist = {'jpg','JPG','jpeg','JPEG','jpe','JPE','png','PNG','apng','APNG','svg','SVG','TIF','tif','TIFF','tiff'}
		
		data = string.gsub(data,'%{%{%s*pagebanner%s*%}%}','') 				--get ride of {{pagebanner}}
		data = string.gsub(data,"@","BULLET")								--because I use @@@@@ as a separator changing @ to BULLET
		data = string.gsub(data,"%s+"," ")									--change multiple spaces to a space
		data = string.gsub(data,"\n","@@@@@")								--change \n to separator @@@@@
		data = string.gsub(data,'%s*%=%s*','=')								--get rid of spaces around = signs
--      special case regionmap image		
		data = string.gsub(data,'regionmap%s*%=%s*@@@@@',"")
		data = string.gsub(data,'regionmap%s*%=%s*','@@@@@[[File:')			--if regionmap then put separator @@@@@ plus [[File:

		-- to consider getting images from quickbar (flag,location)
		-- | flag = Flag of India.svg
		-- | location = LocationIndia.png {{quickbar| location=
		data = string.gsub(data,"flag%s*%=%s*@@@@@","")
		data = string.gsub(data,"flag%s%=%s*%|","")
		data = string.gsub(data,"flag%s*%=%s*","@@@@@[[File:")
		data = string.gsub(data,"location%s*%=%s*@@@@@","")
		data = string.gsub(data,"location%s*%=%s*%|","")
		data = string.gsub(data,"location%s*%=%s*","@@@@@[[File:")

		-- ie. {{pagebanner}} or {{pagebanner|TajMahal Banner.jpg|caption=Taj Mahal}}
		-- ie. {{pagebanner|pgname=aaaaaa|named banner.jpg}} etc will not work in this case figure out when going through for loop??
		data = string.gsub(data,'%{%{%s*pagebanner%s*','@@@@@PAGEBANNERFIX')

-- Issue with SPARQL code - test to see if can eliminate in checking
-- may need to refine further -- sample:(concat(?stateLabel, '\\n', '[[File:', substr(str(?img), 52, 100), '|200px]]') as ?description)
data = string.gsub(data,"%'%[%[File%:%'%,","SPARQL")
data = string.gsub(data,"%]%]%'%)","XSPARQL")
		--     area for flags as found in embassies? {{flag|Afghanistan}} -- make template break up with separator @@@@@
		data = string.gsub(data,'%{%{%s*flag%s*%|','@@@@@{{flag|')
		data = string.gsub(data,'%{%{%s*listing','@@@@@{{listing')
		
		-- try and get images from routebox - special set
		data = string.gsub(data,'%{%{%s*routebox','@@@@@{{routebox')
		data = string.gsub(data,'image...%s*%=%s*','image=')					--picks up image1= or image10= or image10a
		data = string.gsub(data,'image..%s%=%s*','image=')
		data = string.gsub(data,'image.%s*%=%s*','image=')

		-- also consider see,buy,drink,marker etc. as in listing above      -- drop empties
data = string.gsub(data,'image%=%}%}','')
		data = string.gsub(data,'image%=@@@@@','@@@@@')
		data = string.gsub(data,'%s*image%=%s*%|','')
		data = string.gsub(data,'image%s*%=%s*image%s*%=%s*','image=')		-- change image=image= to image=
		data = string.gsub(data,'image%s*%=%s*File%:%s*','image=WHAMMO')			-- change image=File: to image= (Sometimes File may be in another language
		data = string.gsub(data,'%s*image%=%s*@@@@@%|','')					-- more cleanup -- also other languages to consider
		data = string.gsub(data,'%s*image%=%s*@@@@@%}','')
--		data = string.gsub(data,'%s*image%=','@@@@@[[File:')				-- duplicate see below
		data = string.gsub(data,"%[%[%s*File:%s*","@@@@@[[File:")
		data = string.gsub(data,"%[%[%s*file:%s*","@@@@@[[File:")
		data = string.gsub(data,"%[%[%s*image:%s*","@@@@@[[File:")
		data = string.gsub(data,"%[%[%s*Image:%s*","@@@@@[[File:")
		data = string.gsub(data,'%s*image%=','@@@@@[[File:')		 -- simply setting up the breakup of data using separator
																	 -- Issue with names like Budapest districts WV map.svg 2.0.png
																	 
-- Single exception found to -- if many more then need to figure a way around this rather unique situation
		data = string.gsub(data,'Budapest districts WV map%.svg 2%.0.png',"Budapest districts WV map.DUMBFIX 2.0.png")

		data = string.gsub(data,'%.jpg','.jpg|border|250px]]@@@@@')  -- original prep for images remove |border|250px
		data = string.gsub(data,'%.JPG','.JPG|border|250px]]@@@@@')
		data = string.gsub(data,'%.PNG','.PNG|border|250px]]@@@@@')
		data = string.gsub(data,'%.png','.png|border|250px]]@@@@@')
		data = string.gsub(data,'%.SVG','.SVG|border|250px]]@@@@@')
		data = string.gsub(data,'%.svg','.svg|border|250px]]@@@@@')
		data = string.gsub(data,'%.jpeg','.jpeg|border|250px]]@@@@@')
		data = string.gsub(data,'%.JPEG','.JPEG|border|250px]]@@@@@')
		data = string.gsub(data,'%.tif','.tif|border|250px]]@@@@@')		-- add .tif image

-- return exception back to original
		data = string.gsub(data,'Budapest districts WV map%.DUMBFIX 2%.0.png',"Budapest districts WV map.svg 2.0.png")
		
		data = string.gsub(data,"@@@@@@@@@@","@@@@@")					-- getting rid of blank breakup
		data = string.gsub(data,"@@@@@@@@@@","@@@@@")

		for str in string.gmatch(data,"([^"..separator.."]+)") do

			if str ~= nil and str ~= "" then
				if string.find(str,'PAGEBANNERFIX') ~= nil then			--  caption=sometext pgname=sometext diasambig=yes star=yes dotm=yes otb=yes ftt=yes unesco=yes
																		--  toc=black or white notoc=true index=yes fop=yes -- remove to gettheimage????
					str = string.gsub(str,'%|%a*%=','DELETEME=')
					newstr = ""
					if string.find(str,'DELETEME') ~= nil then
						for str2 in string.gmatch(str,"([^".."|".."]+)") do
							str2 = string.gsub(str2,'DELETEME.*',"")
							if str2 ~= nil then
								newstr = newstr .. "|" .. str2
								end
						end
					str = string.gsub(newstr,'%|PAGEBANNERFIX%|','[[File:')
						end	
					str = string.gsub(str,'PAGEBANNERFIX%|','[[File:') 

				end				
				
				str = string.gsub(str,'%s*$','')       					-- drop ending space
				str = string.gsub(str,'File:%s*%}%}','') 				-- JUNKY FIX NEED SOLUTION TO A DISTINCT UNIQ ISSUE
				if string.find(str,'^%{%{flag%|.*%}%}') == 1 then
					str = string.gsub(str,'%{%{flag%s*%|%s*(.*)%}%}.*',"[[File:Flag of %1.svg]]") -- template puts in "the"
    				if flags=="n" then str = "" end
					end
					if string.find(str, '^%[%[File:') == 1 then			-- Key is to have [[File:image...]]
					    str = string.gsub(str,'%_'," ")
						str = string.gsub(str,'%%2C',",")
					    count = count + 1
						tt[count] = str
						end
				end
		end

		table.sort(tt)

					-- BUILD A GALLERY OF PICTURES
		local check = ""
		local previous = ""
		local galleryfile = ""
		for key,value in pairs(tt) do
			if value ~= previous then
				-- Check if ^[[File:.*%.jpg or JPG or jpg or jpeg or JPEG or PNG or png or SVG or svg or tif]]$
				for i,checker in ipairs(imagechecklist) do
					check = "^%[%[File:.*" .. checker .. "%]%]$"
					if string.gmatch(value,check) then
						galleryfile=value
						galleryfile=string.gsub(galleryfile,'%[%[File:%s*','File:')
						galleryfile=string.gsub(galleryfile,'%|.*$','')
						galleryfile=string.gsub(galleryfile,'%]%]','')
-- Special case image=WHAMMO as image=File:somename is an error - in order to pick it up easier using this as test in gallery output
-- instead of outputting File:somename which will work - just output name
galleryfile=string.gsub(galleryfile,'WHAMMO','image=File:')
-- Special case as well image name surrounded by \" -- have to change to "somename" - \" needed for maplink/mapframe - kartographer
-- only dealing with one such known case - if more develop then will just replace \\" with"
galleryfile=string.gsub(galleryfile,'\\"kirti mandir\\".jpg','"kirti mandir".jpg')

						output = output .. galleryfile .. "\n"
						break
						end
					end
					previous = value
			end
		end		
		output = string.gsub(output,"\n$","")
		output = string.gsub(output,"BULLET","@")		
--  return '<gallery mode="packed">\n' .. output .. "\n</gallery>"
	return '<gallery  widths=150px heights=150px perrow=6>\n' .. output .. "\n</gallery>"
end



local function latitude(wikidata)
	local latitude = ""
    local entity = mw.wikibase.getEntityObject(wikidata)	
	if entity == nil then return latitude end    		
	local claims = entity.claims
	if claims == nil then
		return latitude
	end	
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		return latitude
	end
	return latitude
end

--  GET LONGITUDE -- P625

local function longitude(wikidata)
	local longitude = ""
    local entity = mw.wikibase.getEntityObject(wikidata)	
	if entity == nil then return longitude end    		
	local claims = entity.claims
	if claims == nil then
		return longitude
	end	
	if claims.P625 ~= nil then
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		return longitude
	end
	return longitude
end


function p.games(frame)
local data = frame.args[1]
local wikidata = ""
local lat = ""
local long = ""
local lang = ""
local wiki = ""
local wikipedia = ""

data = string.gsub(data,'\n','@@@@@NEWLINE')
data = string.gsub(data,'%s*%|%s*','@@@@@')
data = string.gsub(data,'%s*%=%s*','=')
data = string.gsub(data,'%}%}','@@@@@}}')

if string.find(data,'.*wikidata%=Q%d+.*') == 1 then
		wikidata = string.gsub(data,'.*@@@@@wikidata%=(Q%d+).*',"%1")
   		local entity = mw.wikibase.getEntityObject(wikidata)
   		if entity ~= nil then 
   			lang = mw.language.getContentLanguage(wikidata).code	
    		wiki = lang .. "wiki"
    		wikipedia = entity:getSitelink(wiki) or ""		
			lat = latitude(wikidata) or ""
			long = longitude(wikidata) or ""
		end

if string.find(data,'wikipedia%=') == nil and wikipedia ~= " " then
data = string.gsub(data,'}}','@@@@@wikipedia%='..wikipedia..'}}')
else
data = string.gsub(data,'wikipedia%=@@@@@','wikipedia%='..wikipedia..'@@@@@')
end


		if string.find(data,'lat%s*%=%s*%d') == nil and lat ~= "" then -- check for lat=n and long=n
			data = string.gsub(data,'lat%=','lat='..lat)
		end
		if string.find(data,'lat%=') == nil and lat ~= "" then			-- no lat= something then add parameter
			data = string.gsub(data,'}}','@@@@@lat='..lat..'}}')
		end
		if string.find(data,'long%s*%=%s*%d') == nil and long ~= "" then		
			data = string.gsub(data,'long%=','long='..long)
		end
		if string.find(data,'long%=') == nil and long ~= "" then		-- no long then add parameter
			data = string.gsub(data,'}}','@@@@@long='..long..'}}')
		end
end
		data = string.gsub(data,'@@@@@@@@@@','@@@@@')
		data = string.gsub(data,'@@@@@}}','}}')
		data = string.gsub(data,'NEWLINE@@@@@','\n| ')
		data = string.gsub(data,'@@@@@NEWLINE','\n')
		data = string.gsub(data,'@@@@@',' | ')
		data = string.gsub(data,'NEWLINE','\n')
return data

end

function p.games2(frame)
	local list = frame.args['list'] or ""
	local data = ""
	local separator = ","
	local name = ""
	if list ~= nil and list ~= "" then
		list = string.gsub(list,"%s","")
	else
		return ""
	end
	
	local index = 1
	local items = {}
	local flags = {}

	for str in string.gmatch(list,"([^"..separator.."]+)") do
		items[index] = str
		index = index + 1
		end
		
	for i=1,#items do
		if not flags[items[i]] then
			flags[items[i]] = true
			name = ""
			name = mw.wikibase.sitelink(items[i])
	       if name == "" or name == nil then
	        	name = mw.wikibase.label(items[i]) or ""
			end
			data = data .. items[i] .. " - " .. name .. "XNEWLINEX"
		end
	end
data = string.gsub(data,'XNEWLINEX','</br>')
return data

end

--* {{see
--| name=Akhaura Checkpost | alt= | url= | email=
--| address= | lat=23.838611 | long=91.254444 | directions=
--| phone= | tollfree= | fax=
--| hours= | price=
--| content=It handles the largest number of visitors to and from neighbouring Bangladesh.
--}}
-- dont forget to include a mapframe for the maplinks to work on
-- <mapframe latitude="24.3" longitude="74.4" zoom="5" width="400" height="400" group="locations" show="see,do,buy,eat,drink,sleep,go,site,other"/>

--
local function loadchecklist()
	local checklist = {'see','do','buy','eat','drink','sleep','city','vicinity','go','site','around','other','gold','lime','magenta','mediumaquamarine','orange','plum','red','silver','unknown'}	
 
    return checklist
end 

local function loadcolors()
	local colors = {}		-- table of colors much of which can be used in marker or listings - based on type
	colors['see'] = "#4682B4"
	colors['do'] = "#808080"	
	colors['buy'] = "#008080"	
	colors['eat'] = "#D2691E"
	colors['drink'] = "#000000"	
	colors['sleep'] = "#000080"
-- made extras as people tend to mix marker stuff with listing stuff
	colors['city'] = "#0000FF"
	colors['vicinity'] = "#800000"
	colors['go'] = "#A52A2A"
	colors['view'] = "#4169E1"
	colors['site'] = "#CD2626"
	colors['around'] = "800080"
	colors['other'] = "#228B22"
-- by color
	colors['gold'] = "#FFD700"
	colors['lime'] = "#00FF00"
	colors['magenta'] = "#FF00FF"
	colors['mediumaquamarine'] = "#66CDAA"
	colors['orange'] = "#FFA500"
	colors['plum'] = "#DDA0DD"
	colors['red'] = "#FF0000"
	colors['silver'] = "#C0C0C0"
	colors['unknown'] = "#FF00FF"
    return colors	
	end
	
-- can also create symbols if we dont want to number them which I like better
-- right now limited symbols - use of numbers greater -- Maki symbols not available
local function loadsymbols()
	local symbols = {}
	symbols['see'] = "star"
	symbols['do'] = "marker"	
	symbols['buy'] = "shop"	
	symbols['eat'] = "restaurant"
	symbols['drink'] = "bar"	
	symbols['sleep'] = "lodging"
-- made extras as people tend to mix marker stuff with listing stuff
	symbols['city'] = "city"
	symbols['vicinity'] = "town"
	symbols['go'] = "suitcase"
	symbols['site'] = "monument"	
	symbols['other'] = "triangle"
	return symbols
end
local function imagex(id)
	local id = id
	local image = ""
    local entity = mw.wikibase.getEntityObject(id)	
	if entity == nil then return "" end 
	local claims = entity.claims
	if claims == nil then
		return image
	end		
	if pcall(function () t = claims.P18 end) then
		if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then		
			image = entity.claims.P18[1].mainsnak.datavalue.value
			return image
			end
	end
	return image
end	

-- getting lat long via passing an ID
local function latitudex(id)
	local latitude = ""
	local arg1 = id
    local entity = mw.wikibase.getEntityObject(arg1)	
	if entity == nil then return latitude end    		
	local claims = entity.claims
	if claims == nil then
		return latitude
	end	
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		return latitude
	end
	return latitude
end

--  GET LONGITUDE -- P625

local function longitudex(id)

	local longitude = ""
	local arg1 = id
    local entity = mw.wikibase.getEntityObject(arg1)	
	if entity == nil then return longitude end    		
	local claims = entity.claims
	if claims == nil then
		return longitude
	end	
	if claims.P625 ~= nil then
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		return longitude
	end
	return longitude
end

function p.list2maplink(frame)

    -- checklist has args for main listings but also those found in marker and sometimes used in listing templates
	local data = frame.args[1] or ""
	if data == "" then return data end

	local msymbol = frame.args['symbol'] or "n"     -- symbol=y then use from symbols table else use '-number'
	local separator = "@@@@@"
	local newdata = ""
	local color = ""
	local symbol = ""
	local group = ""
	local wikidata = ""
	local image = ""
	local latitude = ""
	local longitude = ""
	local content = ""
	local name = ""
	local lang = ""
	local wikipedia = ""
	local url = ""
	local counter = ""
	local checklist = loadchecklist()	
	local colors = loadcolors()
	local symbols = loadsymbols()

	data = string.gsub(data,"%@","BULLET")
	data = string.gsub(data,"%s*%|\n","|")
	data = string.gsub(data,"\n%s*%}%}","}}")
	data = string.gsub(data,"%s*%|%s*","|")
	data = string.gsub(data,"\n","@@@@@")
	for i,checker in ipairs(checklist) do
		data = string.gsub(data,"%{%{%s*"..checker,"{{listing|type="..checker)
	end
    data = string.gsub(data,"%{%{%s*listing%|name%=",'{{listing|type=other|name=')
    data = string.gsub(data,"%{%{%s*listing%|image%=",'{{listing|type=other|image=')   
--if data ~= "" then return data end
data = string.gsub(data,'%{%{listing','@@@@@{{listing')
	for str in string.gmatch(data,"([^"..separator.."]+)") do
		if string.find(str,'%{%{listing') == 1 then
			str = string.gsub(str,'%}%}$','|}}')
			str = string.gsub(str,'image%=%|','')
			str = string.gsub(str,'name%=%|','')
			str = string.gsub(str,'content%=%|','')
			str = string.gsub(str,'lat%=%|','')
			str = string.gsub(str,'long%=%|','')
			str = string.gsub(str,'url%=%|','') 
			str = string.gsub(str,'wikipedia%=%|','')

-- I parameter counter= is empty then its a simple -number if counter=aaaa then its a -number-aaaa
if string.find(str,'counter%=%|') then
	counter = "-number"
else
	if string.find(str,'counter%=%|') then
		counter = string.gsub(str,'^.*counter%=','')
		counter = string.gsub(counter,'%|.*','')
	    counter = "-number-" .. counter
-- alpha letters if counter=letter -- special case only - made up --- what about alpha groups (type)
	    if string.find(counter,'%-number%-letter') then
	    	counter = "-letter"
	    end
	 else
	 	counter = ""
	 end
end
			if string.find(str,'name%=')  then
				name = string.gsub(str,'^.*name%=','')
				name = string.gsub(name,'%|.*','')
			else
				name = ""
			end
			if string.find(str,'wikipedia%=') then
				wikipedia = string.gsub(str,'^.*wikipedia%=','')
				wikipedia = string.gsub(wikipedia,'%|.*','')
				wikipedia = " [[w:enwiki:" .. wikipedia .."|" .. wikipedia .. "]]"
			end
			if string.find(str,'image%=')  then
--	xxx			image = string.gsub(str,'^.*image%=','')
image = string.gsub(str,'^.*%|image%=','')
				image = string.gsub(image,'%|.*','')
--	xxx			image = '[[File:' .. image .. '|280px|link=]]' -- should not be necessary
image = '[[File:' .. image .. '|280px|link=]]' -- should not be necessary
			else
				image = ""
			end	
			if string.find(str,'lat%=') then
				latitude = string.gsub(str,'^.*lat%=','')
				latitude = string.gsub(latitude,'%|.*','')
			else
				latitude = ""
				end						
			if string.find(str,'long%=') then
				longitude = string.gsub(str,'^.*long%=','')
				longitude = string.gsub(longitude,'%|.*','')
			else
				longitude = ""
			end
			if string.find(str,'wikidata%=') then	-- If wikidata and lat long ='s "" then get lat long from wikidata		
				wikidata = string.gsub(str,'^.*wikidata%=','')
				wikidata = string.gsub(wikidata,'%|.*','')
if string.match(wikidata,"^[Qq]%d+$") ~= nil then
-- if string.match(arg1,"^[Qq]%d+$") ~= nil then
					if latitude == "" then
						latitude = latitudex(wikidata)
					end
					if longitude == "" then
						longitude  = longitudex(wikidata)
					end
				end
			else
				wikidata = ""
			end

			if string.find(str,'content%=') then
				content = string.gsub(str,'^.*content%=','')
				content = string.gsub(content,'%|.*','')
-- issue with double quotes as they will cause a JSON error - below should fix it list of others may be incorporated
-- xxx				content = string.gsub(content,'%"','\"')
				content = string.gsub(content,'%"','\\"')

-- a blank image not needed as code has been fixed to handle how text comes out when
-- one clicks on the marker -- this was precautionary
--
--				if image == "" then 
--					image = "[[File:3by2white.svg|280px 1px|link=]]"
--					content = string.gsub(content,'^%s*','')
--				end
			else
				content = ""
			end
			
			if string.find(str,'url%=') then
				url = string.gsub(str,'^.*url%=','')
				url = string.gsub(url,'%|.*','')
				url = "[" .. url .. " &nbsp;]"
			else
				url = ""
				end
-- NOT MAKING A DEFAULT OF lat 0 and long 0 as this would bunch up a load of maplinks somewhere in Africa
-- Have to have latitude and longitude to create a maplink
-- or dropping creation of maplink from a listing
			if latitude ~= "" and longitude ~= "" then
				group = string.gsub(str,".*type%=(%a+)(%|.*)","%1")
				if colors[group] == nil then     -- solves two issues - if bad group then it becomes other and we get a color for it
					group = "other"
				end
				color = colors[group]
				if msymbol == "y" then			-- use a symbol from table for certain group (small list) for on a map
					symbol = symbols[group]		-- no numbers alpha or symbols appear on article page - dealing with maplinks not listing output
				else
					if counter ~= "" then		-- if counter= numbered on page then numbered on map instead - symbols are out????
						symbol = counter
						if counter == "-letter" then
							symbol = "-letter" .. "-" .. group
							end
						else
						symbol = "-number" .. "-" .. group
                	end
				end

			newdata = newdata .. '\n<maplink class="no-icon" zoom="5" text="" latitude="' .. latitude .. '" longitude="' .. longitude .. '" group="' .. group .. '">'
			newdata = newdata .. '\n{\n\t"type": "Feature",\n\t"geometry": { "type":"Point", "coordinates":[' .. longitude .. ',' .. latitude ..  '] },'
			newdata = newdata .. '\n\t"properties": {\n\t "title": "' .. name .. '",\n'
--	newdata = newdata .. '\t"description": "' .. image .. content .. url .. '",\n'
			newdata = newdata .. '\t"description": "' .. image .. name .. url .. "&mdash; " .. wikipedia .. " " .. content .. '",\n'			
			newdata = newdata .. '\t"marker-size": "medium",\n'
			newdata = newdata .. '\t"marker-color": "' .. color .. '",\n'
			newdata = newdata .. '\t"marker-symbol": "' .. symbol  .. '"\n'
			newdata = newdata .. '}\n}\n</maplink>'
			end
		end
	end
		
		newdata = string.gsub(newdata,"BULLET","@") -- return orignal input plus maplink(s)
		return frame.args[1] .. "\n" .. newdata

end

--* {{marker|type=vicinity|zoom=13
--| name=Mollem National Park
--| lat=15.33390 | long=74.28835
--| image=
--}} (Bhagwan Mahaveer Sanctuary and Mollem National Park), [[Goa]] &mdash; a pristine area diverse in flowering plant life and vegetation is habitat for many mammals, birds, butterflies and reptiles. The largest protected area in [[Goa]]. One can also find the ''Tambdi Surla Temple'', ''Tambdi Falls'' and other attractions here
-- In progress

function p.marker2maplink(frame)
	local checklist = loadchecklist()
	local colors = loadcolors()
	local symbols = loadsymbols()
	local data = frame.args[1] or ""
	if data == "" then return data end
	local msymbol = frame.args['symbol'] or "n"     -- symbol=y then use from symbols table else use '-number'
	local separator = "@@@@@"
	local newdata = ""
	local color = ""
	local symbol = ""
	local group = ""
    local type = ""
	local name = ""
	local latitude = ""
	local longitude = ""
	local zoom = ""
	local url = ""
	local image = ""
    local wikidata = ""
    local content = ""
    local url = ""
    local counter = ""
    
  	data = string.gsub(data,"%@","BULLET")
	data = string.gsub(data,"%s*%|\n","|")
	data = string.gsub(data,"\n%s*%}%}","}}")
	data = string.gsub(data,"%s*%|%s*","|")
	data = string.gsub(data,"\n","@@@@@")  -- not to mess with &mdash; and text for now
	
	data = string.gsub(data,'%{%{marker','@@@@@{{marker')
	for str in string.gmatch(data,"([^"..separator.."]+)") do
		if string.find(str,'%{%{marker') == 1 then
           if string.find(str,'%{%{%|type=') == nil then
           	str = string.gsub(str,'%{%{marker','{{marker|type=other') -- make default type
           end
           str = string.gsub(str,'%}%}',"|}}")						  -- get end of marker add | to be able to pick out the pieces
           str = string.gsub(str,'%s*%=%s*',"=")
			str = string.gsub(str,'image%=%|','')
			str = string.gsub(str,'name%=%|','')
			str = string.gsub(str,'lat%=%|','')
			str = string.gsub(str,'long%=%|','')
            str = string.gsub(str,'url%=%|','')

			if string.find(str,'name%=') then
				name = string.gsub(str,'^.*name%=','')
				name = string.gsub(name,'%|.*','')
			else
				name = ""
			end	
			if string.find(str,'image%=')  then
				image = string.gsub(str,'^.*image%=','')
				image = string.gsub(image,'%|.*','')
				image = '[[File:' .. image .. '|280px|link=]]'
			else
				image = ""
			end

			if string.find(str,'lat%=') then
				latitude = string.gsub(str,'^.*lat%=','')
				latitude = string.gsub(latitude,'%|.*','')
			else
				latitude = ""
				end						
			if string.find(str,'long%=') then
				longitude = string.gsub(str,'^.*long%=','')
				longitude = string.gsub(longitude,'%|.*','')
			else
				longitude = ""
			end
			content = string.gsub(str,'^.*%}%}','')  -- last ditch attempt at content field for a marker - can be tricky - depends what text entered
            content = string.gsub(content," &mdash; ","")
content = string.gsub(content,'%[%[File.*$','')          -- some have an image in content which won't work
			content = string.gsub(content,'%"','\"')
--			if image == "" then 
--				image = "[[File:3by2white.svg|280px 1px|link=]]"
--				content = string.gsub(content,'^%s*','')
--			end
			if string.find(str,'wikidata%=') then	-- If wikidata and lat long ='s "" then get lat long from wikidata		
				wikidata = string.gsub(str,'^.*wikidata%=','')
				wikidata = string.gsub(wikidata,'%|.*','')
				if string.match(wikidata,"^[Qq]%d+$") ~= nil then				
					if latitude == "" then
						latitude = latitudex(wikidata)
					end
					if longitude == "" then
						longitude  = longitudex(wikidata)
					end
					if image == nil or image == "" then
				        image = imagex(wikidata)
				        if image ~= "" then
				            image = '[[File:' .. image .. '|280px|link=]]'
				          else
					        image = ""
			              end
			        end
				end
			else
				wikidata = ""
			end
			if string.find(str,'url%=') then
				url = string.gsub(str,'^.*url%=','')
				url = string.gsub(url,'%|.*','')
				url = "[" .. url .. " &nbsp;]"
			else
				url = ""
			end
if string.find(str,'counter%=%|') then
	counter = "-number"
else
	if string.find(str,'counter%=%') then
		counter = string.gsub(str,'^.*counter%=','')
		counter = string.gsub(counter,'%|.*','')
	    counter = "-number-" .. counter					-- in case counter has a name
-- alpha letters if counter=letter -- special case only - made up --- what about alpha groups (type)
	    if string.find(counter,'%-number%-letter') then
	    	counter = "-letter"
	    end
	 else
	 	counter = ""
	 end
end

 			if latitude ~= "" and longitude ~= "" then
				group = string.gsub(str,".*type%=(%a+)(%|.*)","%1")
				if colors[group] == nil then     -- solves two issues - if bad group then it becomes other and we get a color for it
					group = "other"
				end
				color = colors[group]
				if msymbol == "y" then
					symbol = symbols[group]
				else
if counter == "-letter" then
	symbol = "-letter" .. "-" .. group
end
					symbol = "-number" .. "-" .. group
				end
-- If counter parameter then it is all numbered either with -number or -number-xxxx
-- Color is retained for the type or group

if counter ~= "" and counter ~= nil then
symbol = counter
end
			newdata = newdata .. '\n<maplink class="icon" zoom="5" text="' .. name .. '" latitude="' .. latitude .. '" longitude="' .. longitude .. '" group="' .. group .. '">'
--			newdata = newdata .. '\n<maplink class="no-icon" zoom="5" text="" latitude="' .. latitude .. '" longitude="' .. longitude .. '" group="' .. group .. '">'
			newdata = newdata .. '\n{\n\t"type": "Feature",\n\t"geometry": { "type":"Point", "coordinates":[' .. longitude .. ',' .. latitude ..  '] },'
			newdata = newdata .. '\n\t"properties": {\n\t "title": "' .. name .. '",\n'
			newdata = newdata .. '\t"description": "' .. image .. content .. url .. '",\n'
			newdata = newdata .. '\t"marker-size": "medium",\n'
			newdata = newdata .. '\t"marker-color": "' .. color .. '",\n'
			newdata = newdata .. '\t"marker-symbol": "' .. symbol  .. '"\n'
			newdata = newdata .. '}\n}\n</maplink> ' .. content
			end         
			
			
		end
	end
  
	return frame.args[1] .. "\n" .. newdata
	
end

function p.pagesincategory(frame)
	local arg1 = frame.args[1]
    local entity = mw.wikibase.getEntityObject(arg1)
    if entity == nil then return end
    	local name=mw.wikibase.sitelink(entity.id)
		return '{{#categorytree:' .. name .. '|hideroot|namespaces="-"}}'
end

function p.wikidataids(frame)

	local separator = ","
	local wikidatax = ""
	local list = frame.args['list'] or ""
	if list ~= nil and list ~= "" then
		list = string.gsub(list,"%s","")
	end
	local index = 1
	local items = {}
	local flags = {}

	for str in string.gmatch(list,"([^"..separator.."]+)") do
		items[index] = str
		index = index + 1
		end
		
	for i=1,#items do
		if not flags[items[i]] then
			flags[items[i]] = true
		wikidatax = wikidatax .. p.getwikidatax(items[i])
		end
	end
	
	return "{|border=1\n" .. "! ID !! name !! countryID !! admin || lat !! long !! image !! wikipedia || wikivoyage !! Description \n|-\n" ..  wikidatax .. "|}"

end
	
function p.getwikidatax(str)
	local id = ""
	local name = ""
	local country = ""
	local lat = ""
	local long = ""
	local image = ""
	local wikiname = ""
	local voysitename = ""
	local description = ""
	local lang = ""
	local admin = ""
	
	if string.match(str,"^[Qq]%d+$") == nil then return "" end
   	local entity = mw.wikibase.getEntityObject(str)

	if entity == nil then return "" end    		
	local claims = entity.claims
	if claims == nil then
		return ""
	end	

	id = str
	
	name = mw.wikibase.sitelink(str)
	if name == "" or name == nil then
		name = mw.wikibase.label(str) or ""
	end	

if pcall(function () t = entity.claims.P17[1].mainsnak.datavalue.value end) then
	for k, v in pairs( entity.claims.P17[1].mainsnak.datavalue.value ) do
		if k == "numeric-id" then
			country = country .. "Q" .. v
		end
	end

    if country ~= "" then country = "[[D:" .. country .. "|" .. country .. "]] - " .. mw.wikibase.label(country) end
end

	if pcall(function () t = claims.P625 end) then
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
			lat = entity.claims.P625[1].mainsnak.datavalue.value.latitude
			end
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			
			long = entity.claims.P625[1].mainsnak.datavalue.value.longitude
			end	
	end
	
		if lat ~= "" and lat ~= nil and long ~= "" and long ~= nil then
			lat = string.format("%.6f",lat) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000
			long = string.format("%.6f",long) -- format number to 6 decimal places see above
			lat = string.gsub(lat,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1.
			long = string.gsub(long,"0+$","") -- string any number of ending zeroes - see above
			late = string.gsub(lat,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1
			long = string.gsub(long,"%.$","") -- strip an ending period
		end
		
	if pcall(function () t = claims.P18 end) then
		if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then		
			image = entity.claims.P18[1].mainsnak.datavalue.value
			end
	end

-- Keeping only 1st value for administrative entity

	if pcall(function () t = claims.P131 end) then
		local t = {}
		if pcall(function () t = entity.claims.P131[1].mainsnak.datavalue.value end ) then		
			t = entity.claims.P131[1].mainsnak.datavalue.value
			for k, v in pairs( t ) do
				admin = v
				if not mw.wikibase.label(admin) then admin = "" break end
				if admin ~= "" and admin ~= nil then
					admin = "[[D:" .. admin .. "|" .. admin  .. "]] - " .. mw.wikibase.label(admin)
					break end
			end
			end
	end
	
	lang = mw.language.getContentLanguage(str).code	or "en"
	local wiki = lang .. "wiki"
	local wikiname = entity:getSitelink(wiki) or ""
	if wikiname ~= "" and wikiname ~= nil then
		wikiname = "[[w:" .. lang .. ":" .. wikiname .. "|" .. wikiname .. "]]"
		end

	description = mw.wikibase.description(entity.id)
	
	if description == "" or description == nil then
		description = ""
	end	
	
	voysitename = ""
	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then
		voysitename = entity:getSitelink("enwikivoyage") or ""
		if voysitename ~= nil and voysitename ~= "" then
			voysitename = "[[" .. voysitename  .."]]"
		end
	end	

if id ~= "" and id ~= nil then
	id = "[[D:" .. id .. "|" .. id .. "]]"
end

	return "\n| " .. id .. " || " .. name .. " || " .. country .. " || " .. admin .. " || " .. lat .. " || " .. long .. " || " .. image .. " || " .. wikiname .. " || " .. voysitename .. " || " .. description .. "\n|-\n"
	
end

-- Create basic initial listings to work on in editor - can add more later
-- Not all parameters are filled just the basic ones

function p.wikidatalistings(frame)

	local separator = ","
	local wikidatax = ""
	local counter = 0
	local interim = ""
	local list = frame.args['list'] or ""
	local listingtype = frame.args['type'] or "see"
	if list ~= nil and list ~= "" then
		list = string.gsub(list,"%s","")
	end
	local index = 1
	local items = {}
	local flags = {}

	for str in string.gmatch(list,"([^"..separator.."]+)") do
		items[index] = str
		index = index + 1
		end
		
	for i=1,#items do
		if not flags[items[i]] then
			flags[items[i]] = true
interim = p.getwikidataxlistings(items[i],listingtype)
if interim ~= "" then wikidatax = wikidatax .. interim end --- For future use as numbers only go to 99 
counter = counter + 1									   --- May want to change listing type or color
--		wikidatax = wikidatax .. p.getwikidataxlistings(items[i],listingtype)
		end
	end
	
	return wikidatax

end
	

function p.getwikidataxlistings(str,listingtype)
--	local alt = ""
--	local email =  ""
--	local address = ""
--	local directions = ""
--	local phone = ""
--	local tollfree = ""		-- THESE PARAMETERS ARE NOT INCLUDED IN MAKING INITIAL BASIC LISTING
--	local fax = ""
--	local hours = ""
--	local price = ""
--	local checkin = ""
--	local lastedit = ""
							-- THESE PARAMETERS ARE INCLUDED	
	local id = ""
	local name = ""
	local url = ""
	local country = ""
	local lat = ""
	local long = ""
	local image = ""
	local wikiname = ""
	local voysitename = ""
	local description = ""
	local wiki = ""
	local lang = ""
	
-- This is to allow this one function to be called separately from a list
	if type(str) == "table" then str = str.args[1] end
	local listingtype = listingtype or "see"
	if string.match(str,"^[Qq]%d+$") == nil then return "" end
   	local entity = mw.wikibase.getEntityObject(str)

	if entity == nil then return "" end    		
	local claims = entity.claims
	if claims == nil then
		return ""
	end	

	id = str
	
	name = mw.wikibase.sitelink(str)
	if name == "" or name == nil then
		name = mw.wikibase.label(str) or ""
	end	
	if claims.P856 ~= nil then
		url = entity.claims.P856[1].mainsnak.datavalue.value
		url = string.gsub(url,"%,.*","") -- KEEP ONLY ONE
	end
		
	if pcall(function () t = claims.P625 end) then
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
			lat = entity.claims.P625[1].mainsnak.datavalue.value.latitude
			end
		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			
			long = entity.claims.P625[1].mainsnak.datavalue.value.longitude
			end	
	end
-- format lat and long	
			if lat ~= "" and lat ~= nil and long ~= "" and long ~= nil then
			lat = string.format("%.6f",lat) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000
			long = string.format("%.6f",long) -- format number to 6 decimal places see above
			lat = string.gsub(lat,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1.
			long = string.gsub(long,"0+$","") -- string any number of ending zeroes - see above
			late = string.gsub(lat,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1
			long = string.gsub(long,"%.$","") -- strip an ending period
		end
		
	if pcall(function () t = claims.P18 end) then
		if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then		
			image = entity.claims.P18[1].mainsnak.datavalue.value
			end
	end

    lang = mw.language.getContentLanguage(arg1).code	
	wiki = lang .. "wiki"
	wikiname = entity:getSitelink(wiki) or ""

	description = mw.wikibase.description(entity.id)
	
	if description == "" or description == nil then
		description = ""
	end	
	
	voysitename = ""
	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then
		voysitename = entity:getSitelink("enwikivoyage") or ""
		end

if voysitename ~= "" and voysitename ~= nil then
	name = "[[" .. voysitename .. "|" .. name .. ']]'
end

	return '\n* {{listing|type=' .. listingtype .. '|name=' .. name .. '|url=' .. url .. '|wikidata=' .. id .. '|wikipedia=' .. wikiname .. '|image=' .. image .. '|lat=' .. lat .. '|long=' .. long .. '|content=' .. description .. '}}'	
	
end



-- gpxmaplink function
-- {{safesubst:#invoke:Gpx|gpxmaplink|Test100|maplink=no|lat=65|long=102}}
-- This module produces <maplinks> - considering argument to produce a <mapframe> will all contained as one <mapframe>
-- Will create a maplink for each segment from a GPX file - will do up to 10 segments only.
--      Most GPX template files contain at most 1-4 - a few have more.
--      Single set of coordinates will produce a marker "Point" multiple coordinates will produce "LineString"
-- colors are random -- all Points are the same color #ff33f3 whereas Lines are random
--      can edit results as you see fit
-- Arguments:
-- "maplink=no" produces group segment of GPX coordinates only - default is "yes" is arg is missing
--     and this will create Maplinks
-- "lat=nnnn" - latitude otherwise a default is used (middle of Atlantic Ocean)
-- "long=nnnn" - longitude otherwise default is used (middle of Atlantic Ocean)
-- "set=n" or "set=all" = which group you want out of the track segments - 1 - 10 or all - all is default
-- "info=" 'before or after' - some input files have <name> and <desc> after <trkseg> others after
--      look at GPX file 1st then go ahead and add this arg. -- default is "before"


function one(xdata,part1,part2,part1a,part2a,name,description,color)
	name = string.gsub(name,'^.*<name>','')
	name = string.gsub(name,'</name>.*$','')
	description = string.gsub(description,'^.*<desc>','')
	description = string.gsub(description,'</desc>.*$','')
	if xdata ~= "" then
		local _, commacount = string.gsub(xdata, '%,', '')
		if commacount > 2 then
			xdata = '[' .. xdata
			xdata = string.gsub(xdata,'^$s+','')
			xdata = string.gsub(xdata,'],$',']],')
			xdata = part1 .. xdata .. part2
			xdata = string.gsub(xdata,'#00e500',color)

		else
			xdata = string.gsub(xdata,',$','')
			xdata = string.gsub(xdata,'^$s+','')
			xdata = part1a .. xdata .. part2a
		end
			xdata = string.gsub(xdata,'"title": ""','"title": "' .. name .. '"')
			xdata = string.gsub(xdata,'"description": ""','"description": "' .. description .. '"')
	end

return xdata

end

function two(vdata)
	vdata = string.gsub(vdata,'.*%<trkpt.*lat%=%"',"")
	vdata = string.gsub(vdata,'%".*lon=%"','ALTERNATE')
	vdata = string.gsub(vdata,'%".*','')
	vdata = string.gsub(vdata,'(.*ALTERNATE)(.*)','%2%,%1')
	vdata = string.gsub(vdata,'ALTERNATE','')
	vdata = '[' .. vdata .. '],'
	return vdata

end

function p.gpxmaplink(frame)
		local page = frame.args[1]
                if page == nil then return end
                local title = mw.title.new(page)
		local lat = frame.args['lat'] or "38.5"
		local long = frame.args['long'] or "38.5"
                local maplink = frame.args['maplink'] or "yes"
                local set = frame.args['set'] or "all"
                local info = frame.args['info'] or "before"
		local tt1 = {}
		local count = 0
		local separator = "@@@@@"
		local newdata = {}
--local ele = ""
--local elevation = {}
--local checker = 0
		local finalnewdata = ""
		local names = {}
		local descriptions = {}
		local colors = {"#662200", "#dc90a9", "#989f4d", "#acedc1", "#b43a32", "#cbffd3", "#bdd52b", "#fbbfb4", "#5c5c5c", "#ffffff"}
		local name = ""
                local description = ""
                local part1 = ""
                local part2 = ""
                local part1a = ""
                local part2a = ""
                local datagroup = 0
                local goahead = 0

         	if title == nil then return end

        	if title.id == 0 then
           	 return "Page does not exist!"
       		end

        	local data = title:getContent()

		if data == nil or data == "" then
			return
		end

		for i=0, 12 do
      			names[i] = ""
       			descriptions[i] = ""
      			newdata[i] = ""
    		end

		if maplink == "yes" then
			part1 = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" zoom="5" group="GPX">\n'
			part1 = part1 .. '{"type":\n\t"Feature","geometry":\n'
			part1 = part1 .. '\t{"coordinates":\n'

			part2 = '\n\t\t"type":"LineString"},'
			part2 = part2 .. '\n\t\t"properties":{'
			part2 = part2 .. '\n\t\t"title": "",'
			part2 = part2 .. '\n\t\t"description": "",'
			part2 = part2 .. '\n\t\t"stroke":"#00e500",'
			part2 = part2 .. '\n\t\t"stroke-width":3\n}}\n</maplink>\n' 

			part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" zoom="5" group="Point">\n'
			part1a = part1a .. '{"type":\n"Feature","geometry":{ "type":"Point", "coordinates":'

			part2a = " },\n"
			part2a = part2a .. '\t"properties": {'
			part2a = part2a .. '\n\t\t"title": "",'
			part2a = part2a .. '\n\t\t"description": "",'
			part2a = part2a .. '\n\t\t"marker-size": "medium",'
			part2a = part2a .. '\n\t\t"marker-color": "#ff33f3",'
			part2a = part2a .. '\n\t\t"marker-symbol": "marker"\n}}</maplink>\n'

		end
--data = string.gsub(data,'%s+%<%s+ele%s+%>','@@@@@<ele')
--data = string.gsub(data,'%s+%<%s+/%s+ele%s+%>','</ele>@@@@@') -- prep for elevation - output maplink and pointers with elevation? future
		data = string.gsub(data,'%s+%<%s+name%s+%>','@@@@@<name')
		data = string.gsub(data,'%s+%<%s+/%s+name%s+%>','</name>@@@@@')
		data = string.gsub(data,'%s+%<%s+desc%s+%>','@@@@@<desc')
		data = string.gsub(data,'%s+%<%s+/%s+desc%s+%>','</desc>@@@@@')
		data = string.gsub(data,'%s+%<%s+trkseg%s+%>','@@@@@<trkseg')
		data = string.gsub(data,'%s+%<%s+/%s+trkseg%s+%>','</trkseg>@@@@@')
		data = string.gsub(data,'%s+%<%s+trkpt%s+%>','@@@@@<trkpt')
		data = string.gsub(data,'%s+%<%s+%/%s+trkpt%s+%>','</trkpt>@@@@@')

		data = string.gsub(data,'%/%>','/>@@@@@')
		data = data .. '@@@@@<trksegENDIT>@@@@@'
		data = string.gsub(data,"\n","@@@@@")
		data = string.gsub(data,"@@@@@@@@@@","@@@@@")


		local _, datagroup = string.gsub(data, "<trkseg>", "")

		if datagroup == 0 then return "no trkseg" end
			for i = 1,datagroup, 1 do
			data = string.gsub(data,"<trkseg>", "<trkseg" .. tostring(i) .. ">",1)
			end

		for line in string.gmatch(data,"([^"..separator.."]+)") do
	                tt1[count] = line
                    count = count + 1
			end
		
		for k,v in pairs(tt1) do
   		    if string.find(v,'<name>',1) ~= nil then
         		name = v
		    end

--if string.find(v,'<trkpt>',1) ~= nil then
--elevation[checker] = v
--checker = checker + 1
--end
--if string.find(v,'<ele>',1) ~= nil then -- prep for creating elevation maplink
--	elevation[checker] = v
--end
     		    if string.find(v,'<desc>',1) ~= nil then
         		description = v
     		    end

		for i=1, 10 do
			if string.find(v,'<trkseg' .. tostring(i) .. '>',1) ~= nil then
				goahead = i
				names[1] = name
				name = ""
				descriptions[i] = description
				description = ""
				break
				end
		end

     		   if string.find(v,'<trksegENDIT>',1) ~= nil then
         		names['END'] = name
         		name = ""
			descriptions['END'] = description
			description = ""
     		   end

     		   for i=1, 10 do
         		   if goahead == i then 
                		   if set == "1" or set == "all" then
		     		       if string.find(v,'<trkpt',1) ~= nil then
                         		  v = two(v)
		        		  newdata[i] = newdata[i] .. v
		     		       end
                		   end
          		   end
     		   end

	end  -- END OF CYCLING THROUGH LINE BY LINE

	if info == "after" then
		for i=1, goahead do
 			names[i] = names[i + 1]
			descriptions[i] = descriptions[i + 1]
		end
			names[goahead] = names['END']
			descriptions[goahead] = descriptions['END']
	end

	for i=1, goahead do
        	newdata[i] = one(newdata[i],part1,part2,part1a,part2a,names[i],descriptions[i],colors[i])
        end

    	for i=1, goahead do
		finalnewdata = finalnewdata .. newdata[i] .. "\n"
        end

	finalnewdata = string.gsub(finalnewdata,'\n+$','\n')
	finalnewdata = string.gsub(finalnewdata,'%]%]%,',']],\n')

        return finalnewdata

end

-- STAGING a CIRCLE start
-- Extra functions while looking at how to build a circle - may be useful for others in building circles etc.
--  using some other method. Little or no useful help was found while searching the internet for
-- the not so mathematically (trigonometry, algebra etc.) inclined such as myself - hardly anything
-- This function is the result of an exhausting trial and error process of what is called Iterative Programming
-- The function newlat below is used by p.circle

function newlat(a)
-- newlat = math.log(math.tan((90 + a) * math.pi / 360)) / (math.pi / 180) -- worked this code elsewhere in function can remove
   newlatitude = 180/math.pi * (2 * math.atan(math.exp( a * math.pi/180)) - math.pi/2 )
  if newlatitude > 89.5 then point = 89.5 end -- END if       -- straight line at top of map
  if newlatitude < -89.5 then point = -89.5 end -- END if     -- straight line at bottom of map
  return newlatitude
end

-- CIRCLE FUNCTION
-- Get coordinates for a circle to use for drawing a line (LineString) - not filled in
-- or get coordinates to build a geoshape (Polygon)
-- Note: Polygon can be edited to do just an outline or a solid filled in circle
-- Colors etc. can also be changed for fill or outline (stroke) - thickness for stroke as well 
-- Latitude and Longitude formatted to %6f or 6 numbers after decimal point - can increase
-- Arguments or parameters:
--         Required:
--                 lat - latitude - ie. 27.0 - error msg will show if missing
--                 long - longitude - ie. 28.0 - error msg will show if missing
--         Optional
--                 type - "line" or "poly" default is "line" 
--                 group - group name to be used as "show" argument in <mapframe> - default is "circle"
--                 title - title to be used in <maplink> -- default is "A circle"
--                 desc - description default is ""
--                 radius - radius of circle to be implemented - default is .5
--                         MAX set at 10 -- and can not be less than or equal to 0
--                 fill - default set to #ccef64 if missing
--                 stroke - default set to #0000ff
--                 marker - y or yes - create a marker - at input lat long
-- Code example:
--     {{safesubst:#invoke:Sandbox/Matroc|circle|lat=22.35|long=70.07|type=poly|radius=10|fill=#000000|stroke=#0000cc}}
--     This creates a <maplink>
--  Uses - function newlat
-- Note: Yes this is OLD STYLE

function p.circle(frame)
        if frame.args['lat'] == nil then error("Missing argument lat!") end -- END if
        if frame.args['long'] == nil then error("Missing argument long!") end -- EMD if
        local x = string.format("%.6f",frame.args['lat'])
        local y = string.format("%.6f",frame.args['long'])
        local lat = frame.args['lat']
        local long = frame.args['long']
        local marker = frame.args['marker'] or "no"
              if marker == nil or marker == "" then marker = "no" end
        if tonumber(frame.args['lat']) > 85.35 or tonumber(frame.args['lat']) < -85.35 then error("Latitude must be between 85.35 and -85.35!") end -- END if
-- I set this as a default - function will not handle the polar circles yet will still handle areas within the majority of a map
        if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then error("Longitude must be between 180 and -180!") end -- END if
-- this will draw a full circle at 0 lat and 180 long
        local group = frame.args['group'] or 'circle'
        local title = frame.args['title'] or 'A circle'
        local description = frame.args['desc'] or ''
        local r = frame.args['radius'] or ".5"   -- default
        -- radius of 10 is approx. 500 km - futz with sizes - below 3 would probably be adequate - .1 is about 20km - .0001 is about 30 m
                r = tonumber(r)
                if r > 10 then error("10 for radius is MAX") end   -- END if - my default
                if r <= 0 then error("radius has to be greater than 0") end -- END if
        local fill = frame.args['fill'] or "#ccef64"
                if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end -- END if
                if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument fill!") end -- END if
        local stroke = frame.args['stroke'] or "#0000ff"
                if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end -- END if
                if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument stroke!") end -- END if
        local data = {}
        local coordinates = ""
        local ptx = 0
        local pty = 0
        local angle = 0
        local type = frame.args['type'] or "line" -- default line for LineString
        if type ~= "line" then
                type = "poly"
        end -- END if

-- Text for building a maplink - added together with circle coordinates in final output
-- This can be modified to output in different order or format if so desired -- my default

        local part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'
        local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

        local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'
        local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

-- fix latitude to position on mercator openstreetmap - -10.5 to + 10.5 is my default as
-- circles in these latitudes are fine for circle drawing

        if tonumber(x) >= 10.5 then
            x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)
        elseif tonumber(x) <= -10.5 then
            x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)
        end -- END if ELSEIF

-- get the latitude & longitudinal places for building or drawing a circle
-- this is a common method to build a 360 degree circle 

        for i = 1, 360 do
           angle = i * math.pi / 180
           ptx = x + r * math.cos( angle )
           pty = y + r * math.sin( angle )
--         ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle ) -- original code split for readability above

-- fix latitude so that the circle is output and not an eliptical polygon at higher or lower latitudes - this would be due
-- to something called isotropy within a mercator projection

        if tonumber(x) >= 10.5 then
         ptx = newlat(ptx) -- makes correction to make circle show up on map - upper latitudes
        end -- END if

        if tonumber(x) <= -10.5 then
          ptx = newlat(ptx) -- makes correction to make circle show up on map - lower latitudes
        end -- END if

          data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'
        end -- END for

-- cycle through array and put in a separator symbol (every fifth) so we can put groups of
-- 5 coordinates on a single line - in the maplink format

        for i = 5,359, 5 do
                data[i] = data[i] .. "@@@@@"
        end -- END for

-- cycle through array and build single string of all coordinates to be output

        for i = 1,360, 1 do
               coordinates = coordinates .. data[i]
        end -- END for

-- fix the string to arrange the coordinates with brackets "[]"s separated by ","

        coordinates = coordinates.gsub(coordinates,'%]%[','],[')
        coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')
        coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"          -- close the circle extra precautionary measure

-- format string coordinates or linestring if a polygon or linestring

        if type == "poly" then
                coordinates  = string.gsub(coordinates,'%]%,$',']],')
                coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b
        else
                coordinates = part1a .. coordinates .. part2a
        end -- END if
        if marker == "yes" or marker == "y" then
              coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Circle|lat=' .. lat .. "|long=" .. long .. '}}\n'
        end
        return coordinates

end

-- BOX or RECTANGLE
-- Build a box
-- Args:
--    upper -- latitude and longitude for upper left hand corner -- upper=latitude,longitude
--    lower -- latitude and longitude for lower right hand corner -- lower=latitude,longitude
--    type -- line or poly
--    marker -- y or yes to build an extra marker to place in center of box
--    group -- group name
--    title -- title
--    description -- brief description
--    fill -- fill color
--    stroke -- color of outline
--  Code to build small box for Kronstadt (Russia):
--  {{#invoke:Sandbox/Matroc|box|upper=60.03732,29.62099|lower=,59.96866,29.82149|type=poly|title=Kronstadt|marker=y}}

function p.box(frame)
        if frame.args['upper'] == nil or frame.args['upper'] == "" then error("Missing argument upper!") end
        if frame.args['lower'] == nil or frame.args['lower'] == "" then error("Missing argument lower!") end
	local separator = "@@@@@"
        local x = string.gsub(frame.args['upper'],'%,','@@@@@')
        local y = string.gsub(frame.args['lower'],'%,','@@@@@')
                x = string.gsub(x,'%s+','')
                y = string.gsub(y,'%s+','')
        local tt = {}
        local data = {}
        local latitudes = {}
        local longitudes = {}
        local count = 1
        local marker = frame.args['marker'] or "no"
        if marker == nil or marker == "" then marker = "no" end

	for str in string.gmatch(x,"([^"..separator.."]+)") do
		if str ~= nil and str ~= "" then
                    tt[count] = str
		    count = count + 1
		end
	end

	for str in string.gmatch(y,"([^"..separator.."]+)") do
		if str ~= nil and str ~= "" then
                    tt[count] = str
		    count = count + 1
		end
	end

        if count >=6 then error("Check the upper and lower arguments for format!") end
        for i=1,4 do
           if tt[i] == nil or tt[i] == "" then error("Check for missing latitude or longitude separated by a comma!") end
        end

longitudes[1] = tonumber(tt[2])
if longitudes[1] > 180 or longitudes[1] <- 180 then error("longitude should be between 180 and -180") end
        data[1] = "[" .. tt[2]

latitudes[1] = tonumber(tt[1])
if latitudes[1] > 90 or latitudes[1] <- 90 then error("latitude should be between 90 and -90") end
        data[2] = "," .. tt[1] .. "]"

longitudes[2] = tonumber(tt[2])
if longitudes[2] > 180 or longitudes[2] <- 180 then error("longitude should be between 180 and -180") end
        data[3] = "[" .. tt[2]


latitudes[2] = tonumber(tt[3])
if latitudes[2] > 90 or latitudes[2] <- 90 then error("latitude should be between 90 and -90") end
        data[4] = "," .. tt[3] .. "]"

longitudes[3] = tonumber(tt[4])
if longitudes[3] > 180 or longitudes[3] <- 180 then error("longitude should be between 180 and -180") end
        data[5] = "[" .. tt[4]

latitudes[3] = tonumber(tt[3])
if latitudes[3] > 90 or latitudes[3] <- 90 then error("latitude should be between 90 and -90") end
        data[6] = "," .. tt[3] .. "]"

longitudes[4] = tonumber(tt[4])
if longitudes[4] > 180 or longitudes[4] <- 180 then error("longitude should be between 180 and -180") end
        data[7] = "[" .. tonumber(tt[4])

latitudes[4] = tonumber(tt[1])
if latitudes[4] > 90 or latitudes[4] <- 90 then error("latitude should be between 90 and -90") end
        data[8] = "," .. tt[1] .. "]"

-- if one wants to output a marker or center of box
-- as well as assign the lat/long arguments to maplink (not for geometry coordinates)
table.sort(latitudes)
table.sort(longitudes)
local lat = latitudes[1] + ((latitudes[4] - latitudes[1]) / 2 )
local long = longitudes[1] + ((longitudes[4] - longitudes[1]) / 2) 

        local group = frame.args['group'] or 'box'
        local title = frame.args['title'] or 'A box'
        local description = frame.args['desc'] or ''
        local fill = frame.args['fill'] or "#ccef64"
                if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end
                if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument fill!") end
        local stroke = frame.args['stroke'] or "#0000ff"
                if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end
                if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument stroke!") end
        local coordinates = ""
        local type = frame.args['type'] or "line" -- default line for LineString
        if type ~= "line" then
                type = "poly"
        end

-- Text for building a maplink - added together with box coordinates in final output
-- This can be modified to output in different order if so desired - my default

        local part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'
        local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

        local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'
        local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

-- cycle through array and build single string of all coordinates to be output

        for i = 1,8, 1 do
        coordinates = coordinates .. data[i]
        end
        coordinates = coordinates .. data[1] .. data[2] -- close the box/rectangle polygon

-- fix the string to arrange the coordinates with brackets "[]"s separated by ","

        coordinates = coordinates.gsub(coordinates,'%]%[','],[')
        coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')
        coordinates = "[" .. coordinates .. "],"

-- format string coordinates or linestring if a polygon or linestring

        if type == "poly" then
                coordinates  = string.gsub(coordinates,'%]%,$',']],')
                coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b
        else
                coordinates = part1a .. coordinates .. part2a
        end
        if marker == "yes" or marker == "y" then
               coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Box|lat=' .. lat .. "|long=" .. long .. '}}\n'
        end
        return coordinates

end

-- TRIANGLE

-- Build a triangle
-- Args:
--    coord1 -- latitude and longitude for point1 of triangle -- coord1=latitude,longitude
--    coord2 -- latitude and longitude for point2 of triangle -- coord2=latitude,longitude
--    coord3 -- latitude and longitude for point3 of triangle -- coord2=latitude,longitude
--    type -- line or poly
--    marker -- y or yes to build an extra vicinity marker to place in center of box
--          with the name "Center Triangle"
--    group -- group name
--    title -- title
--    description -- brief description
--    fill -- fill color
--    stroke -- color of outline
--    Code for Bermuda Triangle:
--   {{safesubst:#invoke:Sandbox/Matroc|triangle|coord1=25.72909,-80.23744|coord2=32.313,-64.765|coord3=18.46633,-66.104736|type=poly|fill=#000000|marker=y}}

function p.triangle(frame)
        if frame.args['coord1'] == nil or frame.args['coord1'] == "" then error("Missing argument coord1!") end
        if frame.args['coord2'] == nil or frame.args['coord2'] == "" then error("Missing argument coord2!") end
        if frame.args['coord3'] == nil or frame.args['coord3'] == "" then error("Missing argument coord3!") end
	local separator = "@@@@@"
        local x = string.gsub(frame.args['coord1'],'%,','@@@@@')
        local y = string.gsub(frame.args['coord2'],'%,','@@@@@')
        local z = string.gsub(frame.args['coord3'],'%,','@@@@@')
                x = string.gsub(x,'%s+','')
                y = string.gsub(y,'%s+','')
                z = string.gsub(z,'%s+','')
        local tt = {}
        local data = {}
        local latitudes = {}
        local longitudes = {}
        local count = 1
        local marker = frame.args['marker'] or "no"
                if marker == nil or marker == "" then marker = "no" end

	for str in string.gmatch(x,"([^"..separator.."]+)") do
		if str ~= nil and str ~= "" then
                    tt[count] = str
		    count = count + 1
		end
	end

	for str in string.gmatch(y,"([^"..separator.."]+)") do
		if str ~= nil and str ~= "" then
                    tt[count] = str
		    count = count + 1
		end
	end

	for str in string.gmatch(z,"([^"..separator.."]+)") do
		if str ~= nil and str ~= "" then
                    tt[count] = str
		    count = count + 1
		end
	end

        if count >=8 then error("Check the upper and lower arguments for format!") end
        for i=1,6 do
           if tt[i] == nil or tt[i] == "" then error("Check for missing latitude or longitude separated by a comma!") end
        end

        longitudes[1] = tonumber(tt[2])
        if longitudes[1] > 180 or longitudes[1] <- 180 then error("longitude should be between 180 and -180") end
        data[1] = "[" .. tt[2]

        latitudes[1] = tonumber(tt[1])
        if latitudes[1] > 90 or latitudes[1] <- 90 then error("latitude should be between 90 and -90") end
        data[2] = "," .. tt[1] .. "]"

        longitudes[2] = tonumber(tt[4])
        if longitudes[2] > 180 or longitudes[2] <- 180 then error("longitude should be between 180 and -180") end
        data[3] = "[" .. tt[4]

        latitudes[2] = tonumber(tt[3])
        if latitudes[2] > 90 or latitudes[2] <- 90 then error("latitude should be between 90 and -90") end
        data[4] = "," .. tt[3] .. "]"

        longitudes[3] = tonumber(tt[6])
        if longitudes[3] > 180 or longitudes[3] <- 180 then error("longitude should be between 180 and -180") end
        data[5] = "[" .. tt[6]

        latitudes[3] = tonumber(tt[5])
        if latitudes[3] > 90 or latitudes[3] <- 90 then error("latitude should be between 90 and -90") end
        data[6] = "," .. tt[5] .. "]"


-- if one wants to output a marker or find center of box
-- as well as assign the lat/long arguments to maplink (not for geometry coordinates)

        local lat = (latitudes[1] + latitudes[2] + latitudes[3]) / 3 
        local long = (longitudes[1] + longitudes[2] + longitudes[3]) / 3
lat = string.format("%.6f",lat)
long = string.format("%.6f",long)
        local group = frame.args['group'] or 'triangle'
        local title = frame.args['title'] or 'A triangle'
        local description = frame.args['desc'] or ''
        local fill = frame.args['fill'] or "#ccef64"
                if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end
                if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument fill!") end
        local stroke = frame.args['stroke'] or "#0000ff"
                if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end
                if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument stroke!") end
        local coordinates = ""
        local type = frame.args['type'] or "line" -- default line for LineString
        if type ~= "line" then
                type = "poly"
        end

-- Text for building a maplink - added together with box coordinates in final output
-- This can be modified to output in different order if so desired - my default

        local part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'
        local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

        local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'
        local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

-- cycle through array and build single string of all coordinates to be output

        for i = 1,6, 1 do
                coordinates = coordinates .. data[i]
                end
        coordinates = coordinates .. data[1] .. data[2] -- close the triangle

-- fix the string to arrange the coordinates with brackets "[]"s separated by ","

        coordinates = coordinates.gsub(coordinates,'%]%[','],[')
        coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')
        coordinates = "[" .. coordinates .. "],"

-- format string coordinates or linestring if a polygon or linestring

        if type == "poly" then
                coordinates  = string.gsub(coordinates,'%]%,$',']],')
                coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b
        else
                coordinates = part1a .. coordinates .. part2a
        end

        if marker == "yes" or marker == "y" then
                coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Triangle|lat=' .. lat .. "|long=" .. long .. '}}\n'
        end

        return coordinates

end

-- ELIPSE
-- Essentially the same code for a circle - this elipise if set to a certain shape
-- Get coordinates for an elipse to use for drawing a line (LineString) - not filled in
-- or get coordinates to build a geoshape (Polygon)
-- Note: Polygon can be edited to do just an outline or a solid filled in elipse
-- Colors etc. can also be changed for fill or outline (stroke) - thickness for stroke as well 
-- Latitude and Longitude formatted to %6f or 6 numbers after decimal point - can increase
-- If its a polygon and you want it to appear with no fill edit output by adding "fill-opacity":, also can change this to a 0 or 1 I think to make
-- the fill solid with no opacity
-- Arguments or parameters:
--         Required:
--                 lat - latitude - ie. 27.0 - error msg will show if missing
--                 long - longitude - ie. 28.0 - error msg will show if missing
--         Optional
--                 type - "line" or "poly" default is "line" 
--                 group - group name to be used as "show" argument in <mapframe> - default is "circle"
--                 title - title to be used in <maplink> -- default is "A circle"
--                 desc - description default is ""
--                 radius - radius of circle before it is changed to be implemented - default is .5
--                         MAX set at 10 -- and can not be less than or equal to 0
--                 fill - default set to #ccef64 if missing
--                 stroke - default set to #0000ff
--                 marker - y or yes - create a marker - at input lat long
--                 style - h or v -- horizontal or vertical - horizontal or h is default
-- Code example:
--     {{safesubst:#invoke:Sandbox/Matroc|elipse|lat=22.35|long=70.07|type=poly|radius=10|marker=y|style=h}}
--     This creates a <maplink> with coordinates and a marker

function p.elipse(frame)
        if frame.args['lat'] == nil then error("Missing argument lat!") end
        if frame.args['long'] == nil then error("Missing argument long!") end
        local x = string.format("%.6f",frame.args['lat'])
        local y = string.format("%.6f",frame.args['long'])
        local lat = frame.args['lat']
        local long = frame.args['long']
        if tonumber(frame.args['lat']) > 90 or tonumber(frame.args['lat']) < -90 then error("Latitude must be between 90 and -90!") end
        if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then error("Longitude must be between 180 and -180!") end
        local group = frame.args['group'] or 'elipse'
        local title = frame.args['title'] or 'An elipse'
        local description = frame.args['desc'] or ''
        local r = frame.args['radius'] or ".5"   -- default
                r = tonumber(r)
                if r > 10 then error("10 for radius is MAX") end   -- my default
                if r <= 0 then error("radius has to be greater than 0") end
        local fill = frame.args['fill'] or "#ccef64"
                if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end
                if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument fill!") end
        local stroke = frame.args['stroke'] or "#0000ff"
                if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end
                if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument stroke!") end
        local marker = frame.args['marker'] or "no"
              if marker == nil or marker == "" then marker = "no" end
        local style = frame.args['style'] or "h"
              if style == nil or style == "" then style = "h" end
              if style ~= "v" then style = "h" end -- if not v (ie. other garbage then force style to be h)
        local data = {}
        local coordinates = ""
        local ptx = 0
        local pty = 0
        local angle = 0
        local type = frame.args['type'] or "line" -- default line for LineString
        if type ~= "line" then
                type = "poly"
        end

-- Text for building a maplink - added together with elipse coordinates in final output
-- This can be modified to output in different order if so desired - my default

        local part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'
        local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

        local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'
        local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

-- fix latitude to position on mercator openstreetmap - -10.5 to + 10.5 is my default as
-- circles in these latitudes are fine for circle drawing

        if tonumber(x) >= 10.5 then
            x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)
        elseif tonumber(x) <= -10.5 then
            x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)
        end

-- get the latitude & longitudinal places for an elipse

        for i = 1, 360 do
           angle = i * math.pi / 180
           ptx = x + r * math.cos( angle )
           if style == "v" then
                pty = y - 0.5 * r * math.sin( angle ) -- for elipse vertical
             elseif style == "h" then
                pty = y + 2.0 * r * math.sin(angle) -- for elipse horizontal
           end
--         ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle )

-- fix latitude so that the elipse is output even at higher or lower latitudes

        if tonumber(x) >= 10.5 then
         ptx = newlat(ptx) -- makes correction to make circle show up on map
        end

        if tonumber(x) <= -10.5 then
          ptx = newlat(ptx) -- makes correction to make circle show up on map
        end

          data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'
        end

-- cycle through array and put in a separator symbol (every fifth) so we can put groups of
-- 5 coordinates on a single line - in the maplink format

        for i = 5,359, 5 do
                data[i] = data[i] .. "@@@@@"
        end

-- cycle through array and build single string of all coordinates to be output

        for i = 1,360, 1 do
        coordinates = coordinates .. data[i]
        end

-- fix the string to arrange the coordinates with brackets "[]"s separated by ","

        coordinates = coordinates.gsub(coordinates,'%]%[','],[')
        coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')
        coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"          -- close the circle extra precautionary measure

-- format string coordinates or linestring if a polygon or linestring

        if type == "poly" then
                coordinates  = string.gsub(coordinates,'%]%,$',']],')
                coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b
        else
                coordinates = part1a .. coordinates .. part2a
        end
        if marker == "yes" or marker == "y" then
                coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Elipse|lat=' .. lat .. "|long=" .. long .. '}}\n'
        end
        return coordinates

end


-- STAR
-- Get coordinates for a star to use for drawing a line (LineString) - not filled in
-- or get coordinates to build a filled in geoshape (Polygon)
-- Note: Polygon can be edited to do just an outline or a solid filled in elipse
-- Colors etc. can also be changed for fill or outline (stroke) - thickness for stroke as well 
-- Latitude and Longitude formatted to %6f or 6 numbers after decimal point - can increase
-- Arguments or parameters:
--         Required:
--                 lat - latitude - ie. 27.0 - error msg will show if missing
--                 long - longitude - ie. 28.0 - error msg will show if missing
--         Optional
--                 type - "line" or "poly" default is "line" 
--                 group - group name to be used as "show" argument in <mapframe> - default is "star"
--                 title - title to be used in <maplink> -- default is "A star"
--                 desc - description default is ""
--                 radius - radius of circle upon which a star is built - default is .5
--                         MAX set at 10 -- and can not be less than or equal to 0
--                 fill - default set to #ccef64 if missing
--                 stroke - default set to #0000ff
--                 marker - y or yes - create a marker - at input lat long

-- Code example:
--     {{safesubst:#invoke:Circle4|star|lat=22.35|long=70.07|type=poly|radius=10}}
--     This creates a <maplink>

function p.star(frame)
        if frame.args['lat'] == nil then error("Missing argument lat!") end
        if frame.args['long'] == nil then error("Missing argument long!") end
        local latitude = string.format("%.6f",frame.args['lat'])
        local longitude = string.format("%.6f",frame.args['long'])
        local lat = frame.args['lat']
        local long = frame.args['long']
        if tonumber(frame.args['lat']) > 90 or tonumber(frame.args['lat']) < -90 then error("Latitude must be between 90 and -90!") end
        if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then error("Longitude must be between 180 and -180!") end
        local group = frame.args['group'] or 'star'
        local title = frame.args['title'] or 'A star'
        local description = frame.args['desc'] or ''
        local radius = frame.args['radius'] or ".5"   -- default
                radius = tonumber(radius)
                if radius > 10 then error("10 for radius is MAX") end   -- my default
                if radius <= 0 then error("radius has to be greater than 0") end
        local radius2 = radius * 3;
        local fill = frame.args['fill'] or "#ccef64"
                if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end
                if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument fill!") end
        local stroke = frame.args['stroke'] or "#0000ff"
                if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end
                if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then
                   error("Incorrect hexidecimal format for argument stroke!") end
        local marker = frame.args['marker'] or "no"
              if marker == nil or marker == "" then marker = "no" end
        latitude = math.log(math.tan((90 + latitude) * math.pi/360)) / (math.pi/180)
        local ra = 0
        local angle = 0
        local points = {}
        local coordinates = ""
        local type = frame.args['type'] or "line" -- default line for LineString
        if type ~= "line" then
                type = "poly"
        end

        local part1a = '<maplink text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'
        local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

        local part1b = '<maplink text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'

        local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'
        local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'


      for i = 1,10, 1 do
         mod = math.mod(i,2)
         if mod == 1 then ra = radius else ra = radius2 end
         angle =  ((2 * math.pi / 10)) * i
         points[i] =  '[' ..  string.format("%.6f",longitude + (ra * math.cos(angle))) .. ","
         points[i] = points[i] .. string.format("%.6f",newlat(latitude + (ra * math.sin(angle)))) .. "],"
      end

      for i = 1,10, 1 do
         coordinates = coordinates .. points[i] .. "\n"
      end

      coordinates = coordinates .. points[1]

        if type == "poly" then
                coordinates  = string.gsub(coordinates,'%]%,$',']]],')
                coordinates = part1b .. string.gsub(coordinates,'^%[','[[[') .. part2b
        else
                coordinates  = string.gsub(coordinates,'%]%,$',']],')
                coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part2a
        end

        if marker == "yes" or marker == "y" then
                coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Star|lat=' .. lat .. "|long=" .. long .. '}}\n'
        end


      return coordinates


end

-- Load a page and scan it for listing templates and find duplicate parameters



function p.checkparameters(frame)
		local page = frame.args[1] or "Main Page"
		local flags = frame.args['flags'] or "n"
		if flags ~= "y" then flags = "n" end       -- Images from {{flag|name}} as in embassies -- y or n
        local title = mw.title.new(page)
        if title == nil then return end

        if title.id == 0 then
            return "Page does not exist!"
        end

        local data = title:getContent()
		
		if data == nil or data == "" then
			return ""
		end

-- Isolate listings,eliminate extra spaces etc. and and pull them out of data

local separator = "@@@@@"


data = string.gsub(data,'\n',' ')
data = string.gsub(data,'%s+',' ')
data = string.gsub(data,"http://www","HTTPWWW")
data = string.gsub(data,"https://www","HTTPSWWW")
data = string.gsub(data,"http://","HTTP")
data = string.gsub(data,"https://",'HTTPS')
data = string.gsub(data,'%s+=%s+','=')
data = string.gsub(data,'%s+|%s+','|')
data = string.gsub(data,'%s+}','}')
data = string.gsub(data,'{%s+','{')
-- eliminate some templates to minimize later processing
data = string.gsub(data,'{{deadlink','DEADLINK')
data = string.gsub(data,'{{dead link','DEADLINK')
data = string.gsub(data,'{{ISBN','ISBN')
data = string.gsub(data,'{{seealso','SEEALSO')
data = string.gsub(data,'{{see also','SEEALSO')
data = string.gsub(data,'{{seeDistricts}}','')   -- other hatnotes could be added here as well
data = string.gsub(data,'{{SeeDistricts}}','')
data = string.gsub(data,'{{pagebanner','PAGEBANNER')
data = string.gsub(data,'{{quickbar','QUICKBAR')
data = string.gsub(data,'{{regionlist','REGIONLIST')
data = string.gsub(data,'{{Regionlist','REGIONLIST')
data = string.gsub(data,'{{translate','TRANSLATE')
data = string.gsub(data,'{{IATA','IATA')
data = string.gsub(data,'{{related','RELATED')
data = string.gsub(data,'{{geo','GEO')
data = string.gsub(data,'{{infobox','INFOBOX')
data = string.gsub(data,'{{','@@@@@')
data = string.gsub(data,'%s+@@@@@%s+','@@@@@')

 local index = 0
 local items = {}
 local flags = {}
 local number = 0
for str in string.gmatch(data,"([^"..separator.."]+)") do

	str = string.gsub(str,'DEADLINK.*%d%d%d%d}}','') -- template inside a template removestring
	str = string.gsub(str,'}}.*','')
    
    local check = {	'Listing', 'Marker', 'See', 'Do', 'Buy', 'Eat', 'Drink', 'Sleep', 'listing', 'marker', 'see', 'do', 'buy', 'eat', 'drink', 'sleep'}
-- pick out listings by type Listing,See, Do, Buy, Eat, Drink and Sleep
   for k,v in ipairs(check) do
        if string.match(str,"^" .. v) then
    	   index = index + 1
    	   items[index] = str
    	   break
        end
    end
end

local dummy = ""
local dump1 = ""
local newitems = {}
local count2 = 0
        check = {'Listing', 'Marker', 'See', 'Do', 'Buy', 'Eat', 'Drink', 'Sleep', 'listing', 'marker', 'see', 'do', 'buy', 'eat', 'drink', 'sleep'}  
if index >= 1 then
	for i=1,index do
        str = items[i]
        str = string.gsub(str,'%|',"@@@@@")
     
             for k,v in ipairs(check) do
   	             str = string.gsub(str,"^"..v.."@@@@@","")
   	             end
        for matchdupes in string.gmatch(str,"([^"..separator.."]+)") do
 --       	matchdupes = string.gsub(matchdupes,"%=.*$","=")   -- split off parameters by name
      	matchdupes = string.gsub(matchdupes,"%=.*","=")   -- split off parameters by name
        	dummy,count = string.gsub(items[i],matchdupes,"")
        	if count >= 2 then
        		items[i] = string.gsub(items[i],matchdupes,"<duplicate>"..matchdupes.."</duplicate>")
        	   end

           end
    end
 end

local testdata = ""
if index >= 1 then
    for i=1,index do
       if string.find(items[i],".*<duplicate>.*") then
       	  items[i] = string.gsub(items[i],"duplicate>","b>")
	      testdata = testdata .. "\n* ---- " .. items[i] .. "\n"
	   end
	end
end
   return "\n----" .. testdata .. "No. of templates reviewed = " .. index .. "\n----"

end 


function p.betadellistparams(frame)

		local page = frame.args[1]

        local title = mw.title.new(page)
        if title == nil then return end

        if title.id == 0 then
            return "Page does not exist!"
        end

        local data = title:getContent()
        local newdata = ""
        if data == nil or data == "" then
         	return
        end
        
local tt = {}
local count = 0
local continue = 0
local separator = "@@@@@"
--data = string.gsub(data,'\n','@@@@@')
--data = string.gsub(data,'\n','@@@@@')
data = string.gsub(data,'%| *[Hh]ours\= *','|hours=')
data = string.gsub(data,'%| *[Pp]rice\= *','|price=')
data = string.gsub(data,'%| *[Cc]ontent\= *','|content=')
data = string.gsub(data,'%| *[Dd]irections\= *','|directions=')
data = string.gsub(data,'%| *[Cc]heckin\= *','|checkin=')
data = string.gsub(data,'%| *[Cc]heckout\= *','|checkout=')
data = string.gsub(data,'|','@@@@@+++++|')
data = string.gsub(data,'\}\}','@@@@@}}')
data = string.gsub(data,'@@@@@@@@@@','@@@@@')
data = string.gsub(data,'@@@@@@@@@@','@@@@@')


for str in string.gmatch(data,"([^"..separator.."]+)") do
	
-- if string.find(str,'content') ~= nil then return str end
if string.find(str,'^\+\+\+\+\+.*') ~= nil then
	str = string.gsub(str,'^\+\+\+\+\+','')
	str = string.gsub(str,'|hours\=.*','|hours=')	
	str = string.gsub(str,'|price\=.*','|price=')	
	str = string.gsub(str,'|checkin\=.*','|checkin=')	
	str = string.gsub(str,'|checkout\=.*','|checkout=')	
	str = string.gsub(str,'|directions\=.*','|directions=')	
	str = string.gsub(str,'|content\=.*','|content=')

-- if string.find(str,'content') ~= nil then return str end 
else
--    str = str" .. "\n"
end

if str ~= nil and str ~= "" then
     count = count + 1	
     tt[count] = str
end

end

for key,value in pairs(tt) do
	newdata = newdata .. value
end


	return newdata

end



-- GET LATITUDE -- P625

local function combo(id)
	local latitude = ""
	local longitude = ""
	local name = ""
	local osm = "none"
	local linkosm = ""
    local entity = mw.wikibase.getEntityObject(id)	
	if entity == nil then return latitude,longitude,name end    		
	local claims = entity.claims
	if claims == nil then
		return latitude,longitude,name
	end	
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		latitude = string.format("%.6f",latitude)
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		longitude = string.format("%.6f",longitude)		
	end
	if claims.P402 ~= nil then
		osm = entity.claims.P402[1].mainsnak.datavalue.value or "none"
		if osm == nil then osm = "none" end
		if osm ~= "none" then linkosm = "[https://www.openstreetmap.org/relation/" .. osm .. " " .. osm .. "]"
			osm = linkosm
			end
	end	
	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then
		name = entity:getSitelink("enwikivoyage") or ""
		if name ~= nil and name ~= "" then
			name = "wv: [[" .. name  .."]]"
			else name = "wv: ----"
		end
	end
	return latitude,longitude,name,osm
end

-- Combine following into 1 function to avoid multiple repeating actions
-- Doing lookup for OSM relation ID move to combo
 local function yikes(v)
     local entity = mw.wikibase.getEntityObject(string.gsub(v,' ',''))
     local claims = entity.claims
     if claims == nil then return "---" end
     if claims.P402 == nil then return "---" end
    local xxx = entity.claims.P402[1].mainsnak.datavalue.value
    return xxx
end

-- GET LATITUDE -- P625

local function latitude2(id)
	local latitude = ""
    local entity = mw.wikibase.getEntityObject(id)	
--	local entity = mw.wikibase.getEntityObject()
	if entity == nil then return latitude end    		
	local claims = entity.claims
	if claims == nil then
		return latitude
	end	
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		return string.format("%.6f",latitude)
	end
	return latitude
end

local function longitude2(id)
	local longitude = ""
    local entity = mw.wikibase.getEntityObject(id)	
	if entity == nil then return longitude end    		
	local claims = entity.claims
	if claims == nil then
		return longitude
	end	
	if claims.P625 ~= nil then
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		return string.format("%.6f",longitude)
	end
	return longitude
end

local function sitename2(id)
	local name = ""
    local entity = mw.wikibase.getEntityObject(id)	
	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then
		name = entity:getSitelink("enwikivoyage") or ""
		if name ~= nil and name ~= "" then
			name = "wv: [[" .. name  .."]]"
		else name = "wv: ----"
		end
	end           	
	return name
end

-- look for admin units and related OSM ID
function p.looksee(frame)
	local newdata = ""
    local previous = ""
    local voysitename = ""
    local name2 = ""
    local lat = ""
    local long = ""
    local wv = ""
    local osm = ""
	local arg1 = frame.args[1]
    local entity = mw.wikibase.getEntityObject(arg1)
    local str = ""
    local strx = ""
    local xxx = ""
	if entity == nil then return newdata end	
	local claims = entity.claims
	if claims == nil then
		return newdata
	end	
	local data = ""
	local t = {}
	local tt = {}
	local separator = "%s"	
	local count = 0

--	P47 for bordering entities

    if claims.P150 ~= nil then
        for k,v in pairs(claims.P150) do
    		count = count + 1
    		t = {}
			if pcall(function () t = entity.claims.P150[count].mainsnak.datavalue.value end) then
					t = entity.claims.P150[count].mainsnak.datavalue.value    	
				else
					return newdata
			end			
			t = entity.claims.P150[count].mainsnak.datavalue.value

			for k, v in pairs( t ) do
				v = string.gsub(v,"item","")
				v = " Q" .. v
				v = string.gsub(v,"^ Q$","")
                v = string.gsub(v,'Q+','Q')
                if v ~= previous then
				    if v ~= nil and v ~= "" then
                        xxx = yikes(v)					
--				        data = data .. v .. "@@@" .. xxx
                        data = data .. " " .. v
            	    end
                    previous = v
              end
		  end
		end
		count = 1
		for str in string.gmatch(data,"([^"..separator.."]+)") do
--            strx = string.gsub(str,'^.*@@@','') -- OSM ID
--            str = string.gsub(str,"@@@.*$",'')  -- Wikidata ID
lat,long,name2,osm=combo(str)
	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then
		voysitename = entity:getSitelink("enwikivoyage") or ""
		if voysitename ~= nil and voysitename ~= "" then
			voysitename = "wv: [[" .. voysitename  .."]]"
		else voysitename = "wv: ----"
		end
	end  
--			if mw.wikibase.sitelink( str ) ~= nil then
--tt[count] = "'''[[" .. mw.wikibase.sitelink( str ) .. "]]''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''" .. strx .. "''')"
--tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2
--
--else
--       if mw.wikibase.label(str) == nil or mw.wikibase.label(str) == "" then
--             tt[count] = "'''No Label''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''No Label ''')"
--             tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2
--             count = count + 1
--             break end
--   	     
--tt[count] = "'''[[" .. mw.wikibase.label(str) .. "]]''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''" .. strx .. "''')"
--tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2
--	  end


if mw.wikibase.label(str) == nil or mw.wikibase.label(str) == "" then
             tt[count] = "'''No Label''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''" .. osm .. "''')"
             tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2	
else
tt[count] = "'''[[" .. mw.wikibase.label(str) .. "]]''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''" .. osm .. "''')"
tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2
	
end


			count = count + 1
end
		table.sort(tt)
		count = 1
		for k, v in pairs (tt) do
			if count == 1 then
					newdata = tt[count]
				else
--					newdata = newdata .. ", " .. tt[count]
					newdata = newdata .. "</br>" .. tt[count]					
				end
				count = count + 1
			end
			if newdata ~= "" then
	    		newdata = "<div style=\"background-color:WhiteSmoke; border-style:solid; border-width:thin; padding-right: 10px; padding-left: 10px;\">" .. newdata .. "</div>"
			end
			return newdata
		end
	return newdata
end	-- END MODULE

function p.convchar(frame)
    local xxx = frame.args[1]
xxx = string.gsub(xxx,"&#39;","\'")
xxx = string.gsub(xxx,"&#34;",'\"')
-- xxx = string.gsub(xxx,"&nbsp;",' ')
	return xxx
end

function p.getname(frame)
	local name=mw.wikibase.getEntityIdForTitle(frame.args[1])
	if name == "" or name == nil then return "" end
	return name
	end


function p.getname2(frame)
	local names=frame.args[1]
	local name = ""
	local image = ""
	local items = {}
	local index = 1
    local id = ""
	local latitude = ''
	local longitude = ''
	local marker = ''
    local entity = ''
    local data = ""
    local separator = '\n'
    local lang = ''
    local wiki = ''
    local wikiname = ''
    
 for str in string.gmatch(names,"([^"..separator.."]+)") do
 	if str ~= nil and str ~= "" then
 		str = string.gsub(str,"^%s+","")
     	str = string.gsub(str,"%s+$","")
     	if str ~= "" then
	       items[index] = str
	       index = index + 1
	       end
	    end
	end    

 for i=1,#items do
 	name = items[i]
 	id = ""
    wikiname = '' 	
	id=mw.wikibase.getEntityIdForTitle(items[i])
    if id == nil then id = '' end
    
if id ~= nil and id ~= '' then
    entity = mw.wikibase.getEntityObject(id)	

    if entity == nil then
		latitude = ""
	    longitude = ""
	    end
	    
	local claims = entity.claims
	if claims == nil then
		latitude = ""
		longitude = ""
	    end	
--	if claims.P625 ~= nil then
if pcall(function () t =claims.P625 end ) then
 		if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		else latitude = "" end
 		if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then		
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		else longitude = "" end
end

--	if claims.P18 ~= nil then
--		image = entity.claims.P18[1].mainsnak.datavalue.value
--		if image == nil then
--			image = ""
--
-- Replace above due to error of getting a nil value
-- Lua error in line 3210: attempt to index field 'datavalue' (a nil value).
image=""
if pcall(function () t =claims.P625 end ) then
 		if pcall(function () t =entity.claims.P18[1].mainsnak.datavalue.value end ) then		
		      image = entity.claims.P18[1].mainsnak.datavalue.value
		    else
		    	image = ""
			end		   

end

		
	end

    wikiname = ""	
	lang = mw.language.getContentLanguage(id).code
	wiki = lang .. "wiki"
	if pcall(function()t1 = entity:getSitelink("wiki") end) then	
        wikiname = entity:getSitelink(wiki) or ""
    else
    	wikiname = ""
    end

if id == "" then wikiname = "" end
if id ~= nil and id ~= "" then
			name = "[[" .. name .. "]]"
end
    marker = '* {{see | name=' .. name .. " | lat=" .. latitude .. " | long=" .. longitude .. " | image=" .. image .. " | wikipedia=" .. wikiname .. " | wikidata=" .. id .. "}}"
    data = data .. marker .. "\n"
    marker = ''
    name = ''
    latitude = ''
    longitude = ''
    image= ''
    id = ''
    wikiname = ''
	
end
    
    return data
    end
function p.getname3(frame)
	local names=frame.args[1]
	local type = ""
	local name = ""
	local image = ""
	local items = {}
	local index = 1
    local id = ""
	local latitude = ''
	local longitude = ''
	local listing = ''
    local entity = ''
    local data = ""
    local separator = '\n'
    local lang = ''
    local wiki = ''
    local wikiname = ''
    local counter = 0
    
 for str in string.gmatch(names,"([^"..separator.."]+)") do
 	if str ~= nil and str ~= "" then
 		str = string.gsub(str,"^%s+","")
     	str = string.gsub(str,"%s+$","")
     	if str ~= "" then
	       items[index] = str
	       index = index + 1
	       end
	    end
	end    

 for i=1,#items do
 	name = items[i]
 	id = ""
    wikiname = '' 	
	id=mw.wikibase.getEntityIdForTitle(items[i])
    if id == nil then id = '' end
    
if id ~= nil and id ~= '' then
    entity = mw.wikibase.getEntityObject(id)	

    if entity == nil then
		latitude = ""
	    longitude = ""
	    end
	    
	local claims = entity.claims
	if claims == nil then
		latitude = ""
		longitude = ""
	    end	
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
	    end
	if claims.P18 ~= nil then
		image = entity.claims.P18[1].mainsnak.datavalue.value
		if image == nil then
			image = ""
			end
		end
	end

    wikiname = ""	
	lang = mw.language.getContentLanguage(id).code
	wiki = lang .. "wiki"
	if pcall(function()t1 = entity:getSitelink("wiki") end) then	
        wikiname = entity:getSitelink(wiki) or ""
    else
    	wikiname = ""
    end

if id == "" then wikiname = "" end
if id ~= nil and id ~= "" then
			name = "[[" .. name .. "]]"
end
if latitude ~= "" then counter = counter + 1 end
-- make different type for listings after groups of 99

    listing = '* {{ listing | type=' .. type .. ' | name=' .. name .. " | lat=" .. latitude .. " | long=" .. longitude .. " | image=" .. image .. " | wikipedia=" .. wikiname .. " | wikidata=" .. id .. "}}"
    data = data .. listing .. "\n"
    listing = ''
    name = ''
    latitude = ''
    longitude = ''
    image= ''
    id = ''
    wikiname = ''
	
end
    
    return data
    

end

function p.dumbidea(frame)
	local data = ""
data = '* {{User:Matroc/Mapdraw2 | map=link '
data = data .. '| group=shape | show=shape | type=poly '
data = data .. '| shape=external | geotype=geoshape | class=no-icon  | title=HELP  | stroke=#4B0082'
data = data .. '| strokewidth=3 | fill=\#ff00ff | id=Q25396 | zoom=9  | text=TEST GEOSHAPE }}'
	return data
end

-- WIKISTIES INFORMATION 

function p.wikisites(frame)
--    if frame.args[1]~=nil and frame.args[1]~='' then
--        return frame.args[1]
--    end

	local arg1 = frame.args[1] or ""
local xarg1 = arg1
	local arg2 = frame.args[2] or "wikivoyage" -- wikiname for program - wikivoyage alternative

-- if not Qnnn then get local Qnnn id

if string.find(arg1,"^w") ~= nil then
	arg2 = arg1
end

if string.find(arg1,"^Q") == nil then
	local item = mw.wikibase.getEntityObject()
	if item == nil then return end
	if item.id ~= nil then
		arg1 = item.id
	else
		return
	end
end

	local wikinames = loadwikinames() -- table of wikinames
	local lukup = ""
	for k,v in pairs(wikinames) do
		if v == arg2 then
			lukup = v .. "$"
		end
	end
	if lukup == "" then
		return
	end
	local entity = mw.wikibase.getEntityObject(arg1)	
--	local entity = mw.wikibase.getEntityObject()
    if entity == nil then return end
	local sites = entity.sitelinks 

	if sites ~= nil and sites ~= '' then
    	local list = ""
    	local newlist = ""
    	local separator = "%s"
    	local tt = {}
    	local asitelink = ""		
		for k,v in pairs(sites) do
			if string.match(k,lukup) == arg2 then
				asitelink = entity:getSitelink(k)
				asitelink = string.gsub(asitelink," ","@@@")
     			list = list .. "'''" .. string.gsub(k,lukup,"") .. "''':''" ..  asitelink .. "'' "
     		end
    	end
		list = string.gsub(list," $","")
		if list == "" then return "" end
		count = 1
		for str in string.gmatch(list,"([^"..separator.."]+)") do
			tt[count] = str
			count = count + 1
		end
		table.sort(tt)
		for k,v in pairs(tt) do
			newlist = newlist .. v .. ", "
		end
		newlist = string.gsub(newlist,", $","")
		newlist = string.gsub(newlist,"@@@"," ")
		newlist = "<span style=\"color:blue; font-family:Times New Roman; font-weight:bold\">" .. arg2 .. "</span>: " .. newlist
		return newlist
	end
    return ""
end

-- Load a page and scan it for images and produce a list of internal links

function p.getinternallinks(frame)
		local page = frame.args[1] or "Main Page"
        local title = mw.title.new(page)
        local displayactual = frame.args['option'] or "yes"
        if title == nil then return end

        if title.id == 0 then
            return "Page does not exist!"
        end

        local data = title:getContent()
		
		if data == nil or data == "" then
			return
		end

		local tt = {}
		local count = 0
		local output = ""
		local separator = "@@@@@"
		local newstr = ""		
			

		data = string.gsub(data,"\n","@@@@@")								--change \n to separator @@@@@
		data = string.gsub(data,"@","BULLET")								--because I use @@@@@ as a separator changing @ to BULLET
		data = string.gsub(data,"%s+"," ")									--change multiple spaces to a space
		data = string.gsub(data,"%[%[","@@@@@[[")							--change [[ to separator @@@@@[[
		data = string.gsub(data,"%]%]","]]@@@@@")							--change ]] to separator ]]@@@@@
		data = string.gsub(data,"@@@@@@@@@@","@@@@@")						--change ]] to separator ]]@@@@@

		for str in string.gmatch(data,"([^"..separator.."]+)") do

			if str ~= nil and str ~= "" then

-- Get rid of File,file,Image,image
 str = string.gsub(str,"%[%[[fF]ile.*",'')
 str = string.gsub(str,"%[%[[iI]mage.*",'')

				str = string.gsub(str,'%s*$','')       					-- drop ending space
				str = string.gsub(str,'^%s+','')
					if string.find(str, '^%[%[') == 1 then			    -- Key is to have [[ at beginning
					    str = string.gsub(str,'%_'," ")                 -- Change _ to space
						str = string.gsub(str,'%%2C',",")
						str = string.gsub(str,'%s+%|%s+','|')
						str = string.gsub(str,'%[%[%#','[[' .. page .. '#')
						
-- If plain [[something]] then change it into [[something|something]]
	if string.find(str, '^%[%[.*%|.*%]%]') == 0 then
       str = string.gsub(str,"(%[%[)(.*)(%]%])","%1%2|%2%3")   -- Change [[something]] to  [[something|something]] 
  end

-- Display only actual link make it an option
if displayactual == "yes" then
	str = string.gsub(str,"%|.*%]%]","]]")
end
					    count = count + 1
--					    localstr = str.gsub(str,'^.*|','')
                        localstr = str.gsub(str,'|.*','')
                        localstr = string.upper (localstr)

						tt[count] = localstr .. "@-@" .. str
						end
				end
		end

		table.sort(tt)
		local previous = ""

		for key,value in pairs(tt) do
value = string.gsub(value,'^.*@-@','')
			if value ~= previous then
                output = output .. value .. " -- "
			end
			    previous = value
		end		

		output = string.gsub(output,"BULLET","@")
		output = string.gsub(output," -- $","")
	return output
end

-- 
function p.grabmarkertype(frame)
local sectionorig = frame.args['section'] or ""
local section = ""
local sectionx = ""
local level = frame.args['level'] or "0"
   if sectionorig == nil or sectionorig == "" then
   	level = "0"
    end
    if tonumber(level) <= 1 or tonumber(level) > 5 then
    	level = "0"
    	sectionorig = ""
    end
local a,b,c,d = ""
local part1 = ""
local part2 = ""
		local page = frame.args['page'] or ""
		local type = frame.args['type'] or ""
        local title = mw.title.new(page)
        local sort = frame.args['sort'] or "no"
        local sortbytype = frame.args['sortbytype'] or "no"
        local sortby = ""
        local sortname = ""
        local data = ""
        local newdata = ""
        if title == nil then return end
        if title.id == 0 then
            return "Page does not exist!"
        end
        newdata = title:getContent()
		if newdata == nil or newdata == "" then
			return
		end
-- IMPORTANT TO INCORPORATE IN SOME OF THE TEST MODULES ABOVE GOING BY LINE TO INITIATE
        for line in string.gmatch(newdata,'[^\r\n]+') do      -- change any @ to BULLET
            line = string.gsub(line,"@","BULLET")             -- add a @@@@@ to each line to act as a separator
            line = string.gsub(line,"%s+|%s+","|")
            line = string.gsub(line,"^%*%s+|","")
            line = string.gsub(line,"^%*+%s+","")
            line = string.gsub(line,"%[%[File:.*%]%]","")
            line = string.gsub(line,"%[%[Image:.*%]%]","")            
            if line ~= "^$" then
                if string.find(line, "^[%||%}|%{]") ~= nil then
                   line = string.gsub(line,"^%}%}","}}@@@@@")
                   data = data .. line
                 else
	               data = data .. line .. "@@@@@"
	              end
	         end
        end
		local tt = {}                                         -- create an arrary for markers
		local count = 0                                       -- local counter for arrary tt
		local output = ""                                     -- output - destination of all markers
		local separator = "@@@@@"                            -- indicator for line separation
		local newstr = ""                                     -- to be used for sorting of markers by name if desired		
if sectionorig ~= nil and sectionorig ~= "" then
	sectionorig = string.gsub(sectionorig,"@","|")
    if level == "5" then
	    section = "section5" .. sectionorig .. "section5"
        sectionx = "section5 " .. sectionorig .. " section5"
        end	
     if level == "4" then
	    section = "section4" .. sectionorig .. "section4"
         sectionx = "section4 " .. sectionorig .. " section4"	         
         end	
      if level == "3" then
         section = "section3" .. sectionorig .. "section3"
         sectionx = "section3 " .. sectionorig .. " section3"
        end
      if level == "2" then
         section = "section2" .. sectionorig .. "section2"
         sectionx = "section2 " .. sectionorig .. " section2"
         end
      data = string.gsub(data,"%(","openparens")
      data = string.gsub(data,"%)","closeparens")
      data = string.gsub(data,"%|","PIPE")
      data = string.gsub(data,"%.","PERIOD")
      data = string.gsub(data,"%,","COMMA")
      data = string.gsub(data,"(==+)(%[+%s*)","%1")
      data = string.gsub(data,"(%s*%]+)(==+)","%2")
      data = string.gsub(data,"openparens","(")
      data = string.gsub(data,"closeparens",")")
      data = string.gsub(data,"PIPE","|")
      data = string.gsub(data,"PERIOD",".")
      data = string.gsub(data,"COMMA",",")
      data = string.gsub(data,"=====","section5")
      data = string.gsub(data,"====","section4")
	  data = string.gsub(data,"===","section3")
	  data = string.gsub(data,"==","section2")
      if string.find(data,sectionx .. ".*") ~= nil
         then section = sectionx
          end
      if string.find(data,section .. ".*") == nil then return "section not found"
      	else
        a,b = string.find(data,section .. ".*")
            data = string.sub(data,a)
            part1 = data
      	end
      if string.find(data,section .. ".*",10) ~= nil then
          c,d=string.find(data,section .. ".*",10)
          part1 = string.sub(data,1,c)
          part2 = string.sub(data,c)
       end
       part1 = string.gsub(part1,section,"BEGINSECTION")
       part2 = string.gsub(part2,section,"BEGINSECTION")
      if level == "2" then
         part1 = string.gsub(part1,"section2.*","")
         part2 = string.gsub(part2,"section2.*","")        		
        end
       if level == "3" then
        	part1 = string.gsub(part1,"section[23].*","")
        	part2 = string.gsub(part2,"section[23].*","")
        end
        if level == "4" then
        	part1 = string.gsub(part1,"section[234].*","")		
        	part2 = string.gsub(part2,"section[234].*","")		
         end
        if level == 5 then
            part1 = string.gsub(part1,"section[2345].*","")
        	part2 = string.gsub(part2,"section[2345].*","")		        		
          end
          data = part1 .. part2
           part1 = ""
           part2 = ""
        data = string.gsub(data,"BEGINSECTION",section)
        data = data
   end


        data = string.gsub(data,"\n%s+%|","|")
		data = string.gsub(data,"%s+"," ")					  --change multiple spaces to a space
		data = string.gsub(data,"%}%}%}","rightcurliesrightcurliesrightcurlies")
		data = string.gsub(data,"%{%{%{","leftcurliesleftcurliesleftcurlies")		
		data = string.gsub(data,"({{)(IATA|)(...)(}}","leftcurliesleftcurlies%2%3rightcurliesrightcurlies") -- Special case
-- SPACE FOR MORE SPECIAL CASES		
		data = string.gsub(data,"%*%s+%{","{")
		data = string.gsub(data,"%*%{","{")
		data = string.gsub(data,"%{ ","{")
		data = string.gsub(data,"%{%{","@@@@@{{")							--change {{ to separator @@@@@{{
		data = string.gsub(data,"%}%}","}}@@@@@")							--change }} to separator ]]@@@@@
		data = string.gsub(data,"==+","@@@@@")
--change to separator@@@@@
		data = string.gsub(data,"@@@@@@@@@@","@@@@@")
		data = string.gsub(data,"%}%}@@@@@ %&mdash;","}} &mdash;")
		data = string.gsub(data,"%}%}@@@@@, ","}}, ")
		data = string.gsub(data,"%}%}@@@@@%s%[","}} [")
		data = string.gsub(data,"%}%}@@@@@%-","}} -")
		data = string.gsub(data,"%}%}@@@@@ –","}}  –")
		data = string.gsub(data,"%}%}@@@@@%s%-","}} -")							-- take care of text at end of line if any 1/2 way
        data = string.gsub(data,"%}%}@@@@@ %(","}} (")                            -- oddballs add here
data = string.gsub(data,"%}%}@@@@@ ","}} ")

        data = "@@@@@" .. data .. "@@@@@"

		for str in string.gmatch(data,"([^"..separator.."]+)") do
			if str ~= nil and str ~= "" then
				str = string.gsub(str,'%s+$','')       					-- drop ending space
				str = string.gsub(str,'^%s+','')
				if string.find(str, '^%{%{marker') ~= nil then		-- Key is to have {{marker at beginning
					str = string.gsub(str,'%_'," ")                 -- Change _ to space
					str = string.gsub(str,'%%2C',",")
					str = string.gsub(str,'%s+%|%s+','|')
					str = string.gsub(str,"BULLET","@")
					if string.find(str,"type=") == nil then           -- no type then add type listing to marker as default
						  str = string.gsub(str,"%{%{marker","{{marker|type=listing")
					    end					
				    if sort == "yes" then
                       sortname = str
                       sortname = str.gsub(sortname,"%s+%|%s+","|")                -- space|space to |
                       sortname = str.gsub(sortname,"^.*%|name=","")               -- chop up to name=
                       sortname = str.gsub(sortname,"%|.*","")                     -- delete | and after - CHANGE
                       sortname = str.gsub(sortname,"%]+.*","")                    -- delete ]] and after
                       sortname = str.gsub(sortname,"%[+","")
                       sortname = str.gsub(sortname,"}+.*","")
                       sortname = sortname .. string.rep(".", 20 - #sortname)       -- pad sortname to 40 chars
                       sortname = sortname:upper()
                       sortname = sortname .. "SORTIT"
                       if sortbytype == "yes" then
                           sortby = str
                           sortby = str.gsub(sortby,"%s+%|%s+","|")                 -- space|space to |
                           sortby = str.gsub(sortby,"^.*type=","")                 -- chop up to type=
                           sortby = str.gsub(sortby,"%|.*","") 
                           sortby = str.gsub(sortby,"}+.*","")
                           sortby = sortby:upper()
                           sortby = sortby .. string.rep(".", 10 - #sortby)
                           sortname = sortby .. sortname
                        end
                    end

                    if type ~= nil and type ~= "" then
                          if string.find(str,"type=" .. type) ~= nil then          	
					         count = count + 1
                             if sort == "yes" then					         
                                 tt[count] = sortname .. str
                                 else
                                	tt[count] = str
                                 end
                             end
                          else
                       	       count = count + 1
                               if sort == "yes" then
                       	             tt[count] = sortname .. str
                                   else
	                                 tt[count] = str
                                 end
                           end
					end
				end
		end

        if sort == "yes" then
		     table.sort(tt)
        end
		local previous = ""
		for key,value in pairs(tt) do
			if value ~= previous then
                if sort == "yes" then
                      output = output .. "* " .. string.gsub(value,".*SORTIT","") .. "\n"
                   else
                     output = output .. "* " .. value .. "\n"
                   end
			end
			    previous = value
		end		
        output = string.gsub(output,"rightcurlies","}")
        output = string.gsub(output,"leftcurlies","{")
		output = string.gsub(output,"BULLET","@")
	return output
end


--  grab a mapmask if possible and convert to different formats
--  for smaller mapmasks only -- otherwise run out of processing time!
function p.grabmapmask(frame)
	    local page = frame.args['name'] or ""
	    local out = frame.args['out'] or "inapoly"
	    local data = ""
	    local mapmask = ""
	    local inapoly = ""
	    local coordinates = ""
        local title = mw.title.new(page)
        if title == nil then return "Need name argument!" end
        if title.id == 0 then
            return "Page does not exist!"
        end
        data = title:getContent()
        
if string.match(data,"{{[M|m]apmask") == nil and string.match(data,"{{ [M|m]apmask") == nil  then 
	return "There is no mapmask in " .. page
	end
        
        data = string.gsub(data,".*{{[M|m]apmask","")
        data = string.gsub(data,".*{{ [M|m]apmask","")
        data = string.gsub(data,"}}.*","")
        data = string.gsub(data,"%s+","")
data = string.gsub(data,"\n","")
        data = string.gsub(data,"%w%=%w%|","")
        
        mapmask = data
        mapmask = string.gsub(mapmask,"^|","")
        mapmask = string.gsub(mapmask,"|"," | ")
        
        inapoly = string.gsub(data,",",":")
        inapoly = string.gsub(inapoly,"^|","")
        inapoly = string.gsub(inapoly,"|",", ")        
 
        coordinates = string.gsub(data,"^|","")
        coordinates = string.gsub(coordinates,"(%d+%.%d+)(,)(%d+%.%d+)","%3%2%1")

        coordinates = string.gsub(coordinates,"%|","],[")
        coordinates = "[[[" .. coordinates .. "]]]"
if out == "inapoly" then 
	return inapoly
elseif out == "mapmask" then 
	return mapmask
elseif out == "json" then
	return coordinates
end

	return "'''mapmask''' - " .. mapmask .. "\n\n'''inapoly''' - " .. inapoly .. "\n\n'''coordinates''' - " .. coordinates
end

function p.grabmarkerinpoly(frame)
		local page = frame.args['page'] or ""
		local type = frame.args['type'] or ""
        local title = mw.title.new(page)
        local data = ""
        local newdata = ""
        if title == nil then return end
        if title.id == 0 then
            return error "Page does not exist!"
        end
        newdata = title:getContent()
		if newdata == nil or newdata == "" or not newdata then
			return
		end
		local separator = "@@"
		local tt = {}                                         -- create an arrary for markers
		local count = 1                                       -- local counter for arrary tt
		local output = ""                                     -- output - destination of all markers
 		    newdata = string.gsub(newdata,"@","BULLET")
 		    newdata = string.gsub(newdata,"\n+"," ")
  		    newdata = string.gsub(newdata,"%s+"," ")
			newdata = string.gsub(newdata,"%{%{ Marker","@@{{marker")
			newdata = string.gsub(newdata,"%{%{ marker","@@{{marker")
			newdata = string.gsub(newdata,"%{%{Marker","@@{{marker")			
			newdata = string.gsub(newdata,"%{%{marker","@@{{marker")
			newdata = string.gsub(newdata,"@@@@","@@")
-- if newdata ~= nil then return newdata end
		for str in string.gmatch(newdata,"([^"..separator.."]+)") do
            if string.find(str,"^%{%{marker") ~= nil then
			   str = str.gsub(str,"}}.*","")
			   str = "@" .. str .. "@"
			   str = str.gsub(str,"= ","=")
			   str = str.gsub(str," =","=")			   
			   str = str.gsub(str,"name=","@n")
			   str = str.gsub(str,"lat=","@a")
			   str = str.gsub(str,"long=","@b")
			   str = str.gsub(str,"wikidata=","@w")
			   str = str.gsub(str,"zoom=","@z")
			   str = str.gsub(str,"type=","@t")
			   str = str.gsub(str,"url=","@u")
			   str = str.gsub(str,"image=","@i")
			   str = str.gsub(str,"^@{{marker","@xmarker")
			   str = str.gsub(str,"%s&s+"," ")
			   str = str.gsub(str,"%s@","@")
			   
			   str = string.gsub(str,"%s*|%s*@","@")
			   str = string.gsub(str,"@$","")
               output = output .. str .. ":"			   
               tt[count] = str
		       count = count + 1
             end				   
		end
			
output,_ = string.gsub(output,":$","")
return output

end

function p.combo(frame)
    local id = frame.args['id'] or ""
	local latitude = ""
	local longitude = ""
	local name = frame.args['name'] or ""
	local osm = "none"
	local linkosm = ""
    local entity = ""
    if id == "" or id == nil then
    	id=mw.wikibase.getEntityIdForTitle(name)
    end
    entity = mw.wikibase.getEntityObject(id)	
	if entity == nil then
		 return  "id=" .. id .. " name=" .. name .. " latitude=" .. latitude .. " longitude=" .. longitude .. " osm=" .. osm
		end    		
	local claims = entity.claims
	if claims == nil then
		return "id=" .. id .. " name=" .. name .. " latitude=" .. latitude .. " longitude=" .. longitude .. " osm=" .. osm 
	end	
	if claims.P625 ~= nil then
 		if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
		    latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
			latitude = string.format("%.6f",latitude)		     
		else
			latitude = ""
		end
 		if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then		
		    longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
		    longitude = string.format("%.6f",longitude)			
		else
			longitude = ""
		end
	end
	if claims.P402 ~= nil then
		osm = entity.claims.P402[1].mainsnak.datavalue.value or "none"
		if osm == nil then osm = "none" end
		if osm ~= "none" then linkosm = "[https://www.openstreetmap.org/relation/" .. osm .. " " .. osm .. "]"
			osm = linkosm
			end
	end	
	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then
		name = entity:getSitelink("enwikivoyage") or ""
		if name ~= nil and name ~= "" then
			name = "wv: [[" .. name  .."]]"
			else name = "wv: ----"
		end
	end
	return "* id='''" .. id .. "''' name=" .. name .. " latitude=" .. latitude .. " longitude=" .. longitude .. " osm=" .. osm
end

function p.checkuni(frame)

		local page = frame.args['page']	
		local separator = frame.args['separator'] or " " -- added so can put in a different separator default is space
		if separator == nil or separator == "" then separator = " " end
        local newdata = ""
        local title = mw.title.new(page)
        if title == nil then return "Non-existant or empty page! " .. page end
        if title.id == 0 then
            return "Page: " .. page .. " does not exist!"
        end

        newdata = title:getContent()
        if newdata == nil or newdata == "" or not newdata == true then
      	   return "No page data to work with! " .. page
        end
        local output = ""
        local counter = 1
         for txt in string.gmatch(newdata,"([^"..separator.."]+)") do        
             if mw.ustring.match(txt,"‎") ~= nil then
                output = output .. counter .. " " .. txt .. " "
                counter = counter + 1
             end
         end
return output
end


function p.checkevent(frame)
		local page = frame.args['page']	
        local newdata = ""
        local title = mw.title.new(page)
        if title == nil then return "Non-existant or empty page! " .. page end

        if title.id == 0 then
            return "Page: " .. page .. " does not exist!"
        end

        newdata = title:getContent()
        if newdata == nil or newdata == "" or not newdata == true then
      	   return "No page data to work with! " .. page
        end
        local name = ""
        local year = ""
        local month = ""
        local date = ""
        local endyear = ""
        local endmonth = ""
        local enddate = ""
        local yymmdd = ""
        local endyymmdd = ""
        local frequency = ""
        local separator = "@@@@"
        local counter = 1       
	    local formatcheck = ""
	    local checkdate = ""
              checkdate = os.date("%Y%m%d")
        local eventenddate = ""
        local output = ""
        local message = ""
        local strcopy = ""        
        
        local list = {}
        list[1] = {month="[Jj]an%a*",value="01"}
        list[2] = {month="[Ff]eb%a*",value="02"}
        list[3] = {month="[Mm]ar%a*",value="03"}
        list[4] = {month="[Aa]pr%a*",value="04"}
        list[5] = {month="[Ma]ay%a*",value="05"}
        list[6] = {month="[Jj]un%a*",value="06"}
        list[7] = {month="[Jj]ul%a*",value="07"}
        list[8] = {month="[Aa]ug%a*",value="08"}
        list[9] = {month="[Ss]ep%a*",value="09"}
        list[10] = {month="[Oo]ct%a*",value="10"}
        list[11] = {month="[Nn]ov%a*",value="11"}
        list[12] = {month="[Dd]ec%a*",value="12"}


        if string.find(newdata,"{{%s*[Ee]vent") == nil then
			return "No events found in page: " .. page .. "\n"
			end
			
         newdata = string.gsub(newdata,"@","BULLETX")			
	     newdata = string.gsub(newdata,"{{%s*[Ee]vent","@@@@{{Event")
		
         for str in string.gmatch(newdata,"([^"..separator.."]+)") do
          if string.find(str,"^%{%{[Ee]vent") ~= nil then 
          	 str = string.gsub(str,"{{%s*[Ee]vent","")
             str = string.gsub(str,"=%{%{","=opencurlyopencurly")
             str = string.gsub(str,"}}%s*|","closecurlyclosecurly|")
             str = string.gsub(str,"}}%s*}}","closecurlyclosecurly}}")

             str = string.gsub(str,"}}.*","")
             str = string.gsub(str,"%s*|%s*","@")
             str = "@" .. str .. "@"             
             str = string.gsub(str,"@%s*@","@")
             str = string.gsub(str,"%s*=%s*","=")
             str = string.gsub(str,"@yymmdd=@","@")
             str = string.gsub(str,"@endyymmdd=@","@")
             str = string.gsub(str,"@endyear=@","@")
             str = string.gsub(str,"@endmonth=@","@")
             str = string.gsub(str,"@enddate=@","@")             
             str = string.gsub(str,"%s@","@")
             
             
              name = string.gsub(string.gsub(str,"^.*@name=",""),"@.*","")
 
              if string.find(str,"yymmdd") ~= nil then
                 yymmdd = string.gsub(string.gsub(str,"^.*@yymmdd=",""),"@.*","")
                 yymmdd = string.gsub(yymmdd,"%s*-%s*","")
                 year = string.sub(yymmdd,1,4)
                 month = string.sub(yymmdd,5,6)
                 date = string.sub(yymmdd,7,8)
               end
 
               if string.find(str,"endyymmdd") ~= nil then
                   endyymmdd = string.gsub(string.gsub(str,"^.*@yymmdd=",""),"@.*","")
                   endyymmdd = string.gsub(yymmdd,"%s*-%s*","")
                   endyear = string.sub(yymmdd,1,4)
                   endmonth = string.sub(yymmdd,5,6)
                   enddate = string.sub(yymmdd,7,8)
               end

              if year == nil or year == "" then
                  year,_  = string.gsub(string.gsub(str,"^.*@year=",""),"@.*","")
              end

              if month == nil or month == "" then
                  month,_ = string.gsub(string.gsub(str,"^.*@month=",""),"@.*","")
              end

              if date == nil or date == ""then
                 date,_ = string.gsub(string.gsub(str,"^.*@date=",""),"@.*","")
              end

              if endyear == nil or endyear == "" then
                   endyear,_  = string.gsub(string.gsub(str,"^.*@endyear=",""),"@.*","")
              end

              if endyear == nil or endyear == "" then
              	endyear = year
              end

              if endmonth == nil or endmonth == "" then
                  endmonth,_  = string.gsub(string.gsub(str,"^.*@endmonth=",""),"@.*","")
              end

              if endmonth == nil or endmonth == "" then
              	endmonth = month
              end

              if endmonth == nil or endmonth == "" == nil then
              	endmonth = "00"
              	formatcheck = formatcheck .. " endmonth - notfound!"
              end

              if enddate == nil or enddate == "" then
              enddate,_ = string.gsub(string.gsub(str,"^.*@enddate=",""),"@.*","")
              end

              if enddate == nil or enddate == "" then
              	enddate = date
              end

              if enddate == nil or enddate == "" then
              	enddate = "00"
              	formatcheck = formatcheck .. " enddate - not found - set check enddate to 00!"
              end

              frequency,_ = string.gsub(string.gsub(str,"^.*@frequency=",""),"@.*","")

               for i=1,#list do
                   endmonth = string.gsub(endmonth,list[i].month,list[i].value)	
               end
               if string.match(endmonth,"^%d$") ~= nil then
                 	endmonth = string.format("%02d",tonumber(endmonth))
               end
               if string.match(endmonth,"^%d%d$") == nil then
               	    formatcheck = formatcheck .. " format for endmonth is invalid - set check endmonth to 00!"
               	endmonth = "00"
               end
                if string.match(enddate,"^%d$") ~= nil then
                 	enddate = string.format("%02d",tonumber(enddate))
               end
               if string.match(enddate,"^%d%d$") == nil then
               	formatcheck = formatcheck .. " format for enddate is invalid! - set check enddate to 00"
               	enddate = "00"
               end
              if string.match(endyear,"^%d%d%d%d$") == nil then
              	if string.match(endyear,"[Aa]nnual") ~= nil or frequency ~= nil or frequency ~= ""
              	   then
              	   	  formatcheck = formatcheck .. " Annual or Frequency set check endyear to 3000 "
              	      endyear = "3000"
              	   else
               	      formatcheck = formatcheck .. " format for endyear/year invalid set check endyear to 1000 "
                      	endyear = "1000"
                    end
               end
              eventenddate = endyear .. endmonth .. string.format("%02d",enddate)

              if frequency ~= nil and frequency ~= "" then
                    message = message .. " '''<span style= \"color:limegreen;\">Event entry of Frequency type! </span>''' "
               	end
 
               if year == "annual" or year == "Annual" then
                   message = message .. " '''<span style= \"color:limegreen;\">Event appears to be an Annual event! Event appears to be still a go!</span>''' "
                   elseif tonumber(checkdate) > tonumber(eventenddate) then 
               	      message = message .. " '''<span style= \"color:red;\">Event appears to be over!</span>''' "
                 else
                        message = message .. " '''<span style= \"color:limegreen;\">Event appears to be still a go! </span>''' " 
               end
               
              str = string.gsub(str,"^@","")
              str = string.gsub(str,"@$","")
              str = string.gsub(str,"@"," | ")
              str = string.gsub(str,"BULLETX","@")
              str = string.gsub(str,"opencurly","{")
              str = string.gsub(str,"closecurly","}")
str = string.gsub(str,"&#123;","{")
str = string.gsub(str,"&#x7b;","{")
str = string.gsub(str,"&#125;","}")
str = string.gsub(str,"&#x7d;","}")
str = string.gsub(str,"&#124;","|")
str = string.gsub(str,"&#x7c;","|")
              strcopy = "<div style=\"color:black; background:papayawhip; border:1px solid black;\">" .. str .. "</div>"
              str = "{{event|" .. str .. "}}"
              formatcheck = string.gsub(formatcheck,"^%s*","")
              output = output .. "<div class=\"rectangle\" style=\"width:100px; height:10px; background-color:black\"></div>" .. "\n"
              output = output .. "----\n* '''Page''': " .. page .. "''' Event''': " .. name .. " '''Results''': " .. message .. " '''Event end date''': "
              output = output .. eventenddate ..  "  '''Check date''': " .. checkdate ..  " '''date''': " .. date .. " '''month''': " .. month .. " '''year''' " .. year ..  " '''enddate''': " .. enddate .. " '''endmonth''': " .. endmonth .. " '''endyear''': " .. endyear .. "\n"
              if formatcheck ~= nil and formatcheck ~= "" then
              	output = output .. "\n* " .. str .. "\n\n* " .. strcopy  .. "\n\n*" .. "'''Verify all parameter format & useage requirements!''' " .. formatcheck
              	else
                  output = output .. "\n* " .. str .. "\n\n* " .. strcopy .. "\n\n* '''Verify all parameter formats & useage requirements!'''\n----\n" 
              end
 
-- clear - start anew
              title = ""
              name = ""
              year = ""
              month = ""
              date = ""
              endyear = ""
              endmonth = ""
              enddate = ""
              yymmdd = ""
              endyymmdd = ""
              eventenddate = ""
              frequency = ""
              message = ""
              formatcheck = ""
              strcopy=""
          end
      end
    return output	

end

function p.events(frame)
    local output = ""
    checkdate = os.date("%Y%m%d")
    local sortby = frame.args['sortby'] or "begindate"
    beginevent = ""
    endevent = ""
    order = {}
    order2 = {}
    order3 = {}
    counter = 1
    local name = ""
    local image = ""
    local list = {}
        list[1] = {month="[Jj]an%a*",value="01"}
        list[2] = {month="[Ff]eb%a*",value="02"}
        list[3] = {month="[Mm]ar%a*",value="03"}
        list[4] = {month="[Aa]pr%a*",value="04"}
        list[5] = {month="[Ma]ay%a*",value="05"}
        list[6] = {month="[Jj]un%a*",value="06"}
        list[7] = {month="[Jj]ul%a*",value="07"}
        list[8] = {month="[Aa]ug%a*",value="08"}
        list[9] = {month="[Ss]ep%a*",value="09"}
        list[10] = {month="[Oo]ct%a*",value="10"}
        list[11] = {month="[Nn]ov%a*",value="11"}
        list[12] = {month="[Dd]ec%a*",value="12"}
    local events = {}    
    events[1] = {name="World Youth Day in Panama City", text="World Youth Day in Panama, [[Panama]], 22-27 January",
    				year="2019", month="January", day="22", endyear="2019", endmonth="January", endday="27"}
    events[2] = {name="Winter Universiade 2019", text="Winter Universiade 2019, in [[Krasnoyarsk]], [[Russia]], March 2-12",
    				year="2019", month="March", day="2", endyear="2019", endmonth="March", endday="12"}
    events[3] = {name="European Capital of Culture", text="European Capital of Culture, [[Matera]] [[Italy]] and [[Plovdiv]] [[Bulgaria]]",
    			year="2019", month="January", day="1", endyear="2020", endmonth="December", endday="31"}
    events[4] = {name="2019 South Asian Games", text="2019 South Asian Games, in [[Kathmandu]] and [[Pokhara]], [[Nepal]], 9–18 March",
    			year="2019", month="March", day="9", endyear="2019", endmonth="March", endday="18"}
    events[5] = {name="Special Olympics World Summer Games", text="Special Olympics World Summer Games, [[Abu Dhabi]], [[United Arab Emirates]], 14–21 March",
    			year="2019", month="March", day="14", endyear="2019", endmonth="March", endday="21"}
    events[6] = {name="Eurovision song contest", text="Eurovision song contest, [[Tel Aviv]], [[Israel]], Tuesday 14, Thursday 16 and Saturday 18 May 2019",
    			year="2019", month="May", day="14", endyear="2019", endmonth="May", endday="18"}
    events[7] = {name="Travelling during Ramadan", text="[[Travelling during Ramadan]], 6 May–3 June",
    			year="2019", month="May", day="6", endyear="2019", endmonth="June", endday="3"}
    events[8] = {name="WorldPride New York",text="2019 WorldPride [[New York City | NYC]], 1-30 June",
    			year="2019", month="June", day="1", endyear="2019", endmonth="June", endday="1"}
    events[9] = {name="2019 Summer Universiade", text="2019 Summer Universiade, [[Naples]], [[Italy]], in July",
    			year="2019", month="July", day="3", endyear="2019", endmonth="July", endday="14"}
    events[10] = {name="2019 Pacific Games", text="2019 Pacific Games, [[Apia]], [[Samoa]], 8-20 July",
    			year="2019", month="July", day="8", endyear="2019", endmonth="July", endday="20"}
    events[11] = {name="Wikimania", text="Wikimania, [[Stockholm]]], [[Sweden]] 14-18 August",
    			year="2019", month="August", day="14", endyear="2019", endmonth="August", endday="18"}
    events[12] = {name="Pan American/Parapan American Games", text="Pan American/Parapan American Games, in [[Lima]], [[Peru]], 26 July 26-1 September",
    			year="2019", month="September", day="26", endyear="2019", endmonth="September", endday="26"}
    events[13] = {name="Toronto International Film Festival", text="Toronto International Film Festival, in [[Toronto]], [[Canada]], 5–15 September",
    			year="2019", month="September", day="5", endyear="2019", endmonth="September", endday="15"}
    events[14] = {name="12th African Games", text="12 African Games, in [[Casablanca]], [[Morocco]], 14-31 October",
    			year="2019", month="October", day="14", endyear="2019", endmonth="October", endday="14"}
    events[15] = {name="Southeast Asian Games", text="Southeast Asian Games, the [[Philippines]], 29 November-10 December",
    	year="2019", month="November", day="29", endyear="2019", endmonth="December", endday="29"}
    events[16] = { name="Invictus Games", image="Invictus games logo cropped.png", text="From Oct 20-27, 2018, [[Sydney]], [[Australia]], will host the '''Invictus Games''', an international multi-sport event in which wounded, injured or sick armed services personnel and veterans take part in sports.",
    			year="2018", month="October", day="20", endyear="2018", endmonth="October", endday="27" }

    for i=1,#events do
         if events[i].endyear == nil then events[i].endyear = events[i].year end
         if events[i].endmonth == nil then events[i].endmonth = events[i].month end
         if events[i].endday == nil then events[i].endday = events[i].day end
    	    for x=1,#list do
               events[i].month = string.gsub(events[i].month,list[x].month,list[x].value)
               events[i].endmonth = string.gsub(events[i].endmonth,list[x].month,list[x].value)            
             end
          if events[i].image == nil then events[i].image = "" end
          events[i].day = string.format("%02d",tonumber(events[i].day))
          events[i].endday = string.format("%02d",tonumber(events[i].endday))
          beginevent = events[i].year .. events[i].month .. events[i].day
          endevent = events[i].endyear .. events[i].endmonth .. events[i].endday
          
          order[counter] = "@a" .. beginevent .. "@b" .. endevent .. "@n" .. events[i].name .. "@i" .. events[i].image .. "@t" .. events[i].text
          order2[counter] = "@b" .. endevent .. "@a" .. beginevent .. "@n" .. events[i].name .. "@i" .. events[i].image .. "@t" .. events[i].text
      
          counter = counter + 1
    end
    
    table.sort(order)

    counter = 1    
    for i=1,#order do
        beginevent = string.gsub(order[i],"^.*@a","")
        beginevent = string.gsub(beginevent,"@.*$","")
        endevent =string.gsub(order[i],"^.*@b","")
        endevent = string.gsub(endevent,"@.*$","")        
        name = string.gsub(order[i],"^.*@n","")
        name = string.gsub(name,"@.*$","")         
        image = string.gsub(order[i],"^.*@i","")
        image = string.gsub(image,"@.*$","")         
        text = string.gsub(order[i],"^.*@t","")
        text = string.gsub(text,"@.*$","")
        

        if tonumber(checkdate) > tonumber(endevent) then
           output = output .. "* Event " .. name .. " has expired!"  .. checkdate .. " " .. beginevent .. " " .. endevent .. "\n"
        elseif tonumber(checkdate) >= tonumber(beginevent) and tonumber(checkdate) <= tonumber(endevent) then
           output = output .. "* Event " .. name .. " is happening"  .. checkdate .. " " .. beginevent .. " " .. endevent .. "\n"

        elseif tonumber(checkdate) > tonumber(beginevent) - 30 and tonumber(checkdate) < tonumber(endevent) then
                output = output .. "* Event " ..name .. " attempt at 30 day notice! !"  .. checkdate .. " " .. beginevent .. " " .. endevent .. "\n"

         elseif tonumber(checkdate) < tonumber(beginevent) and tonumber(checkdate) < tonumber(endevent) then
         	    output = output .. "*Event " .. name .. " is a future event! " .. checkdate .. " " .. beginevent .. " " .. endevent .. "\n"
         else
         	output = output .. checkdate .. "CHECK " .. beginevent .. " " .. endevent .. "\n"
         end
    end
--    output = "|title2=" .. events[1].name .. "|content2=" .. events[1].text
return output

end


-- below replaced with quickgrab2 below
-- TO BE REMOVED

function p.quickgrab(frame)
	    local page = frame.args['page'] or "Ethiopia"
	    local type = frame.args['type'] or "marker"
	    local subtype = frame.args['subtype'] or ""
	    local pattern = ""
	    local counter = 0
	    local copypattern = ""
--	    type = string.gsub(type,"(%a)(.*)","[" .. string.upper(%1) .. string.lower(%1) .. "]%2")
        local title = mw.title.new(page)
        if title == nil then return "Non-existant or empty page! " .. page end
        
        if title.id == 0 then
            return "Page: " .. page .. " does not exist!"
        end

        local newdata = title:getContent()
        
        if newdata == nil or newdata == "" or not newdata == true then
      	   return "No data to work with on page: " .. page
        end
        
-- Special spot for addition-- UTF-8 characters if need be for gsub as they can kill processing in places

        newdata = string.gsub(newdata,"ö","UMLAUT")
        newdata = string.gsub(newdata,"ß","SSSSS")        
-- General can get away with 
       	newdata = string.gsub(newdata,"%s*|%s*","|") -- yes - no spaces around
       	newdata = string.gsub(newdata,"%s+"," ") -- down to single spacing
-- see also
-- anchor
       	if type ~= "IATA" then
             newdata = string.gsub(newdata,"{{IATA(%|*%w*)}}","opencurlyopencurlyIATA%1closecurlyclosecurly")      	
        end
        
        if type ~= "rint" then
            newdata = string.gsub(newdata,"{{rint(%|*%w*%|*%w*)}}","opencurlyopencurlyrint%1closecurlyclosecurly")
            newdata = string.gsub(newdata,"{{rint(%/*%w*%|*%w*)}}","opencurlyopencurlyrint%1closecurlyclosecurly")
            newdata = string.gsub(newdata,"{{rint(%/*%w*%|*%w*%|*%w*)}}","opencurlyopencurlyrint%1closecurlyclosecurly")        	
        end
        if type == "flag+" then
        	type = "flag"
        	newdata = string.gsub(newdata,"{{flag|(%w*%s*%w*%s*%w*%s*%w*%s*%w*%s*%w*%s*)}}%s*{{","{{flag|%1closecurlyclosecurly opencurlyopencurly")
        end
        if type ~= "station" then
             pattern="|%w*%/*%s*%w*"
             counter = 0
             copypattern=pattern
             for i=1,15 do
                newdata,counter = string.gsub(newdata,"{{station(" .. copypattern .. ")}}","opencurlyopencurlystation%1closecurlyclosecurly")
               copypattern = copypattern .. pattern
             end
         end
        if type ~= "station" and type ~= "rint" and type ~= "marker" and type ~= "anchor" then
--        newdata = string.gsub(newdata,"%*%s*%{%{","*{{")
        newdata = string.gsub(newdata,"%{%{%{%{","{{opencurlyopencurly") -- Question - internal template?
        newdata = string.gsub(newdata,"}}}}","closecurlyclosecurly}}")
        newdata = string.gsub(newdata,"%{%{%{","opencurlyopencurlyopencurly")
        newdata = string.gsub(newdata,"}}}","closecurlyclosecurlyclosecurly")
        newdata = string.gsub(newdata,"=%{%{","=opencurlyopencurly") 
        newdata = string.gsub(newdata,"}}%s*|","closecurlyclosecurly|")
--        newdata = string.gsub(newdata,"}} ","closecurlyclosecurly ")
--        newdata = string.gsub(newdata,"}}%,","closecurlyclosecurly,")
--        newdata = string.gsub(newdata,"}}%;","closecurlyclosecurly;")
        newdata = string.gsub(newdata,"}}%s*}}","closecurlyclosecurly}}")
        newdata = string.gsub(newdata,"@","BULLET")
        
        else 
        	
        end
        
        local output = ""

-- local xyz = string.match (mw.title.new ('United States National Parks'):getContent(), '{{ *marker *| *([^}]+) *}}')
        local zip = type
--        zip = "[" .. string.upper(string.sub(type,1,1)) .. string.lower(string.sub(type,1,1)) .. "]"  .. string.sub(zip,2,20)
        if subtype == nil or subtype == "" then
             for i in string.gmatch (newdata, '{{%s*' .. zip .. '%s*|%s*([^}]+)%s*}}') do
                output = output .. "\n* {{" .. type .. "|" .. i .. "}}"
             end
        else
             for i in string.gmatch (newdata, '{{%s*' .. zip .. '%s*|%s*type=' .. subtype .. '%s*|%s*([^}]+)%s*}}') do
                output = output .. "\n* {{" .. type .. "| type=" .. subtype .. "|" .. i .. "}}"
             end	
        end
        output = string.gsub(output,"opencurly","{")
        output = string.gsub(output,"closecurly","}")
        output = string.gsub(output,"BULLET","@")
        output = string.gsub(output,"UMLAUT","ö")
        output = string.gsub(output,"SSSSS","ß")
        return output
    end

-- Generally speaking - listing templates such as see can contain marker, station and rint templates and hopefully not another see template
-- markers, station and rint templates can be extracted on their own - or can grab station & other templates within the confines of
-- an overall template - this insures the complete template one is looking for... -- Matroc
-- getname  local function for quickgrab2

local function getname(page)
	local name=mw.wikibase.getEntityIdForTitle(page)
	if name == "" or name == nil then return "" end
	return name
	end

function p.quickgrab2(frame)
	    local sort = frame.args['sort'] or "no"
	    local sortname = ""
	    local sectionorig = frame.args['section'] or ""
	    local section = ""
	    local sectionx = ""
	    local level = frame.args['level'] or "0"
	    if sectionorig == nil or sectionorig == "" then
	    	level = "0"
	    end
	    if tonumber(level) <= 1 or tonumber(level) > 5 then
	    	level = "0"
	    	sectionorig = ""
	    end
	    local name = frame.args['name'] or ""          -- look for particular name=aaaaa aaa
        local counter = 1                              -- counter for array content
        local content = {}                             -- array for matching template entries
        local x = ""                                   -- beginning position for template str to be output
        local y = ""                                   -- end position of template str to be output
        local output = ""                              -- concatenated output of found template strings
        local separator = "@@@@@"                      -- separator to split page up by	
	    local page = frame.args['page'] or ""          -- page to lookup and work from
	    local type = frame.args['type'] or ""          -- type of listing to search for (ie listing)
		local typeul = ""                              -- type for replacement 1st character becomes {Aa]	    
	    local subtype = frame.args['subtype'] or ""    -- specific type to select from 
	    local subtypeul = ""                           -- 1st character for replacement 1st character becomes [Aa]
	    local zip = ""                                 -- used to copy typeul and/or subtypeul
	    local replacement = ""                         -- replacement string to make templates in common form	    
        local title = mw.title.new(page)               -- create an empty new page workspace -- later get Content of existing page to work with 
        
        if type == nil or type == "" then
        	return "Selection type is missing for page: " .. page end
        
        if title == nil then return "Non-existant or empty page! " .. page end
        
        if title.id == 0 then
            return "Page: " .. page .. " does not exist!"
        end
        local id = getname(page)                 -- certain mapshapes don't have anything but would need id
        local newdata = title:getContent()
        local part1 = ""
        local part2 = ""                           -- split up newdata if need be to 2 parts then recombine
        local a,b,c,d = 0
        
        if newdata == nil or newdata == "" or not newdata == true then
      	   return "No data to work with on page: " .. page
        end
        if sectionorig ~= nil and sectionorig ~= "" then
	         sectionorig = string.gsub(sectionorig,"@","|")
             if level == "5" then
	            section = "section5" .. sectionorig .. "section5"
        	    sectionx = "section5 " .. sectionorig .. " section5"
             end	
             if level == "4" then
	              section = "section4" .. sectionorig .. "section4"
        	      sectionx = "section4 " .. sectionorig .. " section4"	         
             end	
             if level == "3" then
        	      section = "section3" .. sectionorig .. "section3"
        	      sectionx = "section3 " .. sectionorig .. " section3"
              end
             if level == "2" then
        	    section = "section2" .. sectionorig .. "section2"
        	    sectionx = "section2 " .. sectionorig .. " section2"
             end
            newdata = string.gsub(newdata,"%(","openparens")
            newdata = string.gsub(newdata,"%)","closeparens")
            newdata = string.gsub(newdata,"%|","PIPE")
            newdata = string.gsub(newdata,"%.","PERIOD")
            newdata = string.gsub(newdata,"%,","COMMA")
            newdata = string.gsub(newdata,"(==+)(%[+%s*)","%1")
            newdata = string.gsub(newdata,"(%s*%]+)(==+)","%2")
            newdata = string.gsub(newdata,"openparens","(")
            newdata = string.gsub(newdata,"closeparens",")")
            newdata = string.gsub(newdata,"PIPE","|")
            newdata = string.gsub(newdata,"PERIOD",".")
            newdata = string.gsub(newdata,"COMMA",",")
            newdata = string.gsub(newdata,"=====","section5")
            newdata = string.gsub(newdata,"====","section4")
	        newdata = string.gsub(newdata,"===","section3")
	        newdata = string.gsub(newdata,"==","section2")
            if string.find(newdata,sectionx .. ".*") ~= nil
               then section = sectionx
            end
        	if string.find(newdata,section .. ".*") == nil then return "section not found"
        		else
                   a,b = string.find(newdata,section .. ".*")
                   newdata = string.sub(newdata,a)
                   part1 = newdata
       
        	end
        	if string.find(newdata,section .. ".*",10) ~= nil then
                c,d=string.find(newdata,section .. ".*",10)
                part1 = string.sub(newdata,1,c)
                part2 = string.sub(newdata,c)
            end
            part1 = string.gsub(part1,section,"BEGINSECTION")
            part2 = string.gsub(part2,section,"BEGINSECTION")
        	if level == "2" then
        		part1 = string.gsub(part1,"section2.*","")
        		part2 = string.gsub(part2,"section2.*","")        		
        		end
        	if level == "3" then
        		part1 = string.gsub(part1,"section[23].*","")
        		part2 = string.gsub(part2,"section[23].*","")
        		end
        	if level == "4" then
        		part1 = string.gsub(part1,"section[234].*","")		
        		part2 = string.gsub(part2,"section[234].*","")		
                end
            if level == 5 then
        		part1 = string.gsub(part1,"section[2345].*","")
        		part2 = string.gsub(part2,"section[2345].*","")		        		
                end
            newdata = part1 .. part2
            part1 = ""
            part2 = ""
        	newdata = string.gsub(newdata,"BEGINSECTION",section)
        	newdata = newdata
        end

        newdata = string.gsub(newdata,"\n", " ")        
        newdata = string.gsub(newdata,"%s+"," ")
        newdata = string.gsub(newdata,"@","BULLET")                           -- avoiding @ clash with @@@@@ separator
        newdata = string.gsub(newdata,"{{%s*","{{")
        newdata = string.gsub(newdata,"%s*}}","}}")        
        newdata = string.gsub(newdata,"%s*|%s*","|")
        newdata = string.gsub(newdata,'%{%{seealso','{{SEEALSO')
        newdata = string.gsub(newdata,'%{%{see also','{{SEEALSO')
        newdata = string.gsub(newdata,'%{%{[Ss]eeDistricts}}','SEEDISTRICTS')   -- other hatnotes could be added here as well
                                                                                -- to avoid issues with listing templates

-- should always have a type - marker,listing,see,mapframe,station,rint etc.

        if type == "flag+" then     -- common form substitution to get {{flag}} {{listing combinations
        	type = "flag"
            newdata = string.gsub(newdata,"-","HYPHEN")   -- special to be able to make match/substitutions
            newdata = string.gsub(newdata,"ã","AACCENTA")
            newdata = string.gsub(newdata,"é","EACCENTE")
            newdata = string.gsub(newdata,"í","IACCENTI")
            newdata = string.gsub(newdata,"'","ACCENT")
        	newdata = string.gsub(newdata,"{{[Ff]lag|(%w*%s*%w*%s*%w*%s*%w*%s*%w*%s*%w*)}}%s*{{","{{flag|%1closecurlyclosecurly opencurlyopencurly")
            newdata = string.gsub(newdata,"HYPHEN","-")
            newdata = string.gsub(newdata,"AACCENTA","ã")
            newdata = string.gsub(newdata,"EACCENTE","é")
            newdata = string.gsub(newdata,"IACCENTI","í")
            newdata = string.gsub(newdata,"ACCENT","'")
        end
        -- Some put in lowercase first character others uppercase - this should match up ok      
        zip = type        
        typeul = "[" .. string.upper(string.sub(zip,1,1)) .. string.lower(string.sub(zip,1,1)) .. "]"  .. string.sub(zip,2,20)
        replacement = typeul
        
        if subtype ~= nil and subtype ~= "" then
        	 zip = subtype
             subtypeul = "[" .. string.upper(string.sub(zip,1,1)) .. string.lower(string.sub(zip,1,1)) .. "]"  .. string.sub(zip,2,20)
             replacement = replacement .. "|type=" .. subtypeul
             newdata = string.gsub(newdata,"{{" .. replacement,"@@@@@{{" .. type .. "|type=" .. subtype)
           else
             newdata = string.gsub(newdata,"{{" .. replacement,"@@@@@{{" .. type)
        end

        for str in string.gmatch(newdata,"([^"..separator.."]+)") do
            if string.find(str,"^%{%{" .. replacement) ~= nil then
                if str ~= nil then
                   x,y = string.find(str,"%b{}")
                   if x ~= nil and y ~= nil then
                       str = string.sub(str,x,y)
                       str = string.gsub(str,"BULLET","@")
                       if name == nil or name == "" then
--                             str = string.gsub(str,"^","\n%* ")
                               if sort == "yes" then
                                  sortname = string.gsub(str,"^.*name=","")
                         --       sortname = string.gsub(sortname,"|.*","") -- sort by internal link
                                  sortname = string.gsub(sortname,"|%s*%w*=.*","")    -- sort by name
                                  sortname = string.gsub(sortname,"^.*|","")          -- sort by name                                  
                                  sortname = string.gsub(sortname,"}}.*","")
                                  sortname = str.gsub(sortname,"%[+","")
                                  sortname = sortname .. string.rep(".", 20 - #sortname)
                                  sortname = string.upper(sortname)
                                  str = sortname .. "SORTIT" .. str
                                  end
                             content[counter],_ = str
                             counter = counter + 1
elseif string.find(str,"|name=" .. name) ~= nil or string.find(str,"|name=%[%[" .. name) ~= nil or string.find(str,"name=%[%[%s*.*%s*|%s*" .. name) ~= nil then
--                             str = string.gsub(str,"^","\n%* ")
                               if sort == "yes" then
                                  sortname = string.gsub(str,"^.*name=","")
                         --       sortname = string.gsub(sortname,"|.*","") -- sort by internal link
                                  sortname = string.gsub(sortname,"|%s*%w*=.*","")    -- sort by name
                                  sortname = string.gsub(sortname,"^.*|","")           -- sort by name
                                  sortname = string.gsub(sortname,"}}.*","")
                                  sortname = str.gsub(sortname,"%[+","")  
                                  sortname = sortname .. string.rep(".", 20 - #sortname)
                                  sortname = string.upper(sortname)
                                  str = sortname .. "SORTIT" .. str
                                  end
                             content[counter],_ = str
                             counter = counter + 1		
                        end
                   end
                end
            end
       end
       if sort == "yes" then table.sort(content) end
       -- want some output to not be preceded by an *
       -- some templates like geo can't stand apaces befor and after |
       for i=1,#content do
       	   if string.match(type,"^[Mm]ap.*") ~= nil or string.match(type,"^[Gg]eo.*") ~= nil then
       	   	  if string.match(type,"[Mm]apshape") ~= nil and string.match(content[i],"{{[Mm]apshape}}") ~= nil then
                if id ~= nil then
                	content[i] = string.gsub(content[i],"}}","|wikidata=" .. id .. "}}")
   	   	  	        end
   	   	  	    end
       	   	  if string.match(type,"[Mm]apframe") ~= nil and string.match(content[i],"{{[Mm]apframe.*}}") ~= nil then
                if string.match(content[i],"name=") == nil then
                	content[i] = string.gsub(content[i],"}}","|name=" .. page .. "}}")
   	   	  	        end
   	   	  	    end   	   	  	    
   	   	  	    
       	   	  if string.match(type,"^[Gg]eo.*") ~= nil then
       	   	  	  content[i] = string.gsub(content[i],"|","PIPE")
       	   	  	  end
 	          output = output .. "\n" .. string.gsub(content[i],".*SORTIT","")
 	          else
 	          output = output .. "\n* " .. string.gsub(content[i],".*SORTIT","") 	          	
 	          end
         end
      output = string.gsub(output,"opencurly","{")
      output = string.gsub(output,"closecurly","}")
      output = string.gsub(output,"%{%{SEEALSO","{{see also")
      output = string.gsub(output,"%{%{SEEDISTRICTS","SeeDistricts")
      output = string.gsub(output,"|"," | ")
      output = string.gsub(output,"PIPE","|")
      return output	    
   end    



-- getting lat long image via passing an ID
local function returnitems(wikidata)
	local latitude = ""
	local longitude = ""
	local image = ""
	local id = wikidata
    local entity = mw.wikibase.getEntityObject(id)	
	if entity == nil then return latitude,longitude,image end    		
	local claims = entity.claims
	if claims == nil then
		return latitude,longitude,image
	end	
	if claims.P625 ~= nil then
		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
	end
	if claims.P625 ~= nil then
		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
	end
	if claims.P18 ~= nil then
	   image = entity.claims.P18[1].mainsnak.datavalue.value
	end
	return latitude,longitude,image
end

-- MOST OUTPUT FIXED

function p.returnit(frame)
	local data = frame.args[1] or ""
	local group = frame.args['group'] or "luksee"
	local show = frame.args['show'] or group
	local records = {}
	for i=1,100 do
		records[i] = {}
		records[i]['name'] = ""
		records[i]['wikidata'] = ""
		records[i]['lat'] = ""
		records[i]['long'] = ""
		records[i]['image'] = ""
		records[i]['description'] = ""
	end
	local separator = "ENDREC"
	local counter = 1
	local nolistings = 0
	local name= ""
	local wikidata = ""
	local lat = ""
	local long = ""
	local latitude = ""      -- from wikidata
	local longitude = ""     -- from wikidata
	local image = ""
	local latitudexx = ""
	local longitudexx = ""
	local imagexx = ""        -- from wikidata
	local description = ""
	local beginit = ""
	local endit = ""
    local output = ""
    local symbol = frame.args['symbol'] or "star"
    local color = frame.args['color'] or "#ffaabb"

	for line in string.gmatch(data,"([^"..separator.."]+)") do
		if line ~= "" and line ~= nil then
            line = "@@@@@" .. line
line = string.gsub(line,"XPIPEX","|")
--line = string.gsub(line,"EQUALS","=")
            line = string.gsub(line,"%}%}","@@@@@")
            line = string.gsub(line,'%}%}','')
            line = string.gsub(line,"%|","@@@@@")
            name = string.gsub(string.gsub(line,'^.*name%=',''),'@@@@@.*','')
            wikidata = string.gsub(string.gsub(line,'^.*wikidata%=',''),'@@@@@.*','')
            lat = string.gsub(string.gsub(line,'^.*lat%=',''),'@@@@@.*','')
            long = string.gsub(string.gsub(line,'^.*long%=',''),'@@@@@.*','')
            image = string.gsub(string.gsub(line,'^.*image%=',''),'@@@@@.*','')
            description = string.gsub(string.gsub(line,'^.*content%=',''),'@@@@@.*','')

--            if wikidata ~= nil and wikidata ~= "" then
--                latitudexx,longitudexx,imagexx = returnitems(wikidata)
--                if lat == nil or lat == "" then lat = latitudexx end
--                if long == nil or long == "" then long = longitudexx end
--                if image == nil or image == "" then image = imagexx end   
--               end -- end if wikidata

            if image ~= nil and image ~= "" then
               image = "[[File:" .. image .. "|260px]] "
               description = image .. description
              end
	
--            records[counter] = {}
            records[counter]['name'] = name or ""      -- assume there
            records[counter]['wikidata'] = wikidata or ""          -- may or may not be there
            records[counter]['lat'] = lat         -- may or may not be there
            records[counter]['long'] = long      -- may or may not be there
            records[counter]['image'] = image     -- may or ay not be there
            records[counter]['description'] = description  -- may or may not be there
            counter = counter + 1
 if records[2]['description'] ~= nil and records[2]['description'] ~= "" then
 	return records[2]['description'] end
 
-- if line ~= nil then return line end
-- if counter == 2 then return line end

          end
    end
-- checkpoint if counter >= 1 then return counter end
    beginit = "<maplink class=\"no-icon\" text=\"\" zoom=\"11\" group=\"seeSwansea\">{\""
    beginit = beginit .. "\"type\": \"FeatureCollection\", \"features\":  ["   
    endit = "] }</maplink> \n\n"

-- testcheck - if beginit ~= nil then return beginit .. endit end
 
   for i = 1,counter -1 ,1 do
     output = output .. '\<maplink class=\"icon\" text=\"\" zoom=\"11\" group=\"' .. group .. '\"\>\n'
     output = output .. '{\"type\": \"Feature\",\"geometry\": { \"type\":\"Point\", \"coordinates\":\n'
     output = output ..  '[' ..  records[i]['long'] .. "," .. records[i]['lat'] .. ']},\n'
     output = output .. '\"properties\":{\n'
     output = output ..  '\"title\": \"' .. records[i]['name'] .. '\",\n'
     if records[i]['description'] ~= nil and records[i]['description'] ~= "" then
         output = output .. '\"description\": \"' .. records[i]['description'] .. '\",\n'
         end
     output = output .. '\"marker-symbol\": \"' .. symbol .. '",\n'
     output = output .. '\"marker-color\": \"' .. color .. '\"\n}},'
-- testcheck2 - if output ~= nil then return output end   
     end

     if output ~= nil and output ~= "" then
     	output = string.gsub(output,"%,$",'') -- get rid of ending comma
        output = beginit .. output .. endit
        else
        	output = ""
        end
     return output
end

function p.linkref(frame)
	    local name = frame.args['name'] or ""
	    local output = ""
        local maplink = frame.args['maplink'] or "0"
        local id = frame.args['id'] or ""
        local lat = frame.args['lat'] or ""
        local latitude = ""
        local longitude = ""
        local long = frame.args['long'] or ""
        local zoom = frame.args['zoom'] or "11"
        local entity = ""
        local claims = ""
   if lat == nil or lat == '' and long == nil or long == '' then
        if id ~= nil and id ~= '' then
           entity = mw.wikibase.getEntityObject(id)
           claims = entity.claims
           if pcall(function () t =claims.P625 end ) then
 	          if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		
		        latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude
		         else latitude = "" end
 		     if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then		
		        longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude
	     	    else longitude = "" end
           end
       end
    end
    if lat ~= nil and lat ~= "" then latitude = lat end
    if long ~= nil and long ~= "" then longitude = long end
    latitude = string.format("%.4f",latitude)
    longitude = string.format("%.4f",longitude)
        output = "[[{{FULLPAGENAME}}#map/" .. maplink .. "/" .. zoom .. "/" .. latitude .. '/' .. longitude .. "|" .. name .. "]]"
return output
end

function p.newcenter(frame)
        local x = string.format("%.6f",frame.args['lat'])
        local y = string.format("%.6f",frame.args['long'])
        local radius = frame.args['radius']
        local angle = 0
		local ptx = 0
		local pty = 0
		local type = frame.args['type'] or "c"
		local direction = frame.args['direction'] or "e"
		     if direction ~= "e" and direction ~= "w" and direction ~= "n" and direction ~= "s" then
		     	direction = "e"
		     	end
		radius = tonumber(radius)
        if radius > 10 then error("10 for radius is MAX") end   -- my default
        if radius <= 0 then error("radius has to be greater than 0") end
        if type == "c" then
        	    radius = radius * 2
        	else
        		radius = radius * 1.5
        	end
        if direction == "e" then
           angle = 90 * math.pi / 180
           ptx = x + radius * math.cos( angle )
           pty = y + radius * math.sin( angle )
         end
        if direction == "w" then
           angle = 270 * math.pi / 180
           ptx = x + radius * math.cos( angle )
           pty = y + radius * math.sin( angle )
         end 
        if direction == "n" then
           angle = 360 * math.pi / 180
           ptx = x + radius * math.cos( angle )
           pty = y + radius * math.sin( angle )
         end           
        if direction == "s" then
           angle = 180 * math.pi / 180
           ptx = x + radius * math.cos( angle )
           pty = y + radius * math.sin( angle )
         end
         if tonumber(x) >= 10.5 then
         ptx = newlat(ptx) -- makes correction to make circle show up on map
        end
        if tonumber(x) <= -10.5 then
          ptx = newlat(ptx) -- makes correction to make circle show up on map
        end

        ptx = string.format("%.4f",ptx)
        pty = string.format("%.4f",pty)

        return "latitude: " .. ptx .. " - longitude: " .. pty
end
    
    


function p.connect(frame)
local id=frame.args['id']
local count = 0
local latlong = {}
local latitude = ""
local longitude = ""
local cumlat = 0
local cumlong = 0
local line = ""
local output=""
local entity = mw.wikibase.getEntityObject(id)	
	if entity == nil then return "No lat long" end    		
	local claims = entity.claims
	if claims == nil then
		return "No lat long"
	end	
	if claims.P625 ~= nil then
  for _ in pairs(entity.claims.P625) do count = count + 1
 longitude = entity.claims.P625[count].mainsnak.datavalue.value.longitude 
 latitude = entity.claims.P625[count].mainsnak.datavalue.value.latitude
 latlong[count] = longitude .. "," .. latitude
 cumlong = cumlong + longitude
 cumlat = cumlat + latitude
 	end
	end
    for i=1, count do
    	line = line .. "[" .. latlong[i] .. "]" .. ","
    end
line = string.gsub(line,"%,$","")
output = output .. '\n<mapframe text="Test Map" frame="yes" zoom="6" latitude="' .. cumlat/count .. '" longitude="' .. cumlong/count .. '" width="600" height="400" frame="yes">'
output = output .. '\n{"type": "FeatureCollection", "features":  ['	    	
    for i=1, count do
 output = output .. '\n\n{' .. '"type": "Feature",' .. '"properties": {' .. '"marker-color": "#bbccff",'
 output = output .. ' "marker-symbol": "-number",' .. '},' .. '\n\n"geometry": {' .. ' "type": "Point",'  	
    output = output .. ' "coordinates": [' .. latlong[i] .. "]}},"
   	end
   	output = output .. '\n\n{"type":"Feature", "properties": { "stroke":"#D3D3D3", "stroke-opacity":0.7, "stroke-width":50,},'
   	output = output .. '\n\n"geometry": {"type":"LineString", "coordinates": [' .. line .. ']}},'
   	output = output .. ']}<br></mapframe>\n'

end


return p