Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

// request.cf · coarse context

A page that knows where it met you.

Only coarse request metadata is shown. This demo does not display or persist visitor IP addresses.

Country
US
Cloudflare location
CMH
Connection
HTTP/2
Language
Not provided

Ray ID: a21d8ad869c5cf5e

Jump to content

Module:Sandbox/Innesw/test

From Wikipedia, the free encyclopedia
---------------- Defining variables--------------------
local Pop_P = "P1082"          -- population property
local Applies_P = "P518"       -- applies to part property
local Pointin_P = "P585"       -- point in time property
local DetMeth_P = "P459"       -- determination method property
local RefURL_P = "P854"        -- reference URL
local RefTitle_P = "P1476"     -- reference title
local RefPubIn_P = "P1433"     -- reference published in property
local DatePub_P = "P577"       -- date of publication property
local Publisher_P = "P123"     -- publisher property
local Retrieved_P = "P813"     -- retrieved property
local Instof_P = "P31"         -- instance of property
local ShortN_P = "P1813"       -- short name property

local CensusGEN_I = "Q39825"    -- census item (general)
local CensusAU_I = "Q5058971"   -- Australian census item
local SAL_I = "Q33112019"       -- state suburb item (includes SSC and SAL)
--local GCCSA_I = "Q112762887"  -- Greater Capital City Statistical Area item
local LGA_I = "Q33127844"       -- Local Government Area item
local UCL_I = "Q33127891"       -- Urban Centre or Locality
--local SA2_I = "Q33128776"     -- SA2
--local SA3_I = "Q118313924"    -- SA3
--local SA4_I = ""              -- SA4 - most suitable for type=region, but no SA4 Wikidata item is defined
local ILOC_I = "Q112729549"     -- Indigenous Location

local item = nil

local p = {}

--------------- Function LastURLSection returns last section of a url, ie: the text after the last '/' ----------------------

local function LastURLSection(url)
    local pos = 1
    local f
    while true do
        f = string.find(url, '/', pos, true)
        if (f == nil) then
            break
        else
            pos = f + 1
        end
    end
    return string.sub(url, pos)
end

--------------- Function SplitDoubleClaims returns the claims table with any claim with multiple points-in-time split into multiple claims. ----------------------

local function SplitDoubleClaims(claims)
    local oldclaims, newclaims = {}, {}
    for j, s in pairs(claims) do
        local npits = table.maxn(s.qualifiers[Pointin_P])
        if npits > 1 then
            local newc = {}
            -- for each point-in-time
            for a, pit in pairs(s.qualifiers[Pointin_P]) do
            	local c = mw.clone(s) -- a copy of the complete claim

                c.pitLabel = pit.datavalue.value.time -- label the claim with the time of the point-in-time qualifier

            	table.insert(newc, c) -- add the labelled claim to newc
            end

            for k, v in pairs(newc) do
                table.insert(newclaims, mw.clone(v))
            end

            table.insert(oldclaims, j)
            
        end
    end
    
    -- remove the original splitable claims
    for k, v in pairs(oldclaims) do
        table.remove(claims, v)
    end
    -- and add the separate ones they were split into
    for k, v in pairs(newclaims) do
        table.insert(claims, v)
    end
end

--------------- Function IdForGeog returns the wikidata item ID for the specified geography abbreviation. Returns nil if abbreviation is blank. ----------------------

local function IdForGeog(geog)
    if geog == "ucl" then
        return UCL_I
    elseif geog == "sal" then
        return SAL_I -- includes SSC and SAL
    elseif geog == "lga" then
        return LGA_I
    elseif geog == "iloc" then
        return ILOC_I
    end
    return nil
end

--------------- Function GeogIdsForType returns a table of geography IDs that could be shown for the specified type. ----------------------

local function GeogIdsForType(type)
    type = string.lower(type)
    if type == "city" then
        return {UCL_I}
    elseif type == "town" then
        return {UCL_I, SAL_I, ILOC_I}
    elseif type == "locality" then
        return {SAL_I, ILOC_I}
    elseif type == "suburb" then
        return {SAL_I}
    elseif type == "settlement" then
        return {SAL_I, ILOC_I}
    elseif type == "lga" then
        return {LGA_I}
    elseif type == "region" then -- SA4 would be most suitable for type=region, but no SA4 Wikidata item is defined
        return {}
    end
end

--------------- Function GetRefsForClaim to check, collate and format all the reference components ----------------------

local function GetRefsForClaim(claim, defaulttitle)
    local refs = ""
    local r = 0
    for b, x in pairs(claim.references) do -- loop through all references in a claim
        local year
        if claim.pitLabel then
        	year = string.sub(claim.pitLabel, 2, 5) -- extract the year from the point-in-time label
        else
        	year = string.sub(claim.qualifiers[Pointin_P][1].datavalue.value.time, 2, 5) -- extract the year from the claim's only point in time
        end

    	if (not claim.pitLabel)
    	  or (x.snaks[RefURL_P] ~= nil and string.find(x.snaks[RefURL_P][1].datavalue.value, year, 1, true) ~= nil) then
	        -- each reference in the wikidata will produce a citation reference for the claim
            -- except if the claim is labelled with a single point-in-time, and the reference URL does not contain the year of that label

	        r = r + 1
	
	        -- gather various values for potential later use
	    
	        local refurl = ""
	        if claim.references[b].snaks[RefURL_P] ~= nil then -- if reference has a reference url, use it
	            refurl = claim.references[b].snaks[RefURL_P][1].datavalue.value
	        end
	
	        local reftitle = defaulttitle -- default title is the Wikidata item title
	        if claim.references[b].snaks[RefTitle_P] ~= nil then -- if reference has a title, use it
	            reftitle = claim.references[b].snaks[RefTitle_P][1].datavalue.value.text
	        end
	
	        local detmet = mw.wikibase.getEntity(claim.qualifiers[DetMeth_P][1].datavalue.value.id) -- load the claim determination method item
	
	        local pubinlabel = ""
	        if claim.references[b].snaks[RefPubIn_P] ~= nil then -- if reference has a published in (it should for all references), use its item's label
	            local pubin = mw.wikibase.getEntity(claim.references[b].snaks[RefPubIn_P][1].datavalue.value.id)
	            pubinlabel = pubin.labels.en.value
	        end
	
	        local refwork = pubinlabel -- the default reference work for for non-census references, or fall-back for census references with missing parts
	
	        local pubdate = ""
	        if claim.references[b].snaks[DatePub_P] ~= nil then -- if reference has a date published, use it. This is the second-best option for the published date.
	            pubdate = mw.language.getContentLanguage():formatDate('j F Y', claim.references[b].snaks[DatePub_P][1].datavalue.value.time)
	        end
	        
	        if detmet.claims[Instof_P] ~=nil and detmet.claims[Instof_P][1].mainsnak.datavalue.value.id == CensusAU_I then
	            -- if determination method is an instance of an australian census
	            refwork = detmet.labels.en.value .. " " .. pubinlabel -- reference work is determination method label + published in
	            if detmet.claims[DatePub_P] ~=nil then -- if determination method has a date published, use that as the date
	                pubdate = mw.language.getContentLanguage():formatDate('j F Y', detmet.claims[DatePub_P][1].mainsnak.datavalue.value.time)
	            end
	        end
	
	        local refpublisher = ""
	        if detmet.claims[Publisher_P] ~= nil then -- if determination method has a publisher, use its item's label
	            local publisheritem = mw.wikibase.getEntity(detmet.claims[Publisher_P][1].mainsnak.datavalue.value.id)
	            refpublisher = "[[" .. publisheritem.labels.en.value .. "]]"
	        end
	
	        local refaccessdate = ""
	        if claim.references[b].snaks[Retrieved_P] ~= nil then -- if reference has an access date, use it.
	            refaccessdate = mw.language.getContentLanguage():formatDate('j F Y', claim.references[b].snaks[Retrieved_P][1].datavalue.value.time)
	        end
	
	        local appliespart = mw.wikibase.getEntity(claim.qualifiers[Applies_P][1].datavalue.value.id).labels.en.value -- the label of the item of the applies to part of the claim
	
	        local reference
	
	        if (detmet.claims[Instof_P] ~=nil and detmet.claims[Instof_P][1].mainsnak.datavalue.value.id == CensusAU_I) or
	          (string.find(string.lower(refurl), 'abs.gov.au', 1, true)) then
	            -- determination method is an instance of an australian census, or the url is for the abs
	            refwork = detmet.labels.en.value .. " " .. pubinlabel -- reference work is determination method label + published in
	            
	            -- the reference is built using the specific template for the census year, which ensures the link format is correct
	            local geogid = LastURLSection(refurl) -- the id for the specific ABS reference is easiest to get from the ref URL. It may be the only place it is available.
	            reference = mw.getCurrentFrame():expandTemplate{title = 'Census_' .. year .. '_AUS', args = {id = geogid, name = reftitle .. " (" .. appliespart .. ")", ["access-date"] = refaccessdate, quick = 'on'} }
	        else
	            -- use the provided reference url, and whatever other citation data is available
	
	            local citewebargs = {
	                url = refurl,
	                title = reftitle .. " (" .. appliespart .. ")" ,
	                date = pubdate,
	                work = refwork,
	                author = refpublisher, -- author is used to match existing population references
	                accessdate = refaccessdate
	            }
	
	            reference = mw.getCurrentFrame():expandTemplate{ title = 'cite web', args = citewebargs }
	        end
	
	        local wdeditpencil = mw.getCurrentFrame():expandTemplate{title = 'EditAtWikidata', args = {qid = item.id, pid = claim.id, nbsp = 1}} -- the Edit At Wikidata icon & link
	        reference = reference .. wdeditpencil
	
	         -- The name of the citation reference will be the same for each wikidata claim reference. This will allow references to the same data to be combined into a single citation reference.
	        local refname = refwork .. "_" .. year .. "_" .. appliespart .. "_" .. reftitle
	        if r > 1 then -- 2nd and later references in the same wikidata claim have their number appended, to keep them unique
	            refname = refname .. "_" .. r
	        end
	
	        refs = refs .. mw.getCurrentFrame():extensionTag{ name = 'ref', content = reference, args = { name = refname} } -- accumulate the citation references
	    end
    end
    return refs
end

--------------- Function GetAbbrLabel gets the population geography abbreviation ---------------

local function GetAbbrLabel(returnclaim)
    local appliespartitem = mw.wikibase.getEntity(returnclaim.qualifiers[Applies_P][1].datavalue.value.id) -- load the applies to part item
    
    local abbrelabel = appliespartitem.labels.en.value -- the fall back value for the geography label if no abbreviation (short name) value exists in Wikidata item
    if appliespartitem.claims[ShortN_P] ~= nil then -- if a short name value exists, use it, with the full label as a tooltip
        abbrelabel = mw.getCurrentFrame():expandTemplate{title = 'Abbr', args = {appliespartitem.claims[ShortN_P][1].mainsnak.datavalue.value.text, appliespartitem.labels.en.value } }
    end
    return '[[Australian Bureau of Statistics#' .. string.gsub(appliespartitem.labels.en.value, ' ', '_') .. '|' .. abbrelabel .. ']]'
end

--------------- Function GetYearLink gets the Wikipedia article link for the population year ---------------

local function GetYearLink(returnclaim)
    local year
    if returnclaim.pitLabel then
    	year = string.sub(returnclaim.pitLabel, 2, 5) -- extract the year from the point-in-time label
    else
    	year = string.sub(returnclaim.qualifiers[Pointin_P][1].datavalue.value.time, 2, 5) -- extract the year from the claim's only point in time
    end

    local yearreturn = year -- if no links to Wikipedia articles describing population determination method exist, default is the unlinked year

    local detmetitem
    for k, v in pairs(returnclaim.qualifiers[DetMeth_P]) do
        local detmet = mw.wikibase.getEntity(v.datavalue.value.id)
        if string.find(detmet.labels.en.value, year, 1, true) ~= nil then
            detmetitem = detmet
            break -- the first determination method with the required year is used
        end
    end

    if detmetitem then
        if detmetitem.sitelinks ~=nil and detmetitem.sitelinks.enwiki ~=nil then -- if determination method item has an enwiki URL
            yearreturn = "[[" .. detmetitem.sitelinks.enwiki.title .. "|" .. year .. "]]" -- use that URL as the link for the year value
        elseif detmetitem.claims[Instof_P] ~=nil and detmetitem.claims[Instof_P][1].mainsnak.datavalue.value.id == CensusAU_I then -- if determination method is an instance of an australian census
            yearreturn = "[[Census_in_Australia#" .. year .. "|" .. year .. "]]" -- use the section of the Census in Australia article as the link for the year value
        end
    end
    return yearreturn
end

---------------- Function HistoricPopulations returns a wikitable of all census population values for all geography types, or a specified one ---------------
-- parameters:
-- required: type=     the type value as for the Infobox
-- optional: wikidata= the wikidata item to be used instead of the one in the current page
-- optional: geog=     a single geography type to return pop values for. Valid are 'ucl', 'sal', 'lga', 'iloc'. If left blank, all geographies will be returned.
-- optional: note1_year=, note1_text=   the year, and the text of a note to appear in the table row for that year.
--      note2_year, note2_text etc. are allowed

function p.HistoricPopulations( frame )
    if frame.args.wikidata ~= nil and frame.args.wikidata ~= "" then -- if there's a Wikidata item specified, use it
        item = mw.wikibase.getEntity(frame.args.wikidata)
    else
        item = mw.wikibase.getEntity() -- if there's a Wikidata item connected to the article it will find it here.
    end

    -- if there are no population claims in the item, return an empty string
    if not (item and item.claims and item.claims[Pop_P]) then
        return ""
    end

    -- Find claims with:
    -- (1) point in time is not nil
    -- (2) applies to part is not nil
    -- (3) determination method is not nil
    -- (4) References table is not empty
    -- (5) The determination method for the claim is an australian census

    local validpopclaims = {}
    local z = 0
    for j, s in pairs(item.claims[Pop_P]) do
        local isCensus = false
        if s.qualifiers[DetMeth_P] ~= nil then
            -- is determination method an instance of an australian census, or a (generic) census
            local detmetitem = mw.wikibase.getEntity(s.qualifiers[DetMeth_P][1].datavalue.value.id) -- load the claim determination method item
            isCensus = (detmetitem.claims[Instof_P] ~=nil and detmetitem.claims[Instof_P][1].mainsnak.datavalue.value.id == CensusAU_I) or
              s.qualifiers[DetMeth_P][1].datavalue.value.id == CensusGEN_I
        end
        if s.qualifiers ~= nil and
          s.qualifiers[Pointin_P] ~= nil and
          s.qualifiers[Applies_P] ~= nil and
          s.qualifiers[DetMeth_P] ~= nil and
          s.references ~= nil and
          isCensus then
            z = z + 1
            validpopclaims[z] = s -- add to valid claims table
        end
    end

    -- if there are no valid claims, return an empty string
    if #validpopclaims < 1 then
        return ""
    end

    SplitDoubleClaims(validpopclaims) -- any claims with multiple points-in-time are split into separate claims
    
    -- parse note parameters
    local notes = {}
    local nts = 0
    while frame.args['note' .. (nts + 1) .. '_year'] and frame.args['note' ..(nts + 1) .. '_text'] do
        nts = nts + 1
        notes[frame.args['note' .. nts .. '_year']] = frame.args['note' .. nts .. '_text']
    end

    -- add to history table for all (or requested-geography-only) claims

    local showGeogIds = {}

    if frame.args.geog ~= nil and frame.args.geog ~= "" then -- if geog is specified, only claims for its id are returned
        showGeogIds[1] = IdForGeog(string.lower(frame.args.geog))
    else
        showGeogIds = GeogIdsForType(frame.args.type)
    end
    local showGeogIdsString = ',' .. table.concat(showGeogIds, ',') .. ','

    local geog = nil
    if frame.args.geog ~= nil and frame.args.geog ~= "" then
        geog = string.lower(frame.args.geog)
    end

    local oneplaceid = IdForGeog(geog)

    local history = {}
    local years = {}
    local glist = {}
    for i, q in pairs(validpopclaims) do
        local claimgeogid = q.qualifiers[Applies_P][1].datavalue.value.id -- the ID of the applies_to_part item in the claim
        if string.find(showGeogIdsString, ',' .. claimgeogid .. ',', 1, true) then -- the geography ID of the claim is in the list of IDs that could be shown for the type
            if (not oneplaceid) or (claimgeogid == oneplaceid) then -- if geog is not specified, or it is and the claim applies_to_part matches it
		        local claimdate
		        if q.pitLabel then
		            claimdate = q.pitLabel
		        else
		            claimdate = q.qualifiers[Pointin_P][1].datavalue.value.time
		        end
                local claimyear = string.sub(claimdate, 2, 5) -- the population point in time as a year string
                if not history[claimyear] then
                    history[claimyear] = {year = claimyear, claim = {}}
                    table.insert(years, claimyear)
                end
                local refs = GetRefsForClaim(q, item.labels.en.value)
                history[claimyear].claim[claimgeogid] = mw.language.getContentLanguage():formatNum(tonumber(q.mainsnak.datavalue.value.amount)) .. refs
                glist[claimgeogid] = 1
            end
        end
    end

    -- sort the years table
    table.sort(years)
    
    local geogNames = {[UCL_I] = 'UCL', [SAL_I] = 'SAL', [ILOC_I] = 'ILOC', [LGA_I] = 'LGA'}

    -- build the wikidata table contents from the history table
    -- heading row
    local wt = {}
    for g, l in pairs(showGeogIds) do
        if glist[l] then
            table.insert(wt, ' !! ' .. geogNames[l])
        end
    end
    if nts > 0 then
        table.insert(wt, ' !! ' .. 'Notes')
    end
    -- data rows
    for k, v in ipairs(years) do
        table.insert(wt, '\n|-\n! | ' .. v) -- first column, contains years
        for g, l in pairs(showGeogIds) do
            if glist[l] then
                if history[v].claim[l] then
                    table.insert(wt, '\n| ' .. history[v].claim[l])
                else
                    table.insert(wt, '\n| ') -- empty table cell
                end
            end
        end
        if nts > 0 then
	        if notes[v] then
	            table.insert(wt, '\n| ' .. notes[v])
	        else
	            table.insert(wt, '\n| ') -- empty table cell
	        end
	    end
    end

    local wts = table.concat(wt)

    -- if there are table contents, add the start and end of the table
    if #wts > 0 then
        wts = '{| class="wikitable"\n|-\n!' .. wts -- start of table and empty top-left cell
        wts = wts .. '\n|}' -- end of table
    end
    
    local cat = ''
    if mw.title.getCurrentTitle().namespace == 0 then
        -- category not added except in article namespace
        cat = '[[Category:Australian place articles using Wikidata population values]]'
    end

    return wts .. cat
end

---------------- Function LatestPopulation returns the most recent population value for a specified geography ---------------
-- parameters:
-- required: geog=     a single geography type to return pop value for. Valid are 'ucl', 'sal', 'lga', 'iloc'.
-- optional: wikidata= the wikidata item to be used instead of the one in the current page
-- optional: year=     any value requests the year to be shown after the population figure
-- optional: punc=     any value will be inserted into the output before the reference number

function p.LatestPopulation( frame )
    if frame.args.geog == nil then
        return ""
    end

    local geogID = IdForGeog(string.lower(frame.args.geog))
    if geogID == nil then
        return ""
    end 

    if frame.args.wikidata ~= nil and frame.args.wikidata ~= "" then -- if there's a Wikidata item specified, use it
        item = mw.wikibase.getEntity(frame.args.wikidata)
    else
        item = mw.wikibase.getEntity() -- if there's a Wikidata item connected to the article it will find it here.
    end

    -- if there are no population claims in the item, return an empty string
    if not (item and item.claims and item.claims[Pop_P]) then
        return ""
    end

    ------------ PART 1: Find claims that meet mimimum criteria

    -- (1) point in time is not nil
    -- (2) applies to part is not nil
    -- (3) determination method is not nil
    -- (4) References table is not empty

    local validpopclaims = {}
    local z = 0
    for j, s in pairs(item.claims[Pop_P]) do
        if s.qualifiers ~= nil and
          s.qualifiers[Pointin_P]~= nil and
          s.qualifiers[Applies_P] ~= nil and
          s.qualifiers[DetMeth_P] ~= nil and
          s.references ~= nil
        then
            z = z + 1
            validpopclaims[z] = s -- add to valid claims table
        end
    end

    -- if there are no valid claims, return an empty string
    if #validpopclaims <1 then
        return ""
    end
    
    SplitDoubleClaims(validpopclaims) -- any claims with multiple points-in-time are split into separate claims

    --------------- PART 2: Find the latest claim for each geography found
    
    local latestclaim = {}
    
    for i, q in pairs(validpopclaims) do
        local claimdate = q.qualifiers[Pointin_P][1].datavalue.value.time
        local claimgeog = q.qualifiers[Applies_P][1].datavalue.value.id
        if  latestclaim[claimgeog] == nil
          or (latestclaim[claimgeog] ~= nil and claimdate >= latestclaim[claimgeog].qualifiers[Pointin_P][1].datavalue.value.time) then -- if the max date for a particular geography value is later than the previous latest, overwrite with the current latest claim
            latestclaim[claimgeog] = q
        end
    end

    --------------- PART 3: Compile the module output, using only latest claim for the specified geography

    local wikitext = ""
    if latestclaim[geogID] ~= nil then
        local yearlink = ""
        if (frame.args.year or '') ~= '' then -- year is only shown on request
            yearlink = " (" .. GetYearLink(latestclaim[geogID]) .. ")" 
        end
        local refs = GetRefsForClaim(latestclaim[geogID], item.labels.en.value) -- the references for the claim
        wikitext = mw.language.getContentLanguage():formatNum(tonumber(latestclaim[geogID].mainsnak.datavalue.value.amount)) .. yearlink .. (frame.args.punc or '') .. refs
    end

    local cat = ''
    if mw.title.getCurrentTitle().namespace == 0 then
        -- category not added except in article namespace
        cat = '[[Category:Australian place articles using Wikidata population values]]'
    end
    return  wikitext .. cat
end

---------------- Function ListForInfobox returns the most recent population values ---------------
-- parameters:
-- required: type=     the type value as for the Infobox
-- optional: wikidata= the wikidata item to be used instead of the one in the current page
-- optional: geog=     a single geography type to return pop values for. Valid are 'ucl', 'sal', 'lga', 'iloc'. If left blank, all geographies will be returned.
-- optional: check=    any value (eg:1 or yes) means 'yes' will be returned if there would be any population information returned (subject to the other parameter values), 
--                     otherwise an empty string is returned

function p.ListForInfobox( frame )
    if frame.args.type == nil then
        return ""
    end

    local articleplacetype = string.lower(frame.args.type) -- for the place type supplied, change to a lower case string

     -- Check for valid place types
    if articleplacetype == "city" 
      or articleplacetype == "town"
      or articleplacetype == "locality"
      or articleplacetype == "suburb" 
      or articleplacetype == "settlement"
      or articleplacetype == "lga"
      or articleplacetype == "region"
    then
      -- OK to continue
    elseif articleplacetype == "cadastral"
      or articleplacetype == "protected" then
        -- these place types don't have ABS populations
        return ""
    else
        -- unrecognised type supplied
        return ""
    end

    if frame.args.wikidata ~= nil and frame.args.wikidata ~= "" then -- if there's a Wikidata item specified, use it
        item = mw.wikibase.getEntity(frame.args.wikidata)
    else
        item = mw.wikibase.getEntity() -- if there's a Wikidata item connected to the article it will find it here.
    end

    -- if there are no population claims in the item, return an empty string
    if not (item and item.claims and item.claims[Pop_P]) then
        return ""
    end
    
    ------------ PART 1: Find claims that meet mimimum criteria

    -- (1) point in time is not nil
    -- (2) applies to part is not nil
    -- (3) determination method is not nil
    -- (4) References table is not empty

    local validpopclaims = {}
    local z = 0
    for j, s in pairs(item.claims[Pop_P]) do
        if s.qualifiers ~= nil and
          s.qualifiers[Pointin_P] ~= nil and
          s.qualifiers[Applies_P] ~= nil and
          s.qualifiers[DetMeth_P] ~= nil and
          s.references ~= nil
        then
            z = z + 1
            validpopclaims[z] = s -- add to valid claims table
        end
    end

    -- if there are no valid claims, return an empty string
    if #validpopclaims <1 then
        return ""
    end

    SplitDoubleClaims(validpopclaims) -- any claims with multiple points-in-time create separate labelled claims

    --------------- PART 2: Find the latest claim for each geography found
    
    local latestclaim = {}
    
    for i, q in pairs(validpopclaims) do
        local claimdate
        if q.pitLabel then
            claimdate = q.pitLabel
        else
            claimdate = q.qualifiers[Pointin_P][1].datavalue.value.time
        end
        local claimgeog = q.qualifiers[Applies_P][1].datavalue.value.id
        if  latestclaim[claimgeog] == nil
          or (latestclaim[claimgeog] ~= nil and claimdate >= latestclaim[claimgeog].qualifiers[Pointin_P][1].datavalue.value.time) then -- if the max date for a particular geography value is later than the previous latest, overwrite with the current latest claim
            latestclaim[claimgeog] = q
        end
    end

    --------------- PART 3: specify the geography types that can be returned for each place type

    local showGeogIds = {}

    if frame.args.geog ~= nil and frame.args.geog ~= "" then -- if geog is specified, only claims for its id are returned
        showGeogIds[1] = IdForGeog(string.lower(frame.args.geog))
    else
        showGeogIds = GeogIdsForType(articleplacetype)
    end

    --------------- PART 4: Compile the module output, using only latest claims in specified geographies

    local checkonly = frame.args.check ~= nil

    local returnlist = {}

    for j, t in pairs(showGeogIds) do
        if latestclaim[t] ~= nil then
        	local refs = '' 
        	if not checkonly then
                refs = GetRefsForClaim(latestclaim[t], item.labels.en.value) -- the references for the max date claim
            end
            table.insert(returnlist, mw.language.getContentLanguage():formatNum(tonumber(latestclaim[t].mainsnak.datavalue.value.amount)) .. " (" .. GetAbbrLabel(latestclaim[t]) .. " " .. GetYearLink(latestclaim[t]) .. ")" .. refs)
        end
    end

    local wikitext
    if checkonly then
    	if #returnlist < 1 then
            wikitext = '' -- check requested, and no pop data would be returned, return empty string
        else
        	wikitext = 'yes' -- check requested, pop data would be returned, return 'yes'
        end
    elseif #returnlist == 1 then
        -- if there is only one entry in returnlist, return it without a bullet point
        wikitext = returnlist[1]
    else
        -- if there are multiple entries in returnlist, return all the rows with new line and bullet points between them
        wikitext = "\n*" .. table.concat(returnlist, "\n*")
    end
    local cat = ''
    if mw.title.getCurrentTitle().namespace == 0 and not checkonly then
        -- category not added except in article namespace
        cat = '[[Category:Australian place articles using Wikidata population values]]'
    end
    return  wikitext .. cat
    --
end

-- #####  function main is only for testing of the code during development

function p.main()
    local wdata = 'Q649969' -- Ulladulla 
--    local wdata = 'Q4856763' -- Banksiadale - has a merged claim
--    local wdata = 'Q32843813' -- Pigeon Ponds - has a merged claim
--    local wdata = 'Q5032535' -- Cann River - has historic claims with incomplete determination methods

--[[    
    return p.ListForInfobox( { args = {type = 'town', wikidata = wdata} } ) .. '<br>'
      .. p.LatestPopulation( { args = {geog = 'sal', wikidata = wdata, year = 'yes', punc='.'} } )
]]

--[[    
    return p.HistoricPopulations( { args = {type = 'town', wikidata = wdata} } )
      .. '\n\n' .. p.HistoricPopulations( { args = {type = 'town', wikidata = wdata, geog='sal'} } )
      .. p.LatestPopulation( { args = {geog = 'sal', wikidata = wdata} } ) .. '<br>'
      .. p.LatestPopulation( { args = {geog = 'sal', wikidata = wdata, year = 'yes', punc='.'} } ) .. '<br>'
      .. p.ListForInfobox( { args = {type = 'town', wikidata = wdata} } )
]]

    return p.HistoricPopulations( { args = {type = 'town', wikidata = wdata, note1_year='2011', note1_text = 'Note for 2011.'} } )

end

return p