<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://moasspedia.org/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AIATA_and_ICAO_code</id>
	<title>Module:IATA and ICAO code - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://moasspedia.org/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AIATA_and_ICAO_code"/>
	<link rel="alternate" type="text/html" href="https://moasspedia.org/w/index.php?title=Module:IATA_and_ICAO_code&amp;action=history"/>
	<updated>2026-04-19T18:34:00Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.37.2</generator>
	<entry>
		<id>https://moasspedia.org/w/index.php?title=Module:IATA_and_ICAO_code&amp;diff=1414&amp;oldid=prev</id>
		<title>Wikipedia&gt;Bouzinac at 18:06, 30 June 2018</title>
		<link rel="alternate" type="text/html" href="https://moasspedia.org/w/index.php?title=Module:IATA_and_ICAO_code&amp;diff=1414&amp;oldid=prev"/>
		<updated>2018-06-30T18:06:05Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require(&amp;#039;Module:No globals&amp;#039;);&lt;br /&gt;
local getArgs = require (&amp;#039;Module:Arguments&amp;#039;).getArgs;&lt;br /&gt;
local lang = mw.language.getContentLanguage();									-- used for date formatting and validation&lt;br /&gt;
local namespace = mw.title.getCurrentTitle().namespace;							-- used for categorization&lt;br /&gt;
&lt;br /&gt;
local master = mw.loadData(&amp;quot;Module:IATA and ICAO code/data&amp;quot;)&lt;br /&gt;
local IATA_airport = master.IATA&lt;br /&gt;
local ICAO_airport = master.ICAO&lt;br /&gt;
local wikilink_label = master.WikiName&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.count(frame)&lt;br /&gt;
	local count = 0&lt;br /&gt;
		&lt;br /&gt;
	for i, v in ipairs(frame.args) do	&lt;br /&gt;
	count=count+1 end&lt;br /&gt;
	return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ V A L I D _ D A T E &amp;gt;----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Dates must be real.  Returns true if date is a real date; false else.&lt;br /&gt;
&lt;br /&gt;
Done this way because:&lt;br /&gt;
	mw.language.getContentLanguage():formatDate(&amp;#039;Y-m-d&amp;#039;, &amp;#039;2018-02-31&amp;#039;) should return an error but instead returns&lt;br /&gt;
		2018-03-03&lt;br /&gt;
&lt;br /&gt;
TODO: text for min/max years?&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_valid_date (date)&lt;br /&gt;
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};			-- number of days in each month&lt;br /&gt;
local month_length;&lt;br /&gt;
local year, month, day;&lt;br /&gt;
&lt;br /&gt;
	year, month, day = date:match (&amp;#039;(%d%d%d%d)%-(%d%d)%-(%d%d)&amp;#039;);				-- extract year, month, and day parts from date&lt;br /&gt;
	&lt;br /&gt;
	if (year &amp;lt; lang:formatDate (&amp;#039;Y&amp;#039;, &amp;#039;now&amp;#039;)) or (year &amp;gt; lang:formatDate (&amp;#039;Y&amp;#039;, &amp;#039;now+2year&amp;#039;)) then&lt;br /&gt;
		return false;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	month = tonumber (month);&lt;br /&gt;
	if (1 &amp;gt; month) or (12 &amp;lt; month) then											-- check month&lt;br /&gt;
		return false;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (2==month) then															-- if February&lt;br /&gt;
		month_length = 28;														-- then 28 days unless&lt;br /&gt;
		if (0==(year%4) and (0~=(year%100) or 0==(year%400))) then				-- a leap year&lt;br /&gt;
			month_length = 29;													-- in which case: 29 days in February&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		month_length=days_in_month[month];										-- else month length from table&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	day = tonumber (day);&lt;br /&gt;
	if (1 &amp;gt; day) or ( month_length &amp;lt; day) then									-- check day&lt;br /&gt;
		return false;&lt;br /&gt;
	end&lt;br /&gt;
	return true;																-- good day&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[-------------------------&amp;lt; M A K E _ D A T E _ T Y P E _ S T R I N G &amp;gt;------------------------------------&lt;br /&gt;
&lt;br /&gt;
decodes begin, resume, end service date type and date stamps and returns human readable text.  Format is:&lt;br /&gt;
	&amp;lt;type&amp;gt;&amp;lt;date&amp;gt; where:&lt;br /&gt;
		&amp;lt;type&amp;gt; is one of the three-character keywords:&lt;br /&gt;
			beg - new service begins&lt;br /&gt;
			res - service resumes after an interruption&lt;br /&gt;
			end - service ends&lt;br /&gt;
		&amp;lt;date&amp;gt; is a singe date or date-range similar in format to ISO 8601:&lt;br /&gt;
			YYYY-MM-DD - a single YMD date may be begin, resume, or end date&lt;br /&gt;
			YYYY-MM-DD/YYYY-MM-DD - a date range where the first date (left) is a start or resume date and the second (right) is an end date&lt;br /&gt;
	&lt;br /&gt;
returns nil and an error message if:&lt;br /&gt;
	type keyword is not recognized&lt;br /&gt;
	either date is invalid - dates must be real&lt;br /&gt;
	begin or resume date falls on or after end date - events must begin/resume before they end&lt;br /&gt;
	&lt;br /&gt;
event dates that have already occurred (today&amp;#039;s date follows a begin/resume/end date) are quitely muted.  When this occurs&lt;br /&gt;
the function returns only an end date (if a date range and that event is still in the future).  The function will add a hidden category&lt;br /&gt;
to articles with muted begin/resume/end dates.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function make_date_type_string (date_type, date, date2, ref, df)&lt;br /&gt;
local result = {};&lt;br /&gt;
local cat = &amp;#039;&amp;#039;;&lt;br /&gt;
local today = lang:formatDate (&amp;#039;Y-m-d&amp;#039;, &amp;#039;today&amp;#039;);								-- system date in ymd format as a text string&lt;br /&gt;
&lt;br /&gt;
	if not date_type or (&amp;#039;&amp;#039; == date_type) then									-- if not set then this code isn&amp;#039;t dated&lt;br /&gt;
		return &amp;#039;&amp;#039;, nil, &amp;#039;&amp;#039;;														-- return empty string, no error message, empty string for category&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not is_valid_date (date) then											-- dates must be valid&lt;br /&gt;
		return nil, table.concat ({&amp;#039;invalid date: &amp;#039;, date});					-- return nil, an error message, category is nil but we don&amp;#039;t care&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if date2 then																-- if date is a range&lt;br /&gt;
		if &amp;#039;end&amp;#039; == date_type then&lt;br /&gt;
			return nil, &amp;#039;date range not allowed for keyword \&amp;#039;end\&amp;#039;&amp;#039;;			-- :endYYYY-MM-DD/YYYY-MM-DD is nonsensical&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if not is_valid_date (date2) then										-- dates must be valid&lt;br /&gt;
			return nil, table.concat ({&amp;#039;invalid date: &amp;#039;, date2});				-- return nil, an error message, category is nil but we don&amp;#039;t care&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if date &amp;gt;= date2 then													-- start/resume dates must precede end dates&lt;br /&gt;
			return nil, table.concat ({&amp;#039;invalid date order: &amp;#039;, date, &amp;#039;/&amp;#039;, date2});	-- return nil, an error message, category is nil but we don&amp;#039;t care&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if date &amp;lt; today then														-- if date has passed&lt;br /&gt;
		date = nil;																-- quietly hide expired dates&lt;br /&gt;
		cat = &amp;#039;[[Category:Expired airport code]]&amp;#039;;								-- (but categorize)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if date2 then																-- if date is a range&lt;br /&gt;
		if date2 &amp;lt; today then													-- if date has passed&lt;br /&gt;
			date2 = nil;														-- quietly hide expired dates&lt;br /&gt;
			cat = &amp;#039;[[Category:Expired airport code]]&amp;#039;;							-- (but categorize)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	date_type = date_type:lower();												-- make it case insensitive&lt;br /&gt;
	&lt;br /&gt;
	if &amp;#039;beg&amp;#039; == date_type then&lt;br /&gt;
		if date then															-- date may be nil here because it has already passed&lt;br /&gt;
			table.insert (result, &amp;#039; (begins &amp;#039;);									-- begin date is today or in the future&lt;br /&gt;
		elseif date2 then														-- here when date has passed and date timestamp was a range&lt;br /&gt;
			date = date2;														-- begin date is in the past so event has already happened; convert date2 to end&lt;br /&gt;
			date2 = nil;														-- unset&lt;br /&gt;
			table.insert (result, &amp;#039; (ends &amp;#039;);									-- range end date is today or in the future&lt;br /&gt;
		end&lt;br /&gt;
	elseif &amp;#039;res&amp;#039; == date_type then&lt;br /&gt;
		if date then&lt;br /&gt;
			table.insert (result, &amp;#039; (resumes &amp;#039;);								-- resume date is today or in the future&lt;br /&gt;
		elseif date2 then&lt;br /&gt;
			date = date2;														-- resume date is in the past so event has already happened; convert date2 to end&lt;br /&gt;
			date2 = nil;														-- unset&lt;br /&gt;
			table.insert (result, &amp;#039; (ends &amp;#039;);									-- range end date is today or in the future&lt;br /&gt;
		end&lt;br /&gt;
	elseif &amp;#039;end&amp;#039; == date_type then&lt;br /&gt;
		if date then&lt;br /&gt;
			table.insert (result, &amp;#039; (ends &amp;#039;);									-- end date is today or in the future&lt;br /&gt;
		else&lt;br /&gt;
			return nil;															-- date has expired for an end date type; return nil as flag to hide this destination&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return nil, table.concat ({&amp;#039;unexpected date type: &amp;#039;, date_type});		-- return nil, an error message, category is nil but we don&amp;#039;t care&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if date then																-- define formatting strings for lang:formatDate()&lt;br /&gt;
		if &amp;#039;dmy&amp;#039; == df then&lt;br /&gt;
			df = &amp;#039;j F Y&amp;#039;;&lt;br /&gt;
		elseif &amp;#039;mdy&amp;#039; == df then&lt;br /&gt;
			df = &amp;#039;F j, Y&amp;#039;;&lt;br /&gt;
		else&lt;br /&gt;
			df = &amp;#039;Y-m-d&amp;#039;;														-- yeah, sort of pointless, but simple&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		table.insert (result, lang:formatDate (df, date));						-- reformat ymd to selected format according to |df=&lt;br /&gt;
		&lt;br /&gt;
		if date2 then&lt;br /&gt;
			table.insert (result, &amp;#039;; ends &amp;#039;);									-- date2 always an end event&lt;br /&gt;
			table.insert (result, lang:formatDate (df, date2));					-- reformat ymd to selected format according to |df=&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if 0 ~= namespace then&lt;br /&gt;
		cat = &amp;#039;&amp;#039;																-- categorize articles in mainspace only&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if 0 ~= #result then														-- when there is date text, &lt;br /&gt;
		table.insert (result, ref);												-- reference goes just before we ...&lt;br /&gt;
		table.insert (result, &amp;#039;)&amp;#039;);												-- ... close the date text&lt;br /&gt;
		return table.concat (result), nil, cat;									-- return formatted date string, no error message, and category (if mainspace)&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;#039;&amp;#039;, nil, cat;													-- return empty string for concatenation, no error message, and category (if mainspace)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[-------------------------&amp;lt; C O M P &amp;gt;---------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Comparison funtion for table.sort() compares wikilink labels&lt;br /&gt;
&lt;br /&gt;
	[[wikilink target|wikilink label]]&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local function comp (a, b)&lt;br /&gt;
local a_label = a:match (&amp;#039;^[^|]+|([^%]]+)%]%]&amp;#039;):lower();						-- extract the label from a&lt;br /&gt;
local b_label = b:match (&amp;#039;^[^|]+|([^%]]+)%]%]&amp;#039;):lower();						-- extract the label from b&lt;br /&gt;
	return a_label &amp;lt; b_label;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[--------------------------&amp;lt; M A I N &amp;gt;--------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
returns a wikilink to the en.wiki article that matches the IATA or ICAO code provided in the call&lt;br /&gt;
example of data:&lt;br /&gt;
	{&amp;#039;North America&amp;#039;,&amp;#039;USA&amp;#039;,&amp;#039;ABE&amp;#039;,&amp;#039;KABE&amp;#039;,&amp;#039;Lehigh Valley International Airport&amp;#039;,&amp;#039;Allentown/Bethlehem&amp;#039;},&lt;br /&gt;
	&lt;br /&gt;
{{#invoke:IATA and ICAO code|main|ABE}} returns&lt;br /&gt;
	[[Lehigh Valley International Airport|Allentown/Bethlehem]]&lt;br /&gt;
	or an error message&lt;br /&gt;
&lt;br /&gt;
When there are multiple codes, returns comma separated, alpha ascending list of wikilinks or an error message.&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
local args = getArgs(frame);&lt;br /&gt;
local results = {};&lt;br /&gt;
local code;&lt;br /&gt;
local date_type;&lt;br /&gt;
local date, date2;&lt;br /&gt;
local message;&lt;br /&gt;
local ref = &amp;#039;&amp;#039;;&lt;br /&gt;
local cat = &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	for _, value in ipairs (args) do&lt;br /&gt;
		value = mw.text.trim (value);&lt;br /&gt;
		if value:match (&amp;#039;^(%a%a%a%a?) *: *(%a%a%a) *(%d%d%d%d%-%d%d%-%d%d) */ *(%d%d%d%d%-%d%d%-%d%d) *(.*)&amp;#039;) then&lt;br /&gt;
			code, date_type, date, date2, ref = value:match (&amp;#039;^(%a%a%a%a?) *: *(%a%a%a) *(%d%d%d%d%-%d%d%-%d%d) */ *(%d%d%d%d%-%d%d%-%d%d) *(.*)&amp;#039;);&lt;br /&gt;
		elseif value:match (&amp;#039;^(%a%a%a%a?) *: *(%a%a%a) *(%d%d%d%d%-%d%d%-%d%d) *(.*)&amp;#039;) then&lt;br /&gt;
			code, date_type, date, ref = value:match (&amp;#039;^(%a%a%a%a?) *: *(%a%a%a) *(%d%d%d%d%-%d%d%-%d%d) *(.*)&amp;#039;);&lt;br /&gt;
		elseif value:match (&amp;#039;^%a%a%a%a?$&amp;#039;) then&lt;br /&gt;
			code = value:match (&amp;#039;^%a%a%a%a?$&amp;#039;);&lt;br /&gt;
		else&lt;br /&gt;
			return table.concat ({&amp;#039;&amp;lt;span style=\&amp;quot;font-size:100%; font-style:normal;\&amp;quot; class=\&amp;quot;error\&amp;quot;&amp;gt;error: malformed parameter value: &amp;#039;, value, &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;});&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		ref = mw.text.trim (ref);												-- remove extraneous white space; if ref is only white space, makes empty string&lt;br /&gt;
		if &amp;#039;&amp;#039; ~= ref then&lt;br /&gt;
			if not ref:match (&amp;#039;^\127[^\127]*UNIQ%-%-ref%-%x+%-QINU[^\127]*\127&amp;#039;) then&lt;br /&gt;
				return table.concat ({&amp;#039;&amp;lt;span style=\&amp;quot;font-size:100%; font-style:normal;\&amp;quot; class=\&amp;quot;error\&amp;quot;&amp;gt;error: extraneous reference text: &amp;#039;, ref, &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;});&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		date_type, message, cat = make_date_type_string (date_type, date, date2, ref, args.df);&lt;br /&gt;
		&lt;br /&gt;
		if message then															-- if an error message, abandon&lt;br /&gt;
			return table.concat ({&amp;#039;&amp;lt;span style=\&amp;quot;font-size:100%; font-style:normal;\&amp;quot; class=\&amp;quot;error\&amp;quot;&amp;gt;error: &amp;#039;, message, &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;});&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if date_type then														-- nil when end date type has expired&lt;br /&gt;
			code = code:upper();													-- force code to uppercase&lt;br /&gt;
	&lt;br /&gt;
			if IATA_airport[code] then&lt;br /&gt;
				table.insert (results, table.concat ({&amp;#039;[[&amp;#039;, IATA_airport[code], &amp;#039;|&amp;#039;, wikilink_label[code], &amp;#039;]]&amp;#039;, date_type, cat}))	-- make wikilink from iata code&lt;br /&gt;
			elseif ICAO_airport[code] then&lt;br /&gt;
				table.insert (results, table.concat ({&amp;#039;[[&amp;#039;, ICAO_airport[code], &amp;#039;|&amp;#039;, wikilink_label[code], &amp;#039;]]&amp;#039;, date_type, cat}))	-- make wikilink from icao code&lt;br /&gt;
			else&lt;br /&gt;
				return table.concat ({&amp;#039;&amp;lt;span style=\&amp;quot;font-size:100%; font-style:normal;\&amp;quot; class=\&amp;quot;error\&amp;quot;&amp;gt;error: data missing for code: &amp;#039;, code, &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;});&lt;br /&gt;
			end&lt;br /&gt;
		end		&lt;br /&gt;
		date_type = nil;														-- clear so we can reuse these&lt;br /&gt;
		date = nil;&lt;br /&gt;
		date2 = nil;&lt;br /&gt;
		ref = &amp;#039;&amp;#039;;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	table.sort (results, comp);													-- sort in ascending alpha order&lt;br /&gt;
	&lt;br /&gt;
	local i = 1;&lt;br /&gt;
	while i&amp;lt;#results do															-- check for and remove duplicates&lt;br /&gt;
		if results[i] == results[i+1] then										-- compare&lt;br /&gt;
			table.remove (results, i);											-- remove the duplicate at results[i]; do not bump i&lt;br /&gt;
		else&lt;br /&gt;
			i = i + 1;															-- not the same so bump i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat (results, &amp;#039;, &amp;#039;);										-- make a comma separated list&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; D U P L I C A T E _ C H E C K &amp;gt;------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
This function looks at IATA and ICAO code in Module:IATA and ICAO code/data.  It attempts to locate invalid (by&lt;br /&gt;
length) codes and attempts to detect duplicate codes.&lt;br /&gt;
&lt;br /&gt;
  1               2     3     4&lt;br /&gt;
{&amp;#039;North America&amp;#039;,&amp;#039;USA&amp;#039;,&amp;#039;ABE&amp;#039;,&amp;#039;KABE&amp;#039;,&amp;#039;Lehigh Valley International Airport&amp;#039;,&amp;#039;Allentown/Bethlehem&amp;#039;},&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function p.duplicate_check ()&lt;br /&gt;
	local iata_count_table = {};&lt;br /&gt;
	local icao_count_table = {};&lt;br /&gt;
&lt;br /&gt;
	local _master = master._master&lt;br /&gt;
&lt;br /&gt;
	local iata = {}&lt;br /&gt;
	local icao = {}&lt;br /&gt;
&lt;br /&gt;
	for i, v in ipairs(_master) do												-- create tables from master&lt;br /&gt;
		if &amp;#039;&amp;#039; ~= v[3] then														-- iata codes TODO: length checking&lt;br /&gt;
			if not iata[v[3]] then&lt;br /&gt;
				iata[v[3]] = 1;													-- state that this is the first time we&amp;#039;ve seen this code&lt;br /&gt;
			else&lt;br /&gt;
				iata[v[3]] = iata[v[3]] + 1;									-- bump the count for this code&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if &amp;#039;&amp;#039; ~= v[4] then														-- iaco codes TODO: length checking&lt;br /&gt;
			if not icao[v[4]] then&lt;br /&gt;
				icao[v[4]] = 1;													-- state that this is the first time we&amp;#039;ve seen this code&lt;br /&gt;
			else&lt;br /&gt;
				icao[v[4]] = icao[v[4]] + 1;									-- bump the count for this code&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for k, v in pairs (iata) do&lt;br /&gt;
		if 1 &amp;lt; v then&lt;br /&gt;
			table.insert (iata_count_table, table.concat ({k, &amp;#039; (&amp;#039;, v, &amp;#039;×)&amp;#039;}))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for k, v in pairs (icao) do&lt;br /&gt;
		if 1 &amp;lt; v then&lt;br /&gt;
			table.insert (icao_count_table, table.concat ({k, &amp;#039; (&amp;#039;, v, &amp;#039;×)&amp;#039;}))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local iata_msg = &amp;#039;&amp;#039;;														-- error messages go here&lt;br /&gt;
	local icao_msg = &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	if 0 ~= #iata_count_table then&lt;br /&gt;
		iata_msg = table.concat ({&amp;#039;&amp;lt;span style=\&amp;quot;font-size:100%; font-style:normal;\&amp;quot; class=\&amp;quot;error\&amp;quot;&amp;gt;error: more than one IATA code:&amp;lt;br /&amp;gt;	&amp;#039;, table.concat (iata_count_table, &amp;#039;, &amp;#039;), &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;})&lt;br /&gt;
	end&lt;br /&gt;
	if 0 ~= #icao_count_table then&lt;br /&gt;
		icao_msg = table.concat ({&amp;#039;&amp;lt;span style=\&amp;quot;font-size:100%; font-style:normal;\&amp;quot; class=\&amp;quot;error\&amp;quot;&amp;gt;error: more than one ICAO code:&amp;lt;br /&amp;gt;	&amp;#039;, table.concat (icao_count_table, &amp;#039;, &amp;#039;), &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;})&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (0 ~= #iata_count_table) or (0 ~= #icao_count_table) then				-- TODO find a better way of doing this&lt;br /&gt;
		return table.concat ({iata_msg, &amp;#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;#039;, icao_msg})&lt;br /&gt;
	end&lt;br /&gt;
	return &amp;#039;ok&amp;#039;;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Wikipedia&gt;Bouzinac</name></author>
	</entry>
</feed>