commit 7931fab14599b739c18c8f1ebcc24b75688dbc09 Author: Sean B. Palmer Date: Thu Feb 21 12:06:33 2008 +0000 Phenny2, now being tested on Freenode as the main phenny. diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..8137683 --- /dev/null +++ b/__init__.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +""" +__init__.py - Phenny Init Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import sys, time, threading +import bot + +def run_phenny(config): + if hasattr(config, 'delay'): + delay = config.delay + else: delay = 20 + + def connect(config): + p = bot.Phenny(config) + p.run(config.host) + + while True: + connect(config) + if not isinstance(delay, int): break + + warning = 'Warning: Disconnected. Reconnecting in %s seconds...' % delay + print >> sys.stderr, warning + time.sleep(delay) + +def run(config): + t = threading.Thread(target=run_phenny, args=(config,)) + t.start() + +if __name__ == '__main__': + print __doc__ diff --git a/bot.py b/bot.py new file mode 100755 index 0000000..d84a635 --- /dev/null +++ b/bot.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python +""" +bot.py - Phenny IRC Bot +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import sys, os, re, time, threading, optparse +import irc + +home = os.getcwd() + +def decode(bytes): + try: text = bytes.decode('utf-8') + except UnicodeDecodeError: + try: text = bytes.decode('iso-8859-1') + except UnicodeDecodeError: + text = bytes.decode('cp1252') + return text + +class Phenny(irc.Bot): + def __init__(self, config): + irc.Bot.__init__(self, config.nick, config.name, config.channels) + self.config = config + self.doc = {} + self.stats = {} + self.setup() + + def setup(self): + self.variables = {} + + if not hasattr(self.config, 'enable'): + load = [('modules', filename[:-3]) + for filename in os.listdir(os.path.join(home, 'modules')) + if filename.endswith('.py') and + not filename.startswith('_') and + not filename[:-3] in self.config.disable] + else: load = [('modules', e) for e in self.config.enable] + + if hasattr(self.config, 'opt'): + load += [('opt', o) for o in self.config.opt] + + modules = [] + for package, name in load: + try: module = getattr(__import__(package + '.' + name), name) + except Exception, e: + print >> sys.stderr, "Error loading %s: %s" % (name, e) + else: + if hasattr(module, 'setup'): + module.setup(self) + self.register(vars(module)) + modules.append(name) + + if modules: + print >> sys.stderr, 'Registered modules:', ', '.join(modules) + else: print >> sys.stderr, "Warning: Couldn't find any modules" + + self.bind_commands() + + def register(self, variables): + # This is used by reload.py, hence it being methodised + for name, obj in variables.iteritems(): + if hasattr(obj, 'commands') or hasattr(obj, 'rule'): + self.variables[name] = obj + + def bind_commands(self): + self.commands = {'high': {}, 'medium': {}, 'low': {}} + + def bind(self, priority, regexp, func): + print priority, regexp.pattern.encode('utf-8'), func + self.commands[priority].setdefault(regexp, []).append(func) + # @@ register documentation + if func.__doc__: + if hasattr(func, 'name'): + name = func.name + else: name = func.__name__ + if hasattr(func, 'example'): + example = func.example + example = example.replace('$nickname', self.nick) + else: example = None + self.doc[name] = (func.__doc__, example) + + def sub(pattern, self=self): + # These replacements have significant order + pattern = pattern.replace('$nickname', self.nick) + return pattern.replace('$nick', r'%s[,:] +' % self.nick) + + for name, func in self.variables.iteritems(): + # print name, func + if not hasattr(func, 'priority'): + func.priority = 'medium' + + if not hasattr(func, 'thread'): + func.thread = True + + if not hasattr(func, 'event'): + func.event = 'PRIVMSG' + else: func.event = func.event.upper() + + if hasattr(func, 'rule'): + if isinstance(func.rule, str): + pattern = sub(func.rule) + regexp = re.compile(pattern) + bind(self, func.priority, regexp, func) + + if isinstance(func.rule, tuple): + # 1) e.g. ('$nick', '(.*)') + if len(func.rule) == 2 and isinstance(func.rule[0], str): + prefix, pattern = func.rule + prefix = sub(prefix) + regexp = re.compile(prefix + pattern) + bind(self, func.priority, regexp, func) + + # 2) e.g. (['p', 'q'], '(.*)') + elif len(func.rule) == 2 and isinstance(func.rule[0], list): + prefix = self.config.prefix + commands, pattern = func.rule + for command in commands: + command = r'(%s) +' % command + regexp = re.compile(prefix + command + pattern) + bind(self, func.priority, regexp, func) + + # 3) e.g. ('$nick', ['p', 'q'], '(.*)') + elif len(func.rule) == 3: + prefix, commands, pattern = func.rule + prefix = sub(prefix) + for command in commands: + command = r'(%s) +' % command + regexp = re.compile(prefix + command + pattern) + bind(self, func.priority, regexp, func) + + if hasattr(func, 'commands'): + for command in func.commands: + template = r'^%s(%s)(?: +(.*))?$' + pattern = template % (self.config.prefix, command) + regexp = re.compile(pattern) + bind(self, func.priority, regexp, func) + + def wrapped(self, origin, text, match): + class PhennyWrapper(object): + def __init__(self, phenny): + self.bot = phenny + + def __getattr__(self, attr): + if attr == 'reply': + return (lambda msg: + self.bot.msg(origin.sender, origin.nick + ': ' + msg)) + elif attr == 'say': + return lambda msg: self.bot.msg(origin.sender, msg) + return getattr(self.bot, attr) + + return PhennyWrapper(self) + + def input(self, origin, text, bytes, match, event): + class CommandInput(unicode): + def __new__(cls, text, origin, bytes, match, event): + s = unicode.__new__(cls, text) + s.sender = origin.sender + s.nick = origin.nick + s.event = event + s.bytes = bytes + s.match = match + s.group = match.group + s.groups = match.groups + s.admin = origin.nick in self.config.admins + s.owner = origin.nick == self.config.owner + return s + + return CommandInput(text, origin, bytes, match, event) + + def call(self, func, origin, phenny, input): + try: func(phenny, input) + except Exception, e: + self.error(origin) + + def dispatch(self, origin, args): + bytes, event = args[0], args[1] + text = decode(bytes) + + for priority in ('high', 'medium', 'low'): + items = self.commands[priority].items() + for regexp, funcs in items: + for func in funcs: + if event != func.event: continue + + match = regexp.match(text) + if match: + # print 'STATS:', origin.sender, func.__name__ + + phenny = self.wrapped(origin, text, match) + input = self.input(origin, text, bytes, match, event) + + if func.thread: + args = (func, origin, phenny, input) + t = threading.Thread(target=self.call, args=args) + t.start() + else: self.call(func, origin, phenny, input) + +if __name__ == '__main__': + print __doc__ diff --git a/foaf.rdf b/foaf.rdf new file mode 100644 index 0000000..4ac6e13 --- /dev/null +++ b/foaf.rdf @@ -0,0 +1,54 @@ + + + + + + + + Information about phenny + + + + + + Phenny P. Palmersbot + phenny + Ms. + + + + + + Sean B. Palmer + + + + diff --git a/icao.py b/icao.py new file mode 100644 index 0000000..3ee121a --- /dev/null +++ b/icao.py @@ -0,0 +1,4198 @@ +#!/usr/bin/env python +""" +icao.py - Phenny ICAO Codes Data +This data and module are in the public domain. + +http://inamidst.com/phenny/ +""" + +data = ( + ("AYGA", -6.08166666667, 145.391666667), + ("AYMD", -5.20694444444, 145.788611111), + ("AYMH", -5.82611111111, 144.296111111), + ("AYNZ", -6.56972222222, 146.726111111), + ("AYPY", -9.44333333333, 147.22), + ("AYWK", -3.58361111111, 143.669166667), + ("BGBW", 61.1611111111, -45.4275), + ("BGCO", 70.7394444444, -22.6458333333), + ("BGGH", 64.1908333333, -51.6780555556), + ("BGJN", 69.2333333333, -51.0666666667), + ("BGKK", 65.5833333333, -37.15), + ("BGSF", 67.0169444444, -50.6891666667), + ("BGTL", 76.5311111111, -68.7030555556), + ("BIAR", 65.6597222222, -18.0725), + ("BIEG", 65.2833333333, -14.4013888889), + ("BIHN", 64.2955555556, -15.2272222222), + ("BIHU", 65.9522222222, -17.4258333333), + ("BIIS", 66.0580555556, -23.1352777778), + ("BIKF", 63.985, -22.6055555556), + ("BIKP", 66.3136111111, -16.4611111111), + ("BIPA", 65.5558333333, -23.965), + ("BIRK", 64.13, -21.9405555556), + ("BISI", 66.1333333333, -18.9166666667), + ("BIVM", 63.4241666667, -20.2786111111), + ("CYAM", 46.485, -84.5094444444), + ("CYAV", 50.0563888889, -97.0325), + ("CYAW", 44.6397222222, -63.4994444444), + ("CYAY", 51.3916666667, -56.0844444444), + ("CYAZ", 49.0822222222, -125.7725), + ("CYBB", 68.5344444444, -89.8080555556), + ("CYBC", 49.1322222222, -68.2072222222), + ("CYBG", 48.3305555556, -70.9963888889), + ("CYBK", 64.2988888889, -96.0777777778), + ("CYBL", 49.9508333333, -125.270833333), + ("CYBR", 49.91, -99.9519444444), + ("CYCB", 69.1080555556, -105.138333333), + ("CYCD", 49.0522222222, -123.87), + ("CYCG", 49.2963888889, -117.6325), + ("CYCH", 47.0077777778, -65.4491666667), + ("CYCL", 47.9905555556, -66.3313888889), + ("CYCO", 67.8166666667, -115.143888889), + ("CYCT", 52.075, -111.445277778), + ("CYCW", 49.1527777778, -121.938888889), + ("CYCY", 70.4861111111, -68.5166666667), + ("CYCZ", 50.3319444444, -115.873611111), + ("CYDA", 64.0430555556, -139.127777778), + ("CYDB", 61.3711111111, -139.040555556), + ("CYDC", 49.4675, -120.511944444), + ("CYDF", 49.2108333333, -57.3913888889), + ("CYDL", 58.4222222222, -130.032222222), + ("CYDN", 51.1008333333, -100.0525), + ("CYDQ", 55.7416666667, -120.181944444), + ("CYED", 53.6666666667, -113.466666667), + ("CYEG", 53.3097222222, -113.579722222), + ("CYEK", 61.0941666667, -94.0708333333), + ("CYEN", 49.2102777778, -102.965833333), + ("CYET", 53.5788888889, -116.465), + ("CYEU", 79.9947222222, -85.8133333333), + ("CYEV", 68.3041666667, -133.482777778), + ("CYFB", 63.7563888889, -68.5558333333), + ("CYFC", 45.8694444444, -66.5316666667), + ("CYFE", 48.7461111111, -69.0972222222), + ("CYFO", 54.6780555556, -101.681666667), + ("CYFR", 61.1808333333, -113.689722222), + ("CYFS", 61.7602777778, -121.236666667), + ("CYGK", 44.2252777778, -76.5969444444), + ("CYGL", 53.6252777778, -77.7041666667), + ("CYGP", 48.7752777778, -64.4786111111), + ("CYGQ", 49.7783333333, -86.9394444444), + ("CYGR", 47.4247222222, -61.7780555556), + ("CYGW", 55.2833333333, -77.7666666667), + ("CYGX", 56.35, -94.7), + ("CYHB", 52.8166666667, -102.311388889), + ("CYHD", 49.8316666667, -92.7441666667), + ("CYHI", 70.7630555556, -117.805833333), + ("CYHK", 68.6355555556, -95.8497222222), + ("CYHM", 43.1730555556, -79.935), + ("CYHU", 45.5175, -73.4169444444), + ("CYHY", 60.8397222222, -115.782777778), + ("CYHZ", 44.8808333333, -63.5086111111), + ("CYIB", 48.7738888889, -91.6386111111), + ("CYIO", 72.6833333333, -77.9666666667), + ("CYJN", 45.2944444444, -73.2811111111), + ("CYJT", 48.5441666667, -58.55), + ("CYKA", 50.7022222222, -120.441944444), + ("CYKF", 43.4588888889, -80.3844444444), + ("CYKL", 54.805, -66.8052777778), + ("CYKY", 51.5175, -109.180833333), + ("CYKZ", 43.8622222222, -79.37), + ("CYLD", 47.82, -83.3463888889), + ("CYLJ", 54.1252777778, -108.522777778), + ("CYLL", 53.3091666667, -110.0725), + ("CYLT", 82.5177777778, -62.2805555556), + ("CYLW", 49.9561111111, -119.377777778), + ("CYMA", 63.6166666667, -135.866666667), + ("CYMJ", 50.3302777778, -105.559166667), + ("CYMM", 56.6533333333, -111.221944444), + ("CYMO", 51.2911111111, -80.6077777778), + ("CYMW", 46.2744444444, -75.99), + ("CYMX", 45.6797222222, -74.0386111111), + ("CYNA", 50.1897222222, -61.7891666667), + ("CYND", 45.5213888889, -75.5641666667), + ("CYNM", 49.7616666667, -77.8027777778), + ("CYOC", 67.5705555556, -139.839166667), + ("CYOD", 54.405, -110.279444444), + ("CYOJ", 58.6213888889, -117.164722222), + ("CYOW", 45.3225, -75.6691666667), + ("CYPA", 53.2141666667, -105.672777778), + ("CYPE", 56.2269444444, -117.447222222), + ("CYPG", 49.9027777778, -98.2747222222), + ("CYPK", 49.2161111111, -122.71), + ("CYPL", 51.4463888889, -90.2141666667), + ("CYPN", 49.8363888889, -64.2886111111), + ("CYPQ", 44.23, -78.3633333333), + ("CYPR", 54.2861111111, -130.444722222), + ("CYPY", 58.7672222222, -111.117222222), + ("CYQA", 44.9747222222, -79.3033333333), + ("CYQB", 46.7883333333, -71.3975), + ("CYQF", 52.1786111111, -113.893055556), + ("CYQG", 42.2755555556, -82.9555555556), + ("CYQH", 60.1177777778, -128.821944444), + ("CYQK", 49.7883333333, -94.3630555556), + ("CYQL", 49.6302777778, -112.799722222), + ("CYQM", 46.1122222222, -64.6786111111), + ("CYQN", 50.1827777778, -86.6963888889), + ("CYQQ", 49.7108333333, -124.886666667), + ("CYQR", 50.4319444444, -104.665833333), + ("CYQT", 48.3719444444, -89.3238888889), + ("CYQU", 55.1797222222, -118.885), + ("CYQV", 51.2647222222, -102.461666667), + ("CYQW", 52.7691666667, -108.243611111), + ("CYQX", 48.9369444444, -54.5680555556), + ("CYQY", 46.1613888889, -60.0477777778), + ("CYQZ", 53.0261111111, -122.51), + ("CYRB", 74.7169444444, -94.9694444444), + ("CYRI", 47.7644444444, -69.5847222222), + ("CYRJ", 48.52, -72.2655555556), + ("CYRM", 52.4297222222, -114.904166667), + ("CYRT", 62.8113888889, -92.1158333333), + ("CYSB", 46.625, -80.7988888889), + ("CYSC", 45.4380555556, -71.6905555556), + ("CYSJ", 45.3161111111, -65.8902777778), + ("CYSM", 60.0222222222, -111.960277778), + ("CYSR", 72.9822222222, -84.6136111111), + ("CYSU", 46.4427777778, -63.8311111111), + ("CYSY", 71.9938888889, -125.2425), + ("CYTE", 64.23, -76.5266666667), + ("CYTH", 55.8011111111, -97.8641666667), + ("CYTR", 44.1188888889, -77.5280555556), + ("CYTS", 48.5697222222, -81.3766666667), + ("CYTZ", 43.6275, -79.3961111111), + ("CYUB", 69.4333333333, -133.026388889), + ("CYUL", 45.4680555556, -73.7413888889), + ("CYUT", 66.5213888889, -86.2247222222), + ("CYUX", 68.7761111111, -81.2436111111), + ("CYUY", 48.2061111111, -78.8355555556), + ("CYVC", 55.1513888889, -105.261944444), + ("CYVG", 53.3558333333, -110.823888889), + ("CYVM", 67.5458333333, -64.0313888889), + ("CYVO", 48.0533333333, -77.7827777778), + ("CYVP", 58.0961111111, -68.4269444444), + ("CYVQ", 65.2825, -126.800277778), + ("CYVR", 49.195, -123.181944444), + ("CYVT", 55.8419444444, -108.4175), + ("CYVV", 44.7458333333, -81.1072222222), + ("CYWA", 45.9522222222, -77.3191666667), + ("CYWG", 49.91, -97.2344444444), + ("CYWK", 52.9219444444, -66.8644444444), + ("CYWL", 52.1830555556, -122.054166667), + ("CYWY", 63.2094444444, -123.436666667), + ("CYXC", 49.6102777778, -115.7825), + ("CYXD", 53.5725, -113.520555556), + ("CYXE", 52.1708333333, -106.699722222), + ("CYXH", 50.0188888889, -110.720833333), + ("CYXJ", 56.2380555556, -120.740277778), + ("CYXL", 50.1144444444, -91.9041666667), + ("CYXP", 66.145, -65.7136111111), + ("CYXR", 47.695, -79.8488888889), + ("CYXS", 53.8894444444, -122.678888889), + ("CYXT", 54.4663888889, -128.5775), + ("CYXU", 43.0355555556, -81.1538888889), + ("CYXX", 49.0252777778, -122.363333333), + ("CYXY", 60.7094444444, -135.068333333), + ("CYYB", 46.3636111111, -79.4227777778), + ("CYYC", 51.1138888889, -114.020277778), + ("CYYD", 54.8247222222, -127.182777778), + ("CYYE", 58.8363888889, -122.596944444), + ("CYYF", 49.4627777778, -119.602222222), + ("CYYG", 46.29, -63.1211111111), + ("CYYH", 69.5466666667, -93.5766666667), + ("CYYJ", 48.6469444444, -123.425833333), + ("CYYL", 56.8638888889, -101.076111111), + ("CYYN", 50.2919444444, -107.690555556), + ("CYYQ", 58.7391666667, -94.065), + ("CYYR", 53.3191666667, -60.4258333333), + ("CYYT", 47.6186111111, -52.7519444444), + ("CYYU", 49.4138888889, -82.4675), + ("CYYW", 50.2902777778, -88.9097222222), + ("CYYY", 48.6086111111, -68.2080555556), + ("CYYZ", 43.6772222222, -79.6305555556), + ("CYZD", 43.7425, -79.4655555556), + ("CYZE", 45.8852777778, -82.5677777778), + ("CYZF", 62.4627777778, -114.440277778), + ("CYZH", 55.2933333333, -114.778333333), + ("CYZP", 53.2541666667, -131.813888889), + ("CYZR", 42.9994444444, -82.3088888889), + ("CYZT", 50.6805555556, -127.366666667), + ("CYZU", 54.1438888889, -115.786666667), + ("CYZV", 50.2233333333, -66.2655555556), + ("CYZW", 60.1727777778, -132.742777778), + ("CYZX", 44.9844444444, -64.9169444444), + ("CZFA", 62.2075, -133.375833333), + ("CZFM", 67.4077777778, -134.860277778), + ("DAAB", 36.5036111111, 2.81416666667), + ("DAAD", 35.3325, 4.20638888889), + ("DAAE", 36.7119444444, 5.06972222222), + ("DAAG", 36.6908333333, 3.21527777778), + ("DAAJ", 24.2925, 9.45222222222), + ("DAAK", 36.5458333333, 2.87611111111), + ("DAAM", 36.1086111111, 6.36444444444), + ("DAAN", 26.71, 0.285555555556), + ("DAAP", 26.5733333333, 8.48361111111), + ("DAAQ", 35.5252777778, 2.87861111111), + ("DAAS", 36.1780555556, 5.32444444444), + ("DAAT", 22.8108333333, 5.45083333333), + ("DAAV", 36.795, 5.87333333333), + ("DAAY", 33.5358333333, -0.242222222222), + ("DAAZ", 35.7522222222, 0.626111111111), + ("DABB", 36.8222222222, 7.80916666667), + ("DABC", 36.2766666667, 6.62388888889), + ("DABS", 35.4313888889, 8.12055555556), + ("DAFH", 32.9297222222, 3.31222222222), + ("DAOB", 35.3411111111, 1.46305555556), + ("DAOE", 35.7352777778, -0.805277777778), + ("DAOF", 27.7002777778, -8.16694444444), + ("DAOI", 36.2125, 1.33166666667), + ("DAOL", 35.5422222222, -0.532222222222), + ("DAON", 35.0166666667, -1.45), + ("DAOO", 35.6236111111, -0.621111111111), + ("DAOS", 35.1716666667, -0.593055555556), + ("DAOV", 35.2075, 0.146944444444), + ("DAUA", 27.8375, -0.186388888889), + ("DAUB", 34.7930555556, 5.73805555556), + ("DAUE", 30.5711111111, 2.85944444444), + ("DAUG", 32.3838888889, 3.79388888889), + ("DAUH", 31.6727777778, 6.14027777778), + ("DAUI", 27.2508333333, 2.51194444444), + ("DAUK", 33.0677777778, 6.08861111111), + ("DAUL", 33.7638888889, 2.92722222222), + ("DAUT", 29.2369444444, 0.275833333333), + ("DAUU", 31.9172222222, 5.41277777778), + ("DAUZ", 28.0513888889, 9.64277777778), + ("DBBB", 6.35722222222, 2.38416666667), + ("DBBP", 9.35694444444, 2.60888888889), + ("DFFD", 12.3530555556, -1.51222222222), + ("DFOO", 11.16, -4.33083333333), + ("DGAA", 5.60277777778, -0.168055555556), + ("DGLE", 9.56333333333, -0.863333333333), + ("DGLW", 10.0825, -2.5075), + ("DGSN", 7.36166666667, -2.32861111111), + ("DGTK", 4.89333333333, -1.775), + ("DIAP", 5.25972222222, -3.92638888889), + ("DIBK", 7.73861111111, -5.07361111111), + ("DIDL", 6.7925, -6.47305555556), + ("DIKO", 9.38694444444, -5.55638888889), + ("DIMN", 7.27194444444, -7.58694444444), + ("DISP", 4.74666666667, -6.66055555556), + ("DIYO", 6.90305555556, -5.36583333333), + ("DNAA", 9.00666666667, 7.26305555556), + ("DNAK", 7.24666666667, 5.30083333333), + ("DNBE", 6.31722222222, 5.59944444444), + ("DNCA", 4.97583333333, 8.34694444444), + ("DNEN", 6.47416666667, 7.56194444444), + ("DNGU", 12.1716666667, 6.69611111111), + ("DNIB", 7.36222222222, 3.97833333333), + ("DNIL", 8.44, 4.49388888889), + ("DNJO", 9.63972222222, 8.86888888889), + ("DNKA", 10.6958333333, 7.32), + ("DNKN", 12.0475, 8.52444444444), + ("DNMA", 11.8552777778, 13.0808333333), + ("DNMK", 7.70361111111, 8.61388888889), + ("DNMM", 6.57722222222, 3.32111111111), + ("DNMN", 9.65194444444, 6.46222222222), + ("DNPO", 5.01527777778, 6.94944444444), + ("DNSO", 12.9161111111, 5.20694444444), + ("DNYO", 9.26027777778, 12.4297222222), + ("DNZA", 11.13, 7.68555555556), + ("DRRM", 13.5025, 7.12666666667), + ("DRRN", 13.4813888889, 2.18361111111), + ("DRRT", 14.8755555556, 5.26527777778), + ("DRZA", 16.9647222222, 7.99694444444), + ("DRZD", 18.9686111111, 12.8686111111), + ("DRZF", 13.3727777778, 12.6266666667), + ("DRZR", 13.7788888889, 8.98361111111), + ("DRZT", 14.9994444444, 8.76694444444), + ("DTMB", 35.7580555556, 10.7547222222), + ("DTTA", 36.8508333333, 10.2269444444), + ("DTTB", 37.2452777778, 9.79138888889), + ("DTTD", 32.3061111111, 10.3819444444), + ("DTTF", 34.4219444444, 8.8225), + ("DTTG", 33.8766666667, 10.1033333333), + ("DTTI", 36.7211111111, 9.94305555556), + ("DTTJ", 33.875, 10.7752777778), + ("DTTR", 31.7041666667, 9.25444444444), + ("DTTX", 34.7177777778, 10.6908333333), + ("DTTZ", 33.9397222222, 8.11055555556), + ("DXNG", 9.76722222222, 1.09111111111), + ("DXXX", 6.16555555556, 1.25388888889), + ("EBAW", 51.19, 4.46277777778), + ("EBBE", 50.7586111111, 4.76833333333), + ("EBBL", 51.1677777778, 5.47083333333), + ("EBBR", 50.9022222222, 4.49861111111), + ("EBBT", 51.3333333333, 4.5), + ("EBBX", 49.8872222222, 5.22861111111), + ("EBCI", 50.4591666667, 4.45361111111), + ("EBCV", 50.5758333333, 3.83083333333), + ("EBFN", 51.09, 2.65277777778), + ("EBFS", 50.2436111111, 4.64861111111), + ("EBKT", 50.8177777778, 3.20833333333), + ("EBLG", 50.6372222222, 5.44305555556), + ("EBOS", 51.1988888889, 2.86222222222), + ("EBSL", 50.9483333333, 5.59166666667), + ("EBST", 50.7883333333, 5.19277777778), + ("EBUL", 51.1438888889, 3.47416666667), + ("EBWE", 51.395, 4.96055555556), + ("EBZR", 51.2655555556, 4.75472222222), + ("EDAB", 51.1933333333, 14.5197222222), + ("EDAC", 50.9816666667, 12.5061111111), + ("EDAD", 51.8319444444, 12.1858333333), + ("EDAE", 52.1972222222, 14.5855555556), + ("EDAH", 53.8786111111, 14.1522222222), + ("EDAK", 51.3080555556, 13.5547222222), + ("EDAM", 51.3627777778, 11.9408333333), + ("EDAQ", 51.5519444444, 12.0525), + ("EDAU", 51.2944444444, 13.3588888889), + ("EDAX", 53.3063888889, 12.7530555556), + ("EDAY", 52.5797222222, 13.9155555556), + ("EDAZ", 52.2033333333, 13.1586111111), + ("EDBC", 51.8558333333, 11.4180555556), + ("EDBG", 35.4605555556, -77.9647222222), + ("EDBH", 54.3380555556, 12.71), + ("EDBJ", 50.9172222222, 11.7136111111), + ("EDBK", 52.9186111111, 12.4252777778), + ("EDBM", 52.0736111111, 11.6263888889), + ("EDBN", 51.3280555556, 12.6566666667), + ("EDBR", 51.3644444444, 14.9519444444), + ("EDCA", 53.8325, 13.6688888889), + ("EDCD", 51.8894444444, 14.5316666667), + ("EDCK", 51.7211111111, 11.9616666667), + ("EDCM", 51.2961111111, 14.1288888889), + ("EDDB", 52.38, 13.5225), + ("EDDC", 51.1325, 13.7669444444), + ("EDDE", 50.98, 10.9580555556), + ("EDDF", 50.0263888889, 8.54305555556), + ("EDDG", 52.1344444444, 7.68472222222), + ("EDDH", 53.6302777778, 9.98805555556), + ("EDDI", 52.4727777778, 13.4038888889), + ("EDDK", 50.8658333333, 7.1425), + ("EDDL", 51.2894444444, 6.76666666667), + ("EDDM", 48.3536111111, 11.7858333333), + ("EDDN", 49.4986111111, 11.0780555556), + ("EDDP", 51.4238888889, 12.2361111111), + ("EDDR", 49.2144444444, 7.10944444444), + ("EDDS", 48.6897222222, 9.22194444444), + ("EDDT", 52.5594444444, 13.2875), + ("EDDV", 52.4608333333, 9.685), + ("EDDW", 53.0475, 8.78666666667), + ("EDFE", 49.9608333333, 8.64361111111), + ("EDFH", 49.9497222222, 7.26388888889), + ("EDFM", 49.4725, 8.51361111111), + ("EDFQ", 51.0352777778, 8.67888888889), + ("EDFV", 49.6063888889, 8.36833333333), + ("EDFZ", 49.9688888889, 8.1475), + ("EDGE", 50.9927777778, 10.4725), + ("EDGS", 50.7075, 8.08194444444), + ("EDHI", 53.5352777778, 9.83527777778), + ("EDHK", 54.3794444444, 10.145), + ("EDHL", 53.8052777778, 10.7191666667), + ("EDKA", 50.8227777778, 6.18722222222), + ("EDKV", 50.4058333333, 6.52805555556), + ("EDKZ", 51.0994444444, 7.60194444444), + ("EDLA", 51.4833333333, 7.89916666667), + ("EDLC", 51.5302777778, 6.53694444444), + ("EDLE", 51.4013888889, 6.93583333333), + ("EDLN", 51.2302777778, 6.50444444444), + ("EDLP", 51.6141666667, 8.61611111111), + ("EDLS", 51.9958333333, 6.84027777778), + ("EDLW", 51.5180555556, 7.61222222222), + ("EDMA", 48.425, 10.9316666667), + ("EDMB", 48.1108333333, 9.76277777778), + ("EDME", 48.3961111111, 12.7236111111), + ("EDMO", 48.0813888889, 11.2833333333), + ("EDMS", 48.9008333333, 12.5180555556), + ("EDMV", 48.6363888889, 13.1952777778), + ("EDNL", 47.8588888889, 10.0144444444), + ("EDNY", 47.6711111111, 9.51138888889), + ("EDOP", 53.4269444444, 11.7833333333), + ("EDOV", 52.6288888889, 11.8197222222), + ("EDPA", 48.7777777778, 10.2644444444), + ("EDQC", 50.2625, 10.9958333333), + ("EDQD", 49.9841666667, 11.6383333333), + ("EDQE", 49.7941666667, 11.1322222222), + ("EDQM", 50.2886111111, 11.8547222222), + ("EDQP", 49.8627777778, 11.7877777778), + ("EDQT", 50.0177777778, 10.5294444444), + ("EDRK", 50.3247222222, 7.53083333333), + ("EDRT", 49.8633333333, 6.78888888889), + ("EDRY", 49.3025, 8.45111111111), + ("EDRZ", 49.2094444444, 7.40055555556), + ("EDTB", 48.7911111111, 8.18694444444), + ("EDTD", 47.9730555556, 8.52222222222), + ("EDTF", 48.0202777778, 7.83361111111), + ("EDTK", 48.9822222222, 8.33333333333), + ("EDTM", 48.0536111111, 9.37277777778), + ("EDTY", 49.1180555556, 9.77722222222), + ("EDUS", 51.6075, 13.7377777778), + ("EDVE", 52.3191666667, 10.5561111111), + ("EDVK", 51.4083333333, 9.3775), + ("EDVM", 52.1775, 9.94555555556), + ("EDWB", 53.5033333333, 8.57333333333), + ("EDWD", 53.1430555556, 8.62333333333), + ("EDWE", 53.3911111111, 7.22722222222), + ("EDWF", 53.2719444444, 7.44277777778), + ("EDWI", 53.5047222222, 8.05333333333), + ("EDWR", 53.5952777778, 6.70916666667), + ("EDWY", 53.7066666667, 7.23), + ("EDXF", 54.7716666667, 9.37805555556), + ("EDXR", 54.2208333333, 9.60055555556), + ("EDXW", 54.9130555556, 8.34027777778), + ("EEEI", 59.2594444444, 24.2044444444), + ("EEKA", 58.9905555556, 22.8305555556), + ("EEKE", 58.2297222222, 22.5094444444), + ("EEPU", 58.4188888889, 24.4727777778), + ("EETN", 59.4130555556, 24.8327777778), + ("EETU", 58.3072222222, 26.6902777778), + ("EFET", 68.3625, 23.4241666667), + ("EFEU", 61.1161111111, 22.2013888889), + ("EFHA", 61.8558333333, 24.7863888889), + ("EFHF", 60.2544444444, 25.0427777778), + ("EFHK", 60.32, 24.9561111111), + ("EFHM", 61.6894444444, 23.0736111111), + ("EFHN", 59.8486111111, 23.0833333333), + ("EFHV", 60.6544444444, 24.8811111111), + ("EFIK", 60.4625, 23.6525), + ("EFIM", 61.2491666667, 28.9036111111), + ("EFIT", 62.1661111111, 30.0736111111), + ("EFIV", 68.6072222222, 27.4052777778), + ("EFJO", 62.6588888889, 29.6244444444), + ("EFJY", 62.3994444444, 25.6780555556), + ("EFKA", 63.1269444444, 23.0513888889), + ("EFKE", 65.7816666667, 24.5988888889), + ("EFKI", 64.2852777778, 27.6922222222), + ("EFKJ", 62.4625, 22.3930555556), + ("EFKK", 63.7211111111, 23.1430555556), + ("EFKM", 66.7127777778, 27.1566666667), + ("EFKS", 65.9875, 29.2391666667), + ("EFKT", 67.7008333333, 24.8466666667), + ("EFKU", 63.0069444444, 27.7975), + ("EFLA", 61.1438888889, 25.6933333333), + ("EFLP", 61.0444444444, 28.1441666667), + ("EFMA", 60.1219444444, 19.8980555556), + ("EFME", 62.9466666667, 23.5188888889), + ("EFMI", 61.6863888889, 27.2016666667), + ("EFNU", 60.3338888889, 24.2963888889), + ("EFOU", 64.93, 25.3544444444), + ("EFPI", 61.2455555556, 22.1933333333), + ("EFPO", 61.4616666667, 21.7997222222), + ("EFPU", 65.4022222222, 26.9469444444), + ("EFPY", 63.7316666667, 25.9261111111), + ("EFRH", 64.6880555556, 24.6958333333), + ("EFRN", 62.0652777778, 28.3563888889), + ("EFRO", 66.5647222222, 25.8302777778), + ("EFRY", 60.7447222222, 24.1077777778), + ("EFSA", 61.9430555556, 28.945), + ("EFSE", 61.0622222222, 26.7986111111), + ("EFSO", 67.395, 26.6188888889), + ("EFTP", 61.4138888889, 23.6041666667), + ("EFTS", 61.7733333333, 24.0269444444), + ("EFTU", 60.5138888889, 22.2627777778), + ("EFUT", 60.8963888889, 26.9383333333), + ("EFVA", 63.0511111111, 21.7613888889), + ("EFVR", 62.1711111111, 27.8686111111), + ("EFYL", 64.0602777778, 24.7158333333), + ("EGAA", 54.6575, -6.21583333333), + ("EGAB", 54.3988888889, -7.65166666667), + ("EGAC", 54.6180555556, -5.8725), + ("EGAE", 55.0427777778, -7.16111111111), + ("EGBB", 52.4536111111, -1.74777777778), + ("EGBE", 52.3697222222, -1.47972222222), + ("EGBG", 52.6077777778, -1.03194444444), + ("EGBJ", 51.8941666667, -2.16722222222), + ("EGBN", 52.92, -1.07916666667), + ("EGBO", 52.5175, -2.25972222222), + ("EGBP", 51.6680555556, -2.05694444444), + ("EGBT", 52.0408333333, -1.09555555556), + ("EGCC", 53.3536111111, -2.27472222222), + ("EGCD", 53.3380555556, -2.14888888889), + ("EGCF", 53.5597222222, -0.858333333333), + ("EGDC", 51.0869444444, -4.15027777778), + ("EGDG", 50.4405555556, -4.99527777778), + ("EGDL", 51.505, -1.99333333333), + ("EGDM", 51.1519444444, -1.74722222222), + ("EGDR", 50.0858333333, -5.25555555556), + ("EGDX", 51.4047222222, -3.43555555556), + ("EGDY", 51.0091666667, -2.63861111111), + ("EGFE", 51.8330555556, -4.96111111111), + ("EGFF", 51.3966666667, -3.34333333333), + ("EGFH", 51.6052777778, -4.06777777778), + ("EGGD", 51.3825, -2.71888888889), + ("EGGP", 53.3336111111, -2.84972222222), + ("EGGW", 51.8744444444, -0.368333333333), + ("EGHD", 50.4227777778, -4.10583333333), + ("EGHH", 50.78, -1.8425), + ("EGHI", 50.95, -1.35666666667), + ("EGHL", 51.185, -1.03222222222), + ("EGJB", 49.4347222222, -2.60194444444), + ("EGJJ", 49.2077777778, -2.19527777778), + ("EGKA", 50.8355555556, -0.297222222222), + ("EGKB", 51.3308333333, 0.0325), + ("EGKK", 51.1480555556, -0.190277777778), + ("EGLC", 51.505, 0.0541666666667), + ("EGLF", 51.2758333333, -0.776111111111), + ("EGLJ", 51.6761111111, -1.08083333333), + ("EGLK", 51.3238888889, -0.8475), + ("EGLL", 51.4775, -0.461388888889), + ("EGMC", 51.5713888889, 0.695555555556), + ("EGMD", 50.9561111111, 0.939166666667), + ("EGMH", 51.3422222222, 1.34611111111), + ("EGNB", 53.7194444444, -0.566111111111), + ("EGNC", 54.9375, -2.80916666667), + ("EGNH", 53.7716666667, -3.02861111111), + ("EGNJ", 53.5744444444, -0.350833333333), + ("EGNL", 54.1297222222, -3.25611111111), + ("EGNM", 53.8658333333, -1.66055555556), + ("EGNO", 53.745, -2.88305555556), + ("EGNR", 53.1780555556, -2.97777777778), + ("EGNS", 54.0833333333, -4.62388888889), + ("EGNT", 55.0375, -1.69166666667), + ("EGNV", 54.5091666667, -1.42916666667), + ("EGNX", 52.8311111111, -1.32805555556), + ("EGOD", 52.8116666667, -4.12333333333), + ("EGOE", 52.8711111111, -2.53333333333), + ("EGOQ", 53.2583333333, -4.37333333333), + ("EGOS", 52.7980555556, -2.66777777778), + ("EGOV", 53.2480555556, -4.53527777778), + ("EGOW", 53.5813888889, -3.05527777778), + ("EGOY", 54.8511111111, -4.94777777778), + ("EGPA", 58.9580555556, -2.905), + ("EGPB", 59.8788888889, -1.29555555556), + ("EGPC", 58.4586111111, -3.09277777778), + ("EGPD", 57.2041666667, -2.20027777778), + ("EGPE", 57.54, -4.05), + ("EGPF", 55.8719444444, -4.43305555556), + ("EGPH", 55.95, -3.3725), + ("EGPI", 55.6819444444, -6.25666666667), + ("EGPK", 55.5077777778, -4.58666666667), + ("EGPL", 57.4811111111, -7.36277777778), + ("EGPM", 60.4322222222, -1.29805555556), + ("EGPN", 56.4525, -3.02583333333), + ("EGPO", 58.2136111111, -6.32888888889), + ("EGPU", 56.4991666667, -6.86916666667), + ("EGQL", 56.3727777778, -2.86833333333), + ("EGQS", 57.705, -3.33916666667), + ("EGRR", 51.3833333333, -0.783333333333), + ("EGSC", 52.205, 0.175), + ("EGSF", 52.4680555556, -0.251111111111), + ("EGSH", 52.6758333333, 1.28277777778), + ("EGSS", 51.885, 0.235), + ("EGSX", 51.7216666667, 0.154166666667), + ("EGSY", 53.3941666667, -1.38833333333), + ("EGTC", 52.0722222222, -0.616666666667), + ("EGTD", 51.1166666667, -0.534444444444), + ("EGTE", 50.7344444444, -3.41388888889), + ("EGTG", 51.5194444444, -2.59083333333), + ("EGTH", 51.7666666667, 0.25), + ("EGTK", 51.8369444444, -1.32), + ("EGUB", 51.6161111111, -1.09555555556), + ("EGUL", 52.4091666667, 0.560833333333), + ("EGUN", 52.3608333333, 0.488333333333), + ("EGUW", 52.1272222222, 0.955833333333), + ("EGUY", 52.3572222222, -0.107777777778), + ("EGVA", 51.6819444444, -1.79), + ("EGVN", 51.7497222222, -1.58361111111), + ("EGVO", 51.2341666667, -0.942777777778), + ("EGWC", 52.64, -2.30555555556), + ("EGWU", 51.5527777778, -0.418055555556), + ("EGXC", 53.0927777778, -0.165833333333), + ("EGXD", 54.1369444444, -1.42), + ("EGXE", 54.2922222222, -1.535), + ("EGXG", 53.8341666667, -1.19527777778), + ("EGXH", 52.3425, 0.772777777778), + ("EGXJ", 52.7355555556, -0.648611111111), + ("EGXP", 53.3075, -0.550833333333), + ("EGXT", 52.6125, -0.476388888889), + ("EGXU", 54.0494444444, -1.25194444444), + ("EGXW", 53.1661111111, -0.523611111111), + ("EGXZ", 54.2055555556, -1.38222222222), + ("EGYC", 52.7547222222, 1.35722222222), + ("EGYD", 53.0305555556, -0.481111111111), + ("EGYE", 52.9622222222, -0.561388888889), + ("EGYM", 52.6483333333, 0.550277777778), + ("EGYP", -51.8227777778, -58.4472222222), + ("EHAM", 52.3086111111, 4.76388888889), + ("EHBD", 51.2552777778, 5.60138888889), + ("EHBK", 50.9113888889, 5.77), + ("EHDL", 52.0605555556, 5.87305555556), + ("EHDR", 53.1191666667, 6.12972222222), + ("EHEH", 51.45, 5.37444444444), + ("EHGG", 53.1194444444, 6.57944444444), + ("EHGR", 51.5677777778, 4.93305555556), + ("EHKD", 52.9233333333, 4.78055555556), + ("EHLE", 52.4602777778, 5.52722222222), + ("EHLW", 53.2286111111, 5.76055555556), + ("EHRD", 51.9572222222, 4.44166666667), + ("EHSB", 52.1269444444, 5.27638888889), + ("EHTW", 52.27, 6.87416666667), + ("EHVB", 52.1697222222, 4.42611111111), + ("EHWO", 51.4488888889, 4.34194444444), + ("EICK", 51.8427777778, -8.49194444444), + ("EICM", 53.3013888889, -8.93916666667), + ("EIDL", 55.0441666667, -8.34083333333), + ("EIDW", 53.4211111111, -6.27), + ("EIKN", 53.9102777778, -8.81833333333), + ("EIKY", 52.1808333333, -9.52361111111), + ("EIME", 53.3027777778, -6.44277777778), + ("EINN", 52.7019444444, -8.92472222222), + ("EISG", 54.28, -8.59916666667), + ("EIWF", 52.1869444444, -7.08694444444), + ("EKAH", 56.3041666667, 10.6194444444), + ("EKBI", 55.7402777778, 9.15166666667), + ("EKCH", 55.6177777778, 12.6558333333), + ("EKEB", 55.5258333333, 8.55333333333), + ("EKGH", 55.9411111111, 12.3822222222), + ("EKHO", 56.3966666667, 8.44333333333), + ("EKKA", 56.2972222222, 9.12444444444), + ("EKLS", 57.2777777778, 11.0013888889), + ("EKMB", 54.6991666667, 11.44), + ("EKOD", 55.4761111111, 10.3291666667), + ("EKPB", 54.8702777778, 9.27916666667), + ("EKRK", 55.5855555556, 12.1313888889), + ("EKRN", 55.0630555556, 14.7594444444), + ("EKSB", 54.9641666667, 9.79166666667), + ("EKSN", 57.5033333333, 10.2291666667), + ("EKSP", 55.2252777778, 9.26388888889), + ("EKSV", 56.55, 9.17277777778), + ("EKTS", 57.0686111111, 8.705), + ("EKVA", 55.6969444444, 9.19333333333), + ("EKVD", 55.4361111111, 9.33083333333), + ("EKVG", 62.0636111111, -7.27694444444), + ("EKVH", 56.8469444444, 9.45861111111), + ("EKVJ", 55.99, 8.35388888889), + ("EKVL", 55.7672222222, 12.3433333333), + ("EKYT", 57.0927777778, 9.84888888889), + ("ELLX", 49.6263888889, 6.21138888889), + ("ENAL", 62.5602777778, 6.11), + ("ENAN", 69.2925, 16.1441666667), + ("ENAT", 69.9769444444, 23.3661111111), + ("ENBL", 61.3925, 5.76416666667), + ("ENBM", 60.6386111111, 6.50138888889), + ("ENBN", 65.4591666667, 12.2136111111), + ("ENBO", 67.2688888889, 14.3633333333), + ("ENBR", 60.2933333333, 5.21805555556), + ("ENBS", 70.6, 29.6925), + ("ENCN", 58.2041666667, 8.08527777778), + ("ENDI", 60.4166666667, 8.51388888889), + ("ENDU", 69.0555555556, 18.5402777778), + ("ENEV", 68.4911111111, 16.6780555556), + ("ENFB", 59.8955555556, 10.6169444444), + ("ENFG", 61.0111111111, 9.29305555556), + ("ENFL", 61.5838888889, 5.025), + ("ENGM", 60.1938888889, 11.1002777778), + ("ENHA", 60.8183333333, 11.0672222222), + ("ENHD", 59.345, 5.20833333333), + ("ENHK", 70.4866666667, 22.1397222222), + ("ENKB", 63.1116666667, 7.82444444444), + ("ENKJ", 59.9691666667, 11.0358333333), + ("ENKR", 69.725, 29.8875), + ("ENLI", 58.1002777778, 6.625), + ("ENML", 62.7461111111, 7.2725), + ("ENMS", 65.7838888889, 13.2147222222), + ("ENNA", 70.0686111111, 24.9733333333), + ("ENNO", 59.5655555556, 9.21166666667), + ("ENOL", 63.6988888889, 9.60388888889), + ("ENRO", 62.5783333333, 11.3422222222), + ("ENRY", 59.3788888889, 10.7855555556), + ("ENSB", 78.2461111111, 15.4655555556), + ("ENSG", 61.1561111111, 7.13638888889), + ("ENSN", 59.185, 9.56694444444), + ("ENSO", 59.7916666667, 5.34083333333), + ("ENSR", 69.7869444444, 20.9594444444), + ("ENSS", 70.3552777778, 31.0447222222), + ("ENST", 65.9566666667, 12.4688888889), + ("ENTC", 69.6833333333, 18.9188888889), + ("ENTO", 59.1866666667, 10.2586111111), + ("ENVA", 63.4575, 10.9397222222), + ("ENZV", 58.8766666667, 5.63777777778), + ("EPGD", 54.3775, 18.4661111111), + ("EPKK", 50.0775, 19.7847222222), + ("EPKM", 50.2383333333, 19.035), + ("EPKO", 54.0422222222, 16.2636111111), + ("EPKT", 50.4741666667, 19.08), + ("EPLL", 51.7219444444, 19.3980555556), + ("EPML", 50.3222222222, 21.4619444444), + ("EPPO", 52.4211111111, 16.8263888889), + ("EPRZ", 50.11, 22.0188888889), + ("EPSC", 53.5847222222, 14.9019444444), + ("EPSD", 53.3919444444, 14.6336111111), + ("EPSK", 54.4788888889, 17.1075), + ("EPSN", 53.7905555556, 15.8280555556), + ("EPWA", 52.1655555556, 20.9669444444), + ("EPWR", 51.1025, 16.8858333333), + ("EPZG", 52.1386111111, 15.7986111111), + ("ESCF", 58.4022222222, 15.5255555556), + ("ESCK", 58.6108333333, 16.1033333333), + ("ESCM", 59.8972222222, 17.5883333333), + ("ESCN", 59.1808333333, 17.9122222222), + ("ESDB", 56.2958333333, 12.8469444444), + ("ESDF", 56.2666666667, 15.265), + ("ESFH", 58.4091666667, 13.2625), + ("ESFI", 56.1836111111, 14.1322222222), + ("ESFM", 58.5980555556, 14.1136111111), + ("ESFQ", 56.8441666667, 15.4525), + ("ESFR", 58.4980555556, 13.0530555556), + ("ESFY", 56.785, 13.6016666667), + ("ESGG", 57.6627777778, 12.2797222222), + ("ESGJ", 57.7575, 14.0686111111), + ("ESGK", 58.1697222222, 13.5877777778), + ("ESGL", 58.4652777778, 13.1741666667), + ("ESGP", 57.7747222222, 11.8702777778), + ("ESGR", 58.4563888889, 13.9725), + ("ESGT", 58.3180555556, 12.345), + ("ESIA", 58.5136111111, 14.5069444444), + ("ESIB", 58.4263888889, 12.7141666667), + ("ESKA", 60.1327777778, 18.105), + ("ESKB", 59.4186111111, 17.8905555556), + ("ESKK", 59.3458333333, 14.4958333333), + ("ESKM", 60.9577777778, 14.5111111111), + ("ESKN", 58.7886111111, 16.9119444444), + ("ESKS", 59.3138888889, 17.1091666667), + ("ESKV", 59.6758333333, 12.6391666667), + ("ESKX", 58.7908333333, 16.5708333333), + ("ESMA", 56.6105555556, 15.6047222222), + ("ESMG", 56.9502777778, 13.9216666667), + ("ESMK", 55.9216666667, 14.0852777778), + ("ESML", 55.9447222222, 12.8608333333), + ("ESMO", 57.3502777778, 16.4977777778), + ("ESMP", 57.2641666667, 13.5991666667), + ("ESMQ", 56.6852777778, 16.2875), + ("ESMS", 55.53, 13.3713888889), + ("ESMT", 56.6911111111, 12.82), + ("ESMV", 57.2922222222, 14.1372222222), + ("ESMX", 56.9288888889, 14.7277777778), + ("ESNA", 63.7383333333, 15.4583333333), + ("ESNC", 62.4088888889, 13.7472222222), + ("ESND", 62.0477777778, 14.4227777778), + ("ESNF", 61.8980555556, 15.7052777778), + ("ESNG", 67.1322222222, 20.8144444444), + ("ESNH", 61.7680555556, 17.0805555556), + ("ESNI", 63.6336111111, 17.9397222222), + ("ESNJ", 66.4961111111, 20.1469444444), + ("ESNK", 63.0483333333, 17.7686111111), + ("ESNL", 64.5480555556, 18.7161111111), + ("ESNM", 63.1286111111, 14.8027777778), + ("ESNN", 62.5280555556, 17.4438888889), + ("ESNO", 63.4083333333, 18.99), + ("ESNP", 65.3994444444, 21.2652777778), + ("ESNQ", 67.8219444444, 20.3366666667), + ("ESNR", 61.19, 14.7125), + ("ESNS", 64.6247222222, 21.0766666667), + ("ESNT", 62.4811111111, 17.0027777778), + ("ESNU", 63.7916666667, 20.2825), + ("ESNV", 64.5788888889, 16.8333333333), + ("ESNX", 65.59, 19.2816666667), + ("ESOE", 59.2236111111, 15.0377777778), + ("ESOH", 60.02, 13.5788888889), + ("ESOW", 59.5894444444, 16.6336111111), + ("ESPA", 65.5436111111, 22.1219444444), + ("ESPC", 63.1938888889, 14.5019444444), + ("ESPE", 65.8752777778, 20.1497222222), + ("ESPJ", 65.8361111111, 21.4713888889), + ("ESQO", 59.3863888889, 15.9238888889), + ("ESSA", 59.6519444444, 17.9186111111), + ("ESSB", 59.3541666667, 17.9413888889), + ("ESSD", 60.4219444444, 15.515), + ("ESSF", 57.5255555556, 15.8238888889), + ("ESSK", 60.5933333333, 16.9513888889), + ("ESSL", 58.4061111111, 15.6802777778), + ("ESSP", 58.5861111111, 16.2505555556), + ("ESST", 60.1575, 12.9911111111), + ("ESSU", 59.3508333333, 16.7083333333), + ("ESSV", 57.6627777778, 18.3461111111), + ("ESUA", 64.5705555556, 19.3141666667), + ("ESUD", 64.9608333333, 17.6963888889), + ("ESUE", 61.8686111111, 12.6905555556), + ("ESUF", 65.1063888889, 20.7605555556), + ("ESUK", 67.7647222222, 20.2572222222), + ("ESUT", 65.8061111111, 15.0827777778), + ("ETAD", 49.9725, 6.6925), + ("ETAR", 49.4375, 7.60138888889), + ("ETEJ", 49.9202777778, 10.9141666667), + ("ETEK", 49.65, 7.3), + ("ETEU", 49.6480555556, 9.96638888889), + ("ETHB", 52.2783333333, 9.08194444444), + ("ETHC", 52.5911111111, 10.0219444444), + ("ETHE", 52.2911111111, 7.38694444444), + ("ETHF", 51.1144444444, 9.28583333333), + ("ETHI", 53.9944444444, 9.57833333333), + ("ETHL", 48.2202777778, 9.91), + ("ETHM", 50.3658333333, 7.315), + ("ETHN", 49.3916666667, 9.95805555556), + ("ETHR", 49.2175, 11.1005555556), + ("ETHS", 52.9191666667, 10.1836111111), + ("ETHT", 51.7677777778, 14.2919444444), + ("ETIC", 49.6994444444, 11.9411111111), + ("ETID", 50.1691666667, 8.96138888889), + ("ETIE", 49.3933333333, 8.65194444444), + ("ETIH", 49.2180555556, 11.8361111111), + ("ETIN", 49.7430555556, 10.2005555556), + ("ETME", 54.6247222222, 9.34138888889), + ("ETMN", 53.7675, 8.65833333333), + ("ETND", 52.5852777778, 8.34055555556), + ("ETNG", 50.9608333333, 6.0425), + ("ETNH", 54.3119444444, 9.53805555556), + ("ETNJ", 53.5333333333, 7.88861111111), + ("ETNL", 53.9180555556, 12.2791666667), + ("ETNN", 50.8311111111, 6.65805555556), + ("ETNP", 52.3386111111, 7.54111111111), + ("ETNR", 51.6636111111, 14.6336111111), + ("ETNS", 54.4591666667, 9.51611111111), + ("ETNT", 53.5477777778, 7.66722222222), + ("ETNU", 53.6019444444, 13.3058333333), + ("ETNW", 52.4572222222, 9.42694444444), + ("ETOI", 49.6336111111, 11.7672222222), + ("ETOR", 49.5633333333, 8.46333333333), + ("ETOU", 50.0497222222, 8.32527777778), + ("ETSA", 48.0705555556, 10.9058333333), + ("ETSB", 50.1736111111, 7.06333333333), + ("ETSE", 48.3222222222, 11.9486111111), + ("ETSF", 48.2055555556, 11.2669444444), + ("ETSH", 51.7677777778, 13.1675), + ("ETSI", 48.7155555556, 11.5338888889), + ("ETSL", 48.1861111111, 10.8622222222), + ("ETSM", 47.9886111111, 10.2394444444), + ("ETSN", 48.7108333333, 11.2111111111), + ("ETUL", 51.6016666667, 6.1425), + ("ETUO", 51.9227777778, 8.30611111111), + ("ETUR", 51.1997222222, 6.13194444444), + ("FAAB", -28.575, 16.5333333333), + ("FAAG", -29.2816666667, 18.8136111111), + ("FAAP", -25.9436111111, 29.81), + ("FABB", -26.2386111111, 28.3016666667), + ("FABE", -32.8969444444, 27.2788888889), + ("FABL", -29.0925, 26.3022222222), + ("FABM", -28.2483333333, 28.3361111111), + ("FABO", -27.3666666667, 26.6291666667), + ("FACR", -26.3694444444, 27.35), + ("FACT", -33.9647222222, 18.6016666667), + ("FACV", -31.5002777778, 19.7258333333), + ("FADA", -30.6366666667, 23.92), + ("FADB", -24.805, 26.8316666667), + ("FADD", -28.1825, 30.2244444444), + ("FADN", -29.97, 30.9502777778), + ("FAEL", -33.0355555556, 27.8258333333), + ("FAEO", -26.4952777778, 29.98), + ("FAER", -23.7261111111, 27.6875), + ("FAFB", -28.8230555556, 27.9088888889), + ("FAGC", -25.9861111111, 28.14), + ("FAGG", -34.0052777778, 22.3788888889), + ("FAGI", -23.2836111111, 30.6497222222), + ("FAGM", -26.2425, 28.1511111111), + ("FAGT", -33.2847222222, 26.4980555556), + ("FAGY", -29.1219444444, 30.5866666667), + ("FAHA", -28.0786111111, 26.8611111111), + ("FAHE", -25.9794444444, 29.6186111111), + ("FAHG", -26.5061111111, 28.3938888889), + ("FAHO", -27.2783333333, 27.9958333333), + ("FAHR", -28.235, 29.1061111111), + ("FAHS", -24.3686111111, 31.0486111111), + ("FAHV", -30.5619444444, 25.5280555556), + ("FAJS", -26.1391666667, 28.2458333333), + ("FAKD", -26.8708333333, 26.7177777778), + ("FAKG", -26.0933333333, 29.4547222222), + ("FAKL", -26.2516666667, 29.1944444444), + ("FAKM", -28.8027777778, 24.765), + ("FAKP", -25.4405555556, 31.9297222222), + ("FAKR", -26.0808333333, 27.7255555556), + ("FAKS", -27.6605555556, 27.3155555556), + ("FAKU", -27.4566666667, 23.4113888889), + ("FAKZ", -29.6883333333, 17.0938888889), + ("FALA", -25.9383333333, 27.9261111111), + ("FALB", -29.1811111111, 27.4530555556), + ("FALI", -26.1755555556, 26.1844444444), + ("FALT", -23.1597222222, 29.6963888889), + ("FALW", -32.9688888889, 18.1602777778), + ("FALY", -28.5816666667, 29.7497222222), + ("FAMB", -25.6847222222, 29.44), + ("FAMG", -30.8572222222, 30.3427777778), + ("FAMI", -24.9888888889, 29.2830555556), + ("FAMJ", -27.0791666667, 29.7783333333), + ("FAMK", -25.7527777778, 25.6119444444), + ("FAMM", -25.7983333333, 25.5477777778), + ("FAMN", -25.4733333333, 31.5655555556), + ("FAMS", -22.3558333333, 29.9863888889), + ("FAMU", -27.6258333333, 32.0441666667), + ("FANC", -27.7705555556, 29.9766666667), + ("FANS", -25.5005555556, 30.9133333333), + ("FANY", -24.6858333333, 28.4347222222), + ("FAOB", -34.5552777778, 20.2502777778), + ("FAOH", -33.6069444444, 22.1888888889), + ("FAPB", -23.8452777778, 29.4586111111), + ("FAPE", -33.9847222222, 25.6172222222), + ("FAPG", -34.0902777778, 23.3277777778), + ("FAPH", -23.9369444444, 31.1552777778), + ("FAPI", -23.9258333333, 29.4841666667), + ("FAPJ", -31.6058333333, 29.5197222222), + ("FAPM", -29.6488888889, 30.3986111111), + ("FAPN", -25.3336111111, 27.1733333333), + ("FAPP", -24.2302777778, 28.9836111111), + ("FAPQ", -25.8469444444, 23.5377777778), + ("FAPS", -26.6708333333, 27.0816666667), + ("FAPY", -26.8891666667, 27.5033333333), + ("FAQT", -31.92, 26.8819444444), + ("FARB", -28.7408333333, 32.0919444444), + ("FARG", -25.6441666667, 27.2711111111), + ("FARS", -33.8119444444, 19.9027777778), + ("FASB", -29.6891666667, 17.9394444444), + ("FASC", -26.5238888889, 29.17), + ("FASD", -32.9638888889, 17.9691666667), + ("FASI", -26.2483333333, 28.3975), + ("FASK", -25.8094444444, 28.1644444444), + ("FASS", -27.6483333333, 22.9991666667), + ("FASU", -25.9613888889, 29.2086111111), + ("FASZ", -24.9608333333, 31.5886111111), + ("FATF", -28.26, 22.9930555556), + ("FATH", -23.0786111111, 30.3833333333), + ("FATN", -29.3191666667, 26.8233333333), + ("FATP", -29.0327777778, 26.1575), + ("FATT", -26.7763888889, 29.3386111111), + ("FATZ", -23.8241666667, 30.3291666667), + ("FAUL", -28.3205555556, 31.4163888889), + ("FAUP", -28.4008333333, 21.2605555556), + ("FAUT", -31.5477777778, 28.6741666667), + ("FAVB", -26.9822222222, 24.7286111111), + ("FAVG", -29.7705555556, 31.0583333333), + ("FAVP", -26.6922222222, 27.7777777778), + ("FAVR", -31.6408333333, 18.5447222222), + ("FAVV", -26.5661111111, 27.9605555556), + ("FAVY", -27.7866666667, 30.7952777778), + ("FAWB", -25.6536111111, 28.2241666667), + ("FAWI", -25.8322222222, 29.1919444444), + ("FAWK", -25.83, 28.2225), + ("FAWM", -27.9977777778, 26.6694444444), + ("FAWS", -27.8472222222, 26.3497222222), + ("FAYP", -33.9, 18.4980555556), + ("FAZR", -25.5988888889, 26.0422222222), + ("FBFT", -21.1594444444, 27.4744444444), + ("FBJW", -24.6022222222, 24.6908333333), + ("FBKE", -17.8327777778, 25.1622222222), + ("FBMN", -19.9725, 23.4308333333), + ("FBOR", -21.2663888889, 25.3202777778), + ("FBSK", -24.555, 25.9180555556), + ("FBSP", -22.0583333333, 27.8286111111), + ("FCBB", -4.25166666667, 15.2527777778), + ("FCOI", 1.58944444444, 18.0469444444), + ("FCOM", -0.0213888888889, 15.5752777778), + ("FCOO", -0.531111111111, 15.95), + ("FCOU", 1.61583333333, 16.0377777778), + ("FCPA", -3.48333333333, 12.6166666667), + ("FCPD", -4.20777777778, 12.6608333333), + ("FCPP", -4.81333333333, 11.8858333333), + ("FDMS", -26.5288888889, 31.3075), + ("FEFF", 4.39833333333, 18.5186111111), + ("FEFG", 4.78444444444, 22.7813888889), + ("FEFI", 10.2361111111, 22.7172222222), + ("FEFM", 5.84694444444, 20.6494444444), + ("FEFN", 8.42666666667, 20.635), + ("FEFO", 5.95805555556, 15.6375), + ("FEFR", 6.52805555556, 21.9888888889), + ("FEFT", 4.22138888889, 15.7861111111), + ("FEFY", 45.1541666667, -89.1108333333), + ("FGBT", 1.90527777778, 9.80555555556), + ("FGSL", 3.75527777778, 8.70861111111), + ("FHAW", -7.96944444444, -14.3936111111), + ("FIMP", -20.43, 57.6833333333), + ("FIMR", -19.7577777778, 63.3619444444), + ("FJDG", -7.31305555556, 72.4108333333), + ("FKKC", 4.08916666667, 9.36027777778), + ("FKKD", 4.00583333333, 9.71944444444), + ("FKKI", 4.47305555556, 14.3636111111), + ("FKKL", 10.4513888889, 14.2572222222), + ("FKKM", 5.63666666667, 10.7505555556), + ("FKKN", 7.35694444444, 13.5591666667), + ("FKKR", 9.33583333333, 13.37), + ("FKKU", 5.53694444444, 10.3541666667), + ("FKKV", 6.03916666667, 10.1225), + ("FKKY", 3.83527777778, 11.5236111111), + ("FLKE", -12.5727777778, 27.8938888889), + ("FLKL", -14.9975, 22.6475), + ("FLLI", -17.8216666667, 25.8225), + ("FLLS", -15.3305555556, 28.4525), + ("FLMA", -11.1380555556, 28.875), + ("FLMF", -13.2586111111, 31.9363888889), + ("FLMG", -15.2544444444, 23.1622222222), + ("FLML", -12.5647222222, 28.2986111111), + ("FLND", -12.9980555556, 28.6647222222), + ("FLSO", -12.9002777778, 28.1497222222), + ("FLZB", -13.5386111111, 23.1097222222), + ("FMCH", -11.5336111111, 43.2716666667), + ("FMCI", -12.2980555556, 43.7663888889), + ("FMCN", -11.7105555556, 43.2436111111), + ("FMCV", -12.1316666667, 44.4302777778), + ("FMCZ", -12.8047222222, 45.2811111111), + ("FMEE", -20.8869444444, 55.5102777778), + ("FMEP", -21.3208333333, 55.4247222222), + ("FMMI", -18.7966666667, 47.4786111111), + ("FMMN", -19.5627777778, 45.4508333333), + ("FMMS", -17.0938888889, 49.8158333333), + ("FMMT", -18.1094444444, 49.3925), + ("FMMV", -20.2847222222, 44.3175), + ("FMNA", -12.3491666667, 49.2916666667), + ("FMNC", -16.1638888889, 49.7736111111), + ("FMND", -14.6516666667, 49.6205555556), + ("FMNE", -13.1883333333, 48.9877777778), + ("FMNH", -14.9991666667, 50.32), + ("FMNL", -14.6294444444, 47.7636111111), + ("FMNM", -15.6672222222, 46.3516666667), + ("FMNN", -13.3122222222, 48.3138888889), + ("FMNQ", -16.7419444444, 44.4813888889), + ("FMNR", -15.4366666667, 49.6883333333), + ("FMNS", -14.2786111111, 50.1747222222), + ("FMNV", -13.3758333333, 50.0027777778), + ("FMNW", -14.8986111111, 47.9938888889), + ("FMNZ", -13.4847222222, 48.6325), + ("FMSD", -25.0380555556, 46.9561111111), + ("FMSF", -21.4413888889, 47.1116666667), + ("FMSG", -22.8052777778, 47.8205555556), + ("FMSK", -22.1197222222, 48.0216666667), + ("FMSM", -21.2016666667, 48.3580555556), + ("FMSR", -21.7536111111, 43.3752777778), + ("FMST", -23.3833333333, 43.7283333333), + ("FNBC", -6.26972222222, 14.2469444444), + ("FNBG", -12.6088888889, 13.4036111111), + ("FNCA", -5.59694444444, 12.1883333333), + ("FNCH", -7.3575, 20.8036111111), + ("FNCX", -8.37361111111, 18.9236111111), + ("FNCZ", -11.8936111111, 22.9161111111), + ("FNGI", -17.0447222222, 15.6869444444), + ("FNHU", -12.8086111111, 15.7602777778), + ("FNKU", -12.4044444444, 16.9472222222), + ("FNLB", -12.3711111111, 13.5363888889), + ("FNLU", -8.85833333333, 13.2311111111), + ("FNMA", -9.525, 16.3122222222), + ("FNME", -14.6575, 17.7197222222), + ("FNMO", -15.2611111111, 12.1466666667), + ("FNNG", -7.75444444444, 15.2875), + ("FNPA", -10.7219444444, 13.7652777778), + ("FNSA", -9.68888888889, 20.4316666667), + ("FNSO", -6.14083333333, 12.3716666667), + ("FNTO", -7.14722222222, 14.2480555556), + ("FNUE", -11.7680555556, 19.8975), + ("FNUG", -7.60305555556, 15.0277777778), + ("FNXA", -16.7552777778, 14.9652777778), + ("FOGO", 1.54111111111, 11.5808333333), + ("FOGQ", -0.665277777778, 13.6730555556), + ("FOGR", -0.704166666667, 10.2455555556), + ("FOOB", 2.07555555556, 11.4930555556), + ("FOOD", -1.5375, 13.2691666667), + ("FOOG", -0.711666666667, 8.75416666667), + ("FOOH", -1.57472222222, 9.26277777778), + ("FOOK", 0.579166666667, 12.8908333333), + ("FOOL", 0.458333333333, 9.41222222222), + ("FOOM", 0.775555555556, 11.5525), + ("FOON", -1.65611111111, 13.4377777778), + ("FOOR", -0.826388888889, 12.7466666667), + ("FOOT", -2.88888888889, 10.9194444444), + ("FPPR", 1.66277777778, 7.41166666667), + ("FPST", 0.378055555556, 6.71194444444), + ("FQBR", -19.7963888889, 34.9075), + ("FQCB", -14.82, 36.5319444444), + ("FQCH", -19.1511111111, 33.4288888889), + ("FQES", -15.7341666667, 32.7566666667), + ("FQIN", -23.8763888889, 35.4083333333), + ("FQLC", -13.2738888889, 35.2661111111), + ("FQLU", -15.0330555556, 40.6716666667), + ("FQMA", -25.9208333333, 32.5725), + ("FQMD", -11.6727777778, 39.5630555556), + ("FQMP", -11.3616666667, 40.3547222222), + ("FQMR", -13.225, 37.5519444444), + ("FQNC", -14.4880555556, 40.7122222222), + ("FQNP", -15.1055555556, 39.2816666667), + ("FQPB", -12.9866666667, 40.5222222222), + ("FQQL", -17.8555555556, 36.8691666667), + ("FQSG", -15.6025, 32.7730555556), + ("FQTT", -16.1047222222, 33.64), + ("FQUG", -14.7044444444, 34.3522222222), + ("FQVL", -22.0183333333, 35.3130555556), + ("FSAL", -7.00472222222, 52.7261111111), + ("FSDR", -5.69583333333, 53.6544444444), + ("FSFA", -10.1094444444, 51.1761111111), + ("FSIA", -4.67416666667, 55.5216666667), + ("FSPP", -4.31916666667, 55.6913888889), + ("FSSC", -7.16416666667, 56.2638888889), + ("FTTA", 9.15111111111, 18.3794444444), + ("FTTC", 13.8469444444, 20.8441666667), + ("FTTD", 8.62027777778, 16.0683333333), + ("FTTJ", 12.1336111111, 15.0338888889), + ("FTTP", 9.37916666667, 14.9258333333), + ("FTTY", 17.9169444444, 19.1108333333), + ("FVBU", -20.0172222222, 28.6177777778), + ("FVCP", -17.7513888889, 30.9244444444), + ("FVCZ", -21.0080555556, 31.5783333333), + ("FVFA", -18.0961111111, 25.8391666667), + ("FVGR", -18.9775, 32.4505555556), + ("FVHA", -17.9316666667, 31.0927777778), + ("FVKB", -16.5197222222, 28.8847222222), + ("FVMT", -17.4316666667, 32.1844444444), + ("FVMU", -18.9975, 32.6272222222), + ("FVMV", -20.0552777778, 30.8588888889), + ("FVSH", -20.2894444444, 30.0883333333), + ("FVTL", -19.4366666667, 29.8616666667), + ("FVWN", -18.6297222222, 27.0208333333), + ("FVZC", -19.0286111111, 29.7219444444), + ("FWCL", -15.6788888889, 34.9738888889), + ("FWKA", -9.95333333333, 33.8927777778), + ("FWKG", -13.0144444444, 33.4683333333), + ("FWMG", 30.8377777778, -85.1816666667), + ("FWUU", -11.4447222222, 34.0116666667), + ("FXMM", -29.4622222222, 27.5525), + ("FXMU", -29.3038888889, 27.5033333333), + ("FZAA", -4.38555555556, 15.4444444444), + ("FZAB", -4.32472222222, 15.3283333333), + ("FZAG", -5.93083333333, 12.3516666667), + ("FZAI", -5.91805555556, 12.4475), + ("FZAM", -5.79944444444, 13.4408333333), + ("FZBO", -3.31111111111, 17.3816666667), + ("FZCA", -5.03555555556, 18.7855555556), + ("FZEA", 0.0225, 18.2886111111), + ("FZFD", 4.25305555556, 20.9752777778), + ("FZFK", 3.23527777778, 19.7711111111), + ("FZFP", 4.1575, 21.6508333333), + ("FZGA", 2.17055555556, 21.4966666667), + ("FZIA", 0.5175, 25.155), + ("FZJH", 2.8275, 27.5880555556), + ("FZKA", 1.56555555556, 30.2208333333), + ("FZKJ", 2.81777777778, 24.7938888889), + ("FZMA", -2.30888888889, 28.8086111111), + ("FZNA", -1.67055555556, 29.2383333333), + ("FZOA", -2.91916666667, 25.9152777778), + ("FZQA", -11.5911111111, 27.5308333333), + ("FZQM", -10.7658333333, 25.5055555556), + ("FZRF", -5.87555555556, 29.25), + ("FZSA", -8.64194444444, 25.2527777778), + ("FZTL", -9.46944444444, 25.7588888889), + ("FZUA", -5.9, 22.4691666667), + ("FZWA", -6.12111111111, 23.5688888889), + ("GABS", 12.5333333333, -7.94972222222), + ("GAGO", 16.2483333333, -0.00527777777778), + ("GAKY", 14.4311111111, -11.4394444444), + ("GAMB", 14.5127777778, -4.07944444444), + ("GANR", 15.2386111111, -9.57638888889), + ("GATB", 16.7302777778, -3.0075), + ("GATS", 20.2461111111, 0.980833333333), + ("GBYD", 13.3377777778, -16.6519444444), + ("GCFV", 28.4525, -13.8636111111), + ("GCHI", 27.8147222222, -17.8869444444), + ("GCLA", 28.6263888889, -17.7555555556), + ("GCLP", 27.9316666667, -15.3863888889), + ("GCRR", 28.9452777778, -13.605), + ("GCTS", 28.0444444444, -16.5722222222), + ("GCXO", 28.4825, -16.3413888889), + ("GEML", 35.2797222222, -2.95611111111), + ("GFHA", 8.39444444444, -13.1283333333), + ("GFLL", 8.61638888889, -13.1952777778), + ("GGCF", 11.2880555556, -15.1805555556), + ("GGOV", 11.8947222222, -15.6536111111), + ("GLMR", 6.28888888889, -10.7586111111), + ("GLRB", 6.23361111111, -10.3622222222), + ("GMAA", 30.3811111111, -9.54611111111), + ("GMAT", 28.4480555556, -11.1611111111), + ("GMFF", 33.9272222222, -4.97777777778), + ("GMFI", 33.5052777778, -5.15277777778), + ("GMFK", 31.9488888889, -4.40055555556), + ("GMFM", 33.8788888889, -5.515), + ("GMFN", 35.1533333333, -2.92), + ("GMFO", 34.7869444444, -1.92388888889), + ("GMMC", 33.5533333333, -7.66138888889), + ("GMME", 34.0513888889, -6.75138888889), + ("GMMF", 29.3688888889, -10.18), + ("GMMI", 31.4038888889, -9.68472222222), + ("GMMN", 33.3677777778, -7.58777777778), + ("GMMX", 31.6066666667, -8.03611111111), + ("GMMY", 34.2988888889, -6.59583333333), + ("GMMZ", 30.9388888889, -6.90916666667), + ("GMTA", 35.1769444444, -3.83944444444), + ("GMTN", 35.5941666667, -5.32), + ("GMTT", 35.7266666667, -5.91666666667), + ("GOGG", 12.5555555556, -16.2816666667), + ("GOGK", 12.88, -14.9552777778), + ("GOGS", 12.41, -16.7461111111), + ("GOOK", 14.1466666667, -16.0511111111), + ("GOOY", 14.7394444444, -17.49), + ("GOSS", 16.0497222222, -16.4611111111), + ("GOTB", 14.8472222222, -12.4680555556), + ("GOTK", 12.5722222222, -12.2202777778), + ("GOTT", 13.7366666667, -13.6530555556), + ("GQNA", 16.7111111111, -9.63777777778), + ("GQND", 18.5702777778, -11.4230555556), + ("GQNF", 16.5897222222, -11.4061111111), + ("GQNI", 16.6219444444, -7.31444444444), + ("GQNK", 16.1594444444, -13.5075), + ("GQNN", 18.0977777778, -15.9477777778), + ("GQNS", 15.1794444444, -12.2072222222), + ("GQPA", 20.5066666667, -13.0430555556), + ("GQPP", 20.9283333333, -17.0311111111), + ("GQPT", 25.2366666667, -11.5886111111), + ("GUFA", 10.3505555556, -13.5691666667), + ("GUFH", 10.0355555556, -10.7697222222), + ("GULB", 11.3261111111, -12.2869444444), + ("GUMA", 8.48111111111, -9.52583333333), + ("GUNZ", 7.80583333333, -8.70166666667), + ("GVAC", 16.7413888889, -22.9494444444), + ("GVBA", 16.1366666667, -22.8888888889), + ("GVFM", 14.9244444444, -23.4933333333), + ("GVMA", 15.1558333333, -23.2136111111), + ("GVSN", 16.5883333333, -24.2844444444), + ("GVSV", 16.8338888889, -25.0566666667), + ("HAAB", 8.97694444444, 38.8), + ("HAAL", 9.00361111111, 38.7255555556), + ("HABD", 11.6080555556, 37.3213888889), + ("HADR", 9.625, 41.8541666667), + ("HAGM", 8.12833333333, 34.5633333333), + ("HAGN", 12.5183333333, 37.4322222222), + ("HAHM", 8.71555555556, 39.0080555556), + ("HAJM", 7.66583333333, 36.8163888889), + ("HALL", 11.9747222222, 38.9797222222), + ("HAMK", 13.4672222222, 39.5333333333), + ("HBBA", -3.32388888889, 29.3183333333), + ("HCMB", 3.09861111111, 43.6241666667), + ("HCMH", 9.51805555556, 44.0886111111), + ("HCMI", 10.3891666667, 44.9408333333), + ("HCMK", -0.377222222222, 42.4591666667), + ("HCMM", 2.01361111111, 45.3047222222), + ("HEAR", 31.0733333333, 33.8358333333), + ("HEAT", 27.0463888889, 31.0119444444), + ("HEAX", 31.1838888889, 29.9488888889), + ("HEBL", 22.3758333333, 31.6116666667), + ("HECA", 30.1219444444, 31.4055555556), + ("HECW", 30.1161111111, 30.9152777778), + ("HEEM", 30.0744444444, 31.1919444444), + ("HEGN", 27.1838888889, 33.7983333333), + ("HEGR", 31.0688888889, 34.1291666667), + ("HELX", 25.6708333333, 32.7063888889), + ("HEMM", 31.3252777778, 27.2216666667), + ("HEPS", 31.2794444444, 32.24), + ("HESC", 28.6852777778, 34.0625), + ("HESN", 23.9641666667, 32.8197222222), + ("HETR", 28.2088888889, 33.6452777778), + ("HKEL", 0.404166666667, 35.2380555556), + ("HKGA", -0.463333333333, 39.6480555556), + ("HKIS", 0.339166666667, 37.5908333333), + ("HKKG", 0.271111111111, 34.7872222222), + ("HKKI", -0.0861111111111, 34.7288888889), + ("HKKT", 0.971944444444, 34.9583333333), + ("HKLK", 4.20416666667, 34.3480555556), + ("HKLO", 3.12194444444, 35.6086111111), + ("HKLU", -2.25222222222, 40.9130555556), + ("HKLY", 2.76305555556, 36.7183333333), + ("HKMA", 3.93361111111, 41.8441666667), + ("HKMB", 2.345, 37.9991666667), + ("HKMK", 0.230277777778, 38.1702777778), + ("HKML", -3.22916666667, 40.1016666667), + ("HKMO", -4.03472222222, 39.5941666667), + ("HKMY", 3.46972222222, 39.1013888889), + ("HKNI", -0.368888888889, 36.98), + ("HKNV", -0.787777777778, 36.4333333333), + ("HKNW", -1.32166666667, 36.8147222222), + ("HKNY", -0.0608333333333, 37.0386111111), + ("HKRE", -1.27722222222, 36.8622222222), + ("HKWJ", 1.73305555556, 40.0913888889), + ("HLFL", 28.7952777778, 22.0808333333), + ("HLGL", 28.6383333333, 21.4377777778), + ("HLGT", 25.1455555556, 10.1425), + ("HLKF", 24.1786111111, 23.3138888889), + ("HLLB", 32.0966666667, 20.2694444444), + ("HLLQ", 32.7886111111, 21.9641666667), + ("HLLS", 26.9869444444, 14.4725), + ("HLLT", 32.6633333333, 13.1588888889), + ("HLMB", 30.3780555556, 19.5763888889), + ("HLNF", 30.5, 18.5269444444), + ("HLON", 29.11, 15.9655555556), + ("HLRA", 29.4697222222, 17.9311111111), + ("HLTD", 30.1516666667, 9.71527777778), + ("HLZA", 28.59, 17.2941666667), + ("HRYG", -1.67694444444, 29.2586111111), + ("HRYR", -1.96861111111, 30.1394444444), + ("HRZA", -2.46222222222, 28.9077777778), + ("HSDN", 19.1536111111, 30.43), + ("HSDZ", 11.7858333333, 34.3363888889), + ("HSFS", 13.615, 25.3247222222), + ("HSKA", 15.3858333333, 36.3280555556), + ("HSNL", 12.0536111111, 24.9552777778), + ("HSOB", 13.1530555556, 30.2325), + ("HSSJ", 4.87194444444, 31.6011111111), + ("HSSM", 9.55861111111, 31.6525), + ("HSSP", 19.5763888889, 37.2158333333), + ("HSSS", 15.5894444444, 32.5530555556), + ("HSWW", 7.72555555556, 27.9794444444), + ("HTAR", -3.36777777778, 36.6333333333), + ("HTDA", -6.87805555556, 39.2025), + ("HTDO", -6.17027777778, 35.7525), + ("HTIR", -7.66861111111, 35.7519444444), + ("HTKJ", -3.42916666667, 37.0744444444), + ("HTLM", -3.37611111111, 35.8180555556), + ("HTMD", -3.51416666667, 33.6188888889), + ("HTMS", -3.36277777778, 37.3233333333), + ("HTMT", -10.3388888889, 40.1816666667), + ("HTMW", -2.44444444444, 32.9325), + ("HTNG", -6.71722222222, 38.1536111111), + ("HTPE", -5.25722222222, 39.8113888889), + ("HTTG", -5.09222222222, 39.0711111111), + ("HTZA", -6.22194444444, 39.2247222222), + ("HUEN", 0.0422222222222, 32.4433333333), + ("HUGU", 2.80555555556, 32.2716666667), + ("HUSO", 1.7275, 33.6227777778), + ("KABI", 32.4111111111, -99.6816666667), + ("KACK", 41.2527777778, -70.06), + ("KACT", 31.6111111111, -97.2302777778), + ("KACY", 39.4575, -74.5769444444), + ("KADM", 34.3030555556, -97.0194444444), + ("KADW", 38.8105555556, -76.8669444444), + ("KAEX", 31.3272222222, -92.5483333333), + ("KAGS", 33.3697222222, -81.9644444444), + ("KAKR", 41.0375, -81.4666666667), + ("KALB", 42.7480555556, -73.8027777778), + ("KALI", 27.7408333333, -98.0269444444), + ("KAMA", 35.2191666667, -101.705833333), + ("KANB", 33.5880555556, -85.8580555556), + ("KAND", 34.495, -82.7091666667), + ("KAOO", 40.2963888889, -78.32), + ("KAPG", 39.4661111111, -76.1694444444), + ("KARA", 30.0375, 91.8838888889), + ("KART", 43.9916666667, -76.0216666667), + ("KATL", 33.6402777778, -84.4269444444), + ("KAUG", 44.3205555556, -69.7972222222), + ("KAUS", 30.1944444444, -97.6697222222), + ("KBAB", 39.1358333333, -121.436388889), + ("KBAD", 32.5016666667, -93.6625), + ("KBCT", 26.3783333333, -80.1075), + ("KBDE", 48.7283333333, -94.6122222222), + ("KBDL", 41.9388888889, -72.6830555556), + ("KBDR", 41.1633333333, -73.1261111111), + ("KBED", 42.4697222222, -71.2888888889), + ("KBFI", 47.5297222222, -122.301944444), + ("KBFL", 35.4333333333, -119.056666667), + ("KBFM", 30.6263888889, -88.0677777778), + ("KBGR", 44.8072222222, -68.8280555556), + ("KBHM", 33.5627777778, -86.7533333333), + ("KBIF", 31.8494444444, -106.38), + ("KBIX", 30.4108333333, -88.9236111111), + ("KBKF", 39.7016666667, -104.751388889), + ("KBLI", 48.7925, -122.5375), + ("KBLV", 38.545, -89.835), + ("KBNA", 36.1244444444, -86.6780555556), + ("KBOI", 43.5641666667, -116.222777778), + ("KBOS", 42.3641666667, -71.005), + ("KBPT", 29.9508333333, -94.0205555556), + ("KBRO", 25.9066666667, -97.4258333333), + ("KBTR", 30.5330555556, -91.1494444444), + ("KBTV", 44.4716666667, -73.1530555556), + ("KBUF", 42.9402777778, -78.7319444444), + ("KBUR", 34.2005555556, -118.358611111), + ("KBWI", 39.1752777778, -76.6683333333), + ("KBYH", 35.9641666667, -89.9433333333), + ("KBYS", 35.2802777778, -116.63), + ("KCAE", 33.9386111111, -81.1194444444), + ("KCAR", 46.8713888889, -68.0177777778), + ("KCBM", 33.6438888889, -88.4436111111), + ("KCDC", 37.7008333333, -113.098611111), + ("KCDS", 34.4336111111, -100.288055556), + ("KCEF", 42.1980555556, -72.5341666667), + ("KCEW", 30.7786111111, -86.5219444444), + ("KCFD", 30.7155555556, -96.3311111111), + ("KCHA", 35.0352777778, -85.2036111111), + ("KCHS", 32.8986111111, -80.0402777778), + ("KCIC", 39.7952777778, -121.858333333), + ("KCLE", 41.4116666667, -81.8497222222), + ("KCLL", 30.5883333333, -96.3636111111), + ("KCLT", 35.2138888889, -80.9430555556), + ("KCMH", 39.9977777778, -82.8916666667), + ("KCNM", 32.3372222222, -104.263055556), + ("KCNW", 31.6377777778, -97.0738888889), + ("KCOF", 28.2347222222, -80.61), + ("KCOS", 38.8055555556, -104.7), + ("KCOT", 28.4580555556, -99.22), + ("KCOU", 38.8180555556, -92.2194444444), + ("KCPR", 42.9077777778, -106.464166667), + ("KCRP", 27.7702777778, -97.5011111111), + ("KCTB", 48.6083333333, -112.376111111), + ("KCVG", 39.0461111111, -84.6619444444), + ("KCVS", 34.3825, -103.321944444), + ("KCXL", 32.6694444444, -115.513055556), + ("KCXO", 30.3516666667, -95.4144444444), + ("KCYS", 41.1555555556, -104.811666667), + ("KDAL", 32.8469444444, -96.8516666667), + ("KDAY", 39.9022222222, -84.2191666667), + ("KDCA", 38.8519444444, -77.0375), + ("KDEN", 39.8583333333, -104.666944444), + ("KDET", 42.4091666667, -83.0097222222), + ("KDFW", 32.8963888889, -97.0375), + ("KDHN", 31.3211111111, -85.4494444444), + ("KDHT", 36.0225, -102.547222222), + ("KDLF", 29.3594444444, -100.777777778), + ("KDLH", 46.8419444444, -92.1936111111), + ("KDMA", 32.1663888889, -110.883055556), + ("KDOV", 39.13, -75.4663888889), + ("KDPA", 41.9077777778, -88.2486111111), + ("KDRI", 30.8316666667, -93.3397222222), + ("KDRO", 37.1513888889, -107.753611111), + ("KDRT", 29.3727777778, -100.925833333), + ("KDSM", 41.5338888889, -93.6625), + ("KDTW", 42.2122222222, -83.3533333333), + ("KDUG", 31.4688888889, -109.603611111), + ("KDYS", 32.4205555556, -99.8544444444), + ("KECG", 36.2605555556, -76.1744444444), + ("KEDW", 34.9052777778, -117.883611111), + ("KEFD", 29.6072222222, -95.1586111111), + ("KEGP", 28.7, -100.479444444), + ("KEKN", 38.8894444444, -79.8569444444), + ("KELD", 33.2208333333, -92.8130555556), + ("KELP", 31.8066666667, -106.377777778), + ("KEND", 36.3397222222, -97.9161111111), + ("KENV", 40.7186111111, -114.030833333), + ("KESF", 31.3947222222, -92.2955555556), + ("KEWN", 35.0727777778, -77.0427777778), + ("KEWR", 40.6922222222, -74.1686111111), + ("KEYW", 24.5561111111, -81.7594444444), + ("KFAF", 37.1325, -76.6086111111), + ("KFAT", 36.7761111111, -119.718055556), + ("KFCS", 38.6783333333, -104.756388889), + ("KFFO", 39.8261111111, -84.0483333333), + ("KFHU", 31.5883333333, -110.344166667), + ("KFLL", 26.0725, -80.1525), + ("KFLO", 34.1852777778, -79.7238888889), + ("KFLV", 39.3683333333, -94.9144444444), + ("KFME", 39.0852777778, -76.7591666667), + ("KFMH", 41.6583333333, -70.5213888889), + ("KFMN", 36.7411111111, -108.229722222), + ("KFMY", 26.5863888889, -81.8630555556), + ("KFOD", 42.5513888889, -94.1925), + ("KFOE", 38.9508333333, -95.6636111111), + ("KFOK", 40.8436111111, -72.6316666667), + ("KFRI", 39.055, -96.7644444444), + ("KFSI", 34.6497222222, -98.4019444444), + ("KFSM", 35.3363888889, -94.3672222222), + ("KFTK", 37.9069444444, -85.9719444444), + ("KFTW", 32.8197222222, -97.3622222222), + ("KFXE", 26.1972222222, -80.1705555556), + ("KFYV", 36.005, -94.17), + ("KGAG", 36.2952777778, -99.7763888889), + ("KGCK", 37.9275, -100.724166667), + ("KGEG", 47.6197222222, -117.533611111), + ("KGFK", 47.9491666667, -97.1761111111), + ("KGGG", 32.3847222222, -94.7113888889), + ("KGLS", 29.2652777778, -94.8602777778), + ("KGNT", 35.1652777778, -107.900555556), + ("KGNV", 29.69, -82.2716666667), + ("KGRB", 44.485, -88.1294444444), + ("KGRF", 47.0791666667, -122.580555556), + ("KGRK", 31.0672222222, -97.8288888889), + ("KGRR", 42.8808333333, -85.5227777778), + ("KGSB", 35.3391666667, -77.9605555556), + ("KGTB", 44.0555555556, -75.7194444444), + ("KGTF", 47.4819444444, -111.370555556), + ("KGUS", 40.6480555556, -86.1519444444), + ("KGVT", 33.0677777778, -96.0652777778), + ("KGVW", 38.8433333333, -94.5605555556), + ("KGWO", 33.4941666667, -90.0844444444), + ("KHBR", 34.9911111111, -99.0511111111), + ("KHFD", 41.7361111111, -72.65), + ("KHHR", 33.9227777778, -118.335), + ("KHIB", 47.3863888889, -92.8388888889), + ("KHIF", 41.1238888889, -111.972777778), + ("KHKY", 35.7411111111, -81.3894444444), + ("KHLN", 46.6066666667, -111.9825), + ("KHLR", 31.1386111111, -97.7144444444), + ("KHMN", 32.8525, -106.106388889), + ("KHOB", 32.6875, -103.216944444), + ("KHON", 44.385, -98.2283333333), + ("KHOP", 36.6683333333, -87.4961111111), + ("KHOU", 29.6452777778, -95.2788888889), + ("KHPN", 41.0669444444, -73.7075), + ("KHRL", 26.2283333333, -97.6541666667), + ("KHRO", 36.2613888889, -93.1547222222), + ("KHRT", 30.4277777778, -86.6891666667), + ("KHST", 25.4883333333, -80.3836111111), + ("KHTL", 44.3597222222, -84.6711111111), + ("KHUA", 34.6786111111, -86.6847222222), + ("KHUF", 39.4513888889, -87.3075), + ("KHUL", 46.1230555556, -67.7919444444), + ("KHVR", 48.5427777778, -109.762222222), + ("KHWO", 26.0013888889, -80.2402777778), + ("KIAB", 37.6227777778, -97.2672222222), + ("KIAD", 38.9444444444, -77.4555555556), + ("KIAG", 43.1072222222, -78.9461111111), + ("KIAH", 29.9802777778, -95.3397222222), + ("KICT", 37.6497222222, -97.4330555556), + ("KIKK", 41.0713888889, -87.8461111111), + ("KIKR", 35.04, -106.609166667), + ("KILG", 39.6786111111, -75.6063888889), + ("KILM", 34.2705555556, -77.9025), + ("KIND", 39.7172222222, -86.2941666667), + ("KINK", 31.7794444444, -103.201111111), + ("KINL", 48.5661111111, -93.4030555556), + ("KINS", 36.5869444444, -115.673333333), + ("KINT", 36.1336111111, -80.2219444444), + ("KIPL", 32.8341666667, -115.578611111), + ("KIPT", 41.2419444444, -76.9211111111), + ("KISN", 48.1777777778, -103.642222222), + ("KISP", 40.795, -73.1), + ("KJAN", 32.3111111111, -90.0758333333), + ("KJAX", 30.4938888889, -81.6877777778), + ("KJBR", 35.8316666667, -90.6461111111), + ("KJFK", 40.6397222222, -73.7788888889), + ("KLAN", 42.7786111111, -84.5872222222), + ("KLAS", 36.0802777778, -115.152222222), + ("KLAX", 33.9425, -118.408055556), + ("KLBB", 33.6636111111, -101.822777778), + ("KLCH", 30.1261111111, -93.2233333333), + ("KLCK", 39.8136111111, -82.9277777778), + ("KLFI", 37.0827777778, -76.3602777778), + ("KLFK", 31.2338888889, -94.75), + ("KLFT", 30.2052777778, -91.9875), + ("KLGA", 40.7772222222, -73.8725), + ("KLGB", 33.8175, -118.151388889), + ("KLHW", 31.8888888889, -81.5622222222), + ("KLIT", 34.7294444444, -92.2241666667), + ("KLNA", 26.5927777778, -80.085), + ("KLNK", 40.8508333333, -96.7591666667), + ("KLOU", 38.2277777778, -85.6636111111), + ("KLRD", 27.5436111111, -99.4613888889), + ("KLRF", 34.9180555556, -92.1463888889), + ("KLSF", 32.3372222222, -84.9911111111), + ("KLSV", 36.2361111111, -115.034166667), + ("KLTS", 34.6669444444, -99.2666666667), + ("KLUF", 33.535, -112.383055556), + ("KLUK", 39.1033333333, -84.4186111111), + ("KMAF", 31.9425, -102.201666667), + ("KMCC", 38.6675, -121.400555556), + ("KMCF", 27.8491666667, -82.5211111111), + ("KMCI", 39.2975, -94.7138888889), + ("KMCN", 32.6927777778, -83.6491666667), + ("KMCO", 28.4288888889, -81.3158333333), + ("KMDT", 40.1933333333, -76.7633333333), + ("KMDW", 41.7858333333, -87.7522222222), + ("KMEM", 35.0422222222, -89.9766666667), + ("KMER", 37.3802777778, -120.568055556), + ("KMFE", 26.1758333333, -98.2386111111), + ("KMGE", 33.9152777778, -84.5161111111), + ("KMHR", 38.5538888889, -121.2975), + ("KMIA", 25.7930555556, -80.2905555556), + ("KMIB", 48.4155555556, -101.3575), + ("KMIV", 39.3677777778, -75.0722222222), + ("KMKE", 42.9472222222, -87.8963888889), + ("KMKL", 35.5997222222, -88.9155555556), + ("KMKO", 35.6575, -95.3613888889), + ("KMLB", 28.1025, -80.645), + ("KMLC", 34.8822222222, -95.7833333333), + ("KMLT", 45.6477777778, -68.6855555556), + ("KMLU", 32.5108333333, -92.0375), + ("KMMV", 45.1944444444, -123.135833333), + ("KMNM", 45.1263888889, -87.6383333333), + ("KMOB", 30.6913888889, -88.2427777778), + ("KMOD", 37.6255555556, -120.954166667), + ("KMOT", 48.2591666667, -101.280277778), + ("KMPV", 44.2033333333, -72.5622222222), + ("KMQT", 46.5338888889, -87.5616666667), + ("KMSN", 43.1397222222, -89.3375), + ("KMSP", 44.8802777778, -93.2166666667), + ("KMSS", 44.9358333333, -74.8452777778), + ("KMSY", 29.9933333333, -90.2577777778), + ("KMTC", 42.6127777778, -82.8316666667), + ("KMUI", 40.4347222222, -76.5691666667), + ("KMUO", 43.0433333333, -115.872222222), + ("KMWH", 47.2075, -119.32), + ("KMWL", 32.7813888889, -98.06), + ("KMXF", 32.3791666667, -86.3625), + ("KMYR", 33.6797222222, -78.9283333333), + ("KNBC", 32.4772222222, -80.7230555556), + ("KNBG", 29.8252777778, -90.035), + ("KNCA", 34.7083333333, -77.4394444444), + ("KNEL", 40.0333333333, -74.3533333333), + ("KNFL", 39.4163888889, -118.700833333), + ("KNGU", 36.9375, -76.2891666667), + ("KNHK", 38.2858333333, -76.4116666667), + ("KNID", 35.6877777778, -117.690555556), + ("KNIP", 30.2358333333, -81.6805555556), + ("KNJK", 32.8291666667, -115.671666667), + ("KNKT", 34.9025, -76.8808333333), + ("KNKX", 32.8683333333, -117.1425), + ("KNLC", 36.3327777778, -119.951944444), + ("KNMM", 32.5519444444, -88.5555555556), + ("KNOW", 48.1413888889, -123.413888889), + ("KNPA", 30.3525, -87.3186111111), + ("KNQA", 35.3566666667, -89.8702777778), + ("KNQI", 27.5072222222, -97.8097222222), + ("KNQX", 24.5758333333, -81.6888888889), + ("KNSE", 30.7241666667, -87.0219444444), + ("KNTD", 34.1202777778, -119.120833333), + ("KNTK", 33.7061111111, -117.827222222), + ("KNTU", 36.8205555556, -76.0333333333), + ("KNUQ", 37.415, -122.048055556), + ("KNUW", 48.3516666667, -122.655833333), + ("KNXP", 34.2961111111, -116.161944444), + ("KNXX", 40.1997222222, -75.1480555556), + ("KNYG", 38.5016666667, -77.3052777778), + ("KNZC", 30.2186111111, -81.8763888889), + ("KNZY", 32.6991666667, -117.215277778), + ("KOAK", 37.7211111111, -122.220555556), + ("KOFF", 41.1183333333, -95.9125), + ("KOGS", 44.6819444444, -75.4655555556), + ("KOKC", 35.3930555556, -97.6005555556), + ("KOLS", 31.4175, -110.847777778), + ("KOMA", 41.3025, -95.8936111111), + ("KONT", 34.0558333333, -117.601111111), + ("KOPF", 25.9069444444, -80.2783333333), + ("KORD", 41.9794444444, -87.9044444444), + ("KORF", 36.8944444444, -76.2011111111), + ("KORL", 28.5452777778, -81.3327777778), + ("KOSC", 44.4513888889, -83.3938888889), + ("KPAE", 47.9061111111, -122.281388889), + ("KPAM", 30.0697222222, -85.5763888889), + ("KPBF", 34.1747222222, -91.9344444444), + ("KPBG", 44.6508333333, -73.4680555556), + ("KPBI", 26.6830555556, -80.0955555556), + ("KPDX", 45.5886111111, -122.5975), + ("KPHF", 37.1316666667, -76.4927777778), + ("KPHL", 39.8719444444, -75.2411111111), + ("KPHN", 42.9108333333, -82.5286111111), + ("KPHX", 33.4341666667, -112.008055556), + ("KPIE", 27.9105555556, -82.6872222222), + ("KPIT", 40.4913888889, -80.2327777778), + ("KPMB", 48.9425, -97.2408333333), + ("KPMD", 34.6291666667, -118.084444444), + ("KPNC", 36.7305555556, -97.0997222222), + ("KPNE", 40.0819444444, -75.0105555556), + ("KPNM", 45.5597222222, -93.6080555556), + ("KPNS", 30.4730555556, -87.1872222222), + ("KPOB", 35.1708333333, -79.0144444444), + ("KPOE", 31.0447222222, -93.1913888889), + ("KPQI", 46.6888888889, -68.0447222222), + ("KPRC", 34.6544444444, -112.419444444), + ("KPSP", 33.8294444444, -116.506666667), + ("KPSX", 28.7275, -96.2508333333), + ("KPUB", 38.2888888889, -104.496388889), + ("KPVD", 41.7238888889, -71.4280555556), + ("KPWM", 43.6461111111, -70.3086111111), + ("KRAL", 33.9516666667, -117.445), + ("KRBM", 34.85, -92.3), + ("KRCA", 44.145, -103.103333333), + ("KRDR", 47.9608333333, -97.4011111111), + ("KRDU", 35.8775, -78.7872222222), + ("KRIC", 37.505, -77.3194444444), + ("KRIU", 38.4886111111, -121.102222222), + ("KRIV", 33.8805555556, -117.259444444), + ("KRME", 43.2336111111, -75.4069444444), + ("KRND", 29.5294444444, -98.2788888889), + ("KRNO", 39.4983333333, -119.768055556), + ("KROC", 43.1186111111, -77.6722222222), + ("KROW", 33.3013888889, -104.530555556), + ("KRSW", 26.5361111111, -81.755), + ("KSAC", 38.5125, -121.493333333), + ("KSAF", 35.6166666667, -106.088055556), + ("KSAN", 32.7333333333, -117.189444444), + ("KSAT", 29.5336111111, -98.4697222222), + ("KSAV", 32.1275, -81.2019444444), + ("KSAW", 46.3536111111, -87.3958333333), + ("KSBO", 32.6083333333, -82.3686111111), + ("KSBY", 38.3402777778, -75.5102777778), + ("KSCK", 37.8941666667, -121.238611111), + ("KSEA", 47.4488888889, -122.309166667), + ("KSEM", 32.3438888889, -86.9877777778), + ("KSFF", 47.6827777778, -117.3225), + ("KSFO", 37.6188888889, -122.374722222), + ("KSFZ", 41.9205555556, -71.4911111111), + ("KSHV", 32.4463888889, -93.8255555556), + ("KSJC", 37.3616666667, -121.928888889), + ("KSJT", 31.3575, -100.496111111), + ("KSKA", 47.615, -117.655555556), + ("KSKF", 29.3841666667, -98.5808333333), + ("KSKY", 41.4333333333, -82.6522222222), + ("KSLC", 40.7883333333, -111.9775), + ("KSMF", 38.6952777778, -121.590555556), + ("KSNA", 33.6755555556, -117.868055556), + ("KSPB", 45.7725, -122.862222222), + ("KSPG", 27.765, -82.6269444444), + ("KSPS", 33.9886111111, -98.4916666667), + ("KSSC", 33.9727777778, -80.4727777778), + ("KSTL", 38.7475, -90.3597222222), + ("KSUU", 38.2625, -121.927222222), + ("KSUX", 42.4025, -96.3841666667), + ("KSVN", 32.01, -81.1455555556), + ("KSWF", 41.5038888889, -74.1047222222), + ("KSYR", 43.1111111111, -76.1061111111), + ("KSZL", 38.7302777778, -93.5477777778), + ("KTBN", 37.7413888889, -92.1405555556), + ("KTCC", 35.1827777778, -103.603055556), + ("KTCM", 47.1375, -122.476388889), + ("KTCS", 33.2369444444, -107.271666667), + ("KTEB", 40.8497222222, -74.0608333333), + ("KTIK", 35.4147222222, -97.3863888889), + ("KTLH", 30.3963888889, -84.3502777778), + ("KTMB", 25.6477777778, -80.4327777778), + ("KTNT", 25.8616666667, -80.8969444444), + ("KTNX", 37.7944444444, -116.778611111), + ("KTPA", 27.9752777778, -82.5330555556), + ("KTTN", 40.2766666667, -74.8133333333), + ("KTUL", 36.1983333333, -95.8880555556), + ("KTUS", 32.1161111111, -110.941388889), + ("KTXK", 33.4536111111, -93.9908333333), + ("KTYR", 32.3538888889, -95.4022222222), + ("KTYS", 35.8122222222, -83.9927777778), + ("KUGN", 42.4219444444, -87.8677777778), + ("KVAD", 30.9677777778, -83.1927777778), + ("KVBG", 34.7294444444, -120.576666667), + ("KVCV", 34.5930555556, -117.379444444), + ("KVPS", 30.4830555556, -86.5252777778), + ("KVRB", 27.6555555556, -80.4177777778), + ("KWAL", 37.94, -75.4663888889), + ("KWRB", 32.64, -83.5916666667), + ("KWRI", 40.0155555556, -74.5936111111), + ("KWSD", 32.3413888889, -106.4025), + ("KWWD", 39.0083333333, -74.9080555556), + ("KYIP", 42.2377777778, -83.5302777778), + ("KYNG", 41.2605555556, -80.6788888889), + ("KYUM", 32.6563888889, -114.605833333), + ("KZUN", 35.0833333333, -108.791666667), + ("LATI", 41.4147222222, 19.7205555556), + ("LBBG", 42.5688888889, 27.5138888889), + ("LBGO", 43.1513888889, 25.7127777778), + ("LBPD", 42.0677777778, 24.8508333333), + ("LBSF", 42.695, 23.4061111111), + ("LBSZ", 42.3766666667, 25.655), + ("LBWN", 43.2319444444, 27.825), + ("LCLK", 34.875, 33.6247222222), + ("LCPH", 34.7177777778, 32.4855555556), + ("LCRA", 34.5902777778, 32.9877777778), + ("LDDU", 42.5611111111, 18.2680555556), + ("LDOC", 45.5419444444, 18.6361111111), + ("LDOS", 45.4625, 18.8113888889), + ("LDPL", 44.8933333333, 13.9219444444), + ("LDRG", 45.3794444444, 14.5036111111), + ("LDRI", 45.2166666667, 14.57), + ("LDSP", 43.5388888889, 16.2977777778), + ("LDVA", 46.2947222222, 16.3811111111), + ("LDZA", 45.7427777778, 16.0686111111), + ("LDZD", 44.1080555556, 15.3466666667), + ("LDZU", 44.5575, 15.7741666667), + ("LEAB", 38.9483333333, -1.86333333333), + ("LEAL", 38.2819444444, -0.558055555556), + ("LEAM", 36.8438888889, -2.37), + ("LEAS", 43.5633333333, -6.03444444444), + ("LEBA", 37.8419444444, -4.84861111111), + ("LEBB", 43.3008333333, -2.91055555556), + ("LEBG", 42.3575, -3.62055555556), + ("LEBL", 41.2969444444, 2.07833333333), + ("LEBZ", 38.8911111111, -6.82111111111), + ("LECO", 43.3019444444, -8.37722222222), + ("LEGA", 37.1330555556, -3.63555555556), + ("LEGE", 41.9008333333, 2.76027777778), + ("LEGR", 37.1886111111, -3.77722222222), + ("LEGT", 40.2938888889, -3.72361111111), + ("LEIB", 38.8727777778, 1.37305555556), + ("LEJR", 36.7444444444, -6.06), + ("LELC", 37.7747222222, -0.812222222222), + ("LELN", 42.5888888889, -5.65555555556), + ("LEMD", 40.4722222222, -3.56083333333), + ("LEMG", 36.6736111111, -4.49888888889), + ("LEMH", 39.8625, 4.21861111111), + ("LEMM", 40.4166666667, -3.5), + ("LEMO", 37.1747222222, -5.61583333333), + ("LEOC", 39.9375, -3.50333333333), + ("LEPA", 39.55, 2.73333333333), + ("LEPP", 42.77, -1.64611111111), + ("LERI", 37.9511111111, -1.23027777778), + ("LERS", 41.1472222222, 1.16694444444), + ("LERT", 36.645, -6.34944444444), + ("LESA", 40.9519444444, -5.50194444444), + ("LESB", 39.5988888889, 2.70277777778), + ("LESJ", 39.5516666667, 2.73861111111), + ("LESL", 39.8622222222, 4.25833333333), + ("LESO", 43.3563888889, -1.79055555556), + ("LEST", 42.8961111111, -8.415), + ("LESU", 42.3386111111, 1.40916666667), + ("LETO", 40.4866666667, -3.45805555556), + ("LEVC", 39.4891666667, -0.481388888889), + ("LEVD", 41.7061111111, -4.85194444444), + ("LEVS", 40.3705555556, -3.785), + ("LEVT", 42.8827777778, -2.72444444444), + ("LEVX", 42.2316666667, -8.62666666667), + ("LEXJ", 43.4269444444, -3.82), + ("LEZG", 41.6661111111, -1.04138888889), + ("LEZL", 37.4177777778, -5.89305555556), + ("LFAC", 50.9619444444, 1.95472222222), + ("LFAG", 49.8688888889, 3.02777777778), + ("LFAI", 48.5936111111, 3.005), + ("LFAO", 48.5458333333, -0.387222222222), + ("LFAQ", 49.9713888889, 2.69972222222), + ("LFAT", 50.5147222222, 1.62722222222), + ("LFAV", 50.3255555556, 3.46111111111), + ("LFAY", 49.8713888889, 2.38638888889), + ("LFBA", 44.1747222222, 0.590555555556), + ("LFBC", 44.5333333333, -1.125), + ("LFBD", 44.8283333333, -0.715555555556), + ("LFBE", 44.8252777778, 0.518611111111), + ("LFBF", 43.5455555556, 1.3675), + ("LFBG", 45.6583333333, -0.3175), + ("LFBI", 46.5875, 0.306666666667), + ("LFBK", 46.2244444444, 2.36305555556), + ("LFBL", 45.8627777778, 1.17944444444), + ("LFBM", 43.9116666667, -0.5075), + ("LFBN", 46.3111111111, -0.401388888889), + ("LFBO", 43.6288888889, 1.36361111111), + ("LFBP", 43.38, -0.418611111111), + ("LFBR", 43.4488888889, 1.26333333333), + ("LFBT", 43.1786111111, -0.00638888888889), + ("LFBU", 45.7291666667, 0.221388888889), + ("LFBV", 45.1508333333, 1.46916666667), + ("LFBX", 45.1980555556, 0.815555555556), + ("LFBZ", 43.4683333333, -1.52305555556), + ("LFCC", 44.3511111111, 1.47527777778), + ("LFCG", 43.0075, 1.10305555556), + ("LFCH", 44.5963888889, -1.11083333333), + ("LFCI", 43.9136111111, 2.11305555556), + ("LFCK", 43.5561111111, 2.28916666667), + ("LFCL", 43.5861111111, 1.49916666667), + ("LFCM", 43.99, 3.18305555556), + ("LFCR", 44.4077777778, 2.4825), + ("LFCU", 45.5347222222, 2.42388888889), + ("LFCW", 44.3969444444, 0.758888888889), + ("LFCY", 45.6280555556, -0.9725), + ("LFCZ", 44.1461111111, -1.17444444444), + ("LFDA", 43.7094444444, -0.245277777778), + ("LFDB", 44.0255555556, 1.37777777778), + ("LFDH", 43.6877777778, 0.601666666667), + ("LFDI", 44.9822222222, -0.134722222222), + ("LFDJ", 43.0905555556, 1.69583333333), + ("LFDM", 44.4988888889, 0.200277777778), + ("LFDN", 45.8877777778, -0.983055555556), + ("LFEC", 48.4627777778, -5.06388888889), + ("LFED", 48.0583333333, -2.92166666667), + ("LFES", 48.0525, -3.66444444444), + ("LFEY", 46.7186111111, -2.39111111111), + ("LFFI", 47.4080555556, -1.1775), + ("LFFN", 48.4297222222, 4.48111111111), + ("LFGA", 48.1097222222, 7.35888888889), + ("LFGF", 47.0058333333, 4.89333333333), + ("LFGJ", 47.0388888889, 5.42722222222), + ("LFGK", 47.9922222222, 3.39222222222), + ("LFGW", 49.1222222222, 5.46888888889), + ("LFHO", 44.5441666667, 4.37194444444), + ("LFHP", 45.0794444444, 3.76472222222), + ("LFHQ", 45.0763888889, 2.99361111111), + ("LFHS", 46.2008333333, 5.29194444444), + ("LFHV", 45.9163888889, 4.64055555556), + ("LFHY", 46.5344444444, 3.42361111111), + ("LFIG", 44.1775, 2.515), + ("LFIO", 43.5688888889, 1.48083333333), + ("LFJL", 48.9822222222, 6.25361111111), + ("LFKB", 42.5538888889, 9.48333333333), + ("LFKC", 42.5305555556, 8.79305555556), + ("LFKF", 41.5005555556, 9.09777777778), + ("LFKJ", 41.9236111111, 8.80277777778), + ("LFKO", 41.6630555556, 8.89027777778), + ("LFKS", 41.9241666667, 9.40583333333), + ("LFKT", 42.2936111111, 9.19305555556), + ("LFLA", 47.85, 3.49694444444), + ("LFLB", 45.6377777778, 5.88), + ("LFLC", 45.7863888889, 3.16916666667), + ("LFLD", 47.0580555556, 2.37027777778), + ("LFLE", 45.5608333333, 5.97555555556), + ("LFLH", 46.8258333333, 4.8175), + ("LFLI", 46.1919444444, 6.26833333333), + ("LFLL", 45.7261111111, 5.09083333333), + ("LFLM", 46.295, 4.79555555556), + ("LFLN", 46.4125, 4.01305555556), + ("LFLO", 46.0583333333, 4.00138888889), + ("LFLP", 45.9291666667, 6.09861111111), + ("LFLS", 45.3627777778, 5.32916666667), + ("LFLT", 46.3525, 2.57027777778), + ("LFLU", 44.9213888889, 4.96972222222), + ("LFLV", 46.1694444444, 3.40361111111), + ("LFLW", 44.8913888889, 2.42194444444), + ("LFLX", 46.8619444444, 1.73055555556), + ("LFLY", 45.7280555556, 4.94472222222), + ("LFMA", 43.5052777778, 5.36777777778), + ("LFMC", 43.3844444444, 6.38694444444), + ("LFMD", 43.5419444444, 6.95333333333), + ("LFMH", 45.5402777778, 4.29638888889), + ("LFMI", 43.5225, 4.92361111111), + ("LFMK", 43.2158333333, 2.30611111111), + ("LFML", 43.4355555556, 5.21361111111), + ("LFMN", 43.6605555556, 7.2175), + ("LFMO", 44.1402777778, 4.86666666667), + ("LFMP", 42.7402777778, 2.87055555556), + ("LFMQ", 43.2525, 5.785), + ("LFMS", 44.0694444444, 4.14194444444), + ("LFMT", 43.5761111111, 3.96277777778), + ("LFMU", 43.3238888889, 3.35555555556), + ("LFMV", 43.9072222222, 4.90166666667), + ("LFMY", 43.6063888889, 5.10916666667), + ("LFMZ", 43.1758333333, 2.73416666667), + ("LFNB", 44.5019444444, 3.53277777778), + ("LFNH", 44.0297222222, 5.07805555556), + ("LFOA", 47.0533333333, 2.6325), + ("LFOB", 49.4544444444, 2.11277777778), + ("LFOC", 48.0580555556, 1.37638888889), + ("LFOD", 47.2566666667, -0.115), + ("LFOE", 49.0286111111, 1.21972222222), + ("LFOH", 49.5338888889, 0.0880555555556), + ("LFOI", 50.1433333333, 1.83166666667), + ("LFOJ", 47.9877777778, 1.76055555556), + ("LFOK", 48.7758333333, 4.18444444444), + ("LFOP", 49.3841666667, 1.17472222222), + ("LFOT", 47.4322222222, 0.7275), + ("LFOU", 47.0819444444, -0.876944444444), + ("LFOV", 48.0311111111, -0.742777777778), + ("LFOZ", 47.8969444444, 2.16333333333), + ("LFPB", 48.9694444444, 2.44138888889), + ("LFPC", 49.2533333333, 2.51888888889), + ("LFPG", 49.0127777778, 2.55), + ("LFPK", 48.8375, 3.01611111111), + ("LFPM", 48.6047222222, 2.67111111111), + ("LFPN", 48.7516666667, 2.10611111111), + ("LFPO", 48.7252777778, 2.35944444444), + ("LFPT", 49.0963888889, 2.04083333333), + ("LFPV", 48.7741666667, 2.20138888889), + ("LFPY", 48.5966666667, 2.33138888889), + ("LFQA", 49.2077777778, 4.15666666667), + ("LFQB", 48.3227777778, 4.01777777778), + ("LFQC", 48.5972222222, 6.54472222222), + ("LFQE", 49.2266666667, 5.67194444444), + ("LFQF", 46.9663888889, 4.26027777778), + ("LFQG", 47.0011111111, 3.11444444444), + ("LFQI", 50.2216666667, 3.15416666667), + ("LFQJ", 50.3102777778, 4.03305555556), + ("LFQM", 47.2083333333, 6.08305555556), + ("LFQP", 48.7661111111, 7.20027777778), + ("LFQQ", 50.5616666667, 3.08944444444), + ("LFQT", 50.6183333333, 2.64222222222), + ("LFQV", 49.7838888889, 4.64694444444), + ("LFQW", 47.6375, 6.20388888889), + ("LFRA", 47.4972222222, -0.5725), + ("LFRB", 48.4477777778, -4.41833333333), + ("LFRC", 49.65, -1.47027777778), + ("LFRD", 48.5877777778, -2.08), + ("LFRE", 47.2894444444, -2.34638888889), + ("LFRF", 48.8830555556, -1.56416666667), + ("LFRG", 49.3652777778, 0.154166666667), + ("LFRH", 47.7605555556, -3.44), + ("LFRI", 46.7019444444, -1.37861111111), + ("LFRJ", 48.53, -4.15138888889), + ("LFRK", 49.1733333333, -0.45), + ("LFRL", 48.2816666667, -4.445), + ("LFRM", 47.9486111111, 0.201666666667), + ("LFRN", 48.0694444444, -1.73472222222), + ("LFRO", 48.7541666667, -3.47138888889), + ("LFRQ", 47.9747222222, -4.16777777778), + ("LFRS", 47.1530555556, -1.61055555556), + ("LFRT", 48.5377777778, -2.85444444444), + ("LFRU", 48.6030555556, -3.81555555556), + ("LFRV", 47.7230555556, -2.71833333333), + ("LFRZ", 47.3119444444, -2.14916666667), + ("LFSB", 47.5894444444, 7.52972222222), + ("LFSC", 47.9219444444, 7.39944444444), + ("LFSD", 47.2688888889, 5.09), + ("LFSF", 49.0716666667, 6.13166666667), + ("LFSG", 48.3247222222, 6.06972222222), + ("LFSH", 48.7933333333, 7.81611111111), + ("LFSI", 48.6358333333, 4.89916666667), + ("LFSL", 48.78, 5.97972222222), + ("LFSM", 47.4869444444, 6.7925), + ("LFSN", 48.6919444444, 6.23027777778), + ("LFSO", 48.5830555556, 5.955), + ("LFSP", 46.9044444444, 6.32694444444), + ("LFSR", 49.31, 4.05), + ("LFST", 48.5380555556, 7.62805555556), + ("LFSX", 47.7830555556, 6.36388888889), + ("LFTF", 43.2477777778, 6.12666666667), + ("LFTH", 43.0972222222, 6.14583333333), + ("LFTW", 43.7572222222, 4.41611111111), + ("LFVM", 47.0952777778, -56.3802777778), + ("LFVP", 46.7625, -56.1752777778), + ("LFXA", 45.9872222222, 5.32833333333), + ("LFXI", 44.0566666667, 5.49527777778), + ("LFYD", 48.0847222222, 5.665), + ("LFYG", 50.1413888889, 3.26305555556), + ("LFYH", 47.335, 5.51361111111), + ("LFYL", 47.7044444444, 6.54583333333), + ("LFYT", 49.7583333333, 3.21194444444), + ("LGAD", 37.9205555556, 21.2925), + ("LGAG", 38.6019444444, 21.3511111111), + ("LGAL", 40.8558333333, 25.9561111111), + ("LGAT", 37.8877777778, 23.7316666667), + ("LGAX", 40.6511111111, 22.4886111111), + ("LGBL", 39.2194444444, 22.7941666667), + ("LGEL", 38.0636111111, 23.5558333333), + ("LGHI", 38.3430555556, 26.1405555556), + ("LGIO", 39.6963888889, 20.8225), + ("LGIR", 35.3394444444, 25.1802777778), + ("LGKA", 40.4494444444, 21.2761111111), + ("LGKC", 36.2741666667, 23.0169444444), + ("LGKF", 38.1197222222, 20.5005555556), + ("LGKL", 37.0683333333, 22.0255555556), + ("LGKM", 40.9722222222, 24.3416666667), + ("LGKO", 36.7933333333, 27.0916666667), + ("LGKP", 35.4213888889, 27.1458333333), + ("LGKR", 39.6019444444, 19.9116666667), + ("LGKS", 35.4211111111, 26.91), + ("LGKV", 40.9130555556, 24.6191666667), + ("LGKZ", 40.2861111111, 21.8408333333), + ("LGLE", 37.1847222222, 26.8002777778), + ("LGLM", 39.9169444444, 25.2361111111), + ("LGLR", 39.65, 22.4652777778), + ("LGMG", 37.9811111111, 23.3652777778), + ("LGMK", 37.435, 25.3480555556), + ("LGMR", 38.145, 24.0141666667), + ("LGMT", 39.0566666667, 26.5983333333), + ("LGPZ", 38.9252777778, 20.7652777778), + ("LGRD", 36.3830555556, 28.1088888889), + ("LGRP", 36.4052777778, 28.0861111111), + ("LGRX", 38.1511111111, 21.4255555556), + ("LGSA", 35.5316666667, 24.1494444444), + ("LGSK", 39.1769444444, 23.5036111111), + ("LGSM", 37.69, 26.9116666667), + ("LGSO", 37.4227777778, 24.9508333333), + ("LGSP", 36.9733333333, 22.5261111111), + ("LGSR", 36.4002777778, 25.4786111111), + ("LGST", 35.2136111111, 26.0975), + ("LGSV", 39.48, 22.7672222222), + ("LGSY", 38.9675, 24.4872222222), + ("LGTG", 38.3397222222, 23.5647222222), + ("LGTL", 35.1869444444, 25.3266666667), + ("LGTP", 37.5308333333, 22.405), + ("LGTS", 40.5197222222, 22.9708333333), + ("LGTT", 38.1088888889, 23.7836111111), + ("LGZA", 37.75, 20.8819444444), + ("LHBP", 47.4366666667, 19.2555555556), + ("LHDC", 47.4888888889, 21.6152777778), + ("LHGD", 47.5708333333, 19.3386111111), + ("LHKE", 46.9175, 19.7491666667), + ("LHKV", 46.3891666667, 17.7313888889), + ("LHNY", 47.9838888889, 21.6922222222), + ("LHOY", 46.3038888889, 18.7691666667), + ("LHPA", 47.3638888889, 17.5008333333), + ("LHSA", 47.0777777778, 17.9683333333), + ("LHSK", 46.8580555556, 18.0955555556), + ("LHSM", 46.6863888889, 17.1588888889), + ("LHSN", 47.1227777778, 20.2352777778), + ("LHTA", 46.3930555556, 17.9172222222), + ("LHTL", 47.3452777778, 18.9808333333), + ("LIBA", 41.5386111111, 15.7133333333), + ("LIBC", 38.9972222222, 17.08), + ("LIBD", 41.1383333333, 16.7605555556), + ("LIBF", 41.4327777778, 15.535), + ("LIBG", 40.5161111111, 17.4022222222), + ("LIBN", 40.2386111111, 18.1330555556), + ("LIBP", 42.4313888889, 14.1808333333), + ("LIBR", 40.6575, 17.9469444444), + ("LIBV", 40.7677777778, 16.9333333333), + ("LICA", 38.9063888889, 16.2422222222), + ("LICC", 37.4666666667, 15.0661111111), + ("LICD", 35.4977777778, 12.6180555556), + ("LICG", 36.8163888889, 11.9686111111), + ("LICJ", 38.1758333333, 13.0908333333), + ("LICP", 38.1108333333, 13.3133333333), + ("LICR", 38.0711111111, 15.6513888889), + ("LICT", 37.9125, 12.4880555556), + ("LICZ", 37.4013888889, 14.9222222222), + ("LIEA", 40.6319444444, 8.29055555556), + ("LIED", 39.3541666667, 8.97222222222), + ("LIEE", 39.2513888889, 9.05416666667), + ("LIEO", 40.8986111111, 9.5175), + ("LIET", 39.9186111111, 9.68277777778), + ("LIIB", 40.4166666667, 12.3333333333), + ("LIMA", 45.0861111111, 7.60305555556), + ("LIMB", 45.5397222222, 9.20222222222), + ("LIMC", 45.6313888889, 8.72777777778), + ("LIME", 45.6738888889, 9.70416666667), + ("LIMF", 45.2005555556, 7.64944444444), + ("LIMG", 44.0505555556, 8.12722222222), + ("LIMJ", 44.4119444444, 8.84166666667), + ("LIML", 45.4452777778, 9.27694444444), + ("LIMN", 45.5294444444, 8.66916666667), + ("LIMP", 44.8244444444, 10.2961111111), + ("LIMS", 44.9130555556, 9.72333333333), + ("LIMW", 45.7383333333, 7.36777777778), + ("LIMZ", 44.5463888889, 7.62222222222), + ("LIPA", 46.0316666667, 12.5963888889), + ("LIPB", 46.4605555556, 11.3261111111), + ("LIPC", 44.2236111111, 12.3061111111), + ("LIPE", 44.5341666667, 11.2902777778), + ("LIPH", 45.6486111111, 12.1952777778), + ("LIPI", 45.9805555556, 13.0544444444), + ("LIPK", 44.1947222222, 12.07), + ("LIPL", 45.4319444444, 10.2675), + ("LIPN", 45.4719444444, 10.9277777778), + ("LIPO", 45.4288888889, 10.3305555556), + ("LIPQ", 45.8277777778, 13.4663888889), + ("LIPR", 44.0202777778, 12.6119444444), + ("LIPS", 45.6844444444, 12.0861111111), + ("LIPT", 45.5741666667, 11.5305555556), + ("LIPU", 45.3955555556, 11.8477777778), + ("LIPX", 45.3955555556, 10.8883333333), + ("LIPZ", 45.505, 12.3516666667), + ("LIQS", 43.2572222222, 11.2541666667), + ("LIRA", 41.7991666667, 12.5947222222), + ("LIRE", 41.6536111111, 12.4444444444), + ("LIRF", 41.8127777778, 12.2530555556), + ("LIRG", 41.9902777778, 12.7408333333), + ("LIRI", 40.6202777778, 14.9111111111), + ("LIRJ", 42.7602777778, 10.2394444444), + ("LIRL", 41.5422222222, 12.9088888889), + ("LIRM", 41.0608333333, 14.0819444444), + ("LIRN", 40.8858333333, 14.2905555556), + ("LIRP", 43.6838888889, 10.3925), + ("LIRQ", 43.8097222222, 11.205), + ("LIRS", 42.7608333333, 11.0722222222), + ("LIRU", 41.9519444444, 12.4988888889), + ("LIRV", 42.4302777778, 12.0641666667), + ("LIRZ", 43.0958333333, 12.5130555556), + ("LJCE", 45.8997222222, 15.53), + ("LJLJ", 46.2236111111, 14.4575), + ("LJMB", 46.4797222222, 15.6861111111), + ("LJPZ", 45.4733333333, 13.6147222222), + ("LJSG", 46.4719444444, 15.1169444444), + ("LKCS", 48.9461111111, 14.4272222222), + ("LKCT", 49.6844444444, 15.6761111111), + ("LKCV", 49.9394444444, 15.3816666667), + ("LKHK", 50.2530555556, 15.845), + ("LKKB", 50.1211111111, 14.5436111111), + ("LKKU", 49.0294444444, 17.4397222222), + ("LKKV", 50.2027777778, 12.9147222222), + ("LKLN", 49.675, 13.2744444444), + ("LKMH", 50.54, 15.0063888889), + ("LKMT", 49.6963888889, 18.1111111111), + ("LKNA", 49.1658333333, 16.1247222222), + ("LKPD", 50.0133333333, 15.7386111111), + ("LKPM", 49.7186111111, 14.0969444444), + ("LKPO", 49.4258333333, 17.4047222222), + ("LKPR", 50.1008333333, 14.26), + ("LKSO", 49.2447222222, 14.7136111111), + ("LKTB", 49.1511111111, 16.6941666667), + ("LKVO", 50.2163888889, 14.3955555556), + ("LLBG", 32.0094444444, 34.8766666667), + ("LLBS", 31.2869444444, 34.7227777778), + ("LLEK", 31.8394444444, 34.8216666667), + ("LLES", 32.4408333333, 35.0061111111), + ("LLET", 29.5611111111, 34.96), + ("LLEY", 30.6230555556, 35.2019444444), + ("LLHA", 32.8111111111, 35.0438888889), + ("LLHS", 31.7625, 34.7272222222), + ("LLIB", 32.9808333333, 35.5716666667), + ("LLJR", 31.8666666667, 35.2166666667), + ("LLLL", 31.2286111111, 35.1908333333), + ("LLMG", 32.5986111111, 35.2283333333), + ("LLMZ", 31.3280555556, 35.3883333333), + ("LLNV", 31.2083333333, 35.0122222222), + ("LLOV", 29.94, 34.9358333333), + ("LLRD", 32.6602777778, 35.1822222222), + ("LLRM", 30.7761111111, 34.6666666667), + ("LLSD", 32.1144444444, 34.7819444444), + ("LMML", 35.8572222222, 14.4775), + ("LMMM", 35.9166666667, 14.4166666667), + ("LOAN", 47.8433333333, 16.26), + ("LOLW", 48.1830555556, 14.0408333333), + ("LOWG", 47.0, 15.4333333333), + ("LOWI", 47.26, 11.3438888889), + ("LOWK", 46.65, 14.3333333333), + ("LOWL", 48.2333333333, 14.1833333333), + ("LOWM", 48.0, 16.5), + ("LOWS", 47.7930555556, 13.0041666667), + ("LOWW", 48.1102777778, 16.5697222222), + ("LOXG", 46.9908333333, 15.4394444444), + ("LOXK", 46.6425, 14.3375), + ("LOXL", 48.2330555556, 14.1875), + ("LOXT", 48.3208333333, 16.1116666667), + ("LOXZ", 47.2027777778, 14.7441666667), + ("LPAR", 38.8830555556, -9.03), + ("LPAZ", 36.9713888889, -25.1705555556), + ("LPBG", 41.8683333333, -6.71194444444), + ("LPBJ", 38.0788888889, -7.93222222222), + ("LPBR", 41.5869444444, -8.445), + ("LPCO", 40.1572222222, -8.47), + ("LPCS", 38.725, -9.355), + ("LPCV", 40.2647222222, -7.47972222222), + ("LPEV", 38.5333333333, -7.88944444444), + ("LPFL", 39.455, -31.1311111111), + ("LPFR", 37.0141666667, -7.96583333333), + ("LPGR", 39.0919444444, -28.0297222222), + ("LPHR", 38.5197222222, -28.7158333333), + ("LPIN", 40.9741666667, -8.64527777778), + ("LPLA", 38.7641666667, -27.0933333333), + ("LPMG", 38.7166666667, -9.15583333333), + ("LPMR", 39.8311111111, -8.88722222222), + ("LPMT", 38.7036111111, -9.03583333333), + ("LPOV", 40.9158333333, -8.64583333333), + ("LPPD", 37.7411111111, -25.6977777778), + ("LPPI", 38.5544444444, -28.4397222222), + ("LPPM", 37.1491666667, -8.58388888889), + ("LPPR", 41.2480555556, -8.68138888889), + ("LPPS", 33.0733333333, -16.3497222222), + ("LPPT", 38.7811111111, -9.13583333333), + ("LPSJ", 38.6652777778, -28.1755555556), + ("LPST", 38.8308333333, -9.33944444444), + ("LPTN", 39.475, -8.36444444444), + ("LPVR", 41.2741666667, -7.72027777778), + ("LPVZ", 40.7252777778, -7.88888888889), + ("LQBK", 44.9413888889, 17.2975), + ("LQMO", 43.2827777778, 17.8458333333), + ("LQSA", 43.8244444444, 18.3313888889), + ("LRAR", 46.1763888889, 21.2619444444), + ("LRBC", 46.5219444444, 26.9102777778), + ("LRBM", 47.6583333333, 23.47), + ("LRBS", 44.5030555556, 26.1019444444), + ("LRCK", 44.3622222222, 28.4883333333), + ("LRCL", 46.785, 23.6861111111), + ("LRCS", 45.42, 22.2533333333), + ("LRCV", 44.3180555556, 23.8886111111), + ("LRIA", 47.1788888889, 27.62), + ("LROD", 47.0252777778, 21.9025), + ("LROP", 44.5736111111, 26.1033333333), + ("LRSB", 45.7855555556, 24.0911111111), + ("LRSM", 47.7033333333, 22.8855555556), + ("LRSV", 47.6875, 26.3538888889), + ("LRTC", 45.0622222222, 28.7141666667), + ("LRTM", 46.4675, 24.4125), + ("LRTR", 45.81, 21.3377777778), + ("LSAZ", 46.6136111111, 7.67777777778), + ("LSGC", 47.0836111111, 6.79277777778), + ("LSGG", 46.2380555556, 6.10888888889), + ("LSGK", 46.4875, 7.25083333333), + ("LSGS", 46.2194444444, 7.32666666667), + ("LSMA", 46.9438888889, 8.28416666667), + ("LSMC", 46.5011111111, 8.29555555556), + ("LSMD", 47.3986111111, 8.64805555556), + ("LSME", 47.0922222222, 8.305), + ("LSMF", 47.0786111111, 9.06472222222), + ("LSMI", 46.6763888889, 7.87916666667), + ("LSMJ", 46.3038888889, 7.71444444444), + ("LSMM", 46.7433333333, 8.11), + ("LSMN", 46.3036111111, 7.82333333333), + ("LSMP", 46.8430555556, 6.915), + ("LSMU", 46.9747222222, 8.39888888889), + ("LSSW", 47.3833333333, 8.56666666667), + ("LSZA", 46.0041666667, 8.91055555556), + ("LSZB", 46.9138888889, 7.49694444444), + ("LSZG", 47.1813888889, 7.41694444444), + ("LSZH", 47.4647222222, 8.54916666667), + ("LSZR", 47.485, 9.56055555556), + ("LSZS", 46.5325, 9.88277777778), + ("LTAA", 40.0, 32.0), + ("LTAB", 39.9347222222, 32.7405555556), + ("LTAC", 40.1280555556, 32.995), + ("LTAD", 39.9497222222, 32.6886111111), + ("LTAE", 40.0788888889, 32.5655555556), + ("LTAF", 36.9819444444, 35.2802777778), + ("LTAG", 37.0019444444, 35.4258333333), + ("LTAH", 38.7261111111, 30.6011111111), + ("LTAI", 36.9013888889, 30.7916666667), + ("LTAJ", 36.9480555556, 37.4791666667), + ("LTAK", 36.5733333333, 36.1538888889), + ("LTAL", 41.3138888889, 33.7958333333), + ("LTAN", 37.9788888889, 32.5616666667), + ("LTAP", 40.8291666667, 35.5219444444), + ("LTAQ", 41.2763888889, 36.3036111111), + ("LTAR", 39.8136111111, 36.9033333333), + ("LTAS", 41.5158333333, 32.0997222222), + ("LTAT", 38.4358333333, 38.0916666667), + ("LTAU", 38.7702777778, 35.4952777778), + ("LTAV", 39.4513888889, 31.3652777778), + ("LTAW", 40.305, 36.3677777778), + ("LTAX", 41.2544444444, 31.415), + ("LTAY", 37.785, 29.7011111111), + ("LTAZ", 38.7716666667, 34.5341666667), + ("LTBA", 40.9766666667, 28.8211111111), + ("LTBD", 37.8158333333, 27.8861111111), + ("LTBE", 40.2316666667, 29.0091666667), + ("LTBF", 39.6188888889, 27.9247222222), + ("LTBG", 40.3177777778, 27.9775), + ("LTBH", 40.1375, 26.4266666667), + ("LTBI", 39.7838888889, 30.5819444444), + ("LTBJ", 38.2922222222, 27.1569444444), + ("LTBK", 38.3191666667, 27.1597222222), + ("LTBL", 38.5130555556, 27.01), + ("LTBM", 37.7852777778, 30.5816666667), + ("LTBN", 39.4266666667, 30.0163888889), + ("LTBO", 38.6811111111, 29.4713888889), + ("LTBP", 40.6833333333, 29.3786111111), + ("LTBQ", 40.735, 30.0830555556), + ("LTBR", 40.255, 29.5625), + ("LTBS", 36.7130555556, 28.7925), + ("LTBT", 38.8086111111, 27.8336111111), + ("LTBU", 41.1380555556, 27.9188888889), + ("LTBX", 40.9927777778, 29.2163888889), + ("LTBY", 39.8097222222, 30.5194444444), + ("LTCA", 38.6066666667, 39.2913888889), + ("LTCC", 37.8936111111, 40.2005555556), + ("LTCD", 39.71, 39.5261111111), + ("LTCE", 39.9563888889, 41.17), + ("LTCF", 40.5622222222, 43.115), + ("LTCG", 40.995, 39.7897222222), + ("LTCH", 37.0919444444, 38.8461111111), + ("LTCI", 38.4680555556, 43.3322222222), + ("LTCJ", 37.9288888889, 41.1161111111), + ("LTCK", 38.7544444444, 41.6611111111), + ("LTCL", 37.9786111111, 41.8402777778), + ("LTCM", 42.0188888889, 35.0791666667), + ("LTFA", 38.5175, 26.9772222222), + ("LTFB", 37.9505555556, 27.3288888889), + ("LUBL", 47.8377777778, 27.7811111111), + ("LUKK", 46.9277777778, 28.9313888889), + ("LWOH", 41.1797222222, 20.7422222222), + ("LWSK", 41.9613888889, 21.6213888889), + ("LXGB", 36.1508333333, -5.34944444444), + ("LYBE", 44.8183333333, 20.3088888889), + ("LYPG", 42.3591666667, 19.2516666667), + ("LYPR", 42.5727777778, 21.0358333333), + ("LYTV", 42.4044444444, 18.7230555556), + ("LYVR", 45.1466666667, 21.3097222222), + ("LZIB", 48.17, 17.2125), + ("LZKZ", 48.6630555556, 21.2411111111), + ("LZMC", 48.4019444444, 17.1183333333), + ("LZPP", 48.625, 17.8283333333), + ("LZSL", 48.6377777778, 19.1338888889), + ("LZTN", 48.865, 17.9922222222), + ("LZTT", 49.0733333333, 20.2408333333), + ("LZZI", 49.2316666667, 18.6136111111), + ("MBNC", 21.9172222222, -71.9394444444), + ("MBPV", 21.7736111111, -72.2658333333), + ("MBSC", 21.5155555556, -71.5283333333), + ("MDAB", 19.1986111111, -69.43), + ("MDBH", 18.2513888889, -71.1202777778), + ("MDCR", 17.9288888889, -71.6447222222), + ("MDCZ", 18.9080555556, -70.72), + ("MDHE", 18.4711111111, -69.9688888889), + ("MDLR", 18.4519444444, -68.9116666667), + ("MDPC", 18.5672222222, -68.3633333333), + ("MDPP", 19.7572222222, -70.5697222222), + ("MDSD", 18.4294444444, -69.6686111111), + ("MDSI", 18.5036111111, -69.7616666667), + ("MDST", 19.4091666667, -70.6163888889), + ("MGBN", 15.4733333333, -88.8372222222), + ("MGCB", 15.4688888889, -90.4066666667), + ("MGGT", 14.5830555556, -90.5275), + ("MGPB", 15.7308333333, -88.5836111111), + ("MGPP", 16.3261111111, -89.4169444444), + ("MGQZ", 14.8652777778, -91.5019444444), + ("MGRT", 14.5208333333, -91.6972222222), + ("MGSJ", 13.9361111111, -90.8358333333), + ("MHIC", 17.4072222222, -83.9325), + ("MHLC", 15.7422222222, -86.8533333333), + ("MHLM", 15.4525, -87.9233333333), + ("MHNJ", 16.4452777778, -85.9063888889), + ("MHPL", 15.2608333333, -83.7813888889), + ("MHRO", 16.3166666667, -86.5225), + ("MHTE", 15.7758333333, -87.4755555556), + ("MHTG", 14.0608333333, -87.2169444444), + ("MHTJ", 15.9266666667, -85.9380555556), + ("MKBS", 18.4041666667, -76.9688888889), + ("MKJP", 17.9355555556, -76.7875), + ("MKJS", 18.5036111111, -77.9133333333), + ("MKKJ", 18.1986111111, -76.5344444444), + ("MKTP", 17.9883333333, -76.8236111111), + ("MMAA", 16.7566666667, -99.7533333333), + ("MMAN", 25.8655555556, -100.237222222), + ("MMAS", 21.7052777778, -102.317777778), + ("MMBT", 15.7747222222, -96.2608333333), + ("MMCB", 18.835, -99.2619444444), + ("MMCC", 29.3319444444, -100.980833333), + ("MMCE", 18.6536111111, -91.7988888889), + ("MMCG", 30.3972222222, -107.874722222), + ("MMCH", 17.5736111111, -99.5141666667), + ("MMCL", 24.7644444444, -107.474444444), + ("MMCM", 18.5044444444, -88.3266666667), + ("MMCN", 27.3925, -109.833055556), + ("MMCP", 19.8166666667, -90.5002777778), + ("MMCS", 31.6361111111, -106.428611111), + ("MMCU", 28.7027777778, -105.964444444), + ("MMCV", 23.7038888889, -98.9563888889), + ("MMCY", 20.5458333333, -100.886388889), + ("MMCZ", 20.5222222222, -86.9255555556), + ("MMDM", 22.7402777778, -99.0180555556), + ("MMDO", 24.1241666667, -104.527777778), + ("MMEP", 21.4194444444, -104.8425), + ("MMES", 31.7952777778, -116.6025), + ("MMGL", 20.5216666667, -103.311111111), + ("MMGM", 27.9688888889, -110.925), + ("MMHC", 18.4969444444, -97.4197222222), + ("MMHO", 29.0958333333, -111.047777778), + ("MMIA", 19.2769444444, -103.577222222), + ("MMIM", 21.245, -86.7397222222), + ("MMIO", 25.5494444444, -100.928611111), + ("MMIT", 16.4491666667, -95.0936111111), + ("MMJA", 19.475, -96.7975), + ("MMLC", 18.0016666667, -102.220277778), + ("MMLM", 25.685, -109.080555556), + ("MMLO", 20.9933333333, -101.480833333), + ("MMLP", 24.0725, -110.362222222), + ("MMLT", 25.9891666667, -111.348333333), + ("MMMA", 25.7697222222, -97.5252777778), + ("MMMD", 20.9369444444, -89.6575), + ("MMML", 32.6305555556, -115.241388889), + ("MMMM", 19.8497222222, -101.025277778), + ("MMMT", 18.1033333333, -94.5805555556), + ("MMMV", 26.9555555556, -101.47), + ("MMMX", 19.4361111111, -99.0719444444), + ("MMMY", 25.7783333333, -100.106666667), + ("MMMZ", 23.1611111111, -106.265833333), + ("MMNG", 31.2258333333, -110.975555556), + ("MMNL", 27.4438888889, -99.5702777778), + ("MMOX", 16.9997222222, -96.7263888889), + ("MMPA", 20.6025, -97.4608333333), + ("MMPB", 19.1580555556, -98.3713888889), + ("MMPC", 20.0772222222, -98.7822222222), + ("MMPE", 31.3516666667, -113.525555556), + ("MMPG", 28.6272222222, -100.535), + ("MMPN", 19.3966666667, -102.039166667), + ("MMPR", 20.68, -105.254166667), + ("MMPS", 15.8766666667, -97.0888888889), + ("MMQT", 20.6238888889, -100.368611111), + ("MMRX", 26.0088888889, -98.2283333333), + ("MMSD", 23.1516666667, -109.720833333), + ("MMSF", 30.93, -114.808611111), + ("MMSP", 22.2541666667, -100.930555556), + ("MMTA", 19.5363888889, -98.1733333333), + ("MMTC", 25.5680555556, -103.410555556), + ("MMTG", 16.7694444444, -93.3413888889), + ("MMTJ", 32.5408333333, -116.97), + ("MMTM", 22.2963888889, -97.8658333333), + ("MMTN", 22.0380555556, -98.8063888889), + ("MMTO", 19.3369444444, -99.5658333333), + ("MMTP", 14.7941666667, -92.37), + ("MMTX", 19.5983333333, -103.371944444), + ("MMUN", 21.0363888889, -86.8769444444), + ("MMVA", 17.9969444444, -92.8172222222), + ("MMVR", 19.1452777778, -96.1869444444), + ("MMZC", 22.8969444444, -102.686666667), + ("MMZH", 17.6013888889, -101.460277778), + ("MMZM", 20.045, -102.275833333), + ("MMZO", 19.1447222222, -104.558611111), + ("MMZP", 20.7558333333, -103.465277778), + ("MNBL", 11.9888888889, -83.7741666667), + ("MNBR", 12.1894444444, -86.3538888889), + ("MNLN", 12.4277777778, -86.9022222222), + ("MNMG", 12.1411111111, -86.1680555556), + ("MNPC", 14.0469444444, -83.3866666667), + ("MPBO", 9.34083333333, -82.2508333333), + ("MPCH", 9.45861111111, -82.5166666667), + ("MPDA", 8.39083333333, -82.4347222222), + ("MPHO", 8.91444444444, -79.5994444444), + ("MPJE", 7.51722222222, -78.1566666667), + ("MPLP", 8.40666666667, -78.1416666667), + ("MPMG", 8.97333333333, -79.5555555556), + ("MPSA", 8.08555555556, -80.945), + ("MPTO", 9.07111111111, -79.3833333333), + ("MRBA", 9.16694444444, -83.3325), + ("MRBC", 10.7686111111, -83.5858333333), + ("MRCC", 8.60111111111, -82.97), + ("MRCV", 10.3555555556, -85.8527777778), + ("MREC", 10.2019444444, -83.4719444444), + ("MRFI", 8.91611111111, -83.5072222222), + ("MRFS", 8.6525, -83.0652777778), + ("MRGF", 8.65388888889, -83.1819444444), + ("MRGP", 10.2172222222, -83.7947222222), + ("MRLB", 10.5930555556, -85.5441666667), + ("MRLC", 11.0352777778, -84.7061111111), + ("MRLM", 9.95777777778, -83.0219444444), + ("MRNS", 9.97638888889, -85.6527777778), + ("MROC", 9.99361111111, -84.2086111111), + ("MRPD", 9.73194444444, -82.9830555556), + ("MRPM", 8.95083333333, -83.4683333333), + ("MRPV", 9.95722222222, -84.1419444444), + ("MRQP", 9.44305555556, -84.1297222222), + ("MRSG", 10.2883333333, -83.7136111111), + ("MRSV", 8.82611111111, -82.9588888889), + ("MSLP", 13.4405555556, -89.0558333333), + ("MSSS", 13.7, -89.12), + ("MTCH", 19.7325, -72.1947222222), + ("MTPP", 18.58, -72.2925), + ("MUBA", 20.3655555556, -74.5063888889), + ("MUBY", 20.3963888889, -76.6213888889), + ("MUCA", 22.0269444444, -78.7894444444), + ("MUCB", 22.5063888889, -79.4697222222), + ("MUCC", 22.4611111111, -78.3286111111), + ("MUCF", 22.15, -80.4141666667), + ("MUCL", 21.6161111111, -81.5455555556), + ("MUCM", 21.4202777778, -77.8475), + ("MUCU", 19.97, -75.8355555556), + ("MUFL", 21.4997222222, -78.2027777778), + ("MUGM", 19.9063888889, -75.2069444444), + ("MUGT", 20.0852777778, -75.1583333333), + ("MUHA", 22.9891666667, -82.4091666667), + ("MUHG", 20.7855555556, -76.315), + ("MULM", 22.3358333333, -83.6419444444), + ("MUMG", 22.9697222222, -82.2747222222), + ("MUML", 23.0072222222, -82.7675), + ("MUMO", 20.6541666667, -74.9216666667), + ("MUMZ", 20.2880555556, -77.0891666667), + ("MUNC", 20.6886111111, -75.5313888889), + ("MUNG", 21.8347222222, -82.7838888889), + ("MUPB", 23.0327777778, -82.5794444444), + ("MUPR", 22.4211111111, -83.6775), + ("MUSA", 22.8713888889, -82.5091666667), + ("MUSC", 22.4919444444, -79.9436111111), + ("MUSJ", 22.0952777778, -84.1519444444), + ("MUSL", 21.5094444444, -77.0175), + ("MUSN", 21.6425, -82.955), + ("MUSS", 21.9705555556, -79.4422222222), + ("MUTD", 21.7883333333, -79.9972222222), + ("MUVR", 23.0344444444, -81.4352777778), + ("MUVT", 20.9877777778, -76.9358333333), + ("MWCB", 19.6866666667, -79.8827777778), + ("MWCR", 19.2927777778, -81.3575), + ("MYAB", 24.2875, -77.6844444444), + ("MYAF", 24.6977777778, -77.7955555556), + ("MYAK", 24.1586111111, -77.5897222222), + ("MYAM", 26.5113888889, -77.0833333333), + ("MYAN", 25.0536111111, -78.0488888889), + ("MYAP", 22.4416666667, -73.9708333333), + ("MYAS", 26.0044444444, -77.3952777778), + ("MYAT", 26.7452777778, -77.3911111111), + ("MYBC", 25.4169444444, -77.8808333333), + ("MYBG", 25.7380555556, -77.84), + ("MYBS", 25.6997222222, -79.2644444444), + ("MYCA", 24.6291666667, -75.6736111111), + ("MYCB", 24.315, -75.4538888889), + ("MYCI", 22.7455555556, -74.1822222222), + ("MYEF", 23.5625, -75.8777777778), + ("MYEH", 25.4755555556, -76.6811111111), + ("MYEM", 25.2844444444, -76.3308333333), + ("MYEN", 24.5944444444, -76.8319444444), + ("MYER", 24.8916666667, -76.1775), + ("MYES", 24.1688888889, -76.4388888889), + ("MYGF", 26.5586111111, -78.6952777778), + ("MYGW", 26.6861111111, -78.9775), + ("MYIG", 20.975, -73.6666666667), + ("MYLD", 23.1788888889, -75.0933333333), + ("MYLS", 23.5827777778, -75.2686111111), + ("MYMM", 22.3794444444, -73.0133333333), + ("MYNN", 25.0388888889, -77.4661111111), + ("MYRD", 22.1816666667, -75.7294444444), + ("MYSM", 24.0630555556, -74.5238888889), + ("MZBZ", 17.5388888889, -88.3080555556), + ("NCAI", -18.825, -159.773611111), + ("NCRG", -21.2025, -159.805555556), + ("NFFN", -17.7544444444, 177.443333333), + ("NFNA", -18.0430555556, 178.559166667), + ("NFNL", -16.4666666667, 179.339722222), + ("NFTF", -21.2408333333, -175.15), + ("NFTL", -19.7769444444, -174.341111111), + ("NFTV", -18.5852777778, -173.962777778), + ("NGFU", -8.51666666667, 179.216666667), + ("NGTA", 1.38138888889, 173.146944444), + ("NGTE", -1.22361111111, 174.776111111), + ("NIUE", -19.08, -169.925555556), + ("NLWW", -13.2380555556, -176.199166667), + ("NSFA", -13.8297222222, -172.008333333), + ("NSTU", -14.3308333333, -170.710277778), + ("NTAR", -22.4338888889, -151.360555556), + ("NTAT", -23.3652777778, -149.523888889), + ("NTGA", -17.3525, -145.509722222), + ("NTGB", -15.8197222222, -140.886944444), + ("NTGC", -15.1194444444, -148.230555556), + ("NTGE", -18.4658333333, -136.439444444), + ("NTGF", -16.0544444444, -145.656944444), + ("NTGI", -14.4366666667, -146.07), + ("NTGJ", -23.0797222222, -134.890277778), + ("NTGK", -15.6633333333, -146.884722222), + ("NTGM", -16.5847222222, -143.657222222), + ("NTGN", -14.1766666667, -141.267222222), + ("NTGP", -14.8094444444, -138.812777778), + ("NTGT", -14.7125, -145.252777778), + ("NTGU", -15.2480555556, -146.616388889), + ("NTGV", -14.8680555556, -148.717222222), + ("NTGY", -20.7833333333, -138.567777778), + ("NTKR", -14.4555555556, -145.024444444), + ("NTMD", -8.79555555556, -140.228611111), + ("NTMN", -9.76861111111, -139.011111111), + ("NTTB", -16.4441666667, -151.751111111), + ("NTTG", -14.9541666667, -147.660555556), + ("NTTH", -16.6872222222, -151.021666667), + ("NTTM", -17.4897222222, -149.761666667), + ("NTTO", -18.0747222222, -140.945833333), + ("NTTP", -16.4263888889, -152.243611111), + ("NTTR", -16.7227777778, -151.465833333), + ("NTTX", -21.8083333333, -138.794166667), + ("NVSS", -15.5011111111, 167.2225), + ("NVVV", -17.6991666667, 168.319722222), + ("NWWD", -21.0533333333, 164.837777778), + ("NWWK", -20.5461111111, 164.255555556), + ("NWWL", -20.7747222222, 167.239722222), + ("NWWM", -22.2580555556, 166.472777778), + ("NWWR", -21.4816666667, 168.0375), + ("NWWU", -20.7911111111, 165.259166667), + ("NWWV", -20.6405555556, 166.572777778), + ("NWWW", -22.0144444444, 166.212777778), + ("NZAA", -37.0080555556, 174.791666667), + ("NZAP", -38.7397222222, 176.084444444), + ("NZAR", -37.0297222222, 174.973333333), + ("NZCH", -43.4891666667, 172.532222222), + ("NZCI", -43.81, -176.457222222), + ("NZDN", -45.9280555556, 170.198333333), + ("NZGS", -38.6633333333, 177.978333333), + ("NZGT", -43.9066666667, 170.128333333), + ("NZHK", -42.7136111111, 170.985277778), + ("NZHN", -37.8663888889, 175.331944444), + ("NZHS", -39.6466666667, 176.766944444), + ("NZKK", -35.2627777778, 173.911944444), + ("NZKT", -35.07, 173.285277778), + ("NZLX", -45.2116666667, 169.373333333), + ("NZMC", -43.765, 170.133333333), + ("NZMO", -45.5330555556, 167.65), + ("NZMS", -40.9733333333, 175.633611111), + ("NZNP", -39.0086111111, 174.179166667), + ("NZNS", -41.2983333333, 173.221111111), + ("NZNV", -46.4122222222, 168.312777778), + ("NZOH", -40.2058333333, 175.387777778), + ("NZOU", -44.97, 171.081666667), + ("NZPM", -40.3205555556, 175.616944444), + ("NZPP", -40.9047222222, 174.989166667), + ("NZQN", -45.0211111111, 168.739166667), + ("NZRO", -38.1091666667, 176.317222222), + ("NZRU", -39.4463888889, 175.658333333), + ("NZSP", -89.9997222222, 0.0), + ("NZTG", -37.6719444444, 176.196111111), + ("NZTU", -44.3027777778, 171.225277778), + ("NZUK", -44.235, 170.118333333), + ("NZWB", -41.5183333333, 173.870277778), + ("NZWD", -77.8833333333, 166.65), + ("NZWF", -44.7252777778, 169.243055556), + ("NZWG", -43.5511111111, 172.552777778), + ("NZWK", -37.9205555556, 176.914166667), + ("NZWN", -41.3272222222, 174.805277778), + ("NZWO", -39.0069444444, 177.406666667), + ("NZWP", -36.7877777778, 174.630277778), + ("NZWR", -35.7683333333, 174.365), + ("NZWS", -41.7380555556, 171.580833333), + ("NZWU", -39.9622222222, 175.025277778), + ("OAHR", 34.2097222222, 62.2277777778), + ("OAJL", 34.3991666667, 70.4994444444), + ("OAKB", 34.5658333333, 69.2122222222), + ("OAKN", 31.5058333333, 65.8477777778), + ("OAMN", 35.9341666667, 64.7591666667), + ("OAMS", 36.7069444444, 67.2091666667), + ("OASD", 33.3911111111, 62.2608333333), + ("OASG", 36.7502777778, 65.9122222222), + ("OATQ", 36.775, 69.5325), + ("OAUZ", 36.665, 68.9108333333), + ("OBBI", 26.2708333333, 50.6336111111), + ("OBBS", 25.9183333333, 50.5905555556), + ("OEAB", 18.24, 42.6555555556), + ("OEAH", 25.2841666667, 49.4861111111), + ("OEBA", 20.2961111111, 41.6341666667), + ("OEBH", 19.9838888889, 42.6227777778), + ("OEBQ", 25.9113888889, 49.5913888889), + ("OEDF", 26.4711111111, 49.7977777778), + ("OEDR", 26.2652777778, 50.1519444444), + ("OEGN", 16.9011111111, 42.5858333333), + ("OEGS", 26.3027777778, 43.7744444444), + ("OEGT", 31.4108333333, 37.2788888889), + ("OEHL", 27.4377777778, 41.6861111111), + ("OEJB", 27.0388888889, 49.405), + ("OEJF", 21.3480555556, 39.1727777778), + ("OEJN", 21.6794444444, 39.1563888889), + ("OEKK", 27.9008333333, 45.5280555556), + ("OEMA", 24.5533333333, 39.705), + ("OENG", 17.6113888889, 44.4191666667), + ("OEPA", 28.335, 46.125), + ("OEPC", 25.1744444444, 47.4883333333), + ("OEPF", 24.7102777778, 44.9644444444), + ("OEPJ", 24.1072222222, 41.0358333333), + ("OERB", 22.7025, 39.0697222222), + ("OERF", 29.6263888889, 43.4905555556), + ("OERK", 24.9575, 46.6986111111), + ("OERM", 28.0794444444, 48.6108333333), + ("OERR", 30.9072222222, 41.1383333333), + ("OERT", 26.7230555556, 50.0305555556), + ("OESH", 17.4666666667, 47.1211111111), + ("OESK", 29.785, 40.1), + ("OESL", 20.4647222222, 45.6194444444), + ("OETB", 28.3652777778, 36.6188888889), + ("OETF", 21.4833333333, 40.5441666667), + ("OETH", 25.2141666667, 46.6405555556), + ("OETN", 27.8688888889, 48.7683333333), + ("OETR", 31.6925, 38.7311111111), + ("OEWD", 20.5041666667, 45.1994444444), + ("OEWJ", 26.1975, 36.4761111111), + ("OEYN", 24.1441666667, 38.0633333333), + ("OIAA", 30.365, 48.2330555556), + ("OIAD", 32.4344444444, 48.3975), + ("OIAG", 30.7452777778, 49.6761111111), + ("OIAH", 30.3375, 50.8277777778), + ("OIAI", 32.0022222222, 49.2705555556), + ("OIAJ", 30.835, 49.5347222222), + ("OIAM", 30.5561111111, 49.1516666667), + ("OIAW", 31.3372222222, 48.7619444444), + ("OIBA", 25.8758333333, 55.0327777778), + ("OIBB", 28.9447222222, 50.8344444444), + ("OIBH", 27.2125, 54.3183333333), + ("OIBI", 27.4838888889, 52.6183333333), + ("OIBK", 26.5266666667, 53.9816666667), + ("OIBL", 26.5316666667, 54.8216666667), + ("OIBQ", 29.2591666667, 50.3238888889), + ("OIBS", 25.9094444444, 54.5391666667), + ("OIBV", 26.81, 53.3563888889), + ("OICC", 34.3463888889, 47.1563888889), + ("OICD", 32.9344444444, 47.4833333333), + ("OICI", 33.5855555556, 46.4052777778), + ("OICK", 33.4363888889, 48.2858333333), + ("OICS", 35.2469444444, 47.0069444444), + ("OIFE", 32.9294444444, 51.5608333333), + ("OIFH", 32.5669444444, 51.6913888889), + ("OIFM", 32.7505555556, 51.8616666667), + ("OIFP", 32.6208333333, 51.6966666667), + ("OIGG", 37.3252777778, 49.6055555556), + ("OIHH", 34.8680555556, 48.5522222222), + ("OIHR", 34.1402777778, 49.8483333333), + ("OIID", 35.7027777778, 51.475), + ("OIIG", 35.6447222222, 51.3805555556), + ("OIII", 35.6891666667, 51.3133333333), + ("OIIK", 36.2413888889, 50.0475), + ("OIIS", 35.5908333333, 53.495), + ("OIKB", 27.2180555556, 56.3777777778), + ("OIKJ", 28.7266666667, 57.67), + ("OIKK", 30.2611111111, 56.9566666667), + ("OIKM", 29.0838888889, 58.4502777778), + ("OIKP", 27.1580555556, 56.1722222222), + ("OIKQ", 26.755, 55.9019444444), + ("OIKR", 30.2977777778, 56.0519444444), + ("OIKY", 29.5508333333, 55.6725), + ("OIMB", 32.8955555556, 59.2755555556), + ("OIMC", 36.5011111111, 61.0647222222), + ("OIMJ", 36.4236111111, 55.1058333333), + ("OIMN", 37.4930555556, 57.3005555556), + ("OIMT", 33.6677777778, 56.8925), + ("OIMX", 37.6277777778, 56.1730555556), + ("OINE", 37.3830555556, 55.4519444444), + ("OING", 36.9091666667, 54.4016666667), + ("OINM", 34.1691666667, 51.3175), + ("OINN", 36.6633333333, 51.4647222222), + ("OINR", 36.9097222222, 50.6794444444), + ("OINZ", 36.6436111111, 53.1883333333), + ("OISD", 28.7213888889, 54.4411111111), + ("OISF", 28.8919444444, 53.7227777778), + ("OISJ", 28.5863888889, 53.5788888889), + ("OISL", 27.6736111111, 54.3813888889), + ("OISO", 29.7541666667, 52.6941666667), + ("OISR", 27.3708333333, 53.1891666667), + ("OISS", 29.5391666667, 52.5894444444), + ("OITL", 38.3261111111, 48.4241666667), + ("OITM", 37.3486111111, 46.1261111111), + ("OITP", 39.6036111111, 47.8811111111), + ("OITT", 38.1327777778, 46.2347222222), + ("OITZ", 36.7741666667, 48.3597222222), + ("OIYY", 31.9047222222, 54.2763888889), + ("OIZB", 31.0969444444, 61.5438888889), + ("OIZC", 25.4433333333, 60.3819444444), + ("OIZH", 29.4761111111, 60.9058333333), + ("OIZI", 27.2363888889, 60.72), + ("OIZJ", 25.6533333333, 57.7991666667), + ("OJAI", 31.7225, 35.9930555556), + ("OJAM", 31.9725, 35.9913888889), + ("OJAQ", 29.6113888889, 35.0180555556), + ("OJJR", 31.8647222222, 35.2191666667), + ("OJMF", 32.3561111111, 36.2591666667), + ("OKBK", 29.2266666667, 47.98), + ("OLBA", 33.8133333333, 35.4886111111), + ("OLKA", 34.5891666667, 36.0111111111), + ("OMAA", 24.4327777778, 54.6511111111), + ("OMAD", 24.4283333333, 54.4580555556), + ("OMAH", 24.0736111111, 52.4633333333), + ("OMAJ", 24.1872222222, 52.6138888889), + ("OMAL", 24.2616666667, 55.6091666667), + ("OMAM", 24.2480555556, 54.5475), + ("OMAR", 24.7802777778, 52.5597222222), + ("OMAS", 25.1461111111, 52.8736111111), + ("OMAZ", 24.8613888889, 53.0777777778), + ("OMDB", 25.2547222222, 55.3641666667), + ("OMFJ", 25.1122222222, 56.3238888889), + ("OMRK", 25.6133333333, 55.9386111111), + ("OMSJ", 25.3283333333, 55.5169444444), + ("OOKB", 26.1711111111, 56.2405555556), + ("OOMA", 20.6752777778, 58.8902777778), + ("OOMS", 23.5930555556, 58.2844444444), + ("OOSA", 17.0386111111, 54.0911111111), + ("OOSQ", 23.0666666667, 57.65), + ("OOTH", 17.6658333333, 54.0244444444), + ("OPBN", 32.9719444444, 70.5247222222), + ("OPBW", 29.3469444444, 71.7113888889), + ("OPCH", 35.8863888889, 71.8005555556), + ("OPDB", 28.8747222222, 64.4044444444), + ("OPDG", 29.9611111111, 70.4855555556), + ("OPDI", 31.9091666667, 70.8963888889), + ("OPFA", 31.365, 72.9952777778), + ("OPGD", 25.2330555556, 62.3294444444), + ("OPGT", 35.9186111111, 74.3336111111), + ("OPJA", 28.2841666667, 68.4494444444), + ("OPJI", 25.0677777778, 61.8052777778), + ("OPKC", 24.9063888889, 67.1605555556), + ("OPKD", 25.3180555556, 68.3661111111), + ("OPKH", 27.7925, 66.6427777778), + ("OPKN", 28.5944444444, 65.4247222222), + ("OPLA", 31.5213888889, 74.4033333333), + ("OPLH", 31.4947222222, 74.3461111111), + ("OPMA", 33.05, 73.6383333333), + ("OPMF", 34.3383333333, 73.5083333333), + ("OPMI", 32.5630555556, 71.5705555556), + ("OPMJ", 27.335, 68.1427777778), + ("OPMK", 25.6825, 69.0727777778), + ("OPMN", 33.0125, 70.0641666667), + ("OPMR", 24.8933333333, 66.9386111111), + ("OPMT", 30.2030555556, 71.4188888889), + ("OPNH", 26.2191666667, 68.39), + ("OPNK", 29.5377777778, 66.0222222222), + ("OPOK", 30.7408333333, 73.3575), + ("OPOR", 25.2730555556, 64.5883333333), + ("OPPC", 33.9025, 70.0713888889), + ("OPPG", 26.9544444444, 64.1325), + ("OPPI", 25.2836111111, 63.3327777778), + ("OPPS", 33.9938888889, 71.5144444444), + ("OPQS", 33.5611111111, 73.0319444444), + ("OPQT", 30.2511111111, 66.9375), + ("OPRK", 28.3852777778, 70.2797222222), + ("OPRN", 33.6163888889, 73.0991666667), + ("OPRQ", 30.7580555556, 72.2825), + ("OPRS", 34.0811111111, 71.9725), + ("OPRT", 33.8491666667, 73.7977777778), + ("OPSD", 35.3347222222, 75.5363888889), + ("OPSK", 27.7219444444, 68.7916666667), + ("OPSR", 32.0486111111, 72.665), + ("OPSS", 34.8130555556, 72.3519444444), + ("OPSU", 28.645, 69.1766666667), + ("OPSW", 31.8894444444, 72.3091666667), + ("OPTA", 33.9861111111, 72.6113888889), + ("OPTH", 24.8413888889, 68.8383333333), + ("OPTU", 25.9861111111, 63.03), + ("OPWN", 32.3052777778, 69.5694444444), + ("OPZB", 31.3583333333, 69.4633333333), + ("ORBS", 33.2619444444, 44.2338888889), + ("ORMM", 30.5486111111, 47.6622222222), + ("OSAP", 36.1805555556, 37.2241666667), + ("OSDI", 33.4113888889, 36.5155555556), + ("OSDZ", 35.2852777778, 40.1758333333), + ("OSKL", 37.0236111111, 41.1944444444), + ("OSLK", 35.4008333333, 35.9486111111), + ("OSPR", 34.5572222222, 38.3166666667), + ("OTBD", 25.2611111111, 51.565), + ("PAAQ", 61.5947222222, -149.088611111), + ("PABA", 70.1338888889, -143.576944444), + ("PABE", 60.7797222222, -161.837777778), + ("PABI", 63.9944444444, -145.721388889), + ("PABM", 59.3616666667, -155.257222222), + ("PABR", 71.2852777778, -156.765833333), + ("PABT", 66.9152777778, -151.528055556), + ("PACD", 55.2055555556, -162.724166667), + ("PACL", 64.3011111111, -149.12), + ("PACV", 60.4916666667, -145.4775), + ("PACZ", 61.7802777778, -166.038611111), + ("PADK", 51.8777777778, -176.645833333), + ("PADL", 59.0452777778, -158.503333333), + ("PADQ", 57.75, -152.493611111), + ("PADU", 53.9, -166.543333333), + ("PAED", 61.2511111111, -149.806388889), + ("PAEH", 58.6472222222, -162.060555556), + ("PAEI", 64.6655555556, -147.101388889), + ("PAEN", 60.5730555556, -151.245), + ("PAFA", 64.815, -147.856111111), + ("PAFB", 64.8375, -147.614444444), + ("PAFR", 61.2661111111, -149.653055556), + ("PAGA", 64.7361111111, -156.937222222), + ("PAGK", 62.1547222222, -145.456388889), + ("PAGY", 59.46, -135.315555556), + ("PAHO", 59.6455555556, -151.476388889), + ("PAIL", 59.7536111111, -154.910833333), + ("PAIM", 65.9927777778, -153.704166667), + ("PAJN", 58.3547222222, -134.576111111), + ("PAKN", 58.6766666667, -156.649166667), + ("PAKT", 55.3555555556, -131.713611111), + ("PALU", 68.875, -166.11), + ("PAMC", 62.9527777778, -155.605555556), + ("PAMD", 59.4497222222, -146.308611111), + ("PAMR", 61.2141666667, -149.846111111), + ("PANC", 61.1741666667, -149.996111111), + ("PANT", 55.0422222222, -131.572222222), + ("PAOM", 64.5119444444, -165.445), + ("PAOR", 62.9611111111, -141.928888889), + ("PAOT", 66.8844444444, -162.598333333), + ("PAPB", 56.5783333333, -169.661388889), + ("PAPM", 59.0111111111, -161.819444444), + ("PASC", 70.1947222222, -148.465), + ("PASI", 57.0469444444, -135.361388889), + ("PASN", 57.1672222222, -170.220277778), + ("PASV", 61.0972222222, -155.574166667), + ("PASY", 52.7122222222, 174.113611111), + ("PATA", 65.1741666667, -152.109166667), + ("PATC", 65.5630555556, -167.922222222), + ("PATK", 62.3202777778, -150.093611111), + ("PATL", 62.8941666667, -155.976388889), + ("PAUN", 63.8883333333, -160.798888889), + ("PAVD", 61.1338888889, -146.248333333), + ("PAWT", 70.6133333333, -159.860277778), + ("PAYA", 59.5030555556, -139.66), + ("PCIS", -2.76666666667, -0.0), + ("PFYU", 66.5713888889, -145.250277778), + ("PGRO", 14.1744444444, 145.243333333), + ("PGSN", 15.1194444444, 145.729166667), + ("PGTW", 13.5, 144.833333333), + ("PGUA", 13.5838888889, 144.93), + ("PGUM", 13.4838888889, 144.796944444), + ("PGWT", 14.9977777778, 145.619166667), + ("PHBK", 22.0216666667, -159.786666667), + ("PHDH", 21.5791666667, -158.210277778), + ("PHHI", 21.4833333333, -158.039444444), + ("PHHN", 20.7955555556, -156.014166667), + ("PHJH", 20.9627777778, -156.674166667), + ("PHKO", 19.7386111111, -156.045555556), + ("PHLI", 21.9761111111, -159.338611111), + ("PHMK", 21.1527777778, -157.096111111), + ("PHMU", 20.0011111111, -155.668055556), + ("PHNG", 21.4491666667, -157.767777778), + ("PHNL", 21.3158333333, -157.926666667), + ("PHNY", 20.7855555556, -156.951388889), + ("PHOG", 20.8986111111, -156.430555556), + ("PHSF", 19.76, -155.553611111), + ("PHTO", 19.7202777778, -155.048611111), + ("PHUP", 20.265, -155.859722222), + ("PJON", 16.7286111111, -169.534166667), + ("PKMA", 11.3408333333, 162.327777778), + ("PKMJ", 7.06472222222, 171.271944444), + ("PKRO", 9.39666666667, 167.470833333), + ("PKWA", 8.72, 167.731388889), + ("PLCH", 1.98611111111, -157.349722222), + ("PMDY", 28.2013888889, -177.381388889), + ("POLI", 70.4994444444, -149.879444444), + ("PPIZ", 69.7327777778, -163.005277778), + ("PTKK", 7.46166666667, 151.842777778), + ("PTPN", 6.985, 158.208888889), + ("PTRO", 7.3675, 134.543888889), + ("PTSA", 5.35666666667, 162.958333333), + ("PTYA", 9.49861111111, 138.082222222), + ("RCBS", 24.4319444444, 118.359444444), + ("RCDC", 22.6722222222, 120.461666667), + ("RCDI", 24.855, 121.2375), + ("RCFN", 22.7566666667, 121.093333333), + ("RCGI", 22.6744444444, 121.458333333), + ("RCGM", 25.0555555556, 121.2425), + ("RCKH", 22.5752777778, 120.350833333), + ("RCKU", 23.4616666667, 120.392777778), + ("RCLG", 24.1861111111, 120.653611111), + ("RCLY", 22.0294444444, 121.527222222), + ("RCMQ", 24.2644444444, 120.620555556), + ("RCMT", 26.2238888889, 120.0025), + ("RCNN", 22.9502777778, 120.205555556), + ("RCPO", 24.8177777778, 120.939166667), + ("RCQC", 23.5686111111, 119.628055556), + ("RCQS", 22.7930555556, 121.181944444), + ("RCRA", 22.7047222222, 120.280555556), + ("RCSQ", 22.7, 120.482222222), + ("RCSS", 25.0694444444, 121.551666667), + ("RCTP", 25.08, 121.232222222), + ("RCWA", 23.3708333333, 119.494444444), + ("RCYU", 24.0230555556, 121.617777778), + ("RJAA", 35.7647222222, 140.386388889), + ("RJAF", 36.1666666667, 137.922777778), + ("RJAH", 36.1808333333, 140.415277778), + ("RJAM", 24.2894444444, 153.978888889), + ("RJAW", 24.7838888889, 141.3225), + ("RJBD", 33.6622222222, 135.364444444), + ("RJBK", 34.5908333333, 133.933055556), + ("RJCB", 42.7333333333, 143.217222222), + ("RJCC", 42.775, 141.692222222), + ("RJCH", 41.77, 140.821944444), + ("RJCJ", 42.7944444444, 141.666388889), + ("RJCM", 43.8805555556, 144.163888889), + ("RJCN", 43.5772222222, 144.959722222), + ("RJCO", 43.1161111111, 141.38), + ("RJCT", 42.8902777778, 143.158333333), + ("RJCW", 45.4038888889, 141.800833333), + ("RJDB", 33.7488888889, 129.785277778), + ("RJDC", 33.93, 131.278888889), + ("RJDT", 34.2847222222, 129.330277778), + ("RJEB", 44.3038888889, 143.403888889), + ("RJEC", 43.6708333333, 142.4475), + ("RJER", 45.2419444444, 141.186388889), + ("RJFA", 33.8830555556, 130.652777778), + ("RJFC", 30.3855555556, 130.658888889), + ("RJFE", 32.6661111111, 128.832777778), + ("RJFF", 33.5863888889, 130.45), + ("RJFG", 30.5466666667, 130.95), + ("RJFK", 31.8033333333, 130.719166667), + ("RJFM", 31.8769444444, 131.448333333), + ("RJFN", 32.0836111111, 131.451666667), + ("RJFO", 33.4794444444, 131.737222222), + ("RJFR", 33.8361111111, 130.946944444), + ("RJFT", 32.8372222222, 130.855), + ("RJFU", 32.9225, 129.923333333), + ("RJFY", 31.3675, 130.845277778), + ("RJFZ", 33.6852777778, 131.040555556), + ("RJKA", 28.4305555556, 129.7125), + ("RJKB", 27.4252777778, 128.700833333), + ("RJKN", 27.8361111111, 128.881111111), + ("RJNF", 36.1427777778, 136.223888889), + ("RJNG", 35.3941666667, 136.869444444), + ("RJNH", 34.75, 137.703055556), + ("RJNK", 36.3936111111, 136.407777778), + ("RJNN", 35.255, 136.924444444), + ("RJNO", 36.1811111111, 133.324722222), + ("RJNT", 36.6483333333, 137.187222222), + ("RJNY", 34.8125, 138.297777778), + ("RJOA", 34.4352777778, 132.921944444), + ("RJOB", 34.7569444444, 133.855555556), + ("RJOC", 35.4136111111, 132.89), + ("RJOF", 34.0344444444, 131.549166667), + ("RJOH", 35.4922222222, 133.236388889), + ("RJOI", 34.1436111111, 132.235555556), + ("RJOK", 33.5444444444, 133.671388889), + ("RJOM", 33.8272222222, 132.699722222), + ("RJOO", 34.7852777778, 135.438055556), + ("RJOR", 35.53, 134.166388889), + ("RJOS", 34.1327777778, 134.606388889), + ("RJOT", 34.2138888889, 134.015555556), + ("RJOY", 34.5961111111, 135.602777778), + ("RJOZ", 34.0452777778, 131.051944444), + ("RJSA", 40.7344444444, 140.690833333), + ("RJSC", 38.4116666667, 140.371111111), + ("RJSH", 40.5563888889, 141.466111111), + ("RJSI", 39.4308333333, 141.135833333), + ("RJSK", 39.6155555556, 140.218611111), + ("RJSM", 40.7030555556, 141.368333333), + ("RJSS", 38.1394444444, 140.916666667), + ("RJST", 38.4047222222, 141.219444444), + ("RJSY", 38.8116666667, 139.786944444), + ("RJTA", 35.4544444444, 139.45), + ("RJTE", 34.9869444444, 139.829166667), + ("RJTF", 35.6716666667, 139.528055556), + ("RJTH", 33.115, 139.785555556), + ("RJTJ", 35.8413888889, 139.409722222), + ("RJTK", 35.3980555556, 139.909722222), + ("RJTL", 35.7988888889, 140.011111111), + ("RJTO", 34.7844444444, 139.361388889), + ("RJTQ", 34.0719444444, 139.559722222), + ("RJTR", 35.5136111111, 139.393611111), + ("RJTT", 35.5522222222, 139.779444444), + ("RJTY", 35.7483333333, 139.348333333), + ("RKJJ", 35.1255555556, 126.809722222), + ("RKJK", 35.9036111111, 126.615833333), + ("RKJM", 34.7588888889, 126.379722222), + ("RKJU", 35.8783333333, 127.119444444), + ("RKJY", 34.8397222222, 127.615277778), + ("RKNC", 37.8836111111, 127.717777778), + ("RKND", 38.1475, 128.600555556), + ("RKNN", 37.7533333333, 128.943888889), + ("RKNW", 37.4380555556, 127.960277778), + ("RKNY", 38.0611111111, 128.668888889), + ("RKPC", 33.5111111111, 126.492777778), + ("RKPE", 35.1411111111, 128.695555556), + ("RKPK", 35.1794444444, 128.938055556), + ("RKPP", 35.1708333333, 129.128611111), + ("RKPS", 35.0883333333, 128.070277778), + ("RKPU", 35.5933333333, 129.351666667), + ("RKSG", 36.9605555556, 127.033333333), + ("RKSM", 37.4458333333, 127.113888889), + ("RKSO", 37.0905555556, 127.029444444), + ("RKSS", 37.5580555556, 126.790555556), + ("RKSW", 37.2391666667, 127.006944444), + ("RKTH", 35.9877777778, 129.420277778), + ("RKTJ", 35.8563888889, 129.211388889), + ("RKTN", 35.8938888889, 128.658611111), + ("RKTU", 36.7163888889, 127.498888889), + ("RKTY", 36.6316666667, 128.354722222), + ("ROAH", 26.1955555556, 127.645833333), + ("RODE", 26.7286111111, 127.761666667), + ("RODN", 26.3555555556, 127.7675), + ("ROIG", 24.3444444444, 124.186944444), + ("ROKJ", 26.3633333333, 126.713611111), + ("ROMD", 25.8463888889, 131.263333333), + ("ROMY", 24.7827777778, 125.295), + ("RORK", 25.9477777778, 131.321388889), + ("RORS", 24.8266666667, 125.144722222), + ("RORY", 27.0438888889, 128.401388889), + ("ROTM", 26.2741666667, 127.756388889), + ("ROYN", 24.4669444444, 122.977777778), + ("RPLL", 14.5086111111, 121.019444444), + ("RPMB", 6.10555555556, 125.236111111), + ("RPMC", 7.16472222222, 124.210277778), + ("RPML", 8.41444444444, 124.611388889), + ("RPMM", 7.61722222222, 124.058611111), + ("RPMP", 7.82777777778, 123.460277778), + ("RPMR", 6.05805555556, 125.096111111), + ("RPMS", 9.75777777778, 125.480833333), + ("RPMZ", 6.92222222222, 122.059444444), + ("RPUB", 16.375, 120.618888889), + ("RPUD", 14.1291666667, 122.980277778), + ("RPUF", 14.9863888889, 120.4925), + ("RPUG", 16.0347222222, 120.240833333), + ("RPUH", 12.3613888889, 121.046388889), + ("RPUI", 15.3255555556, 119.968888889), + ("RPUL", 13.955, 121.124722222), + ("RPUM", 13.2080555556, 120.605277778), + ("RPUN", 13.5852777778, 123.270833333), + ("RPUO", 20.4516666667, 121.98), + ("RPUP", 14.2927777778, 122.645555556), + ("RPUQ", 17.5536111111, 120.3575), + ("RPUS", 16.5955555556, 120.303055556), + ("RPUT", 17.6380555556, 121.730555556), + ("RPUV", 13.5775, 124.206111111), + ("RPUW", 13.3611111111, 121.825277778), + ("RPUY", 16.9297222222, 121.753333333), + ("RPUZ", 16.6188888889, 121.252222222), + ("RPVA", 11.2272222222, 125.027777778), + ("RPVB", 10.6425, 122.929444444), + ("RPVC", 12.0725, 124.545), + ("RPVD", 9.33416666667, 123.301944444), + ("RPVF", 12.5022222222, 124.635555556), + ("RPVG", 11.0355555556, 125.742777778), + ("RPVI", 10.7130555556, 122.545), + ("RPVK", 11.6811111111, 122.377777778), + ("RPVM", 10.3075, 123.979166667), + ("RPVO", 11.0558333333, 124.565555556), + ("RPVP", 9.74194444444, 118.758611111), + ("RPVR", 11.5975, 122.752777778), + ("RPVS", 10.7661111111, 121.932222222), + ("SAAC", -31.2969444444, -57.9963888889), + ("SAAG", -33.0058333333, -58.6130555556), + ("SAAI", -35.3477777778, -57.2938888889), + ("SAAJ", -34.5458333333, -60.9305555556), + ("SAAP", -31.7947222222, -60.4802777778), + ("SAAR", -32.9033333333, -60.7844444444), + ("SAAV", -31.7116666667, -60.8116666667), + ("SABE", -34.5591666667, -58.4155555556), + ("SACC", -31.0066666667, -64.5325), + ("SACO", -31.3236111111, -64.2077777778), + ("SACT", -30.3452777778, -66.2936111111), + ("SADD", -34.5005555556, -58.6041666667), + ("SADF", -34.4530555556, -58.5894444444), + ("SADJ", -34.5605555556, -58.7894444444), + ("SADL", -34.9722222222, -57.8944444444), + ("SADM", -34.6761111111, -58.6425), + ("SADP", -34.6097222222, -58.6125), + ("SADS", -34.7313888889, -58.5994444444), + ("SAHC", -37.4444444444, -70.2222222222), + ("SAHR", -39.0005555556, -67.6202777778), + ("SAME", -32.8316666667, -68.7927777778), + ("SAMM", -35.4838888889, -69.5825), + ("SAMQ", -32.8658333333, -68.8722222222), + ("SAMR", -34.5880555556, -68.4025), + ("SANC", -28.5955555556, -65.7516666667), + ("SANE", -27.7655555556, -64.31), + ("SANI", -28.0375, -67.5802777778), + ("SANL", -29.3813888889, -66.7958333333), + ("SANO", -29.2238888889, -67.4388888889), + ("SANT", -26.8408333333, -65.1047222222), + ("SANU", -31.5713888889, -68.4180555556), + ("SAOC", -33.0855555556, -64.2613888889), + ("SAOD", -31.9411111111, -65.1422222222), + ("SAOL", -34.1352777778, -63.3622222222), + ("SAOM", -32.6836111111, -62.1577777778), + ("SAOR", -33.7297222222, -65.3872222222), + ("SAOU", -33.2730555556, -66.3563888889), + ("SARC", -27.4452777778, -58.7616666667), + ("SARE", -27.4497222222, -59.0561111111), + ("SARF", -26.2125, -58.2280555556), + ("SARI", -25.7375, -54.4730555556), + ("SARL", -29.6891666667, -57.1519444444), + ("SARM", -30.2716666667, -57.64), + ("SARP", -27.3858333333, -55.9705555556), + ("SARS", -26.7563888889, -60.4930555556), + ("SASA", -24.8558333333, -65.4861111111), + ("SASJ", -24.3927777778, -65.0977777778), + ("SASO", -23.1527777778, -64.3291666667), + ("SASQ", -22.1622222222, -65.5697222222), + ("SAST", -22.6197222222, -63.7936111111), + ("SATG", -29.1058333333, -59.2186111111), + ("SATK", -24.7211111111, -60.5486111111), + ("SATM", -29.2230555556, -58.0880555556), + ("SATO", -27.5180555556, -55.1238888889), + ("SATR", -29.21, -59.6908333333), + ("SATU", -29.7705555556, -57.9788888889), + ("SAVB", -41.9430555556, -71.5322222222), + ("SAVC", -45.785, -67.4655555556), + ("SAVD", -42.0305555556, -71.1697222222), + ("SAVE", -42.9077777778, -71.1394444444), + ("SAVH", -46.5383333333, -68.9658333333), + ("SAVT", -43.2102777778, -65.2702777778), + ("SAVV", -40.8691666667, -63.0002777778), + ("SAVY", -42.7588888889, -65.1025), + ("SAWA", -50.3352777778, -72.2483333333), + ("SAWB", -64.2383333333, -56.6308333333), + ("SAWD", -47.7352777778, -65.9038888889), + ("SAWE", -53.7775, -67.7491666667), + ("SAWG", -51.6086111111, -69.3125), + ("SAWH", -54.8430555556, -68.2955555556), + ("SAWJ", -49.3066666667, -67.8025), + ("SAWS", -44.0480555556, -70.4591666667), + ("SAWT", -51.6063888889, -72.2166666667), + ("SAWU", -50.0163888889, -68.5791666667), + ("SAZB", -38.7247222222, -62.1691666667), + ("SAZC", -37.4461111111, -61.8891666667), + ("SAZD", -36.3202777778, -57.7216666667), + ("SAZF", -36.8908333333, -60.2161111111), + ("SAZG", -35.6961111111, -63.7580555556), + ("SAZH", -38.3866666667, -60.3294444444), + ("SAZI", -36.1869444444, -61.0761111111), + ("SAZL", -36.5422222222, -56.7216666667), + ("SAZM", -37.9341666667, -57.5733333333), + ("SAZN", -38.9488888889, -68.1555555556), + ("SAZO", -38.4894444444, -58.8158333333), + ("SAZP", -35.8455555556, -61.8577777778), + ("SAZR", -36.5880555556, -64.2752777778), + ("SAZS", -41.1511111111, -71.1575), + ("SAZT", -37.2372222222, -59.2277777778), + ("SAZV", -37.2352777778, -57.0291666667), + ("SAZW", -38.9394444444, -69.2644444444), + ("SAZY", -40.0752777778, -71.1372222222), + ("SBAA", -8.34833333333, -49.3013888889), + ("SBAF", -22.875, -43.3844444444), + ("SBAM", 2.07666666667, -50.8622222222), + ("SBAQ", -21.8119444444, -48.1327777778), + ("SBAR", -10.9838888889, -37.0702777778), + ("SBAS", -22.6383333333, -50.4558333333), + ("SBAT", -9.86583333333, -56.1061111111), + ("SBAU", -21.1411111111, -50.4247222222), + ("SBAV", -22.5255555556, -52.9719444444), + ("SBBE", -1.37916666667, -48.4761111111), + ("SBBG", -31.3902777778, -54.1122222222), + ("SBBH", -19.8516666667, -43.9502777778), + ("SBBI", -25.405, -49.2319444444), + ("SBBQ", -21.2669444444, -43.7608333333), + ("SBBR", -15.8625, -47.9125), + ("SBBU", -22.345, -49.0536111111), + ("SBBV", 2.84611111111, -60.69), + ("SBBW", -15.8611111111, -52.3888888889), + ("SBCA", -25.0002777778, -53.5005555556), + ("SBCC", -9.33388888889, -54.9652777778), + ("SBCF", -19.6336111111, -43.9686111111), + ("SBCG", -20.4686111111, -54.6725), + ("SBCH", -27.1341666667, -52.6563888889), + ("SBCI", -7.32027777778, -47.4586111111), + ("SBCM", -28.7255555556, -49.4247222222), + ("SBCO", -29.9458333333, -51.1444444444), + ("SBCP", -21.6983333333, -41.3016666667), + ("SBCR", -19.0116666667, -57.6727777778), + ("SBCT", -25.5283333333, -49.1755555556), + ("SBCV", -17.6522222222, -39.2530555556), + ("SBCX", -29.1969444444, -51.1875), + ("SBCY", -15.6527777778, -56.1166666667), + ("SBCZ", -7.6, -72.7694444444), + ("SBDN", -22.175, -51.4244444444), + ("SBEG", -3.03861111111, -60.0497222222), + ("SBEK", -6.23305555556, -57.7766666667), + ("SBES", -22.8127777778, -42.0925), + ("SBFC", -20.5919444444, -47.3827777778), + ("SBFI", -25.5961111111, -54.4869444444), + ("SBFL", -27.6725, -48.5477777778), + ("SBFN", -3.85472222222, -32.4233333333), + ("SBFT", -20.2783333333, -49.1872222222), + ("SBFU", -20.7027777778, -46.335), + ("SBFZ", -3.77611111111, -38.5325), + ("SBGL", -22.8088888889, -43.2436111111), + ("SBGM", -10.7861111111, -65.2847222222), + ("SBGO", -16.6311111111, -49.2222222222), + ("SBGR", -23.4322222222, -46.4691666667), + ("SBGS", -25.1844444444, -50.1438888889), + ("SBGW", -22.7913888889, -45.2047222222), + ("SBHT", -3.25388888889, -52.2538888889), + ("SBIC", -3.12722222222, -58.4811111111), + ("SBIH", -4.24222222222, -56.0005555556), + ("SBIL", -14.8158333333, -39.0330555556), + ("SBIP", -19.4705555556, -42.4875), + ("SBIT", -18.4444444444, -49.2133333333), + ("SBIZ", -5.53111111111, -47.46), + ("SBJC", -1.41388888889, -48.4605555556), + ("SBJF", -21.7913888889, -43.3866666667), + ("SBJP", -7.26972222222, -35.8961111111), + ("SBJV", -26.2247222222, -48.7972222222), + ("SBKP", -23.0080555556, -47.1344444444), + ("SBLJ", -27.7819444444, -50.2813888889), + ("SBLN", -21.6638888889, -49.7302777778), + ("SBLO", -23.3336111111, -51.13), + ("SBLP", -13.2619444444, -43.4080555556), + ("SBLS", -19.6613888889, -43.8963888889), + ("SBMA", -5.36833333333, -49.1377777778), + ("SBMD", -0.889722222222, -52.6022222222), + ("SBMG", -23.4397222222, -51.9069444444), + ("SBMK", -16.7066666667, -43.8188888889), + ("SBML", -22.1966666667, -49.9263888889), + ("SBMN", -3.14555555556, -59.9861111111), + ("SBMO", -9.51027777778, -35.7933333333), + ("SBMQ", 0.0505555555556, -51.0719444444), + ("SBMS", -5.20166666667, -37.3641666667), + ("SBMT", -23.5088888889, -46.6375), + ("SBMY", -5.81138888889, -61.2786111111), + ("SBNF", -26.88, -48.6513888889), + ("SBNM", -28.2816666667, -54.1688888889), + ("SBNT", -5.91111111111, -35.2477777778), + ("SBOI", 3.85527777778, -51.7966666667), + ("SBPA", -29.9941666667, -51.1713888889), + ("SBPB", -2.89361111111, -41.7319444444), + ("SBPC", -21.8427777778, -46.5677777778), + ("SBPF", -28.2438888889, -52.3263888889), + ("SBPK", -31.7183333333, -52.3275), + ("SBPL", -9.36388888889, -40.5638888889), + ("SBPN", -10.7191666667, -48.3997222222), + ("SBPP", -22.5494444444, -55.7025), + ("SBPV", -8.70916666667, -63.9022222222), + ("SBQV", -14.8625, -40.8630555556), + ("SBRB", -9.86888888889, -67.8936111111), + ("SBRF", -8.12638888889, -34.9233333333), + ("SBRG", -32.0825, -52.1663888889), + ("SBRJ", -22.9102777778, -43.1630555556), + ("SBRP", -21.1341666667, -47.7741666667), + ("SBSC", -22.9322222222, -43.7188888889), + ("SBSJ", -23.2291666667, -45.8613888889), + ("SBSL", -2.58861111111, -44.2363888889), + ("SBSM", -29.7111111111, -53.6880555556), + ("SBSP", -23.6266666667, -46.6552777778), + ("SBSR", -20.8163888889, -49.4063888889), + ("SBST", -23.925, -46.2875), + ("SBSV", -12.9108333333, -38.3308333333), + ("SBTB", -1.48944444444, -56.3966666667), + ("SBTE", -5.05972222222, -42.8233333333), + ("SBTF", -3.38277777778, -64.7238888889), + ("SBTK", -8.155, -70.7830555556), + ("SBTL", -24.3175, -50.6513888889), + ("SBTS", 2.22333333333, -55.9458333333), + ("SBTT", -4.25555555556, -69.9355555556), + ("SBTU", -3.785, -49.7194444444), + ("SBUA", -0.148333333333, -66.9855555556), + ("SBUF", -9.40083333333, -38.2505555556), + ("SBUG", -29.7819444444, -57.0380555556), + ("SBUL", -18.8827777778, -48.2255555556), + ("SBUP", -20.7769444444, -51.5647222222), + ("SBUR", -19.765, -47.9647222222), + ("SBVG", -21.59, -45.4733333333), + ("SBVH", -12.6941666667, -60.0980555556), + ("SBVT", -20.2555555556, -40.2888888889), + ("SBYA", 0.6075, -69.1858333333), + ("SBYS", -21.9852777778, -47.3380555556), + ("SCAC", -41.9061111111, -73.7966666667), + ("SCAP", -43.6152777778, -71.8069444444), + ("SCAR", -18.3483333333, -70.3386111111), + ("SCBA", -45.9158333333, -71.6891666667), + ("SCBQ", -33.5616666667, -70.6883333333), + ("SCCC", -46.5816666667, -71.6975), + ("SCCF", -22.4986111111, -68.9041666667), + ("SCCH", -36.5827777778, -72.0316666667), + ("SCCI", -53.0027777778, -70.8547222222), + ("SCCY", -45.5941666667, -72.1061111111), + ("SCDA", -20.535, -70.1811111111), + ("SCEL", -33.3927777778, -70.7855555556), + ("SCFA", -23.4444444444, -70.445), + ("SCFM", -53.2536111111, -70.3191666667), + ("SCGE", -37.4016666667, -72.4255555556), + ("SCGZ", -54.9308333333, -67.6261111111), + ("SCHA", -27.2961111111, -70.4136111111), + ("SCIC", -34.9669444444, -71.2169444444), + ("SCIE", -36.7725, -73.0630555556), + ("SCIP", -27.1647222222, -109.421666667), + ("SCJO", -40.6113888889, -73.0602777778), + ("SCLL", -28.5975, -70.7591666667), + ("SCRG", -34.1736111111, -70.7755555556), + ("SCRM", -62.1908333333, -58.9866666667), + ("SCSE", -29.9163888889, -71.1911111111), + ("SCSN", -33.6566666667, -71.6155555556), + ("SCST", -42.4908333333, -73.7744444444), + ("SCTB", -33.4563888889, -70.5466666667), + ("SCTC", -38.7686111111, -72.6358333333), + ("SCTE", -41.4386111111, -73.0938888889), + ("SCTI", -33.4933333333, -70.6975), + ("SCTN", -42.9330555556, -72.6991666667), + ("SCVD", -39.6497222222, -73.0861111111), + ("SEAM", -1.2125, -78.5741666667), + ("SECM", -1.70611111111, -79.3788888889), + ("SECO", -0.462777777778, -76.9863888889), + ("SECU", -2.88944444444, -78.9841666667), + ("SEGS", -0.453611111111, -90.2658333333), + ("SEGU", -2.15777777778, -79.8838888889), + ("SEGZ", -3.42333333333, -78.5730555556), + ("SEIB", 0.338333333333, -78.1363888889), + ("SELA", 0.0922222222222, -76.8691666667), + ("SELJ", -1.70416666667, -79.5522222222), + ("SELM", -1.50138888889, -79.4808333333), + ("SELT", -0.906666666667, -78.6155555556), + ("SEMA", -4.38027777778, -79.9405555556), + ("SEMC", -2.29916666667, -78.1205555556), + ("SEMH", -3.26888888889, -79.9616666667), + ("SEMO", -2.06694444444, -76.9752777778), + ("SEMT", -0.945555555556, -80.6780555556), + ("SEMX", -2.85083333333, -79.8036111111), + ("SEMY", -1.73972222222, -79.6216666667), + ("SEPD", 0.0730555555556, -80.0522222222), + ("SEPV", -1.04138888889, -80.4719444444), + ("SEQU", -0.141111111111, -78.4880555556), + ("SERB", -1.65361111111, -78.6561111111), + ("SERO", -3.43527777778, -79.9777777778), + ("SESA", -2.20472222222, -80.9886111111), + ("SESD", -0.248055555556, -79.2144444444), + ("SEST", -0.909722222222, -89.6158333333), + ("SETA", -2.26083333333, -79.6891666667), + ("SETE", -0.986666666667, -77.8194444444), + ("SETR", -0.122777777778, -76.3375), + ("SETU", 0.809444444444, -77.7080555556), + ("SFAL", -51.6855555556, -57.7775), + ("SGAS", -25.2397222222, -57.5188888889), + ("SGAY", -27.3705555556, -56.8538888889), + ("SGCO", -23.4416666667, -57.4269444444), + ("SGFI", -22.3597222222, -60.0536111111), + ("SGIB", -25.4075, -54.6194444444), + ("SGME", -22.0447222222, -60.6216666667), + ("SGPI", -26.8813888889, -58.3177777778), + ("SKAR", 4.45361111111, -75.7652777778), + ("SKAS", 0.505, -76.5008333333), + ("SKBC", 9.04527777778, -73.9747222222), + ("SKBG", 7.12638888889, -73.1847222222), + ("SKBO", 4.70138888889, -74.1469444444), + ("SKBQ", 10.8894444444, -74.7805555556), + ("SKBS", 6.20277777778, -77.3944444444), + ("SKBU", 3.81944444444, -76.9897222222), + ("SKCC", 7.9275, -72.5113888889), + ("SKCD", 5.07166666667, -76.6763888889), + ("SKCG", 10.4422222222, -75.5127777778), + ("SKCL", 3.54305555556, -76.3813888889), + ("SKCO", 1.81416666667, -78.7491666667), + ("SKCZ", 9.3325, -75.2855555556), + ("SKEJ", 7.02416666667, -73.8066666667), + ("SKFL", 1.59027777778, -75.5638888889), + ("SKGI", 4.27611111111, -74.7966666667), + ("SKGO", 4.75805555556, -75.9555555556), + ("SKGP", 2.57, -77.8983333333), + ("SKGY", 4.81222222222, -74.0647222222), + ("SKIB", 4.42138888889, -75.1330555556), + ("SKIP", 0.861666666667, -77.6716666667), + ("SKLC", 7.81194444444, -76.7163888889), + ("SKLM", 11.2325, -72.49), + ("SKLT", -4.19305555556, -69.9425), + ("SKMD", 6.22, -75.5905555556), + ("SKMG", 9.28333333333, -74.8394444444), + ("SKMR", 8.82361111111, -75.8258333333), + ("SKMU", 1.25361111111, -70.2336111111), + ("SKMZ", 5.02972222222, -75.465), + ("SKNV", 2.95, -75.2938888889), + ("SKOC", 8.31472222222, -73.3583333333), + ("SKOT", 7.01027777778, -74.7152777778), + ("SKPB", 12.2213888889, -71.9847222222), + ("SKPC", 6.18444444444, -67.4930555556), + ("SKPE", 4.8125, -75.7394444444), + ("SKPI", 1.85833333333, -76.0858333333), + ("SKPP", 2.45416666667, -76.61), + ("SKPS", 1.39638888889, -77.2908333333), + ("SKPV", 13.3569444444, -81.3583333333), + ("SKQU", 5.2125, -74.8836111111), + ("SKRG", 6.16444444444, -75.4230555556), + ("SKRH", 11.5261111111, -72.9258333333), + ("SKSA", 6.95805555556, -71.855), + ("SKSJ", 2.57944444444, -72.6391666667), + ("SKSM", 11.1194444444, -74.2305555556), + ("SKSP", 12.5833333333, -81.7111111111), + ("SKSV", 2.15194444444, -74.7661111111), + ("SKTD", 5.43027777778, -71.6580555556), + ("SKTM", 6.45083333333, -71.76), + ("SKTU", 8.07444444444, -76.7411111111), + ("SKUC", 7.06861111111, -70.7366666667), + ("SKUI", 5.69055555556, -76.6411111111), + ("SKUL", 4.08833333333, -76.235), + ("SKVP", 10.435, -73.2494444444), + ("SKVV", 4.16777777778, -73.6136111111), + ("SKYP", 5.31888888889, -72.3838888889), + ("SLAP", -14.7394444444, -68.4108333333), + ("SLAS", -15.7191666667, -63.0922222222), + ("SLBJ", -22.7694444444, -64.315), + ("SLCA", -20.0069444444, -63.5275), + ("SLCB", -17.4208333333, -66.1769444444), + ("SLCH", -16.99, -65.1413888889), + ("SLCN", -17.5938888889, -69.4341666667), + ("SLCO", -11.0402777778, -68.7827777778), + ("SLCP", -16.1433333333, -62.0258333333), + ("SLGY", -10.8216666667, -65.3458333333), + ("SLJO", -13.0527777778, -64.6616666667), + ("SLLP", -16.5130555556, -68.1922222222), + ("SLMG", -13.2536111111, -64.0627777778), + ("SLOR", -17.9633333333, -67.0761111111), + ("SLPO", -19.5433333333, -65.7238888889), + ("SLPS", -18.9752777778, -57.8205555556), + ("SLRA", -13.2636111111, -64.6052777778), + ("SLRB", -18.3280555556, -59.7661111111), + ("SLRI", -11.0102777778, -66.0733333333), + ("SLRQ", -14.4283333333, -67.5013888889), + ("SLRY", -14.3061111111, -67.3536111111), + ("SLSA", -13.7619444444, -65.435), + ("SLSB", -14.8575, -66.7375), + ("SLSI", -16.3844444444, -60.9627777778), + ("SLSM", -14.9655555556, -65.6336111111), + ("SLSU", -19.0069444444, -65.2888888889), + ("SLTI", -16.3386111111, -58.4016666667), + ("SLTJ", -21.5555555556, -64.7008333333), + ("SLTR", -14.8194444444, -64.9183333333), + ("SLVR", -17.6447222222, -63.1352777778), + ("SMJP", 5.45277777778, -55.1877777778), + ("SMZO", 5.81083333333, -55.1905555556), + ("SOCA", 4.81972222222, -52.3602777778), + ("SOOG", 3.8975, -51.8038888889), + ("SPAC", -4.6075, -77.9408333333), + ("SPAS", -2.795, -76.4661111111), + ("SPAY", -10.7288888889, -73.7663888889), + ("SPBB", -6.01888888889, -76.9883333333), + ("SPBC", -3.91666666667, -70.5080555556), + ("SPBR", -11.4113888889, -69.4886111111), + ("SPCL", -8.37777777778, -74.5741666667), + ("SPEO", -9.15083333333, -78.5236111111), + ("SPEP", -9.76805555556, -70.7063888889), + ("SPEQ", -17.1788888889, -70.9305555556), + ("SPGM", -9.29, -76.0058333333), + ("SPHI", -6.78722222222, -79.8280555556), + ("SPHO", -13.1547222222, -74.2041666667), + ("SPHY", -13.7063888889, -73.3502777778), + ("SPHZ", -9.34722222222, -77.5983333333), + ("SPIM", -12.0216666667, -77.1141666667), + ("SPJI", -7.16944444444, -76.7277777778), + ("SPJJ", -11.7830555556, -75.4733333333), + ("SPJL", -15.4669444444, -70.1580555556), + ("SPJN", -15.3575, -75.1355555556), + ("SPJR", -7.13638888889, -78.49), + ("SPLO", -17.695, -71.3438888889), + ("SPLP", -12.1605555556, -76.9988888889), + ("SPME", -3.5525, -80.3808333333), + ("SPMS", -5.89388888889, -76.1183333333), + ("SPNC", -9.87805555556, -76.2041666667), + ("SPOL", -11.9286111111, -77.0611111111), + ("SPPY", -6.20166666667, -77.8558333333), + ("SPQT", -3.78472222222, -73.3086111111), + ("SPQU", -16.3408333333, -71.5830555556), + ("SPRM", -11.1286111111, -75.3502777778), + ("SPRU", -8.08472222222, -79.1094444444), + ("SPSO", -13.7447222222, -76.2202777778), + ("SPST", -6.50861111111, -76.3730555556), + ("SPTN", -18.0533333333, -70.2758333333), + ("SPTP", -4.54972222222, -81.2238888889), + ("SPTU", -12.6136111111, -69.2288888889), + ("SPUR", -5.20555555556, -80.6163888889), + ("SPYL", -4.57638888889, -81.2538888889), + ("SPZA", -14.8538888889, -74.9613888889), + ("SPZO", -13.5355555556, -71.9386111111), + ("SUAA", -34.7891666667, -56.2644444444), + ("SUAG", -30.4005555556, -56.5077777778), + ("SUCA", -34.4563888889, -57.7705555556), + ("SUDU", -33.3586111111, -56.4991666667), + ("SULS", -34.855, -55.0941666667), + ("SUMO", -32.3377777778, -54.2166666667), + ("SUMU", -34.8377777778, -56.0302777778), + ("SUPE", -34.9136111111, -54.9205555556), + ("SUPU", -32.365, -58.0611111111), + ("SURV", -30.9744444444, -55.4761111111), + ("SUSO", -31.4397222222, -57.9905555556), + ("SUTB", -31.7488888889, -55.9255555556), + ("SVAC", 9.55333333333, -69.2377777778), + ("SVAN", 9.42916666667, -64.4708333333), + ("SVAT", 4.05166666667, -67.7008333333), + ("SVBC", 10.1069444444, -64.6888888889), + ("SVBI", 8.61944444444, -70.2205555556), + ("SVBL", 10.1833333333, -67.5572222222), + ("SVBM", 10.0425, -69.3583333333), + ("SVBS", 10.2497222222, -67.6491666667), + ("SVCB", 8.12194444444, -63.5369444444), + ("SVCD", 7.62583333333, -66.1647222222), + ("SVCJ", 9.64888888889, -68.5752777778), + ("SVCL", 8.92444444444, -67.4169444444), + ("SVCN", 6.23194444444, -62.8541666667), + ("SVCO", 10.1755555556, -70.065), + ("SVCP", 10.66, -63.2616666667), + ("SVCR", 11.4147222222, -69.6808333333), + ("SVCS", 10.2861111111, -66.8158333333), + ("SVCU", 10.4502777778, -64.1302777778), + ("SVCZ", 9.37194444444, -66.9227777778), + ("SVED", 6.715, -61.6388888889), + ("SVEZ", 7.05972222222, -69.4966666667), + ("SVGD", 7.21083333333, -70.7563888889), + ("SVGI", 10.5738888889, -62.3125), + ("SVGU", 9.02694444444, -69.755), + ("SVHG", 10.4622222222, -66.0925), + ("SVIE", 10.7941666667, -63.9813888889), + ("SVJC", 11.7808333333, -70.1516666667), + ("SVJM", 9.90694444444, -67.3794444444), + ("SVLF", 8.23916666667, -72.2708333333), + ("SVLO", 11.8086111111, -66.1791666667), + ("SVMC", 10.5580555556, -71.7277777778), + ("SVMD", 8.58194444444, -71.1608333333), + ("SVMG", 10.9125, -63.9663888889), + ("SVMI", 10.6030555556, -66.9905555556), + ("SVMT", 9.74916666667, -63.1522222222), + ("SVPA", 5.61972222222, -67.6058333333), + ("SVPC", 10.4802777778, -68.0727777778), + ("SVPM", 7.80111111111, -72.2027777778), + ("SVPR", 8.28833333333, -62.7602777778), + ("SVPT", 7.57555555556, -70.1741666667), + ("SVSA", 7.85222222222, -72.4347222222), + ("SVSB", 7.80333333333, -71.1655555556), + ("SVSO", 7.565, -72.035), + ("SVSP", 10.2786111111, -68.755), + ("SVSR", 7.8825, -67.4436111111), + ("SVST", 8.945, -64.1508333333), + ("SVSZ", 8.97444444444, -71.9430555556), + ("SVTC", 9.08888888889, -62.0941666667), + ("SVTM", 7.24916666667, -61.5288888889), + ("SVVA", 10.1580555556, -67.9266666667), + ("SVVG", 8.62416666667, -71.6727777778), + ("SVVL", 9.34055555556, -70.5838888889), + ("SVVP", 9.22194444444, -65.9933333333), + ("SYKM", 5.86527777778, -60.6141666667), + ("SYLD", 5.96583333333, -58.2702777778), + ("SYLT", 3.3725, -59.7891666667), + ("TAPA", 17.1366666667, -61.7925), + ("TBPB", 13.0744444444, -59.4922222222), + ("TDCF", 15.3366666667, -61.3919444444), + ("TDPD", 15.5469444444, -61.3), + ("TFFF", 14.5908333333, -61.0030555556), + ("TFFG", 18.0997222222, -63.0469444444), + ("TFFJ", 17.9, -62.85), + ("TFFM", 15.8686111111, -61.27), + ("TFFR", 16.2652777778, -61.5316666667), + ("TGPY", 12.0041666667, -61.7861111111), + ("TIST", 18.3372222222, -64.9733333333), + ("TISX", 17.7016666667, -64.7983333333), + ("TJBQ", 18.4947222222, -67.1294444444), + ("TJFA", 18.3088888889, -65.6616666667), + ("TJIG", 18.4566666667, -66.0980555556), + ("TJMZ", 18.2555555556, -67.1483333333), + ("TJNR", 18.245, -65.6433333333), + ("TJPS", 18.0080555556, -66.5627777778), + ("TJSJ", 18.4391666667, -66.0016666667), + ("TKPK", 17.3111111111, -62.7186111111), + ("TKPN", 17.2055555556, -62.5897222222), + ("TLPC", 14.02, -60.9927777778), + ("TLPL", 13.7330555556, -60.9525), + ("TNCA", 12.5013888889, -70.015), + ("TNCB", 12.1308333333, -68.2683333333), + ("TNCC", 12.1886111111, -68.9597222222), + ("TNCE", 17.4963888889, -62.9791666667), + ("TNCM", 18.0408333333, -63.1088888889), + ("TQPF", 18.2047222222, -63.055), + ("TRPM", 33.5869444444, -80.2086111111), + ("TTCP", 11.1494444444, -60.8319444444), + ("TTPP", 10.5952777778, -61.3372222222), + ("TUPJ", 18.4447222222, -64.5427777778), + ("TVSB", 12.9883333333, -61.2619444444), + ("TVSC", 12.6988888889, -61.3422222222), + ("TVSM", 12.8875, -61.18), + ("TVSV", 13.1441666667, -61.2108333333), + ("UAAA", 43.3519444444, 77.0402777778), + ("UAAH", 46.8941666667, 75.0047222222), + ("UACC", 51.0222222222, 71.4672222222), + ("UAFM", 43.0616666667, 74.4783333333), + ("UAFO", 40.6088888889, 72.7930555556), + ("UAII", 42.3644444444, 69.4791666667), + ("UAKD", 47.7083333333, 67.7333333333), + ("UARR", 51.1516666667, 51.5455555556), + ("UASS", 50.3511111111, 80.2341666667), + ("UATE", 43.86, 51.0919444444), + ("UATT", 50.245, 57.2033333333), + ("UAUU", 53.2063888889, 63.5508333333), + ("UBBB", 40.4675, 50.0466666667), + ("UEEA", 34.8041666667, -96.6711111111), + ("UEEE", 62.0930555556, 129.770555556), + ("UERP", 66.4166666667, 112.05), + ("UGEE", 40.1483333333, 44.3966666667), + ("UGGG", 41.6691666667, 44.9547222222), + ("UGSS", 42.8580555556, 41.1280555556), + ("UHBB", 50.4216666667, 127.41), + ("UHHH", 48.5277777778, 135.188333333), + ("UHMA", 64.7347222222, 177.741388889), + ("UHMD", 64.38, -173.246666667), + ("UHMM", 59.91, 150.716666667), + ("UHMP", 67.5, 171.0), + ("UHPP", 53.1663888889, 158.452777778), + ("UHSH", 53.515, 142.888333333), + ("UHSS", 46.8886111111, 142.717222222), + ("UHWW", 43.3988888889, 132.151388889), + ("UIAA", 52.0261111111, 113.305), + ("UIBB", 56.3708333333, 101.698611111), + ("UIII", 52.2669444444, 104.394722222), + ("UIUU", 51.8066666667, 107.438055556), + ("UKBB", 50.345, 30.895), + ("UKCC", 48.0733333333, 37.74), + ("UKDD", 48.3566666667, 35.1016666667), + ("UKFF", 45.0386111111, 33.9830555556), + ("UKHH", 49.3588888889, 26.9338888889), + ("UKKK", 50.4016666667, 30.4516666667), + ("UKLL", 49.8125, 23.9561111111), + ("UKLN", 48.26, 25.9816666667), + ("UKOO", 46.4269444444, 30.6780555556), + ("ULLI", 59.8, 30.265), + ("ULMM", 68.7816666667, 32.7505555556), + ("UMGG", 52.5269444444, 31.0166666667), + ("UMII", 55.1666666667, 30.1333333333), + ("UMKK", 54.89, 20.5925), + ("UMMM", 53.8644444444, 27.5394444444), + ("UMMS", 53.8822222222, 28.0305555556), + ("UNAA", 53.74, 91.385), + ("UNBB", 53.3638888889, 83.5419444444), + ("UNEE", 55.2697222222, 86.1069444444), + ("UNOO", 54.9669444444, 73.31), + ("URKK", 45.035, 39.1716666667), + ("URML", 42.8166666667, 47.6522222222), + ("URMM", 44.225, 43.0816666667), + ("URMT", 45.1091666667, 42.1127777778), + ("URRR", 47.2580555556, 39.8177777778), + ("URSS", 43.4458333333, 39.9475), + ("URWA", 46.2833333333, 48.0061111111), + ("URWW", 48.7822222222, 44.3447222222), + ("USCC", 55.3033333333, 61.5066666667), + ("USCM", 53.3933333333, 58.76), + ("USDD", 66.59, 66.6102777778), + ("USNN", 60.95, 76.4666666667), + ("USPP", 57.9166666667, 56.0255555556), + ("USRR", 61.25, 73.5), + ("USSS", 56.7413888889, 60.8036111111), + ("USTO", 37.1322222222, -92.0838888889), + ("USUU", 55.475, 65.4147222222), + ("UTAA", 37.9916666667, 58.3633333333), + ("UTAK", 40.0333333333, 52.9833333333), + ("UTAV", 39.0833333333, 63.6133333333), + ("UTDD", 38.5433333333, 68.825), + ("UTNN", 42.4863888889, 59.6225), + ("UTSB", 39.775, 64.48), + ("UTSS", 39.7005555556, 66.9847222222), + ("UTST", 37.2863888889, 67.3083333333), + ("UTTT", 41.2572222222, 69.2816666667), + ("UUBP", 53.2141666667, 34.1763888889), + ("UUEE", 55.9716666667, 37.415), + ("UUEM", 56.8247222222, 35.7575), + ("UUOO", 51.8141666667, 39.2297222222), + ("UUWW", 55.5913888889, 37.2613888889), + ("UUYY", 61.6475, 50.8455555556), + ("UWKD", 55.6077777778, 49.2772222222), + ("UWOO", 51.7955555556, 55.4566666667), + ("UWPP", 28.9541666667, -98.5197222222), + ("UWUU", 54.5575, 55.8741666667), + ("UWWW", 53.5052777778, 50.1644444444), + ("VAAH", 23.0747222222, 72.6316666667), + ("VAAK", 20.6988888889, 77.0563888889), + ("VAAU", 19.8630555556, 75.3980555556), + ("VABB", 19.0886111111, 72.8677777778), + ("VABI", 21.9886111111, 82.1111111111), + ("VABJ", 23.2877777778, 69.67), + ("VABM", 15.8591666667, 74.6180555556), + ("VABO", 22.3361111111, 73.2261111111), + ("VABP", 23.285, 77.3372222222), + ("VABV", 21.7519444444, 72.185), + ("VADN", 20.435, 72.8436111111), + ("VADS", 24.2677777778, 72.2052777778), + ("VAGO", 15.3805555556, 73.8330555556), + ("VAID", 22.7216666667, 75.8008333333), + ("VAJB", 23.1777777778, 80.0519444444), + ("VAJJ", 19.0980555556, 72.8338888889), + ("VAJM", 22.4663888889, 70.0113888889), + ("VAKE", 23.1125, 70.1002777778), + ("VAKJ", 24.8194444444, 79.9191666667), + ("VAKP", 16.6638888889, 74.2880555556), + ("VAKS", 21.3166666667, 70.27), + ("VANP", 21.0919444444, 79.0469444444), + ("VANR", 19.9625, 73.8069444444), + ("VAPO", 18.5819444444, 73.9194444444), + ("VAPR", 21.6494444444, 69.6563888889), + ("VARK", 22.3091666667, 70.7794444444), + ("VARP", 21.1802777778, 81.7386111111), + ("VASL", 17.6277777778, 75.9347222222), + ("VASU", 21.115, 72.7427777778), + ("VAUD", 24.6175, 73.9127777778), + ("VCBI", 7.18111111111, 79.8836111111), + ("VCCA", 8.30111111111, 80.4280555556), + ("VCCB", 7.70555555556, 81.6777777778), + ("VCCC", 6.82194444444, 79.8861111111), + ("VCCG", 7.3375, 81.6255555556), + ("VCCJ", 9.79222222222, 80.07), + ("VCCT", 8.53888888889, 81.1813888889), + ("VCCW", 6.25444444444, 81.235), + ("VDBG", 13.0955555556, 103.224166667), + ("VDKH", 12.255, 104.563611111), + ("VDPP", 11.5463888889, 104.843888889), + ("VDSR", 13.4105555556, 103.812777778), + ("VDST", 13.5313888889, 106.014166667), + ("VEAN", 28.1747222222, 94.8019444444), + ("VEAT", 23.8888888889, 91.2408333333), + ("VEAZ", 23.7461111111, 92.8030555556), + ("VEBD", 26.6813888889, 88.3280555556), + ("VEBG", 25.2608333333, 88.7955555556), + ("VEBK", 23.6433333333, 86.1486111111), + ("VEBS", 20.2441666667, 85.8177777778), + ("VECC", 22.6547222222, 88.4466666667), + ("VECO", 26.3302777778, 89.4669444444), + ("VEDB", 23.8338888889, 86.425), + ("VEDZ", 27.9888888889, 94.2233333333), + ("VEGK", 26.7394444444, 83.4494444444), + ("VEGT", 26.1061111111, 91.5847222222), + ("VEGY", 24.7480555556, 84.9425), + ("VEHK", 21.5791666667, 84.0061111111), + ("VEIM", 24.7597222222, 93.8969444444), + ("VEJH", 21.9133333333, 84.0502777778), + ("VEJP", 18.8797222222, 82.5519444444), + ("VEJS", 22.8119444444, 86.1675), + ("VEJT", 26.7305555556, 94.1755555556), + ("VEKM", 24.135, 91.8105555556), + ("VEKR", 24.3083333333, 92.0075), + ("VEKU", 24.9127777778, 92.9786111111), + ("VELR", 27.2905555556, 94.0966666667), + ("VEMN", 27.4833333333, 95.0175), + ("VEMZ", 26.12, 85.3130555556), + ("VENP", 20.87, 82.5194444444), + ("VEPG", 28.0661111111, 95.3355555556), + ("VEPH", 23.4744444444, 87.4277777778), + ("VEPT", 25.5905555556, 85.0877777778), + ("VEPU", 25.76, 87.4091666667), + ("VERC", 23.3147222222, 85.3213888889), + ("VERK", 22.2563888889, 84.8144444444), + ("VEUK", 20.0975, 83.1833333333), + ("VEZO", 27.5880555556, 93.8283333333), + ("VGCB", 21.4519444444, 91.9641666667), + ("VGEG", 22.2494444444, 91.8130555556), + ("VGIS", 24.1525, 89.0494444444), + ("VGJR", 23.1836111111, 89.1608333333), + ("VGRJ", 24.4369444444, 88.6163888889), + ("VGSD", 25.7591666667, 88.9086111111), + ("VGSY", 24.9627777778, 91.8672222222), + ("VGTJ", 23.7783333333, 90.3825), + ("VGZR", 23.8433333333, 90.3977777778), + ("VHHH", 22.3088888889, 113.914444444), + ("VHSK", 22.4363888889, 114.080277778), + ("VIAG", 27.1555555556, 77.9608333333), + ("VIAL", 25.4388888889, 81.7341666667), + ("VIAR", 31.7075, 74.7991666667), + ("VIBK", 28.0725, 73.2066666667), + ("VIBL", 26.9883333333, 80.8930555556), + ("VIBN", 25.4519444444, 82.8588888889), + ("VIBR", 31.8816666667, 77.1844444444), + ("VIBT", 30.27, 74.7555555556), + ("VIBW", 28.8375, 76.1775), + ("VIBY", 28.4222222222, 79.4497222222), + ("VICG", 30.6733333333, 76.7883333333), + ("VICX", 26.4041666667, 80.41), + ("VIDD", 28.5841666667, 77.2052777778), + ("VIDN", 30.1872222222, 78.18), + ("VIDP", 28.5663888889, 77.1030555556), + ("VIGN", 24.6544444444, 77.3472222222), + ("VIGR", 26.2938888889, 78.2275), + ("VIHR", 29.1805555556, 75.7530555556), + ("VIJN", 25.4897222222, 78.5594444444), + ("VIJO", 26.2513888889, 73.0480555556), + ("VIJP", 26.8238888889, 75.8097222222), + ("VIJR", 26.8891666667, 70.8644444444), + ("VIJU", 32.6897222222, 74.8380555556), + ("VIKA", 26.4411111111, 80.3633333333), + ("VIKO", 25.1605555556, 75.8447222222), + ("VILD", 30.8544444444, 75.9511111111), + ("VILH", 34.1355555556, 77.5455555556), + ("VILK", 26.7605555556, 80.8863888889), + ("VIPK", 32.2336111111, 75.6344444444), + ("VIPL", 30.315, 76.3633333333), + ("VIPT", 29.0330555556, 79.4736111111), + ("VIRB", 26.2502777778, 81.3805555556), + ("VISM", 31.0816666667, 77.0580555556), + ("VISP", 29.9941666667, 77.4241666667), + ("VISR", 33.9866666667, 74.7736111111), + ("VLHS", 20.2572222222, 100.437222222), + ("VLLB", 19.8972222222, 102.160833333), + ("VLPS", 15.1319444444, 105.781388889), + ("VLPV", 19.4547222222, 103.218055556), + ("VLSK", 16.5563888889, 104.759444444), + ("VLVT", 17.9880555556, 102.563055556), + ("VMMC", 22.1494444444, 113.591388889), + ("VNBW", 27.5055555556, 83.4161111111), + ("VNCG", 26.5705555556, 88.0794444444), + ("VNJP", 26.7086111111, 85.9222222222), + ("VNKT", 27.6963888889, 85.3591666667), + ("VNNG", 28.1036111111, 81.6669444444), + ("VNPK", 28.2002777778, 83.9811111111), + ("VNSI", 27.1594444444, 84.98), + ("VNVT", 26.4833333333, 87.2636111111), + ("VOAT", 10.8233333333, 72.1755555556), + ("VOBG", 12.9497222222, 77.6680555556), + ("VOBR", 17.9077777778, 77.4858333333), + ("VOBZ", 16.5302777778, 80.7966666667), + ("VOCB", 11.0313888889, 77.0438888889), + ("VOCL", 11.1355555556, 75.9547222222), + ("VOCP", 14.5097222222, 78.7727777778), + ("VOCX", 9.15305555556, 92.8191666667), + ("VODG", 17.6291666667, 78.4033333333), + ("VOHY", 17.4522222222, 78.4611111111), + ("VOMD", 9.83444444444, 78.0933333333), + ("VOML", 12.96, 74.8925), + ("VOMM", 12.9941666667, 80.1802777778), + ("VONS", 16.5408333333, 79.3177777778), + ("VOPB", 11.6455555556, 92.7330555556), + ("VORY", 17.1094444444, 81.8183333333), + ("VOSM", 11.7819444444, 78.0652777778), + ("VOTJ", 10.7197222222, 79.1036111111), + ("VOTP", 13.6319444444, 79.5430555556), + ("VOTR", 10.7652777778, 78.7088888889), + ("VOTV", 8.48194444444, 76.9180555556), + ("VOTX", 12.9066666667, 80.1211111111), + ("VOWA", 17.9180555556, 79.5986111111), + ("VQPR", 27.4030555556, 89.4258333333), + ("VRMM", 4.19166666667, 73.5288888889), + ("VTBD", 13.9125, 100.606666667), + ("VTBK", 14.1019444444, 99.9169444444), + ("VTBL", 14.8744444444, 100.663333333), + ("VTBU", 12.6797222222, 101.005), + ("VTBW", 13.7686111111, 102.315277778), + ("VTCB", 19.4972222222, 100.285555556), + ("VTCL", 18.2719444444, 99.5038888889), + ("VTCP", 18.1319444444, 100.164444444), + ("VTPH", 12.6338888889, 99.9508333333), + ("VTPI", 15.2772222222, 100.295833333), + ("VTPL", 16.8208333333, 101.253888889), + ("VTPM", 16.6997222222, 98.545), + ("VTPN", 15.6727777778, 100.136666667), + ("VTPP", 16.7827777778, 100.278888889), + ("VTPU", 17.6736111111, 100.234722222), + ("VTPY", 17.2341666667, 99.0577777778), + ("VTSC", 6.51972222222, 101.743333333), + ("VTSG", 8.09888888889, 98.9861111111), + ("VTSH", 7.18638888889, 100.607777778), + ("VTSK", 6.78527777778, 101.153333333), + ("VTSM", 9.54777777778, 100.062222222), + ("VTSN", 8.47111111111, 99.9555555556), + ("VTSP", 8.11305555556, 98.3166666667), + ("VTSR", 9.7775, 98.5852777778), + ("VTSS", 6.93305555556, 100.392777778), + ("VTST", 7.50861111111, 99.6163888889), + ("VTSY", 6.52666666667, 101.241944444), + ("VTUD", 17.3863888889, 102.788055556), + ("VTUI", 17.195, 104.118611111), + ("VTUJ", 14.8691666667, 103.488888889), + ("VTUL", 17.4388888889, 101.721944444), + ("VTUN", 14.9341666667, 102.078611111), + ("VTUP", 17.4125, 104.777222222), + ("VTUW", 17.3836111111, 104.642777778), + ("VVDN", 16.0438888889, 108.199166667), + ("VVNB", 21.2216666667, 105.805555556), + ("VVNT", 12.2180555556, 109.2), + ("VVTS", 10.82, 106.661666667), + ("VYBG", 21.1819444444, 94.9291666667), + ("VYBM", 24.2688888889, 97.2461111111), + ("VYCI", 14.1413888889, 93.3683333333), + ("VYDW", 14.0980555556, 98.2016666667), + ("VYHH", 20.7430555556, 96.7916666667), + ("VYKG", 21.3005555556, 99.6366666667), + ("VYKL", 23.1886111111, 94.0508333333), + ("VYKP", 19.4266666667, 93.5344444444), + ("VYKT", 10.0491666667, 98.5377777778), + ("VYLK", 19.6922222222, 97.2147222222), + ("VYLS", 22.9775, 97.7522222222), + ("VYLY", 20.9402777778, 94.8225), + ("VYMD", 21.7019444444, 95.9777777778), + ("VYME", 12.4433333333, 98.6211111111), + ("VYMK", 25.3825, 97.3527777778), + ("VYMM", 16.4447222222, 97.6605555556), + ("VYMO", 23.0925, 96.645), + ("VYMS", 20.5166666667, 99.2566666667), + ("VYNP", 25.3541666667, 97.295), + ("VYNS", 20.89, 97.7361111111), + ("VYPA", 16.8944444444, 97.6752777778), + ("VYPN", 16.8127777778, 94.7752777778), + ("VYPT", 27.3297222222, 97.4261111111), + ("VYPY", 18.8244444444, 95.2658333333), + ("VYST", 20.9416666667, 95.9144444444), + ("VYSW", 20.1325, 92.8725), + ("VYTD", 18.4605555556, 94.2994444444), + ("VYTL", 20.4836111111, 99.9352777778), + ("VYTO", 19.0311111111, 96.4013888889), + ("VYYY", 16.9072222222, 96.1330555556), + ("WAAA", -5.06166666667, 119.553888889), + ("WAAL", -4.31666666667, 122.466666667), + ("WAAM", -2.55777777778, 120.324166667), + ("WAAS", -2.52944444444, 121.357222222), + ("WAAT", -3.045, 119.821666667), + ("WAAU", -4.08222222222, 122.416666667), + ("WABB", -1.19, 136.107777778), + ("WABI", -3.36805555556, 135.496388889), + ("WABP", -4.52805555556, 136.887222222), + ("WAJJ", -2.57694444444, 140.516111111), + ("WAJW", -4.09611111111, 138.9525), + ("WAKK", -8.52027777778, 140.418333333), + ("WAMG", 0.636666666667, 122.851944444), + ("WAMH", 3.68305555556, 125.527777778), + ("WAML", -0.918333333333, 119.909444444), + ("WAMM", 1.54916666667, 124.926388889), + ("WAMP", -1.41666666667, 120.6575), + ("WAMT", 0.831944444444, 127.380555556), + ("WAMW", -1.03888888889, 122.771666667), + ("WAPL", -5.66138888889, 132.731388889), + ("WAPP", -3.70888888889, 128.09), + ("WASK", -3.64388888889, 133.695277778), + ("WASR", -0.88, 134.050277778), + ("WASS", -0.925833333333, 131.12), + ("WBGB", 3.17222222222, 113.044444444), + ("WBGG", 1.48472222222, 110.346388889), + ("WBGM", 4.17805555556, 114.331388889), + ("WBGR", 4.325, 113.988333333), + ("WBGS", 2.26388888889, 111.982777778), + ("WBKD", 5.03222222222, 118.323888889), + ("WBKK", 5.93722222222, 116.051111111), + ("WBKL", 5.30055555556, 115.25), + ("WBKW", 4.31333333333, 118.121944444), + ("WBSB", 4.94555555556, 114.927777778), + ("WIAA", 5.87388888889, 95.3394444444), + ("WIAM", -7.34555555556, 108.246388889), + ("WIAR", -7.61583333333, 111.433888889), + ("WIAS", -7.92611111111, 112.713888889), + ("WIBB", 0.461111111111, 101.444444444), + ("WIBD", 1.60916666667, 101.433333333), + ("WIIA", -6.29305555556, 106.569722222), + ("WIIB", -6.90055555556, 107.576111111), + ("WIIC", -6.75583333333, 108.539444444), + ("WIIH", -6.26638888889, 106.891111111), + ("WIII", -6.12555555556, 106.655833333), + ("WIIJ", -7.78805555556, 110.431944444), + ("WIIL", -7.645, 109.033888889), + ("WIIP", -6.33694444444, 106.764444444), + ("WIIS", -6.97305555556, 110.375277778), + ("WIIT", -5.24222222222, 105.178888889), + ("WIKB", 1.12083333333, 104.118611111), + ("WIKD", -2.74555555556, 107.754722222), + ("WIKK", -2.16277777778, 106.139166667), + ("WIKN", 0.9225, 104.532222222), + ("WIKS", -0.479166666667, 104.579166667), + ("WIMB", 1.16638888889, 97.7027777778), + ("WIME", 1.39916666667, 99.4319444444), + ("WIMG", -0.876111111111, 100.3525), + ("WIMM", 3.55805555556, 98.6716666667), + ("WIMS", 1.55472222222, 98.8902777778), + ("WIOG", -0.348611111111, 111.7475), + ("WIOK", -1.81638888889, 109.963333333), + ("WION", 3.90861111111, 108.387777778), + ("WIOO", -0.150555555556, 109.403888889), + ("WIOP", 0.835833333333, 112.935555556), + ("WIOS", 0.0636111111111, 111.474722222), + ("WIPA", -1.63777777778, 103.644166667), + ("WIPL", -3.86388888889, 102.340833333), + ("WIPP", -2.89777777778, 104.701111111), + ("WIPQ", -3.28583333333, 103.879444444), + ("WIPR", -0.352777777778, 102.334722222), + ("WIPU", -2.54222222222, 101.088333333), + ("WITL", 5.06944444444, 97.2591666667), + ("WITM", 5.22666666667, 96.9502777778), + ("WITT", 5.52333333333, 95.4202777778), + ("WMAP", 2.04138888889, 103.307222222), + ("WMBT", 2.81805555556, 104.16), + ("WMKA", 6.19388888889, 100.4025), + ("WMKB", 5.46583333333, 100.391111111), + ("WMKC", 6.16638888889, 102.293611111), + ("WMKD", 3.77527777778, 103.208888889), + ("WMKE", 4.53722222222, 103.426388889), + ("WMKF", 3.11222222222, 101.7025), + ("WMKI", 4.56777777778, 101.091944444), + ("WMKJ", 1.64111111111, 103.669444444), + ("WMKK", 2.74555555556, 101.709722222), + ("WMKL", 6.32972222222, 99.7286111111), + ("WMKM", 2.26333333333, 102.251388889), + ("WMKN", 5.3825, 103.103333333), + ("WMKP", 5.29694444444, 100.276666667), + ("WPDB", -9.30305555556, 125.286666667), + ("WPEC", -8.48527777778, 126.398888889), + ("WRBB", -3.44194444444, 114.761111111), + ("WRBC", -3.4125, 115.995555556), + ("WRBI", -2.705, 111.673055556), + ("WRBP", -2.225, 113.9425), + ("WRBS", -2.50111111111, 112.976944444), + ("WRKC", -8.64055555556, 122.236666667), + ("WRKE", -8.84888888889, 121.661944444), + ("WRKG", -8.59555555556, 120.4775), + ("WRKK", -10.1713888889, 123.671111111), + ("WRKO", -8.48611111111, 119.889166667), + ("WRLK", 2.15444444444, 117.432222222), + ("WRLL", -1.26805555556, 116.894444444), + ("WRLR", 3.32638888889, 117.566388889), + ("WRLS", -0.484444444444, 117.156944444), + ("WRLT", -0.0930555555556, 117.439166667), + ("WRRA", -8.56055555556, 116.094444444), + ("WRRB", -8.53944444444, 118.687222222), + ("WRRR", -8.74833333333, 115.167222222), + ("WRRS", -8.48888888889, 117.411944444), + ("WRRT", -9.40944444444, 119.246111111), + ("WRRW", -9.67, 120.303611111), + ("WRSJ", -7.37972222222, 112.786666667), + ("WRSQ", -7.51583333333, 110.756666667), + ("WSAG", 1.42361111111, 103.811388889), + ("WSAP", 1.36027777778, 103.909444444), + ("WSAT", 1.38722222222, 103.708611111), + ("WSSL", 1.41694444444, 103.8675), + ("WSSS", 1.35555555556, 103.987222222), + ("YBAF", -27.5702777778, 153.008055556), + ("YBAM", -10.9508333333, 142.459444444), + ("YBAS", -23.8069444444, 133.902222222), + ("YBBN", -27.3841666667, 153.1175), + ("YBCG", -28.1644444444, 153.504722222), + ("YBCS", -16.8858333333, 145.755277778), + ("YBCV", -26.4133333333, 146.2625), + ("YBMA", -20.6638888889, 139.488611111), + ("YBMC", -26.6033333333, 153.091111111), + ("YBMK", -21.1716666667, 149.179722222), + ("YBOK", -27.4113888889, 151.735277778), + ("YBPN", -20.495, 148.552222222), + ("YBRK", -23.3819444444, 150.475277778), + ("YBTL", -19.2525, 146.765277778), + ("YBWP", -12.6786111111, 141.925277778), + ("YMAV", -38.0394444444, 144.469444444), + ("YMAY", -36.0677777778, 146.958055556), + ("YMEN", -37.7280555556, 144.901944444), + ("YMES", -38.0988888889, 147.149444444), + ("YMHB", -42.8361111111, 147.510277778), + ("YMLT", -41.5452777778, 147.214166667), + ("YMMB", -37.9758333333, 145.102222222), + ("YMML", -37.6733333333, 144.843333333), + ("YMPC", -37.9322222222, 144.753333333), + ("YPAD", -34.945, 138.530555556), + ("YPAG", -32.5069444444, 137.716666667), + ("YPED", -34.7025, 138.620833333), + ("YPJT", -32.0972222222, 115.881111111), + ("YPKA", -20.7122222222, 116.773333333), + ("YPKG", -30.7894444444, 121.461666667), + ("YPKU", -15.7780555556, 128.7075), + ("YPLM", -22.2355555556, 114.088611111), + ("YPPD", -20.3777777778, 118.626388889), + ("YPPF", -34.7933333333, 138.633055556), + ("YPPH", -31.9402777778, 115.966944444), + ("YPWR", -31.1441666667, 136.816944444), + ("YPXM", -10.4505555556, 105.690277778), + ("YSBK", -33.9244444444, 150.988333333), + ("YSCB", -35.3083333333, 149.193888889), + ("YSCH", -30.3205555556, 153.116388889), + ("YSCN", -34.0402777778, 150.687222222), + ("YSDU", -32.2166666667, 148.574722222), + ("YSNF", -29.0413888889, 167.938611111), + ("YSRI", -33.6005555556, 150.780833333), + ("YSSY", -33.9461111111, 151.177222222), + ("YSTW", -31.0838888889, 150.846666667), + ("YSWG", -35.1652777778, 147.466388889), + ("ZBAA", 40.08, 116.584444444), + ("ZBHH", 40.8533333333, 111.821666667), + ("ZBLA", 49.205, 119.825), + ("ZBSJ", 38.2805555556, 114.696388889), + ("ZBTJ", 39.1238888889, 117.346111111), + ("ZBYN", 37.7466666667, 112.628611111), + ("ZGGG", 23.1841666667, 113.265833333), + ("ZGHA", 28.1888888889, 113.219444444), + ("ZGKL", 25.2177777778, 110.039166667), + ("ZGNN", 22.6080555556, 108.172222222), + ("ZGOW", 23.4, 116.683333333), + ("ZGSZ", 22.6394444444, 113.812222222), + ("ZHCC", 34.5194444444, 113.840833333), + ("ZHHH", 30.7836111111, 114.208055556), + ("ZHYC", 30.5522222222, 111.468611111), + ("ZKPY", 39.0333333333, 125.783333333), + ("ZLLL", 36.5166666667, 103.621666667), + ("ZLXY", 34.4458333333, 108.7525), + ("ZMUB", 47.8430555556, 106.766388889), + ("ZPJH", 21.975, 100.76), + ("ZPPP", 24.9922222222, 102.743333333), + ("ZSAM", 24.5438888889, 118.1275), + ("ZSCN", 28.6, 115.916666667), + ("ZSFZ", 25.9333333333, 119.661666667), + ("ZSHC", 30.2283333333, 120.431666667), + ("ZSNB", 29.8247222222, 121.465), + ("ZSNJ", 31.74, 118.86), + ("ZSOF", 31.78, 117.298333333), + ("ZSQD", 36.2625, 120.375277778), + ("ZSSS", 31.1977777778, 121.336111111), + ("ZSYT", 37.4016666667, 121.371666667), + ("ZUCK", 29.7188888889, 106.641388889), + ("ZUUU", 30.5783333333, 103.946944444), + ("ZUXC", 27.9886111111, 102.184166667), + ("ZWSH", 39.5433333333, 76.0216666667), + ("ZWTN", 37.0377777778, 79.8658333333), + ("ZWWW", 43.9069444444, 87.4741666667), + ("ZYHB", 45.6233333333, 126.250277778), + ("ZYJM", 46.8433333333, 130.465277778), + ("ZYMD", 44.5238888889, 129.568888889), + ("ZYTL", 38.9655555556, 121.538333333), + ("ZYYJ", 42.8816666667, 129.448333333) +) diff --git a/irc.py b/irc.py new file mode 100755 index 0000000..5916396 --- /dev/null +++ b/irc.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +""" +irc.py - A Utility IRC Bot +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import sys, re, time, traceback +import socket, asyncore, asynchat + +class Origin(object): + source = re.compile(r'([^!]*)!?([^@]*)@?(.*)') + + def __init__(self, bot, source, args): + match = Origin.source.match(source or '') + self.nick, self.user, self.host = match.groups() + + if len(args) > 1: + target = args[1] + else: target = None + + mappings = {bot.nick: self.nick, None: None} + self.sender = mappings.get(target, target) + +class Bot(asynchat.async_chat): + def __init__(self, nick, name, channels): + asynchat.async_chat.__init__(self) + self.set_terminator('\n') + self.buffer = '' + + self.nick = nick + self.user = nick + self.name = name + + self.verbose = True + self.channels = channels or [] + self.stack = [] + + import threading + self.sending = threading.RLock() + + def write(self, args, text=None): + if text is not None: + self.push(' '.join(args) + ' :' + text + '\r\n') + else: self.push(' '.join(args) + '\r\n') + + def run(self, host, port=6667): + self.initiate_connect(host, port) + + def initiate_connect(self, host, port): + if self.verbose: + message = 'Connecting to %s:%s...' % (host, port) + print >> sys.stderr, message, + self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + self.connect((host, port)) + asyncore.loop() + + def handle_connect(self): + if self.verbose: + print >> sys.stderr, 'connected!' + self.write(('NICK', self.nick)) + self.write(('USER', self.user, '+iw', self.nick), self.name) + + def handle_close(self): + self.close() + print >> sys.stderr, 'Closed!' + + def collect_incoming_data(self, data): + self.buffer += data + + def found_terminator(self): + line = self.buffer + if line.endswith('\r'): + line = line[:-1] + self.buffer = '' + + # print line + if line.startswith(':'): + source, line = line[1:].split(' ', 1) + else: source = None + + if ' :' in line: + argstr, text = line.split(' :', 1) + else: argstr, text = line, '' + args = argstr.split() + + origin = Origin(self, source, args) + self.dispatch(origin, tuple([text] + args)) + + if args[0] == 'PING': + self.write(('PONG', text)) + + def dispatch(self, origin, args): + pass + + def msg(self, recipient, text): + self.sending.acquire() + + # Cf. http://swhack.com/logs/2006-03-01#T19-43-25 + if isinstance(text, unicode): + try: text = text.encode('utf-8') + except UnicodeEncodeError, e: + text = e.__class__ + ': ' + str(e) + + # No messages within the last 3 seconds? Go ahead! + # Otherwise, wait so it's been at least 0.8 seconds + penalty + if self.stack: + elapsed = time.time() - self.stack[-1][0] + if elapsed < 3: + penalty = float(max(0, len(text) - 50)) / 70 + wait = 0.8 + penalty + if elapsed < wait: + time.sleep(wait - elapsed) + + # Loop detection + messages = [m[1] for m in self.stack[-5:]] + if messages.count(text) >= 3: + text = '...' + if messages.count('...') >= 1: + self.sending.release() + return + + self.write(('PRIVMSG', recipient), text) + self.stack.append((time.time(), text)) + self.stack = self.stack[-10:] + + self.sending.release() + + def notice(self, dest, text): + self.write(('NOTICE', dest), text) + + def error(self, origin): + try: + import traceback + trace = traceback.format_exc() + print trace + lines = list(reversed(trace.splitlines())) + + report = [lines[0].strip()] + for line in lines: + line = line.strip() + if line.startswith('File "/'): + report.append(line[0].lower() + line[1:]) + break + else: report.append('source unknown') + + self.msg(origin.sender, report[0] + ' (' + report[1] + ')') + except: self.msg(origin.sender, "Got an error.") + +class TestBot(Bot): + def f_ping(self, origin, match, args): + delay = m.group(1) + if delay is not None: + import time + time.sleep(int(delay)) + self.msg(origin.sender, 'pong (%s)' % delay) + else: self.msg(origin.sender, 'pong') + f_ping.rule = r'^\.ping(?:[ \t]+(\d+))?$' + +def main(): + # bot = TestBot('testbot', ['#d8uv.com']) + # bot.run('irc.freenode.net') + print __doc__ + +if __name__=="__main__": + main() diff --git a/modules/__init__.py b/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/modules/admin.py b/modules/admin.py new file mode 100644 index 0000000..de2a7a7 --- /dev/null +++ b/modules/admin.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +""" +admin.py - Phenny Admin Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +def join(phenny, input): + # Can only be done in privmsg by an admin + if input.sender.startswith('#'): return + if input.admin: + phenny.write(['JOIN'], input.group(2)) +join.commands = ['join'] +join.priority = 'low' + +def part(phenny, input): + # Can only be done in privmsg by an admin + if input.sender.startswith('#'): return + if input.admin: + phenny.write(['PART'], input.group(2)) +part.commands = ['part'] +part.priority = 'low' + +def quit(phenny, input): + # Can only be done in privmsg by the owner + if input.sender.startswith('#'): return + if input.owner: + phenny.write(['QUIT']) + __import__('os')._exit(0) +quit.commands = ['quit'] +quit.priority = 'low' + +def msg(phenny, input): + # Can only be done in privmsg by an admin + if input.sender.startswith('#'): return + if input.admin: + phenny.msg(input.group(2), input.group(3)) +msg.rule = (['msg'], r'(#\S+) (.*)') +msg.priority = 'low' + +def me(phenny, input): + # Can only be done in privmsg by an admin + if input.sender.startswith('#'): return + if input.admin: + msg = '\x01ACTION %s\x01' % input.group(3) + phenny.msg(input.group(2), msg) +me.rule = (['me'], r'(#\S+) (.*)') +me.priority = 'low' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/clock.py b/modules/clock.py new file mode 100755 index 0000000..210f8fb --- /dev/null +++ b/modules/clock.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python +""" +clock.py - Phenny Clock Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import math, time, urllib +from tools import deprecated + +TimeZones = {'KST': 9, 'CADT': 10.5, 'EETDST': 3, 'MESZ': 2, 'WADT': 9, + 'EET': 2, 'MST': -7, 'WAST': 8, 'IST': 5.5, 'B': 2, + 'MSK': 3, 'X': -11, 'MSD': 4, 'CETDST': 2, 'AST': -4, + 'HKT': 8, 'JST': 9, 'CAST': 9.5, 'CET': 1, 'CEST': 2, + 'EEST': 3, 'EAST': 10, 'METDST': 2, 'MDT': -6, 'A': 1, + 'UTC': 0, 'ADT': -3, 'EST': -5, 'E': 5, 'D': 4, 'G': 7, + 'F': 6, 'I': 9, 'H': 8, 'K': 10, 'PDT': -7, 'M': 12, + 'L': 11, 'O': -2, 'MEST': 2, 'Q': -4, 'P': -3, 'S': -6, + 'R': -5, 'U': -8, 'T': -7, 'W': -10, 'WET': 0, 'Y': -12, + 'CST': -6, 'EADT': 11, 'Z': 0, 'GMT': 0, 'WETDST': 1, + 'C': 3, 'WEST': 1, 'CDT': -5, 'MET': 1, 'N': -1, 'V': -9, + 'EDT': -4, 'UT': 0, 'PST': -8, 'MEZ': 1, 'BST': 1, + 'ACS': 9.5, 'ATL': -4, 'ALA': -9, 'HAW': -10, 'AKDT': -8, + 'AKST': -9, + 'BDST': 2} + +TZ1 = { + 'NDT': -2.5, + 'BRST': -2, + 'ADT': -3, + 'EDT': -4, + 'CDT': -5, + 'MDT': -6, + 'PDT': -7, + 'YDT': -8, + 'HDT': -9, + 'BST': 1, + 'MEST': 2, + 'SST': 2, + 'FST': 2, + 'CEST': 2, + 'EEST': 3, + 'WADT': 8, + 'KDT': 10, + 'EADT': 13, + 'NZD': 13, + 'NZDT': 13, + 'GMT': 0, + 'UT': 0, + 'UTC': 0, + 'WET': 0, + 'WAT': -1, + 'AT': -2, + 'FNT': -2, + 'BRT': -3, + 'MNT': -4, + 'EWT': -4, + 'AST': -4, + 'EST': -5, + 'ACT': -5, + 'CST': -6, + 'MST': -7, + 'PST': -8, + 'YST': -9, + 'HST': -10, + 'CAT': -10, + 'AHST': -10, + 'NT': -11, + 'IDLW': -12, + 'CET': 1, + 'MEZ': 1, + 'ECT': 1, + 'MET': 1, + 'MEWT': 1, + 'SWT': 1, + 'SET': 1, + 'FWT': 1, + 'EET': 2, + 'UKR': 2, + 'BT': 3, + 'ZP4': 4, + 'ZP5': 5, + 'ZP6': 6, + 'WST': 8, + 'HKT': 8, + 'CCT': 8, + 'JST': 9, + 'KST': 9, + 'EAST': 10, + 'GST': 10, + 'NZT': 12, + 'NZST': 12, + 'IDLE': 12 +} + +TZ2 = { + 'ACDT': -10.5, + 'ACST': -9.5, + 'ADT': 3, + 'AEDT': 11, # hmm + 'AEST': 10, # hmm + 'AHDT': 9, + 'AHST': 10, + 'AST': 4, + 'AT': 2, + 'AWDT': -9, + 'AWST': -8, + 'BAT': -3, + 'BDST': -2, + 'BET': 11, + 'BST': -1, + 'BT': -3, + 'BZT2': 3, + 'CADT': -10.5, + 'CAST': -9.5, + 'CAT': 10, + 'CCT': -8, + # 'CDT': 5, + 'CED': -2, + 'CET': -1, + 'CST': 6, + 'EAST': -10, + # 'EDT': 4, + 'EED': -3, + 'EET': -2, + 'EEST': -3, + 'EST': 5, + 'FST': -2, + 'FWT': -1, + 'GMT': 0, + 'GST': -10, + 'HDT': 9, + 'HST': 10, + 'IDLE': -12, + 'IDLW': 12, + 'IST': -5.5, + 'IT': -3.5, + 'JST': -9, + 'JT': -7, + 'KST': -9, + 'MDT': 6, + 'MED': -2, + 'MET': -1, + 'MEST': -2, + 'MEWT': -1, + 'MST': 7, + 'MT': -8, + 'NDT': 2.5, + 'NFT': 3.5, + 'NT': 11, + 'NST': -6.5, + 'NZ': -11, + 'NZST': -12, + 'NZDT': -13, + 'NZT': -12, + # 'PDT': 7, + 'PST': 8, + 'ROK': -9, + 'SAD': -10, + 'SAST': -9, + 'SAT': -9, + 'SDT': -10, + 'SST': -2, + 'SWT': -1, + 'USZ3': -4, + 'USZ4': -5, + 'USZ5': -6, + 'USZ6': -7, + 'UT': 0, + 'UTC': 0, + 'UZ10': -11, + 'WAT': 1, + 'WET': 0, + 'WST': -8, + 'YDT': 8, + 'YST': 9, + 'ZP4': -4, + 'ZP5': -5, + 'ZP6': -6 +} + +TimeZones.update(TZ2) +TimeZones.update(TZ1) + +@deprecated +def f_time(self, origin, match, args): + """.t [ ] - Returns the current time""" + tz = match.group(1) or 'GMT' + + # Personal time zones, because they're rad + if hasattr(self.config, 'timezones'): + People = self.config.timezones + else: People = {} + + if People.has_key(tz): + tz = People[tz] + elif (not match.group(1)) and People.has_key(origin.nick): + tz = People[origin.nick] + + TZ = tz.upper() + if len(tz) > 30: return + + if (TZ == 'UTC') or (TZ == 'Z'): + msg = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) + self.msg(origin.sender, msg) + elif TimeZones.has_key(TZ): + offset = TimeZones[TZ] * 3600 + timenow = time.gmtime(time.time() + offset) + msg = time.strftime("%a, %d %b %Y %H:%M:%S " + str(TZ), timenow) + self.msg(origin.sender, msg) + elif tz and tz[0] in ('+', '-') and 4 <= len(tz) <= 6: + timenow = time.gmtime(time.time() + (int(tz[:3]) * 3600)) + msg = time.strftime("%a, %d %b %Y %H:%M:%S " + str(tz), timenow) + self.msg(origin.sender, msg) + else: + try: t = float(tz) + except ValueError: + import os, re, subprocess + r_tz = re.compile(r'^[A-Za-z]+(?:/[A-Za-z_]+)*$') + if r_tz.match(tz) and os.path.isfile('/usr/share/zoneinfo/' + tz): + cmd, PIPE = 'TZ=%s date' % tz, subprocess.PIPE + proc = subprocess.Popen(cmd, shell=True, stdout=PIPE) + self.msg(origin.sender, proc.communicate()[0]) + else: + error = "Sorry, I don't know about the '%s' timezone." % tz + self.msg(origin.sender, origin.nick + ': ' + error) + else: + timenow = time.gmtime(time.time() + (t * 3600)) + msg = time.strftime("%a, %d %b %Y %H:%M:%S " + str(tz), timenow) + self.msg(origin.sender, msg) +f_time.commands = ['t'] + +def beats(phenny, input): + beats = ((time.time() + 3600) % 86400) / 86.4 + beats = int(math.floor(beats)) + phenny.say('@%03i' % beats) +beats.commands = ['beats'] +beats.priority = 'low' + +def divide(input, by): + return (input / by), (input % by) + +def yi(phenny, input): + quadraels, remainder = divide(int(time.time()), 1753200) + raels = quadraels * 4 + extraraels, remainder = divide(remainder, 432000) + if extraraels == 4: + return phenny.say('Yes!') + else: phenny.say('Not yet...') +yi.commands = ['yi'] +yi.priority = 'low' + +# d8uv d8uv d8uv d8uv d8uv d8uv d8uv + +def tock(phenny, input): + u = urllib.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') + info = u.info() + u.close() + phenny.say('"' + info['Date'] + '" - tycho.usno.navy.mil') +tock.commands = ['tock'] +tock.priority = 'high' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/codepoints.py b/modules/codepoints.py new file mode 100644 index 0000000..83425c5 --- /dev/null +++ b/modules/codepoints.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +""" +codepoints.py - Phenny Codepoints Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re, unicodedata +from itertools import islice + +def about(u, cp=None, name=None): + if cp is None: cp = ord(u) + if name is None: name = unicodedata.name(u) + + if not unicodedata.combining(u): + template = 'U+%04X %s (%s)' + else: template = 'U+%04X %s (\xe2\x97\x8c%s)' + return template % (cp, name, u.encode('utf-8')) + +def codepoint_simple(arg): + arg = arg.upper() + r_label = re.compile('\\b' + arg.replace(' ', '.*\\b')) + + results = [] + for cp in xrange(0xFFFF): + u = unichr(cp) + try: name = unicodedata.name(u) + except ValueError: continue + + if r_label.search(name): + results.append((len(name), u, cp, name)) + if not results: + return None + + length, u, cp, name = sorted(results)[0] + return about(u, cp, name) + +def codepoint_extended(arg): + arg = arg.upper() + try: r_search = re.compile(arg) + except: raise ValueError('Broken regexp: %r' % arg) + + for cp in xrange(1, 0x10FFFF): + u = unichr(cp) + name = unicodedata.name(u, '-') + + if r_search.search(name): + yield about(u, cp, name) + +def u(phenny, input): + arg = input.bytes[3:] + + ascii = True + for c in arg: + if ord(c) >= 0x80: + ascii = False + + if ascii: + if set(arg.upper()) - set('ABCDEFGHIJKLMNOPQRSTUVWXYZ '): + extended = True + else: extended = False + + if extended: + # look up a codepoint with regexp + results = list(islice(codepoint_extended(arg), 4)) + for i, result in enumerate(results): + if (i < 2) or ((i == 2) and (len(results) < 4)): + phenny.say(result) + elif (i == 2) and (len(results) > 3): + phenny.say(result + ' [...]') + else: + # look up a codepoint freely + result = codepoint_simple(arg) + if result is not None: + phenny.say(result) + else: phenny.reply("Sorry, no results for %r." % arg) + else: + text = arg.decode('utf-8') + # look up less than three podecoints + if len(text) <= 3: + for u in text: + phenny.say(about(u)) + # look up more than three podecoints + elif len(text) <= 8: + phenny.reply(' '.join('U+%04X' % ord(c) for c in text)) + else: phenny.reply('Sorry, your input is too long!') +u.commands = ['u'] diff --git a/modules/etymology.py b/modules/etymology.py new file mode 100755 index 0000000..ecdbb7b --- /dev/null +++ b/modules/etymology.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +""" +etymology.py - Phenny Etymology Module +Copyright 2007, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re +import web +from tools import deprecated + +etyuri = 'http://etymonline.com/?term=%s' +etysearch = 'http://etymonline.com/?search=%s' + +r_definition = re.compile(r'(?ims)]*>.*?') +r_tag = re.compile(r'<(?!!)[^>]+>') +r_whitespace = re.compile(r'[\t\r\n ]+') + +abbrs = [ + 'cf', 'lit', 'etc', 'Ger', 'Du', 'Skt', 'Rus', 'Eng', 'Amer.Eng', 'Sp', + 'Fr', 'N', 'E', 'S', 'W', 'L', 'Gen', 'J.C', 'dial', 'Gk', + '19c', '18c', '17c', '16c', 'St', 'Capt' +] +t_sentence = r'^.*?(?') + s = s.replace('<', '<') + s = s.replace('&', '&') + return s + +def text(html): + html = r_tag.sub('', html) + html = r_whitespace.sub(' ', html) + return unescape(html).strip() + +def etymology(word): + # @@ sbp, would it be possible to have a flag for .ety to get 2nd/etc + # entries? - http://swhack.com/logs/2006-07-19#T15-05-29 + + if len(word) > 25: + raise ValueError("Word too long: %s[...]" % word[:10]) + word = {'axe': 'ax/axe'}.get(word, word) + + bytes = web.get(etyuri % word) + definitions = r_definition.findall(bytes) + + if not definitions: + return None + + defn = text(definitions[0]) + m = r_sentence.match(defn) + if not m: + return None + sentence = m.group(0) + + try: + sentence = unicode(sentence, 'iso-8859-1') + sentence = sentence.encode('utf-8') + except: pass + + maxlength = 275 + if len(sentence) > maxlength: + sentence = sentence[:maxlength] + words = sentence[:-5].split(' ') + words.pop() + sentence = ' '.join(words) + ' [...]' + + sentence = '"' + sentence.replace('"', "'") + '"' + return sentence + ' - ' + (etyuri % word) + +@deprecated +def f_etymology(self, origin, match, args): + word = match.group(2) + + try: result = etymology(word) + except IOError: + msg = "Can't connect to etymonline.com (%s)" % (etyuri % word) + self.msg(origin.sender, msg) + return + + if result is not None: + if (origin.sender == '#esp') and (origin.nick == 'nsh'): + self.msg(origin.nick, result) + note = 'nsh: see privmsg (yes, this only happens for you)' + self.msg(origin.sender, note) + else: self.msg(origin.sender, result) + else: + uri = etysearch % word + msg = 'Can\'t find the etymology for "%s". Try %s' % (word, uri) + self.msg(origin.sender, msg) +# @@ Cf. http://swhack.com/logs/2006-01-04#T01-50-22 +f_etymology.rule = (['ety'], r"([A-Za-z0-9' -]+)") +f_etymology.thread = True +f_etymology.priority = 'high' + +if __name__=="__main__": + import sys + print etymology(sys.argv[1]) diff --git a/modules/head.py b/modules/head.py new file mode 100755 index 0000000..4b75cb4 --- /dev/null +++ b/modules/head.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +""" +head.py - Phenny HTTP Metadata Utilities +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re, urllib +from htmlentitydefs import name2codepoint +import web +from tools import deprecated + +@deprecated +def f_httphead(self, origin, match, args): + """.head ? - Perform an HTTP HEAD on URI.""" + if origin.sender == '#talis': return + uri = match.group(2) + header = match.group(3) + + try: info = web.head(uri) + except IOError: + self.msg(origin.sender, "Can't connect to %s" % uri) + return + + if not isinstance(info, list): + info = dict(info) + info['Status'] = '200' + else: + newInfo = dict(info[0]) + newInfo['Status'] = str(info[1]) + info = newInfo + + if header is None: + msg = 'Status: %s (for more, try ".head uri header")' % info['Status'] + self.msg(origin.sender, msg) + else: + headerlower = header.lower() + if info.has_key(headerlower): + self.msg(origin.sender, header + ': ' + info.get(headerlower)) + else: + msg = 'There was no %s header in the response.' % header + self.msg(origin.sender, msg) +f_httphead.rule = (['head'], r'(\S+)(?: +(\S+))?') +f_httphead.thread = True + +r_title = re.compile(r'(?ims)]*>(.*?)') +r_entity = re.compile(r'&[A-Za-z0-9#]+;') + +@deprecated +def f_title(self, origin, match, args): + """.title - Return the title of URI.""" + uri = match.group(2) + if not ':' in uri: + uri = 'http://' + uri + + try: + redirects = 0 + while True: + info = web.head(uri) + + if not isinstance(info, list): + status = '200' + else: + status = str(info[1]) + info = info[0] + if status.startswith('3'): + uri = info['Location'] + else: break + + redirects += 1 + if redirects >= 25: + self.msg(origin.sender, origin.nick + ": Too many redirects") + return + + try: mtype = info['Content-Type'] + except: + self.msg(origin.sender, origin.nick + ": Document isn't HTML") + return + if not (('/html' in mtype) or ('/xhtml' in mtype)): + self.msg(origin.sender, origin.nick + ": Document isn't HTML") + return + + u = urllib.urlopen(uri) + bytes = u.read(32768) + u.close() + + except IOError: + self.msg(origin.sender, "Can't connect to %s" % uri) + return + + m = r_title.search(bytes) + if m: + title = m.group(1) + title = title.strip() + title = title.replace('\t', ' ') + title = title.replace('\r', ' ') + title = title.replace('\n', ' ') + while ' ' in title: + title = title.replace(' ', ' ') + if len(title) > 200: + title = title[:200] + '[...]' + + def e(m): + entity = m.group(0) + if entity.startswith('&#x'): + cp = int(entity[3:-1], 16) + return unichr(cp).encode('utf-8') + elif entity.startswith('&#'): + cp = int(entity[2:-1]) + return unichr(cp).encode('utf-8') + else: + char = name2codepoint[entity[1:-1]] + return unichr(char).encode('utf-8') + title = r_entity.sub(e, title) + + if not title: + title = '[Title is the empty document, "".]' + self.msg(origin.sender, origin.nick + ': ' + title) + else: self.msg(origin.sender, origin.nick + ': No title found') +f_title.rule = (['title'], r'(\S+)') +f_title.thread = True + +if __name__ == '__main__': + print __doc__ diff --git a/modules/info.py b/modules/info.py new file mode 100644 index 0000000..a70c823 --- /dev/null +++ b/modules/info.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +""" +info.py - Phenny Information Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +def doc(phenny, input): + """Shows a command's documentation, and possibly an example.""" + name = input.group(1) + name = name.lower() + + if phenny.doc.has_key(name): + phenny.reply(phenny.doc[name][0]) + if phenny.doc[name][1]: + phenny.say('e.g. ' + phenny.doc[name][1]) +doc.rule = ('$nick', '(?i)help +([A-Za-z]+)(?:\?+)?$') +doc.example = '$nickname: help tell?' +doc.priority = 'low' + +def commands(phenny, input): + # This function only works in private message + if input.startswith('#'): return + names = ', '.join(sorted(phenny.doc.iterkeys())) + phenny.say('Commands I recognise: ' + names + '.') + phenny.say(("For help, do '%s: help example?' where example is the " + + "name of the command you want help for.") % phenny.nick) +commands.commands = ['commands'] +commands.priority = 'low' + +def help(phenny, input): + response = ( + 'Hi, I\'m a bot. Say ".commands" to me in private for a list ' + + 'of my commands, or see http://inamidst.com/phenny/ for more ' + + 'general details. My owner is %s.' + ) % phenny.config.owner + phenny.reply(response) +help.rule = ('$nick', r'(?i)help(?:[?!]+)?$') +help.priority = 'low' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/ping.py b/modules/ping.py new file mode 100755 index 0000000..97e41e1 --- /dev/null +++ b/modules/ping.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +""" +ping.py - Phenny Ping Module +Author: Sean B. Palmer, inamidst.com +About: http://inamidst.com/phenny/ +""" + +import random + +def hello(phenny, input): + greeting = random.choice(('Hi', 'Hey', 'Hello')) + punctuation = random.choice(('', '!')) + phenny.say(greeting + ' ' + input.nick + punctuation) +hello.rule = r'(?i)(hi|hello|hey) $nickname\b' + +def interjection(phenny, input): + phenny.say(input.nick + '!') +interjection.rule = r'$nickname!' +interjection.priority = 'high' +interjection.thread = False + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/reload.py b/modules/reload.py new file mode 100755 index 0000000..257eaf7 --- /dev/null +++ b/modules/reload.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +""" +reload.py - Phenny Module Reloader Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import irc + +def f_reload(phenny, input): + """Reloads a module, for use by admins only.""" + if not input.admin: return + + name = match.group(2) + module = getattr(__import__('modules.' + name), name) + reload(module) + + if hasattr(module, '__file__'): + import os.path, time + mtime = os.path.getmtime(module.__file__) + modified = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(mtime)) + else: modified = 'unknown' + + self.register(vars(module)) + self.bind_commands() + + phenny.reply('%r (version: %s)' % (module, modified)) +f_reload.name = 'reload' +f_reload.rule = ('$nick', ['reload'], r'(\S+)') + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/search.py b/modules/search.py new file mode 100755 index 0000000..9ad1a04 --- /dev/null +++ b/modules/search.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +""" +search.py - Phenny Web Search Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re +import web + +r_string = re.compile(r'("(\\.|[^"\\])*")') +r_json = re.compile(r'^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]+$') +env = {'__builtins__': None, 'null': None, 'true': True, 'false': False} + +def json(text): + """Evaluate JSON text safely (we hope).""" + if r_json.match(r_string.sub('', text)): + text = r_string.sub(lambda m: 'u' + m.group(1), text) + return eval(text.strip(' \t\r\n'), env, {}) + raise ValueError('Input must be serialised JSON.') + +def search(query, n=1): + """Search using SearchMash, return its JSON.""" + q = web.urllib.quote(query.encode('utf-8')) + uri = 'http://www.searchmash.com/results/' + q + '?n=' + str(n) + bytes = web.get(uri) + return json(bytes) + +def result(query): + results = search(query) + return results['results'][0]['url'] + +def count(query): + results = search(query) + return results['estimatedCount'] + +def formatnumber(n): + """Format a number with beautiful commas.""" + parts = list(str(n)) + for i in range((len(parts) - 3), 0, -3): + parts.insert(i, ',') + return ''.join(parts) + +def g(phenny, input): + uri = result(input.group(2)) + phenny.reply(uri) +g.commands = ['g'] +g.priority = 'high' + +def gc(phenny, input): + query = input.group(2) + num = count(query) + phenny.say(query + ': ' + num) +gc.commands = ['gc'] +gc.priority = 'high' + +r_query = re.compile( + r'\+?"[^"\\]*(?:\\.[^"\\]*)*"|\[[^]\\]*(?:\\.[^]\\]*)*\]|\S+' +) + +def compare(phenny, input): + queries = r_query.findall(input.group(2)) + if len(queries) > 6: + return phenny.reply('Sorry, can only compare up to six things.') + + results = [] + for i, query in enumerate(queries): + query = query.strip('[]') + n = int((count(query) or '0').replace(',', '')) + results.append((n, query)) + if i >= 2: __import__('time').sleep(0.25) + if i >= 4: __import__('time').sleep(0.25) + + results = [(term, n) for (n, term) in reversed(sorted(results))] + reply = ', '.join('%s (%s)' % (t, formatnumber(n)) for (t, n) in results) + phenny.say(reply) +compare.commands = ['gco', 'comp'] + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/seen.py b/modules/seen.py new file mode 100755 index 0000000..189be61 --- /dev/null +++ b/modules/seen.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +""" +seen.py - Phenny Seen Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import time +from tools import deprecated + +@deprecated +def f_seen(self, origin, match, args): + """.seen - Reports when was last seen.""" + if origin.sender == '#talis': return + nick = match.group(2).lower() + if not hasattr(self, 'seen'): + return self.msg(origin.sender, '?') + if self.seen.has_key(nick): + channel, t = self.seen[nick] + t = time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime(t)) + + msg = "I last saw %s at %s on %s" % (nick, t, channel) + self.msg(origin.sender, str(origin.nick) + ': ' + msg) + else: self.msg(origin.sender, "Sorry, I haven't seen %s around." % nick) +f_seen.rule = (['seen'], r'(\S+)') + +@deprecated +def f_note(self, origin, match, args): + def note(self, origin, match, args): + if not hasattr(self.bot, 'seen'): + self.bot.seen = {} + if origin.sender.startswith('#'): + # if origin.sender == '#inamidst': return + self.seen[origin.nick.lower()] = (origin.sender, time.time()) + + # if not hasattr(self, 'chanspeak'): + # self.chanspeak = {} + # if (len(args) > 2) and args[2].startswith('#'): + # self.chanspeak[args[2]] = args[0] + + try: note(self, origin, match, args) + except Exception, e: print e +f_note.rule = r'(.*)' +f_note.priority = 'low' + +if __name__ == '__main__': + print __doc__ diff --git a/modules/startup.py b/modules/startup.py new file mode 100644 index 0000000..1fd7348 --- /dev/null +++ b/modules/startup.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +""" +startup.py - Phenny Startup Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +def startup(phenny, input): + if hasattr(phenny.config, 'password'): + phenny.msg('NickServ', 'IDENTIFY %s' % phenny.config.password) + __import__('time').sleep(5) + + # Cf. http://swhack.com/logs/2005-12-05#T19-32-36 + for channel in phenny.channels: + phenny.write(('JOIN', channel)) +startup.rule = r'(.*)' +startup.event = '251' +startup.priority = 'low' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/tell.py b/modules/tell.py new file mode 100755 index 0000000..3b487c8 --- /dev/null +++ b/modules/tell.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python +""" +tell.py - Phenny Tell and Ask Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import os, re, time, random +import web + +maximum = 4 +lispchannels = frozenset([ '#lisp', '#scheme', '#opendarwin', '#macdev', +'#fink', '#jedit', '#dylan', '#emacs', '#xemacs', '#colloquy', '#adium', +'#growl', '#chicken', '#quicksilver', '#svn', '#slate', '#squeak', '#wiki', +'#nebula', '#myko', '#lisppaste', '#pearpc', '#fpc', '#hprog', +'#concatenative', '#slate-users', '#swhack', '#ud', '#t', '#compilers', +'#erights', '#esp', '#scsh', '#sisc', '#haskell', '#rhype', '#sicp', '#darcs', +'#hardcider', '#lisp-it', '#webkit', '#launchd', '#mudwalker', '#darwinports', +'#muse', '#chatkit', '#kowaleba', '#vectorprogramming', '#opensolaris', +'#oscar-cluster', '#ledger', '#cairo', '#idevgames', '#hug-bunny', '##parsers', +'#perl6', '#sdlperl', '#ksvg', '#rcirc', '#code4lib', '#linux-quebec', +'#programmering', '#maxima', '#robin', '##concurrency', '#paredit' ]) + +def loadReminders(fn): + result = {} + f = open(fn) + for line in f: + line = line.strip() + if line: + tellee, teller, verb, timenow, msg = line.split('\t', 4) + result.setdefault(tellee, []).append((teller, verb, timenow, msg)) + f.close() + return result + +def dumpReminders(fn, data): + f = open(fn, 'w') + for tellee in data.iterkeys(): + for remindon in data[tellee]: + line = '\t'.join((tellee,) + remindon) + f.write(line + '\n') + f.close() + return True + +def setup(self): + fn = self.nick + '-' + self.config.host + '.tell.db' + self.tell_filename = os.path.join(os.path.expanduser('~/.phenny'), fn) + if not os.path.exists(self.tell_filename): + try: f = open(self.tell_filename, 'w') + except OSError: pass + else: + f.write('') + f.close() + self.reminders = loadReminders(self.tell_filename) # @@ tell + +def f_remind(phenny, input): + teller = input.nick + + # @@ Multiple comma-separated tellees? Cf. Terje, #swhack, 2006-04-15 + verb, tellee, msg = input.groups() + tellee_original = tellee.rstrip(',:;') + tellee = tellee.lower() + + if not os.path.exists(phenny.tell_filename): + return + + if len(tellee) > 20: + return phenny.reply('That nickname is too long.') + + timenow = time.strftime('%d %b %H:%MZ', time.gmtime()) + if not tellee in (teller.lower(), phenny.nick, 'me'): # @@ + # @@ and year, if necessary + warn = False + if not phenny.reminders.has_key(tellee): + phenny.reminders[tellee] = [(teller, verb, timenow, msg)] + else: + if len(phenny.reminders[tellee]) >= maximum: + warn = True + phenny.reminders[tellee].append((teller, verb, timenow, msg)) + # @@ Stephanie's augmentation + response = "I'll pass that on when %s is around." % tellee_original + if warn: response += (" I'll have to use a pastebin, though, so " + + "your message may get lost.") + + rand = random.random() + if rand > 0.9999: response = "yeah, yeah" + elif rand > 0.999: response = "%s: yeah, sure, whatever" % teller + + phenny.reply(response) + elif teller.lower() == tellee: + phenny.say('You can %s yourself that.' % verb) + else: phenny.say("Hey, I'm not as stupid as Monty you know!") + + dumpReminders(phenny.tell_filename, phenny.reminders) # @@ tell +f_remind.rule = ('$nick', ['tell', 'ask'], r'(\S+) (.*)') + +def getReminders(phenny, channel, key, tellee): + lines = [] + template = "%s: %s <%s> %s %s %s" + today = time.strftime('%d %b', time.gmtime()) + + for (teller, verb, datetime, msg) in phenny.reminders[key]: + if datetime.startswith(today): + datetime = datetime[len(today)+1:] + lines.append(template % (tellee, datetime, teller, verb, tellee, msg)) + + try: del phenny.reminders[key] + except KeyError: phenny.msg(channel, 'Er...') + return lines + +def message(phenny, input): + if not input.sender.startswith('#'): return + + tellee = input.nick + channel = input.sender + + if not os.path.exists(phenny.tell_filename): + return + + reminders = [] + remkeys = list(reversed(sorted(phenny.reminders.keys()))) + for remkey in remkeys: + if not remkey.endswith('*'): + if tellee.lower() == remkey: + reminders.extend(getReminders(phenny, channel, remkey, tellee)) + elif tellee.lower().startswith(remkey.rstrip('*')): + reminders.extend(getReminders(phenny, channel, remkey, tellee)) + + for line in reminders[:maximum]: + phenny.say(line) + + if reminders[maximum:]: + try: + if origin.sender in lispchannels: + chan = origin.sender + else: chan = 'None' + + result = web.post('http://paste.lisp.org/submit', + {'channel': chan, + 'username': phenny.nick, + 'title': 'Further Messages for %s' % tellee, + 'colorize': 'None', + 'text': '\n'.join(reminders[maximum:]) + '\n', + 'captcha': 'lisp', + 'captchaid': 'bdf447484f62a3e8b23816f9acee79d9' + } + ) + uris = re.findall('http://paste.lisp.org/display/\d+', result) + uri = list(reversed(uris)).pop() + if not origin.sender in lispchannels: + message = '%s: see %s for further messages' % (tellee, uri) + phenny.say(message) + except: + error = '[Sorry, some messages were elided and lost...]' + phenny.say(error) + + if len(phenny.reminders.keys()) != remkeys: + dumpReminders(phenny.tell_filename, phenny.reminders) # @@ tell +message.rule = r'(.*)' +message.priority = 'low' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/translate.py b/modules/translate.py new file mode 100644 index 0000000..ed3589f --- /dev/null +++ b/modules/translate.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# coding=utf-8 +""" +translate.py - Phenny Translation Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re +import web + +r_translation = re.compile(r'
([^<]+)
') + +def guess_language(phrase): + languages = { + 'english': 'en', + 'french': 'fr', + 'spanish': 'es', + 'portuguese': 'pt', + 'german': 'de', + 'italian': 'it', + 'korean': 'ko', + 'japanese': 'ja', + 'chinese': 'zh', + 'dutch': 'nl', + 'greek': 'el', + 'russian': 'ru' + } + + uri = 'http://www.xrce.xerox.com/cgi-bin/mltt/LanguageGuesser' + form = {'Text': phrase} + bytes = web.post(uri, form) + for line in bytes.splitlines(): + if '' in line: + i = line.find('') + lang = line[i+len(''):].strip() + lang = lang.lower() + if '_' in lang: + j = lang.find('_') + lang = lang[:j] + try: return languages[lang] + except KeyError: + return lang + return 'unknown' + +def translate(phrase, lang, target='en'): + babelfish = 'http://world.altavista.com/tr' + form = { + 'doit': 'done', + 'intl': '1', + 'tt': 'urltext', + 'trtext': phrase, + 'lp': lang + '_' + target + } + + bytes = web.post(babelfish, form) + m = r_translation.search(bytes) + if m: + translation = m.group(1) + translation = translation.replace('\r', ' ') + translation = translation.replace('\n', ' ') + while ' ' in translation: + translation = translation.replace(' ', ' ') + return translation + return None + +def tr(phenny, input): + lang, phrase = input.groups() + + if (len(phrase) > 350) and (not phenny.admin(input.nick)): + return phenny.reply('Phrase must be under 350 characters.') + + language = guess_language(phrase) + if language is None: + return phenny.reply('Unable to guess the language, sorry.') + + if language != 'en': + translation = translate(phrase, language) + if translation is not None: + return phenny.reply(u'"%s" (%s)' % (translation, language)) + + error = "I think it's %s, but I can't translate that language." + return phenny.reply(error % language.title()) + + # Otherwise, it's English, so mangle it for fun + for other in ['de', 'ja']: + phrase = translate(phrase, 'en', other) + phrase = translate(phrase, other, 'en') + + if phrase is not None: + return phenny.reply(u'"%s" (en-unmangled)' % phrase) + return phenny.reply("I think it's English already.") + # @@ or 'Why but that be English, sire.' +tr.doc = ('phenny: ""? or phenny: ""?', + 'Translate , optionally forcing the interpretation.') +tr.rule = ('$nick', ur'(?:([a-z]{2}) +)?["“](.+?)["”]\? *$') +tr.priority = 'low' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/modules/weather.py b/modules/weather.py new file mode 100755 index 0000000..9e03bf4 --- /dev/null +++ b/modules/weather.py @@ -0,0 +1,422 @@ +#!/usr/bin/env python +""" +weather.py - Phenny Weather Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re, urllib +import web +from tools import deprecated + +r_from = re.compile(r'(?i)([+-]\d+):00 from') + +r_json = re.compile(r'^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]+$') +r_string = re.compile(r'("(\\.|[^"\\])*")') +env = {'__builtins__': None, 'null': None, + 'true': True, 'false': False} + +def json(text): + """Evaluate JSON text safely (we hope).""" + if r_json.match(r_string.sub('', text)): + text = r_string.sub(lambda m: 'u' + m.group(1), text) + return eval(text.strip(' \t\r\n'), env, {}) + raise ValueError('Input must be serialised JSON.') + +def location(name): + name = urllib.quote(name) + uri = 'http://ws.geonames.org/searchJSON?q=%s&maxRows=1' % name + for i in xrange(10): + u = urllib.urlopen(uri) + if u is not None: break + bytes = u.read() + u.close() + + results = json(bytes) + try: name = results['geonames'][0]['name'] + except IndexError: + return '?', '?', '0', '0' + countryName = results['geonames'][0]['countryName'] + lat = results['geonames'][0]['lat'] + lng = results['geonames'][0]['lng'] + return name, countryName, lat, lng + +class GrumbleError(object): + pass + +def local(icao, hour, minute): + uri = ('http://www.flightstats.com/' + + 'go/Airport/airportDetails.do?airportCode=%s') + try: bytes = web.get(uri % icao) + except AttributeError: + raise GrumbleError('A WEBSITE HAS GONE DOWN WTF STUPID WEB') + m = r_from.search(bytes) + if m: + offset = m.group(1) + lhour = int(hour) + int(offset) + lhour = lhour % 24 + return (str(lhour) + ':' + str(minute) + ', ' + str(hour) + + str(minute) + 'Z') + # return (str(lhour) + ':' + str(minute) + ' (' + str(hour) + + # ':' + str(minute) + 'Z)') + return str(hour) + ':' + str(minute) + 'Z' + +def code(phenny, search): + name, country, latitude, longitude = location(search) + if name == '?': return False + + sumOfSquares = (99999999999999999999999999999, 'ICAO') + from icao import data + for icao_code, lat, lon in data: + latDiff = abs(latitude - lat) + lonDiff = abs(longitude - lon) + diff = (latDiff * latDiff) + (lonDiff * lonDiff) + if diff < sumOfSquares[0]: + sumOfSquares = (diff, icao_code) + return sumOfSquares[1] + +@deprecated +def f_weather(self, origin, match, args): + """.weather - Show the weather at airport with the code .""" + if origin.sender == '#talis': + if args[0].startswith('.weather '): return + + icao_code = match.group(2) + if (not len(icao_code) == 4) or \ + (len(icao_code) > 1 and icao_code[0] in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' and + icao_code[1] in 'abcdefghijklmnopqrstuvwxyz'): + icao_code = code(self, icao_code) + else: icao_code = icao_code.upper() + + if not icao_code: + self.msg(origin.sender, 'No ICAO code found, sorry') + return + + uri = 'http://weather.noaa.gov/pub/data/observations/metar/stations/%s.TXT' + try: bytes = web.get(uri % icao_code) + except AttributeError: + raise GrumbleError('OH CRAP NOAA HAS GONE DOWN THE WEB IS BROKEN') + if 'Not Found' in bytes: + self.msg(origin.sender, icao_code+': no such ICAO code, or no NOAA data') + return + + metar = bytes.splitlines().pop() + metar = metar.split(' ') + + if len(metar[0]) == 4: + metar = metar[1:] + + if metar[0].endswith('Z'): + time = metar[0] + metar = metar[1:] + else: time = None + + if metar[0] == 'AUTO': + metar = metar[1:] + if metar[0] == 'VCU': + self.msg(origin.sender, icao_code + ': no data provided') + return + + if metar[0].endswith('KT'): + wind = metar[0] + metar = metar[1:] + else: wind = None + + if ('V' in metar[0]) and (metar[0] != 'CAVOK'): + vari = metar[0] + metar = metar[1:] + else: vari = None + + if ((len(metar[0]) == 4) or + metar[0].endswith('SM')): + visibility = metar[0] + metar = metar[1:] + else: visibility = None + + while metar[0].startswith('R') and (metar[0].endswith('L') + or 'L/' in metar[0]): + metar = metar[1:] + + if len(metar[0]) == 6 and (metar[0].endswith('N') or + metar[0].endswith('E') or + metar[0].endswith('S') or + metar[0].endswith('W')): + metar = metar[1:] # 7000SE? + + cond = [] + while (((len(metar[0]) < 5) or + metar[0].startswith('+') or + metar[0].startswith('-')) and (not (metar[0].startswith('VV') or + metar[0].startswith('SKC') or metar[0].startswith('CLR') or + metar[0].startswith('FEW') or metar[0].startswith('SCT') or + metar[0].startswith('BKN') or metar[0].startswith('OVC')))): + cond.append(metar[0]) + metar = metar[1:] + + while '/P' in metar[0]: + metar = metar[1:] + + if not metar: + self.msg(origin.sender, icao_code + ': no data provided') + return + + cover = [] + while (metar[0].startswith('VV') or metar[0].startswith('SKC') or + metar[0].startswith('CLR') or metar[0].startswith('FEW') or + metar[0].startswith('SCT') or metar[0].startswith('BKN') or + metar[0].startswith('OVC')): + cover.append(metar[0]) + metar = metar[1:] + if not metar: + self.msg(origin.sender, icao_code + ': no data provided') + return + + if metar[0] == 'CAVOK': + cover.append('CLR') + metar = metar[1:] + + if metar[0] == 'PRFG': + cover.append('CLR') # @@? + metar = metar[1:] + + if metar[0] == 'NSC': + cover.append('CLR') + metar = metar[1:] + + if ('/' in metar[0]) or (len(metar[0]) == 5 and metar[0][2] == '.'): + temp = metar[0] + metar = metar[1:] + else: temp = None + + if metar[0].startswith('QFE'): + metar = metar[1:] + + if metar[0].startswith('Q') or metar[0].startswith('A'): + pressure = metar[0] + metar = metar[1:] + else: pressure = None + + if time: + hour = time[2:4] + minute = time[4:6] + time = local(icao_code, hour, minute) + else: time = '(time unknown)' + + if wind: + speed = int(wind[3:5]) + if speed < 1: + description = 'Calm' + elif speed < 4: + description = 'Light air' + elif speed < 7: + description = 'Light breeze' + elif speed < 11: + description = 'Gentle breeze' + elif speed < 16: + description = 'Moderate breeze' + elif speed < 22: + description = 'Fresh breeze' + elif speed < 28: + description = 'Strong breeze' + elif speed < 34: + description = 'Near gale' + elif speed < 41: + description = 'Gale' + elif speed < 48: + description = 'Strong gale' + elif speed < 56: + description = 'Storm' + elif speed < 64: + description = 'Violent storm' + else: description = 'Hurricane' + + degrees = wind[0:3] + if degrees == 'VRB': + degrees = u'\u21BB'.encode('utf-8') + elif (degrees <= 22.5) or (degrees > 337.5): + degrees = u'\u2191'.encode('utf-8') + elif (degrees > 22.5) and (degrees <= 67.5): + degrees = u'\u2197'.encode('utf-8') + elif (degrees > 67.5) and (degrees <= 112.5): + degrees = u'\u2192'.encode('utf-8') + elif (degrees > 112.5) and (degrees <= 157.5): + degrees = u'\u2198'.encode('utf-8') + elif (degrees > 157.5) and (degrees <= 202.5): + degrees = u'\u2193'.encode('utf-8') + elif (degrees > 202.5) and (degrees <= 247.5): + degrees = u'\u2199'.encode('utf-8') + elif (degrees > 247.5) and (degrees <= 292.5): + degrees = u'\u2190'.encode('utf-8') + elif (degrees > 292.5) and (degrees <= 337.5): + degrees = u'\u2196'.encode('utf-8') + + if not icao_code.startswith('EN') and not icao_code.startswith('ED'): + wind = '%s %skt (%s)' % (description, speed, degrees) + elif icao_code.startswith('ED'): + kmh = int(round(speed * 1.852, 0)) + wind = '%s %skm/h (%skt) (%s)' % (description, kmh, speed, degrees) + elif icao_code.startswith('EN'): + ms = int(round(speed * 0.514444444, 0)) + wind = '%s %sm/s (%skt) (%s)' % (description, ms, speed, degrees) + else: wind = '(wind unknown)' + + if visibility: + visibility = visibility + 'm' + else: visibility = '(visibility unknown)' + + if cover: + level = None + for c in cover: + if c.startswith('OVC') or c.startswith('VV'): + if (level is None) or (level < 8): + level = 8 + elif c.startswith('BKN'): + if (level is None) or (level < 5): + level = 5 + elif c.startswith('SCT'): + if (level is None) or (level < 3): + level = 3 + elif c.startswith('FEW'): + if (level is None) or (level < 1): + level = 1 + elif c.startswith('SKC') or c.startswith('CLR'): + if level is None: + level = 0 + + if level == 8: + cover = u'Overcast \u2601'.encode('utf-8') + elif level == 5: + cover = 'Cloudy' + elif level == 3: + cover = 'Scattered' + elif (level == 1) or (level == 0): + cover = u'Clear \u263C'.encode('utf-8') + else: cover = 'Cover Unknown' + else: cover = 'Cover Unknown' + + if temp: + if '/' in temp: + temp = temp.split('/')[0] + else: temp = temp.split('.')[0] + if temp.startswith('M'): + temp = '-' + temp[1:] + try: temp = int(temp) + except ValueError: temp = '?' + else: temp = '?' + + if pressure: + if pressure.startswith('Q'): + pressure = pressure.lstrip('Q') + if pressure != 'NIL': + pressure = str(int(pressure)) + 'mb' + else: pressure = '?mb' + elif pressure.startswith('A'): + pressure = pressure.lstrip('A') + if pressure != 'NIL': + inches = pressure[:2] + '.' + pressure[2:] + mb = int(float(inches) * 33.7685) + pressure = '%sin (%smb)' % (inches, mb) + else: pressure = '?mb' + + if isinstance(temp, int): + f = round((temp * 1.8) + 32, 2) + temp = u'%s\u2109 (%s\u2103)'.encode('utf-8') % (f, temp) + else: pressure = '?mb' + if isinstance(temp, int): + temp = u'%s\u2103'.encode('utf-8') % temp + + if cond: + conds = cond + cond = '' + + intensities = { + '-': 'Light', + '+': 'Heavy' + } + + descriptors = { + 'MI': 'Shallow', + 'PR': 'Partial', + 'BC': 'Patches', + 'DR': 'Drifting', + 'BL': 'Blowing', + 'SH': 'Showers of', + 'TS': 'Thundery', + 'FZ': 'Freezing', + 'VC': 'In the vicinity:' + } + + phenomena = { + 'DZ': 'Drizzle', + 'RA': 'Rain', + 'SN': 'Snow', + 'SG': 'Snow Grains', + 'IC': 'Ice Crystals', + 'PL': 'Ice Pellets', + 'GR': 'Hail', + 'GS': 'Small Hail', + 'UP': 'Unknown Precipitation', + 'BR': 'Mist', + 'FG': 'Fog', + 'FU': 'Smoke', + 'VA': 'Volcanic Ash', + 'DU': 'Dust', + 'SA': 'Sand', + 'HZ': 'Haze', + 'PY': 'Spray', + 'PO': 'Whirls', + 'SQ': 'Squalls', + 'FC': 'Tornado', + 'SS': 'Sandstorm', + 'DS': 'Duststorm', + # ? Cf. http://swhack.com/logs/2007-10-05#T07-58-56 + 'TS': 'Thunderstorm', + 'SH': 'Showers' + } + + for c in conds: + if c.endswith('//'): + if cond: cond += ', ' + cond += 'Some Precipitation' + elif len(c) == 5: + intensity = intensities[c[0]] + descriptor = descriptors[c[1:3]] + phenomenon = phenomena.get(c[3:], c[3:]) + if cond: cond += ', ' + cond += intensity + ' ' + descriptor + ' ' + phenomenon + elif len(c) == 4: + descriptor = descriptors.get(c[:2], c[:2]) + phenomenon = phenomena.get(c[2:], c[2:]) + if cond: cond += ', ' + cond += descriptor + ' ' + phenomenon + elif len(c) == 3: + intensity = intensities.get(c[0], c[0]) + phenomenon = phenomena.get(c[1:], c[1:]) + if cond: cond += ', ' + cond += intensity + ' ' + phenomenon + elif len(c) == 2: + phenomenon = phenomena.get(c, c) + if cond: cond += ', ' + cond += phenomenon + + # if not cond: + # format = u'%s at %s: %s, %s, %s, %s' + # args = (icao, time, cover, temp, pressure, wind) + # else: + # format = u'%s at %s: %s, %s, %s, %s, %s' + # args = (icao, time, cover, temp, pressure, cond, wind) + + if not cond: + format = u'%s, %s, %s, %s - %s %s' + args = (cover, temp, pressure, wind, str(icao_code), time) + else: + format = u'%s, %s, %s, %s, %s - %s, %s' + args = (cover, temp, pressure, cond, wind, str(icao_code), time) + + self.msg(origin.sender, format.encode('utf-8') % args) +f_weather.rule = (['weather'], r'(.*)') + +if __name__ == '__main__': + print __doc__ diff --git a/modules/wikipedia.py b/modules/wikipedia.py new file mode 100644 index 0000000..893ecab --- /dev/null +++ b/modules/wikipedia.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python +""" +wikipedia.py - Phenny Wikipedia Module +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import re, urllib +import web + +wikiuri = 'http://en.wikipedia.org/wiki/%s' +wikisearch = 'http://en.wikipedia.org/wiki/Special:Search?' \ + + 'search=%s&fulltext=Search' + +r_tr = re.compile(r'(?ims)]*>.*?') +r_paragraph = re.compile(r'(?ims)]*>.*?

|]*>.*?') +r_tag = re.compile(r'<(?!!)[^>]+>') +r_whitespace = re.compile(r'[\t\r\n ]+') +r_redirect = re.compile( + r'(?ims)class=.redirectText.>\s*') + s = s.replace('<', '<') + s = s.replace('&', '&') + s = s.replace(' ', ' ') + return s + +def text(html): + html = r_tag.sub('', html) + html = r_whitespace.sub(' ', html) + return unescape(html).strip() + +def search(term): + try: import google + except ImportError, e: + print e + return term + + term = term.replace('_', ' ') + uri = google.google('site:en.wikipedia.org %s' % term) + if uri: + return uri[len('http://en.wikipedia.org/wiki/'):] + else: return term + +def wikipedia(term, last=False): + bytes = web.get(wikiuri % urllib.quote(term)) + bytes = r_tr.sub('', bytes) + + if not last: + r = r_redirect.search(bytes[:4096]) + if r: + term = urllib.unquote(r.group(1)) + return wikipedia(term, last=True) + + paragraphs = r_paragraph.findall(bytes) + + if not paragraphs: + if not last: + term = search(term) + return wikipedia(term, last=True) + return None + + # Pre-process + paragraphs = [para for para in paragraphs + if (para and 'technical limitations' not in para + and 'window.showTocToggle' not in para + and 'Deletion_policy' not in para + and 'Template:AfD_footer' not in para + and not (para.startswith('

') and + para.endswith('

')) + and not 'disambiguation)"' in para) + and not '(images and media)' in para + and not 'This article contains a' in para + and not 'id="coordinates"' in para] + + for i, para in enumerate(paragraphs): + para = para.replace('', '|') + para = para.replace('', '|') + paragraphs[i] = text(para).strip() + + # Post-process + paragraphs = [para for para in paragraphs if + (para and not (para.endswith(':') and len(para) < 150))] + + para = text(paragraphs[0]) + m = r_sentence.match(para) + + if not m: + if not last: + term = search(term) + return wikipedia(term, last=True) + return None + sentence = m.group(0) + + maxlength = 275 + if len(sentence) > maxlength: + sentence = sentence[:maxlength] + words = sentence[:-5].split(' ') + words.pop() + sentence = ' '.join(words) + ' [...]' + + if ((sentence == 'Wikipedia does not have an article with this exact name.') + or (sentence == 'Wikipedia does not have a page with this exact name.')): + if not last: + term = search(term) + return wikipedia(term, last=True) + return None + + sentence = '"' + sentence.replace('"', "'") + '"' + return sentence + ' - ' + (wikiuri % term) + +def wik(phenny, input): + origterm = input.groups()[1] + term = urllib.unquote(origterm) + if not term: + return phenny.say(origin.sender, 'Maybe you meant ".wik Zen"?') + + term = term[0].upper() + term[1:] + term = term.replace(' ', '_') + + try: result = wikipedia(term) + except IOError: + error = "Can't connect to en.wikipedia.org (%s)" % (wikiuri % term) + return phenny.say(error) + + if result is not None: + phenny.say(result) + else: phenny.say('Can\'t find anything in Wikipedia for "%s".' % origterm) + +wik.commands = ['wik'] +wik.priority = 'high' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/opt/__init__.py b/opt/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/opt/freenode.py b/opt/freenode.py new file mode 100644 index 0000000..50e6b5d --- /dev/null +++ b/opt/freenode.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +""" +freenode.py - Freenode Specific Stuff +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +def replaced(phenny, input): + command = input.group(1) + response = { + 'cp': '.cp has been replaced by .u', + 'pc': '.pc has been replaced by .u', + 'unicode': '.unicode has been replaced by .u' + }[command] + phenny.reply(response) +replaced.commands = ['cp', 'pc', 'unicode'] +replaced.priority = 'low' + +if __name__ == '__main__': + print __doc__.strip() diff --git a/phenny b/phenny new file mode 100755 index 0000000..ca52b6d --- /dev/null +++ b/phenny @@ -0,0 +1,143 @@ +#!/usr/bin/env python +""" +phenny - An IRC Bot +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +import sys, os, imp, optparse +from textwrap import dedent as trim + +dotdir = os.path.expanduser('~/.phenny') + +def check_python_version(): + if sys.version_info < (2, 4): + error = 'Error: Requires Python 2.4 or later, from www.python.org' + print >> sys.stderr, error + sys.exit(1) + +def create_default_config(fn): + f = open(fn, 'w') + print >> f, trim("""\ + nick = 'phenny' + host = 'irc.example.net' + channels = ['#example', '#test'] + owner = 'yournickname' + + # These are people who will be able to use admin.py's functions... + admins = [owner, 'someoneyoutrust'] + # But admin.py is disabled by default, as follows: + disable = ['admin'] + + # If you want to enumerate a list of modules rather than disabling + # some, use "enable = ['example']", which takes precedent over disable + # + # enable = [] + + # Modules to load from the opt directory + opt = [] + + # EOF + """) + f.close() + +def create_dotdir(dotdir): + print 'Creating a config directory at ~/.phenny...' + try: os.mkdir(dotdir) + except Exception, e: + print >> sys.stderr, 'There was a problem creating %s:' % dotdir + print >> sys.stderr, e.__class__, str(e) + print >> sys.stderr, 'Please fix this and then run phenny again.' + sys.exit(1) + + print 'Creating a default config file at ~/.phenny/default.py...' + default = os.path.join(dotdir, 'default.py') + create_default_config(default) + + print 'Done; now you can edit default.py, and run phenny! Enjoy.' + sys.exit(0) + +def check_dotdir(): + if not os.path.isdir(dotdir): + create_dotdir(dotdir) + +def config_names(config): + config = config or 'default' + + def files(d): + names = os.listdir(d) + return list(os.path.join(d, fn) for fn in names if fn.endswith('.py')) + + here = os.path.join('.', config) + if os.path.isfile(here): + return [here] + if os.path.isfile(here + '.py'): + return [here + '.py'] + if os.path.isdir(here): + return files(here) + + there = os.path.join(dotdir, config) + if os.path.isfile(there): + return [there] + if os.path.isfile(there + '.py'): + return [there + '.py'] + if os.path.isdir(there): + return files(there) + + print >> sys.stderr, "Error: Couldn't find a config file!" + print >> sys.stderr, 'What happened to ~/.phenny/default.py?' + sys.exit(1) + +def main(argv=None): + # Step One: Check Dependencies + + check_python_version() # require python2.4 or later + check_dotdir() # require ~/.phenny, or make it and exit + + # Step Two: Parse The Command Line + + parser = optparse.OptionParser('%prog [options]') + parser.add_option('-c', '--config', metavar='fn', + help='use this configuration file or directory') + opts, args = parser.parse_args(argv) + if args: print >> sys.stderr, 'Warning: ignoring spurious arguments' + + # Step Three: Load The Configurations + + config_modules = [] + for config_name in config_names(opts.config): + name = os.path.basename(config_name).split('.')[0] + '_config' + module = imp.load_source(name, config_name) + module.filename = config_name + if not hasattr(module, 'prefix'): + module.prefix = r'\.' + if not hasattr(module, 'name'): + module.name = 'Phenny Palmersbot, http://inamidst.com/phenny/' + + if module.host == 'irc.example.net': + error = ('Error: you must edit the config file first!\n' + + "You're currently using %s" % module.filename) + print >> sys.stderr, error + sys.exit(1) + + config_modules.append(module) + + # Step Four: Load Phenny + + try: from __init__ import run + except ImportError: + try: from phenny import run + except ImportError: + print >> sys.stderr, "Error: Couldn't find phenny to import" + sys.exit(1) + + # Step Five: Initialise And Run The Phennies + + # @@ ignore SIGHUP + for config_module in config_modules: + run(config_module) # @@ thread this + +if __name__ == '__main__': + main() diff --git a/tools.py b/tools.py new file mode 100644 index 0000000..b1da848 --- /dev/null +++ b/tools.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +""" +tools.py - Phenny Tools +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +http://inamidst.com/phenny/ +""" + +def deprecated(old): + def new(phenny, input, old=old): + self = phenny + origin = type('Origin', (object,), { + 'sender': input.sender, + 'nick': input.nick + })() + match = input.match + args = [input.bytes, input.sender, '@@'] + + old(self, origin, match, args) + new.__name__ = old.__name__ + return new + +if __name__ == '__main__': + print __doc__.strip() diff --git a/web.py b/web.py new file mode 100755 index 0000000..fff4a7f --- /dev/null +++ b/web.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +""" +web.py - Web Facilities +Author: Sean B. Palmer, inamidst.com +About: http://inamidst.com/phenny/ +""" + +import urllib + +class Grab(urllib.URLopener): + def __init__(self, *args): + self.version = 'Mozilla/5.0 (Phenny)' + urllib.URLopener.__init__(self, *args) + def http_error_default(self, url, fp, errcode, errmsg, headers): + return urllib.addinfourl(fp, [headers, errcode], "http:" + url) +urllib._urlopener = Grab() + +def get(uri): + u = urllib.urlopen(uri) + bytes = u.read() + u.close() + return bytes + +def head(uri): + u = urllib.urlopen(uri) + info = u.info() + u.close() + return info + +def post(uri, query): + data = urllib.urlencode(query) + u = urllib.urlopen(uri, data) + bytes = u.read() + u.close() + return bytes + +if __name__=="__main__": + main()