diff --git a/.github/workflows/build-docker.yaml b/.github/workflows/build-docker.yaml index d4bcf85..285b50b 100644 --- a/.github/workflows/build-docker.yaml +++ b/.github/workflows/build-docker.yaml @@ -1,5 +1,10 @@ name: build-docker -on: push + +on: + push: + branches: ["main"] + +workflow_dispatch: jobs: build: diff --git a/build.mjs b/build.mjs deleted file mode 100644 index 580e7d9..0000000 --- a/build.mjs +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -import fs from 'fs'; -import path from 'path'; -import { fileURLToPath } from 'url'; - -// Helpers -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -const distDir = path.join(__dirname, 'dist'); - -// Cleanup old dist folder -if (fs.existsSync(distDir)) fs.rmSync(distDir, { recursive: true, force: true }); - -// List of files and folders to include in the build -const includePaths = ['cors', 'datagenerators', 'server', 'views', 'public', 'index.js']; - -// Function to copy files/folders -const copy = (src, dest) => { - if (!fs.existsSync(src)) return; - - const stats = fs.lstatSync(src); - if (stats.isDirectory()) { - fs.mkdirSync(dest, { recursive: true }); - fs.readdirSync(src).forEach((file) => copy(path.join(src, file), path.join(dest, file))); - } else { - fs.copyFileSync(src, dest); - } -}; - -// Copy each included file/folder -includePaths.forEach((item) => copy(path.join(__dirname, item), path.join(distDir, item))); - -console.log('✅ Build completed: Files copied to dist/'); diff --git a/dist/cors/index.js b/dist/cors/index.js deleted file mode 100644 index e964565..0000000 --- a/dist/cors/index.js +++ /dev/null @@ -1,43 +0,0 @@ -// pass through api requests - -// http(s) modules -const https = require('https'); - -// url parsing -const queryString = require('querystring'); - -// return an express router -module.exports = (req, res) => { - // add out-going headers - const headers = {}; - headers['user-agent'] = '(WeatherStar 4000+, ws4000@netbymatt.com)'; - headers.accept = req.headers.accept; - - // get query paramaters if the exist - const queryParams = Object.keys(req.query).reduce((acc, key) => { - // skip the paramater 'u' - if (key === 'u') return acc; - // add the paramter to the resulting object - acc[key] = req.query[key]; - return acc; - }, {}); - let query = queryString.encode(queryParams); - if (query.length > 0) query = `?${query}`; - - // get the page - https.get(`https://api.weather.gov${req.path}${query}`, { - headers, - }, (getRes) => { - // pull some info - const { statusCode } = getRes; - // pass the status code through - res.status(statusCode); - - // set headers - res.header('content-type', getRes.headers['content-type']); - // pipe to response - getRes.pipe(res); - }).on('error', (e) => { - console.error(e); - }); -}; diff --git a/dist/cors/outlook.js b/dist/cors/outlook.js deleted file mode 100644 index 5474ab4..0000000 --- a/dist/cors/outlook.js +++ /dev/null @@ -1,44 +0,0 @@ -// pass through api requests - -// http(s) modules -const https = require('https'); - -// url parsing -const queryString = require('querystring'); - -// return an express router -module.exports = (req, res) => { - // add out-going headers - const headers = {}; - headers['user-agent'] = '(WeatherStar 4000+, ws4000@netbymatt.com)'; - headers.accept = req.headers.accept; - - // get query paramaters if the exist - const queryParams = Object.keys(req.query).reduce((acc, key) => { - // skip the paramater 'u' - if (key === 'u') return acc; - // add the paramter to the resulting object - acc[key] = req.query[key]; - return acc; - }, {}); - let query = queryString.encode(queryParams); - if (query.length > 0) query = `?${query}`; - - // get the page - https.get(`https://www.cpc.ncep.noaa.gov/${req.path}${query}`, { - headers, - }, (getRes) => { - // pull some info - const { statusCode } = getRes; - // pass the status code through - res.status(statusCode); - - // set headers - res.header('content-type', getRes.headers['content-type']); - res.header('last-modified', getRes.headers['last-modified']); - // pipe to response - getRes.pipe(res); - }).on('error', (e) => { - console.error(e); - }); -}; diff --git a/dist/cors/radar.js b/dist/cors/radar.js deleted file mode 100644 index 7f5c361..0000000 --- a/dist/cors/radar.js +++ /dev/null @@ -1,44 +0,0 @@ -// pass through api requests - -// http(s) modules -const https = require('https'); - -// url parsing -const queryString = require('querystring'); - -// return an express router -module.exports = (req, res) => { - // add out-going headers - const headers = {}; - headers['user-agent'] = '(WeatherStar 4000+, ws4000@netbymatt.com)'; - headers.accept = req.headers.accept; - - // get query paramaters if the exist - const queryParams = Object.keys(req.query).reduce((acc, key) => { - // skip the paramater 'u' - if (key === 'u') return acc; - // add the paramter to the resulting object - acc[key] = req.query[key]; - return acc; - }, {}); - let query = queryString.encode(queryParams); - if (query.length > 0) query = `?${query}`; - - // get the page - https.get(`https://radar.weather.gov${req.path}${query}`, { - headers, - }, (getRes) => { - // pull some info - const { statusCode } = getRes; - // pass the status code through - res.status(statusCode); - - // set headers - res.header('content-type', getRes.headers['content-type']); - res.header('last-modified', getRes.headers['last-modified']); - // pipe to response - getRes.pipe(res); - }).on('error', (e) => { - console.error(e); - }); -}; diff --git a/dist/datagenerators/chunk.js b/dist/datagenerators/chunk.js deleted file mode 100644 index 2fe6478..0000000 --- a/dist/datagenerators/chunk.js +++ /dev/null @@ -1,22 +0,0 @@ -// turn a long array into a set of smaller chunks - -const chunk = (data, chunkSize = 10) => { - const chunks = []; - - let thisChunk = []; - - data.forEach((d) => { - if (thisChunk.length >= chunkSize) { - chunks.push(thisChunk); - thisChunk = []; - } - thisChunk.push(d); - }); - - // final chunk - if (thisChunk.length > 0) chunks.push(thisChunk); - - return chunks; -}; - -module.exports = chunk; diff --git a/dist/datagenerators/https.js b/dist/datagenerators/https.js deleted file mode 100644 index 87a9a81..0000000 --- a/dist/datagenerators/https.js +++ /dev/null @@ -1,24 +0,0 @@ -// async https wrapper - -const https = require('https'); - -module.exports = (url) => new Promise((resolve, reject) => { - const headers = {}; - headers['user-agent'] = '(WeatherStar 4000+ data generator, ws4000@netbymatt.com)'; - - https.get(url, { - headers, - }, (res) => { - if (res.statusCode === 200) { - const buffers = []; - res.on('data', (data) => buffers.push(data)); - res.on('end', () => resolve(Buffer.concat(buffers).toString())); - } else { - console.log(res); - reject(new Error(`Unable to get: ${url}`)); - } - }).on('error', (e) => { - console.log(e); - reject(e); - }); -}); diff --git a/dist/datagenerators/output/regionalcities.json b/dist/datagenerators/output/regionalcities.json deleted file mode 100644 index 93717b1..0000000 --- a/dist/datagenerators/output/regionalcities.json +++ /dev/null @@ -1,1162 +0,0 @@ -[ - { - "city": "Atlanta", - "lat": 33.749, - "lon": -84.388, - "point": { - "x": 50, - "y": 86, - "wfo": "FFC" - } - }, - { - "city": "Boston", - "lat": 42.3584, - "lon": -71.0598, - "point": { - "x": 71, - "y": 90, - "wfo": "BOX" - } - }, - { - "city": "Chicago", - "lat": 41.9796, - "lon": -87.9045, - "point": { - "x": 65, - "y": 76, - "wfo": "LOT" - } - }, - { - "city": "Cleveland", - "lat": 41.4995, - "lon": -81.6954, - "point": { - "x": 82, - "y": 64, - "wfo": "CLE" - } - }, - { - "city": "Dallas", - "lat": 32.8959, - "lon": -97.0372, - "point": { - "x": 79, - "y": 108, - "wfo": "FWD" - } - }, - { - "city": "Denver", - "lat": 39.7391, - "lon": -104.9847, - "point": { - "x": 62, - "y": 60, - "wfo": "BOU" - } - }, - { - "city": "Detroit", - "lat": 42.3314, - "lon": -83.0457, - "point": { - "x": 65, - "y": 33, - "wfo": "DTX" - } - }, - { - "city": "Hartford", - "lat": 41.7637, - "lon": -72.6851, - "point": { - "x": 21, - "y": 54, - "wfo": "BOX" - } - }, - { - "city": "Houston", - "lat": 29.7633, - "lon": -95.3633, - "point": { - "x": 65, - "y": 97, - "wfo": "HGX" - } - }, - { - "city": "Indianapolis", - "lat": 39.7684, - "lon": -86.158, - "point": { - "x": 57, - "y": 68, - "wfo": "IND" - } - }, - { - "city": "Los Angeles", - "lat": 34.0522, - "lon": -118.2437, - "point": { - "x": 154, - "y": 44, - "wfo": "LOX" - } - }, - { - "city": "Miami", - "lat": 25.7743, - "lon": -80.1937, - "point": { - "x": 109, - "y": 50, - "wfo": "MFL" - } - }, - { - "city": "Minneapolis", - "lat": 44.98, - "lon": -93.2638, - "point": { - "x": 107, - "y": 71, - "wfo": "MPX" - } - }, - { - "city": "New York", - "lat": 40.78, - "lon": -73.88, - "point": { - "x": 36, - "y": 38, - "wfo": "OKX" - } - }, - { - "city": "Norfolk", - "lat": 36.8468, - "lon": -76.2852, - "point": { - "x": 89, - "y": 51, - "wfo": "AKQ" - } - }, - { - "city": "Orlando", - "lat": 28.5383, - "lon": -81.3792, - "point": { - "x": 26, - "y": 68, - "wfo": "MLB" - } - }, - { - "city": "Philadelphia", - "lat": 39.9523, - "lon": -75.1638, - "point": { - "x": 49, - "y": 75, - "wfo": "PHI" - } - }, - { - "city": "Pittsburgh", - "lat": 40.4406, - "lon": -79.9959, - "point": { - "x": 77, - "y": 65, - "wfo": "PBZ" - } - }, - { - "city": "St. Louis", - "lat": 38.6273, - "lon": -90.1979, - "point": { - "x": 94, - "y": 73, - "wfo": "LSX" - } - }, - { - "city": "San Francisco", - "lat": 37.6148, - "lon": -122.3918, - "point": { - "x": 84, - "y": 98, - "wfo": "MTR" - } - }, - { - "city": "Seattle", - "lat": 47.6062, - "lon": -122.3321, - "point": { - "x": 124, - "y": 67, - "wfo": "SEW" - } - }, - { - "city": "Syracuse", - "lat": 43.0481, - "lon": -76.1474, - "point": { - "x": 51, - "y": 98, - "wfo": "BGM" - } - }, - { - "city": "Tampa", - "lat": 27.9756, - "lon": -82.5329, - "point": { - "x": 67, - "y": 97, - "wfo": "TBW" - } - }, - { - "city": "Washington DC", - "lat": 38.8951, - "lon": -77.0364, - "point": { - "x": 97, - "y": 71, - "wfo": "LWX" - } - }, - { - "city": "Albany", - "lat": 42.6526, - "lon": -73.7562, - "point": { - "x": 58, - "y": 58, - "wfo": "ALY" - } - }, - { - "city": "Albuquerque", - "lat": 35.0845, - "lon": -106.6511, - "point": { - "x": 97, - "y": 118, - "wfo": "ABQ" - } - }, - { - "city": "Amarillo", - "lat": 35.222, - "lon": -101.8313, - "point": { - "x": 47, - "y": 25, - "wfo": "AMA" - } - }, - { - "city": "Anchorage", - "lat": 61.2181, - "lon": -149.9003, - "point": { - "x": 125, - "y": 236, - "wfo": "AER" - } - }, - { - "city": "Austin", - "lat": 30.2671, - "lon": -97.7431, - "point": { - "x": 155, - "y": 90, - "wfo": "EWX" - } - }, - { - "city": "Baker", - "lat": 44.7502, - "lon": -117.6677, - "point": { - "x": 93, - "y": 145, - "wfo": "BOI" - } - }, - { - "city": "Baltimore", - "lat": 39.2904, - "lon": -76.6122, - "point": { - "x": 109, - "y": 91, - "wfo": "LWX" - } - }, - { - "city": "Bangor", - "lat": 44.8012, - "lon": -68.7778, - "point": { - "x": 72, - "y": 62, - "wfo": "CAR" - } - }, - { - "city": "Birmingham", - "lat": 33.5207, - "lon": -86.8025, - "point": { - "x": 58, - "y": 83, - "wfo": "BMX" - } - }, - { - "city": "Bismarck", - "lat": 46.8083, - "lon": -100.7837, - "point": { - "x": 109, - "y": 46, - "wfo": "BIS" - } - }, - { - "city": "Boise", - "lat": 43.6135, - "lon": -116.2034, - "point": { - "x": 132, - "y": 85, - "wfo": "BOI" - } - }, - { - "city": "Buffalo", - "lat": 42.8864, - "lon": -78.8784, - "point": { - "x": 35, - "y": 46, - "wfo": "BUF" - } - }, - { - "city": "Carlsbad", - "lat": 32.4207, - "lon": -104.2288, - "point": { - "x": 44, - "y": 156, - "wfo": "MAF" - } - }, - { - "city": "Charleston", - "lat": 32.7766, - "lon": -79.9309, - "point": { - "x": 86, - "y": 76, - "wfo": "CHS" - } - }, - { - "city": "Charleston", - "lat": 38.3498, - "lon": -81.6326, - "point": { - "x": 62, - "y": 66, - "wfo": "RLX" - } - }, - { - "city": "Charlotte", - "lat": 35.2271, - "lon": -80.8431, - "point": { - "x": 118, - "y": 64, - "wfo": "GSP" - } - }, - { - "city": "Cheyenne", - "lat": 41.14, - "lon": -104.8202, - "point": { - "x": 109, - "y": 13, - "wfo": "CYS" - } - }, - { - "city": "Cincinnati", - "lat": 39.162, - "lon": -84.4569, - "point": { - "x": 36, - "y": 40, - "wfo": "ILN" - } - }, - { - "city": "Columbia", - "lat": 34.0007, - "lon": -81.0348, - "point": { - "x": 65, - "y": 61, - "wfo": "CAE" - } - }, - { - "city": "Columbus", - "lat": 39.9612, - "lon": -82.9988, - "point": { - "x": 84, - "y": 80, - "wfo": "ILN" - } - }, - { - "city": "Des Moines", - "lat": 41.6005, - "lon": -93.6091, - "point": { - "x": 73, - "y": 49, - "wfo": "DMX" - } - }, - { - "city": "Dubuque", - "lat": 42.5006, - "lon": -90.6646, - "point": { - "x": 62, - "y": 110, - "wfo": "DVN" - } - }, - { - "city": "Duluth", - "lat": 46.7833, - "lon": -92.1066, - "point": { - "x": 91, - "y": 69, - "wfo": "DLH" - } - }, - { - "city": "Eastport", - "lat": 44.9062, - "lon": -66.99, - "point": { - "x": 129, - "y": 79, - "wfo": "CAR" - } - }, - { - "city": "El Centro", - "lat": 32.792, - "lon": -115.563, - "point": { - "x": 26, - "y": 46, - "wfo": "PSR" - } - }, - { - "city": "El Paso", - "lat": 31.7587, - "lon": -106.4869, - "point": { - "x": 99, - "y": 55, - "wfo": "EPZ" - } - }, - { - "city": "Eugene", - "lat": 44.0521, - "lon": -123.0867, - "point": { - "x": 84, - "y": 38, - "wfo": "PQR" - } - }, - { - "city": "Fargo", - "lat": 46.8772, - "lon": -96.7898, - "point": { - "x": 99, - "y": 56, - "wfo": "FGF" - } - }, - { - "city": "Flagstaff", - "lat": 35.1981, - "lon": -111.6513, - "point": { - "x": 73, - "y": 88, - "wfo": "FGZ" - } - }, - { - "city": "Fresno", - "lat": 36.7477, - "lon": -119.7724, - "point": { - "x": 53, - "y": 100, - "wfo": "HNX" - } - }, - { - "city": "Grand Junction", - "lat": 39.0639, - "lon": -108.5506, - "point": { - "x": 94, - "y": 101, - "wfo": "GJT" - } - }, - { - "city": "Grand Rapids", - "lat": 42.9634, - "lon": -85.6681, - "point": { - "x": 40, - "y": 46, - "wfo": "GRR" - } - }, - { - "city": "Havre", - "lat": 48.55, - "lon": -109.6841, - "point": { - "x": 154, - "y": 187, - "wfo": "TFX" - } - }, - { - "city": "Helena", - "lat": 46.5927, - "lon": -112.0361, - "point": { - "x": 68, - "y": 103, - "wfo": "TFX" - } - }, - { - "city": "Honolulu", - "lat": 21.3069, - "lon": -157.8583, - "point": { - "x": 153, - "y": 144, - "wfo": "HFO" - } - }, - { - "city": "Hot Springs", - "lat": 34.5037, - "lon": -93.0552, - "point": { - "x": 53, - "y": 60, - "wfo": "LZK" - } - }, - { - "city": "Idaho Falls", - "lat": 43.4666, - "lon": -112.0341, - "point": { - "x": 115, - "y": 72, - "wfo": "PIH" - } - }, - { - "city": "Jackson", - "lat": 32.2988, - "lon": -90.1848, - "point": { - "x": 75, - "y": 62, - "wfo": "JAN" - } - }, - { - "city": "Jacksonville", - "lat": 30.3322, - "lon": -81.6556, - "point": { - "x": 65, - "y": 64, - "wfo": "JAX" - } - }, - { - "city": "Juneau", - "lat": 58.3019, - "lon": -134.4197, - "point": { - "x": 194, - "y": 163, - "wfo": "AJK" - } - }, - { - "city": "Kansas City", - "lat": 39.1142, - "lon": -94.6275, - "point": { - "x": 41, - "y": 50, - "wfo": "EAX" - } - }, - { - "city": "Key West", - "lat": 24.5557, - "lon": -81.7826, - "point": { - "x": 61, - "y": 47, - "wfo": "KEY" - } - }, - { - "city": "Klamath Falls", - "lat": 42.2249, - "lon": -121.7817, - "point": { - "x": 141, - "y": 61, - "wfo": "MFR" - } - }, - { - "city": "Knoxville", - "lat": 35.9606, - "lon": -83.9207, - "point": { - "x": 71, - "y": 51, - "wfo": "MRX" - } - }, - { - "city": "Las Vegas", - "lat": 36.175, - "lon": -115.1372, - "point": { - "x": 122, - "y": 97, - "wfo": "VEF" - } - }, - { - "city": "Lewiston", - "lat": 46.4165, - "lon": -117.0177, - "point": { - "x": 144, - "y": 30, - "wfo": "OTX" - } - }, - { - "city": "Lincoln", - "lat": 40.8, - "lon": -96.667, - "point": { - "x": 56, - "y": 38, - "wfo": "OAX" - } - }, - { - "city": "Long Beach", - "lat": 33.767, - "lon": -118.1892, - "point": { - "x": 154, - "y": 31, - "wfo": "LOX" - } - }, - { - "city": "Louisville", - "lat": 38.2542, - "lon": -85.7594, - "point": { - "x": 49, - "y": 77, - "wfo": "LMK" - } - }, - { - "city": "Manchester", - "lat": 42.9956, - "lon": -71.4548, - "point": { - "x": 41, - "y": 20, - "wfo": "GYX" - } - }, - { - "city": "Memphis", - "lat": 35.1495, - "lon": -90.049, - "point": { - "x": 41, - "y": 66, - "wfo": "MEG" - } - }, - { - "city": "Milwaukee", - "lat": 43.0389, - "lon": -87.9065, - "point": { - "x": 87, - "y": 64, - "wfo": "MKX" - } - }, - { - "city": "Mobile", - "lat": 30.6944, - "lon": -88.043, - "point": { - "x": 51, - "y": 66, - "wfo": "MOB" - } - }, - { - "city": "Montgomery", - "lat": 32.3668, - "lon": -86.3, - "point": { - "x": 80, - "y": 34, - "wfo": "BMX" - } - }, - { - "city": "Montpelier", - "lat": 44.2601, - "lon": -72.5754, - "point": { - "x": 110, - "y": 49, - "wfo": "BTV" - } - }, - { - "city": "Nashville", - "lat": 36.1659, - "lon": -86.7844, - "point": { - "x": 49, - "y": 56, - "wfo": "OHX" - } - }, - { - "city": "Newark", - "lat": 40.7357, - "lon": -74.1724, - "point": { - "x": 26, - "y": 34, - "wfo": "OKX" - } - }, - { - "city": "New Haven", - "lat": 41.3081, - "lon": -72.9282, - "point": { - "x": 65, - "y": 67, - "wfo": "OKX" - } - }, - { - "city": "New Orleans", - "lat": 29.9546, - "lon": -90.0751, - "point": { - "x": 68, - "y": 88, - "wfo": "LIX" - } - }, - { - "city": "Nome", - "lat": 64.5011, - "lon": -165.4064, - "point": { - "x": 217, - "y": 139, - "wfo": "AFG" - } - }, - { - "city": "Oklahoma City", - "lat": 35.4676, - "lon": -97.5164, - "point": { - "x": 97, - "y": 93, - "wfo": "OUN" - } - }, - { - "city": "Omaha", - "lat": 41.2586, - "lon": -95.9378, - "point": { - "x": 82, - "y": 59, - "wfo": "OAX" - } - }, - { - "city": "Phoenix", - "lat": 33.4484, - "lon": -112.074, - "point": { - "x": 158, - "y": 57, - "wfo": "PSR" - } - }, - { - "city": "Pierre", - "lat": 44.3683, - "lon": -100.351, - "point": { - "x": 54, - "y": 43, - "wfo": "ABR" - } - }, - { - "city": "Portland", - "lat": 43.6615, - "lon": -70.2553, - "point": { - "x": 75, - "y": 58, - "wfo": "GYX" - } - }, - { - "city": "Portland", - "lat": 45.5234, - "lon": -122.6762, - "point": { - "x": 112, - "y": 103, - "wfo": "PQR" - } - }, - { - "city": "Providence", - "lat": 41.824, - "lon": -71.4128, - "point": { - "x": 64, - "y": 64, - "wfo": "BOX" - } - }, - { - "city": "Raleigh", - "lat": 35.7721, - "lon": -78.6386, - "point": { - "x": 74, - "y": 56, - "wfo": "RAH" - } - }, - { - "city": "Reno", - "lat": 39.4986, - "lon": -119.7681, - "point": { - "x": 45, - "y": 104, - "wfo": "REV" - } - }, - { - "city": "Richfield", - "lat": 38.7725, - "lon": -112.0841, - "point": { - "x": 81, - "y": 86, - "wfo": "SLC" - } - }, - { - "city": "Richmond", - "lat": 37.5538, - "lon": -77.4603, - "point": { - "x": 44, - "y": 76, - "wfo": "AKQ" - } - }, - { - "city": "Roanoke", - "lat": 37.271, - "lon": -79.9414, - "point": { - "x": 73, - "y": 68, - "wfo": "RNK" - } - }, - { - "city": "Sacramento", - "lat": 38.5816, - "lon": -121.4944, - "point": { - "x": 40, - "y": 67, - "wfo": "STO" - } - }, - { - "city": "Salt Lake City", - "lat": 40.7608, - "lon": -111.891, - "point": { - "x": 99, - "y": 174, - "wfo": "SLC" - } - }, - { - "city": "San Antonio", - "lat": 29.4241, - "lon": -98.4936, - "point": { - "x": 125, - "y": 53, - "wfo": "EWX" - } - }, - { - "city": "San Diego", - "lat": 32.7153, - "lon": -117.1573, - "point": { - "x": 56, - "y": 13, - "wfo": "SGX" - } - }, - { - "city": "San Jose", - "lat": 37.3394, - "lon": -121.895, - "point": { - "x": 99, - "y": 82, - "wfo": "MTR" - } - }, - { - "city": "Santa Fe", - "lat": 35.687, - "lon": -105.9378, - "point": { - "x": 125, - "y": 143, - "wfo": "ABQ" - } - }, - { - "city": "Savannah", - "lat": 32.0835, - "lon": -81.0998, - "point": { - "x": 46, - "y": 40, - "wfo": "CHS" - } - }, - { - "city": "Shreveport", - "lat": 32.5251, - "lon": -93.7502, - "point": { - "x": 76, - "y": 69, - "wfo": "SHV" - } - }, - { - "city": "Sioux Falls", - "lat": 43.55, - "lon": -96.7003, - "point": { - "x": 99, - "y": 65, - "wfo": "FSD" - } - }, - { - "city": "Sitka", - "lat": 57.0531, - "lon": -135.33, - "point": { - "x": 188, - "y": 112, - "wfo": "AJK" - } - }, - { - "city": "Spokane", - "lat": 47.6597, - "lon": -117.4291, - "point": { - "x": 140, - "y": 90, - "wfo": "OTX" - } - }, - { - "city": "Springfield", - "lat": 39.8017, - "lon": -89.6437, - "point": { - "x": 47, - "y": 55, - "wfo": "ILX" - } - }, - { - "city": "Springfield", - "lat": 42.1015, - "lon": -72.5898, - "point": { - "x": 22, - "y": 69, - "wfo": "BOX" - } - }, - { - "city": "Springfield", - "lat": 37.2153, - "lon": -93.2982, - "point": { - "x": 66, - "y": 34, - "wfo": "SGF" - } - }, - { - "city": "Toledo", - "lat": 41.6639, - "lon": -83.5552, - "point": { - "x": 18, - "y": 66, - "wfo": "CLE" - } - }, - { - "city": "Tulsa", - "lat": 36.154, - "lon": -95.9928, - "point": { - "x": 40, - "y": 104, - "wfo": "TSA" - } - }, - { - "city": "Virginia Beach", - "lat": 36.8529, - "lon": -75.978, - "point": { - "x": 100, - "y": 52, - "wfo": "AKQ" - } - }, - { - "city": "Wichita", - "lat": 37.6922, - "lon": -97.3375, - "point": { - "x": 61, - "y": 33, - "wfo": "ICT" - } - }, - { - "city": "Wilmington", - "lat": 34.2257, - "lon": -77.9447, - "point": { - "x": 88, - "y": 67, - "wfo": "ILM" - } - }, - { - "city": "Tuscan", - "lat": 32.2216, - "lon": -110.9698, - "point": { - "x": 90, - "y": 48, - "wfo": "TWC" - } - } -] \ No newline at end of file diff --git a/dist/datagenerators/output/stations - Copy.js b/dist/datagenerators/output/stations - Copy.js deleted file mode 100644 index 5688564..0000000 --- a/dist/datagenerators/output/stations - Copy.js +++ /dev/null @@ -1,19540 +0,0 @@ -const StationInfo = { - MADC: { - id: 'MADC', - city: 'Durango Complex', - state: 'AZ', - lat: 33.42, - lon: -112.12, - }, - MAHB: { - id: 'MAHB', - city: 'Horsethief Basin', - state: 'AZ', - lat: 34.14, - lon: -112.27, - }, - MAUP: { - id: 'MAUP', - city: 'Usery Park WS', - state: 'AZ', - lat: 33.4799999, - lon: -111.61, - }, - MAGB: { - id: 'MAGB', - city: 'Gila Bend Mountains', - state: 'AZ', - lat: 33.24, - lon: -113.2, - }, - MATW: { - id: 'MATW', - city: 'Tiger Wash Fan', - state: 'AZ', - lat: 33.67, - lon: -113.31, - }, - MATA: { - id: 'MATA', - city: 'Thunderbird Academy', - state: 'AZ', - lat: 33.6, - lon: -111.92, - }, - MALP: { - id: 'MALP', - city: 'Lake Pleasant North', - state: 'AZ', - lat: 33.90464, - lon: -112.27083, - }, - MASF: { - id: 'MASF', - city: 'South Mountain Fan', - state: 'AZ', - lat: 33.31, - lon: -112.14, - }, - MAGU: { - id: 'MAGU', - city: 'Saguaro Lake', - state: 'AZ', - lat: 33.58, - lon: -111.54, - }, - MAEF: { - id: 'MAEF', - city: 'Estrella Fan', - state: 'AZ', - lat: 33.27, - lon: -112.32, - }, - MAIS: { - id: 'MAIS', - city: 'Osborn Rd. @ 64th St.', - state: 'AZ', - lat: 33.48511, - lon: -111.94267, - }, - MAHR: { - id: 'MAHR', - city: 'Hassayampa R @ I-10', - state: 'AZ', - lat: 33.46, - lon: -112.76, - }, - MACP: { - id: 'MACP', - city: 'Crossroads Park', - state: 'AZ', - lat: 33.32, - lon: -111.74, - }, - MAMF: { - id: 'MAMF', - city: 'Magma FRS', - state: 'AZ', - lat: 33.12, - lon: -111.4, - }, - MAPJ: { - id: 'MAPJ', - city: 'Pima Rd. @ Jomax Rd.', - state: 'AZ', - lat: 33.72, - lon: -111.89, - }, - MASP: { - id: 'MASP', - city: 'South Mountain Park', - state: 'AZ', - lat: 33.34, - lon: -112.03, - }, - MAHM: { - id: 'MAHM', - city: 'Humboldt Mountain', - state: 'AZ', - lat: 33.97, - lon: -111.79, - }, - MATP: { - id: 'MATP', - city: 'Thompson Peak', - state: 'AZ', - lat: 33.64, - lon: -111.82, - }, - MACH: { - id: 'MACH', - city: 'Columbia Hill', - state: 'AZ', - lat: 34.02, - lon: -112.35, - }, - MAMU: { - id: 'MAMU', - city: 'Mt. Union Wx', - state: 'AZ', - lat: 34.4099999, - lon: -112.41, - }, - MAFH: { - id: 'MAFH', - city: 'Fountain Hills Fire Dept.', - state: 'AZ', - lat: 33.6111, - lon: -111.7251, - }, - MAWA: { - id: 'MAWA', - city: 'Wickenburg Airport', - state: 'AZ', - lat: 33.97, - lon: -112.8, - }, - MACR: { - id: 'MACR', - city: 'Carefree Ranch', - state: 'AZ', - lat: 33.87, - lon: -111.85, - }, - MABL: { - id: 'MABL', - city: 'Bartlett Lake', - state: 'AZ', - lat: 33.84, - lon: -111.64, - }, - MAGL: { - id: 'MAGL', - city: 'Gila Bend Landfill', - state: 'AZ', - lat: 32.99, - lon: -112.68, - }, - MAHL: { - id: 'MAHL', - city: 'Horseshoe Lake', - state: 'AZ', - lat: 33.9799999, - lon: -111.71, - }, - MAGC: { - id: 'MAGC', - city: 'GateWay Community College', - state: 'AZ', - lat: 33.45028, - lon: -111.99806, - }, - MAMC: { - id: 'MAMC', - city: 'McMicken Floodway', - state: 'AZ', - lat: 33.68531, - lon: -112.40861, - }, - MAMD: { - id: 'MAMD', - city: 'McMicken Dam', - state: 'AZ', - lat: 33.677, - lon: -112.4235, - }, - MADM: { - id: 'MADM', - city: 'Desert Mountain School', - state: 'AZ', - lat: 33.80933, - lon: -112.07717, - }, - MABU: { - id: 'MABU', - city: 'Buckeye FRS #1', - state: 'AZ', - lat: 33.425, - lon: -112.6252, - }, - MRKC: { - id: 'MRKC', - city: 'Rackensack Canyon', - state: 'AZ', - lat: 33.90164, - lon: -111.84506, - }, - MAMO: { - id: 'MAMO', - city: 'Mobile', - state: 'AZ', - lat: 33.0384, - lon: -112.2441, - }, - MAPL: { - id: 'MAPL', - city: 'Lake Pleasant', - state: 'AZ', - lat: 33.84739, - lon: -112.27806, - }, - MACY: { - id: 'MACY', - city: 'Coyote Wash', - state: 'AZ', - lat: 33.697, - lon: -112.9236, - }, - MAPH: { - id: 'MAPH', - city: 'Phoenix Dam 2A', - state: 'AZ', - lat: 33.60367, - lon: -112.06464, - }, - MAGD: { - id: 'MAGD', - city: 'City of Glendale', - state: 'AZ', - lat: 33.5436, - lon: -112.1936, - }, - MEMF: { - id: 'MEMF', - city: 'EMF @ Arizona Ave.', - state: 'AZ', - lat: 33.169333, - lon: -111.842583, - }, - MSYC: { - id: 'MSYC', - city: 'Sycamore Creek - Upper', - state: 'AZ', - lat: 33.9876099, - lon: -111.46431, - }, - BFOP: { - id: 'BFOP', - city: 'Forage Plot', - state: 'AZ', - lat: 32.45306, - lon: -113.38028, - }, - MACC: { - id: 'MACC', - city: 'Camelback Rd. @ Citrus Rd.', - state: 'AZ', - lat: 33.50803, - lon: -112.44442, - }, - BSTO: { - id: 'BSTO', - city: 'Stoval', - state: 'AZ', - lat: 32.68556, - lon: -113.65944, - }, - BWET: { - id: 'BWET', - city: 'Weather Top', - state: 'AZ', - lat: 32.55694, - lon: -112.62389, - }, - BSPO: { - id: 'BSPO', - city: 'Spot Road', - state: 'AZ', - lat: 32.72889, - lon: -113.33778, - }, - BETC: { - id: 'BETC', - city: 'ETAC Con Point', - state: 'AZ', - lat: 32.7083299, - lon: -112.66806, - }, - BBLC: { - id: 'BBLC', - city: 'Black Cross', - state: 'AZ', - lat: 32.57111, - lon: -113.21778, - }, - BUKE: { - id: 'BUKE', - city: 'Uken', - state: 'AZ', - lat: 32.43278, - lon: -113.13667, - }, - MAGV: { - id: 'MAGV', - city: 'Aguila VFD', - state: 'AZ', - lat: 33.94093, - lon: -113.17214, - }, - MABM: { - id: 'MABM', - city: 'Belmont Mountains', - state: 'AZ', - lat: 33.65735, - lon: -112.91167, - }, - KPHX: { - id: 'KPHX', - city: 'Phoenix, Phoenix Sky Harbor International Airport', - state: 'AZ', - lat: 33.427799, - lon: -112.003465, - }, - KDVT: { - id: 'KDVT', - city: 'Phoenix, Phoenix-Deer Valley Municipal Airport', - state: 'AZ', - lat: 33.69026, - lon: -112.06618, - }, - KTUS: { - id: 'KTUS', - city: 'Tucson, Tucson International Airport', - state: 'AZ', - lat: 32.13153, - lon: -110.95635, - }, - KFLG: { - id: 'KFLG', - city: 'Flagstaff Pulliam Airport', - state: 'AZ', - lat: 35.1443299, - lon: -111.66637, - }, - KIWA: { - id: 'KIWA', - city: 'Phoenix-Mesa Gateway Airport', - state: 'AZ', - lat: 33.31667, - lon: -111.65, - }, - KPRC: { - id: 'KPRC', - city: 'Prescott, Love Field', - state: 'AZ', - lat: 34.64917, - lon: -112.42222, - }, - KPGA: { - id: 'KPGA', - city: 'Page, Page Municipal Airport', - state: 'AZ', - lat: 36.92056, - lon: -111.44806, - }, - KINW: { - id: 'KINW', - city: 'Winslow, Winslow Municipal Airport', - state: 'AZ', - lat: 35.02806, - lon: -110.72083, - }, - KGCN: { - id: 'KGCN', - city: 'Grand Canyon National Park Airport', - state: 'AZ', - lat: 35.94582, - lon: -112.15538, - }, - KSJN: { - id: 'KSJN', - city: 'St. Johns, St. Johns Industrial Airpark', - state: 'AZ', - lat: 34.51833, - lon: -109.37917, - }, - KLUF: { - id: 'KLUF', - city: 'Luke Air Force Base / Phoenix', - state: 'AZ', - lat: 33.53333, - lon: -112.38333, - }, - KDUG: { - id: 'KDUG', - city: 'Bisbee Douglas International Airport', - state: 'AZ', - lat: 31.45838, - lon: -109.60676, - }, - KSOW: { - id: 'KSOW', - city: 'Show Low, Show Low Regional Airport', - state: 'AZ', - lat: 34.26528, - lon: -110.00556, - }, - KDMA: { - id: 'KDMA', - city: 'Davis-Monthan Air Force Base', - state: 'AZ', - lat: 32.16667, - lon: -110.88333, - }, - KOLS: { - id: 'KOLS', - city: 'Nogales, Nogales International Airport', - state: 'AZ', - lat: 31.42083, - lon: -110.84583, - }, - KNYL: { - id: 'KNYL', - city: 'Yuma, Marine Corps Air Station', - state: 'AZ', - lat: 32.6594399, - lon: -114.59306, - }, - KSAD: { - id: 'KSAD', - city: 'Safford, Safford Municipal Airport', - state: 'AZ', - lat: 32.85722, - lon: -109.63556, - }, - KFHU: { - id: 'KFHU', - city: 'Fort Huachuca, Libby AAF Ft Huachuca', - state: 'AZ', - lat: 31.58333, - lon: -110.33333, - }, - KFFZ: { - id: 'KFFZ', - city: 'Mesa / Falcon Field', - state: 'AZ', - lat: 33.46667, - lon: -111.73333, - }, - KIFP: { - id: 'KIFP', - city: 'Bullhead City, Laughlin/Bullhead International Airport', - state: 'AZ', - lat: 35.1575, - lon: -114.55944, - }, - KGEU: { - id: 'KGEU', - city: 'Glendale, Glendale Municipal Airport', - state: 'AZ', - lat: 33.52722, - lon: -112.29528, - }, - KIGM: { - id: 'KIGM', - city: 'Kingman, Kingman Airport', - state: 'AZ', - lat: 35.2577799, - lon: -113.93306, - }, - KGXF: { - id: 'KGXF', - city: 'Gila Bend Air Force Auxiliary Field', - state: 'AZ', - lat: 32.8875, - lon: -112.72, - }, - KGYR: { - id: 'KGYR', - city: 'Goodyear Municipal', - state: 'AZ', - lat: 33.41667, - lon: -112.38333, - }, - KCGZ: { - id: 'KCGZ', - city: 'Casa Grande, Casa Grande Municipal Airport', - state: 'AZ', - lat: 32.95, - lon: -111.76667, - }, - KSDL: { - id: 'KSDL', - city: 'Scottsdale Airport', - state: 'AZ', - lat: 33.61235, - lon: -111.92316, - }, - KRQE: { - id: 'KRQE', - city: 'Window Rock, Window Rock Airport', - state: 'AZ', - lat: 35.65, - lon: -109.06667, - }, - YABA: { - id: 'YABA', - city: 'Bagdad Airport', - state: 'AZ', - lat: 34.59583, - lon: -113.17, - }, - KJTC: { - id: 'KJTC', - city: 'Springerville Municipal Airport', - state: 'AZ', - lat: 34.1293999, - lon: -109.3109, - }, - KAZC: { - id: 'KAZC', - city: 'Colorado City, Colorado City Municipal Airport', - state: 'AZ', - lat: 36.95, - lon: -113, - }, - KSEZ: { - id: 'KSEZ', - city: 'Sedona Airport', - state: 'AZ', - lat: 34.85, - lon: -111.78333, - }, - KCHD: { - id: 'KCHD', - city: 'Chandler, Chandler Municipal Airport', - state: 'AZ', - lat: 33.26917, - lon: -111.81111, - }, - KALK: { - id: 'KALK', - city: 'Pioneer Airfield', - state: 'AZ', - lat: 31.60564, - lon: -110.4281, - }, - KRYN: { - id: 'KRYN', - city: 'Tucson Ryan Field Airport', - state: 'AZ', - lat: 32.1422, - lon: -111.1746, - }, - KBXK: { - id: 'KBXK', - city: 'Buckeye Municipal Airport', - state: 'AZ', - lat: 33.4204, - lon: -112.6862, - }, - KHII: { - id: 'KHII', - city: 'Havasu City Airport', - state: 'AZ', - lat: 34.56595, - lon: -114.35224, - }, - KAVQ: { - id: 'KAVQ', - city: 'Tucson Marana Regional Airport', - state: 'AZ', - lat: 32.4096, - lon: -111.2184, - }, - KPAN: { - id: 'KPAN', - city: 'Payson Airport', - state: 'AZ', - lat: 34.2568364, - lon: -111.3392558, - }, - CEDC: { - id: 'CEDC', - city: 'CEDARVILLE', - state: 'CA', - lat: 41.58528, - lon: -120.17139, - }, - CSSL: { - id: 'CSSL', - city: 'CENTRAL SIERRA SNOW LAB', - state: 'CA', - lat: 39.32556, - lon: -120.36667, - }, - HLPK: { - id: 'HLPK', - city: 'HIGHLANDS PEAK', - state: 'CA', - lat: 36.0675, - lon: -121.55917, - }, - CCRF: { - id: 'CCRF', - city: 'CROOKED CREEK RESEARCH FACILITY', - state: 'CA', - lat: 37.4996, - lon: -118.1718, - }, - KTNP: { - id: 'KTNP', - city: 'TWENTY NINE PALMS', - state: 'CA', - lat: 34.13159, - lon: -115.94582, - }, - CIWP: { - id: 'CIWP', - city: 'Whitleys Peak - Santa Catalina Is.', - state: 'CA', - lat: 33.3725, - lon: -118.37583, - }, - CITR: { - id: 'CITR', - city: 'Silver Peak Trail - Santa Catalina Is.', - state: 'CA', - lat: 33.44611, - lon: -118.54306, - }, - CICP: { - id: 'CICP', - city: 'Cactus Peak - Santa Catalina Is.', - state: 'CA', - lat: 33.33583, - lon: -118.43611, - }, - CIDP: { - id: 'CIDP', - city: 'Dakin Peak - Santa Catalina Is.', - state: 'CA', - lat: 33.35056, - lon: -118.35194, - }, - UCJA: { - id: 'UCJA', - city: 'James Reserve (UCNRS)', - state: 'CA', - lat: 33.80944, - lon: -116.77528, - }, - UCGR: { - id: 'UCGR', - city: 'Sweeney Granite Mountains (UCNRS)', - state: 'CA', - lat: 34.7819999, - lon: -115.653, - }, - UCEL: { - id: 'UCEL', - city: 'Elliot Chaparral Reserve (UCNRS)', - state: 'CA', - lat: 32.89167, - lon: -117.09222, - }, - UCSE: { - id: 'UCSE', - city: 'Sedgwick Reserve (UCNRS)', - state: 'CA', - lat: 34.69389, - lon: -120.04167, - }, - CIAV: { - id: 'CIAV', - city: 'Avalon School, Santa Catalina Island', - state: 'CA', - lat: 33.33861, - lon: -118.33361, - }, - UCMO: { - id: 'UCMO', - city: 'Motte Rimrock Reserve (UCNRS)', - state: 'CA', - lat: 33.80472, - lon: -117.25556, - }, - UCBO: { - id: 'UCBO', - city: 'Blue Oak Ranch Reserve (UCNRS)', - state: 'CA', - lat: 37.38167, - lon: -121.73639, - }, - UCRM: { - id: 'UCRM', - city: 'Norris Rancho Marino Reserve (UCNRS)', - state: 'CA', - lat: 35.53417, - lon: -121.08333, - }, - UCBU: { - id: 'UCBU', - city: 'Burns Pinion Ridge Reserve (UCNRS)', - state: 'CA', - lat: 34.14806, - lon: -116.45583, - }, - UCDE: { - id: 'UCDE', - city: 'Boyd Deep Canyon Reserve (UCNRS)', - state: 'CA', - lat: 33.64806, - lon: -116.37833, - }, - UCHA: { - id: 'UCHA', - city: 'Hastings Natural History Reservation (UCNRS)', - state: 'CA', - lat: 36.38639, - lon: -121.55028, - }, - UCBC: { - id: 'UCBC', - city: 'Big Creek Reserve - Gatehouse (UCNRS)', - state: 'CA', - lat: 36.07083, - lon: -121.59861, - }, - UCJP: { - id: 'UCJP', - city: 'Jepson Prairie Reserve (UCNRS)', - state: 'CA', - lat: 38.26806, - lon: -121.82778, - }, - CBVA: { - id: 'CBVA', - city: 'Bridgeport Valley', - state: 'CA', - lat: 38.2230599, - lon: -119.25222, - }, - UCSC: { - id: 'UCSC', - city: 'Santa Cruz Island Reserve (UCNRS)', - state: 'CA', - lat: 33.99944, - lon: -119.68556, - }, - UCAB: { - id: 'UCAB', - city: 'Anza Borrego Desert Research Center (UCNRS)', - state: 'CA', - lat: 33.25583, - lon: -116.40444, - }, - UCBM: { - id: 'UCBM', - city: 'Bodega Marine Reserve (UCNRS)', - state: 'CA', - lat: 38.31389, - lon: -123.06028, - }, - UCSR: { - id: 'UCSR', - city: 'Stunt Ranch Reserve (UCNRS)', - state: 'CA', - lat: 34.09472, - lon: -118.65667, - }, - UCSH: { - id: 'UCSH', - city: 'Valentine Eastern Sierra Reserve (UCNRS)', - state: 'CA', - lat: 37.61361, - lon: -118.83306, - }, - KCPM: { - id: 'KCPM', - city: 'Compton - Woodley', - state: 'CA', - lat: 33.8899199, - lon: -118.24381, - }, - CSRR: { - id: 'CSRR', - city: 'Sorensens Resort - Hope Valley', - state: 'CA', - lat: 38.77583, - lon: 119.90389, - }, - UCYL: { - id: 'UCYL', - city: 'Younger Lagoon Reserve', - state: 'CA', - lat: 36.94889, - lon: 122.06639, - }, - KSFO: { - id: 'KSFO', - city: 'San Francisco, San Francisco International Airport', - state: 'CA', - lat: 37.61961, - lon: -122.36558, - }, - KLAX: { - id: 'KLAX', - city: 'Los Angeles, Los Angeles International Airport', - state: 'CA', - lat: 33.93806, - lon: -118.38889, - }, - KONT: { - id: 'KONT', - city: 'Ontario, Ontario International Airport', - state: 'CA', - lat: 34.05333, - lon: -117.57583, - }, - KOAK: { - id: 'KOAK', - city: 'Oakland, Metro Oakland International Airport', - state: 'CA', - lat: 37.7177999, - lon: -122.23294, - }, - KFAT: { - id: 'KFAT', - city: 'Fresno, Fresno Air Terminal', - state: 'CA', - lat: 36.78, - lon: -119.71944, - }, - KSAC: { - id: 'KSAC', - city: 'Sacramento Executive Airport', - state: 'CA', - lat: 38.50674, - lon: -121.49597, - }, - KSAN: { - id: 'KSAN', - city: 'San Diego, San Diego International-Lindbergh Field', - state: 'CA', - lat: 32.73361, - lon: -117.18306, - }, - KMRY: { - id: 'KMRY', - city: 'Monterey, Monterey Peninsula Airport', - state: 'CA', - lat: 36.59056, - lon: -121.8475, - }, - KPSP: { - id: 'KPSP', - city: 'Palm Springs Regional Airport', - state: 'CA', - lat: 33.82219, - lon: -116.50431, - }, - KEDW: { - id: 'KEDW', - city: 'Edwards Air Force Base', - state: 'CA', - lat: 34.91667, - lon: -117.9, - }, - KRDD: { - id: 'KRDD', - city: 'Redding Municipal Airport', - state: 'CA', - lat: 40.51461, - lon: -122.2977, - }, - KVBG: { - id: 'KVBG', - city: 'Lompoc, Vandenberg Air Force Base', - state: 'CA', - lat: 34.7294399, - lon: -120.57667, - }, - KNID: { - id: 'KNID', - city: 'China Lake, Naval Air Facility', - state: 'CA', - lat: 35.68639, - lon: -117.69, - }, - KNKX: { - id: 'KNKX', - city: 'San Diego, Miramar MCAS/Mitscher Field Airport', - state: 'CA', - lat: 32.86833, - lon: -117.1425, - }, - KSMF: { - id: 'KSMF', - city: 'Sacramento International Airport', - state: 'CA', - lat: 38.70071, - lon: -121.59479, - }, - KACV: { - id: 'KACV', - city: 'Arcata / Eureka, Arcata Airport', - state: 'CA', - lat: 40.97806, - lon: -124.10861, - }, - KBAB: { - id: 'KBAB', - city: 'Marysville, Beale Air Force Base', - state: 'CA', - lat: 39.13333, - lon: -121.43333, - }, - KMCE: { - id: 'KMCE', - city: 'Merced Regional Airport', - state: 'CA', - lat: 37.28306, - lon: -120.50778, - }, - KTRK: { - id: 'KTRK', - city: 'Truckee-Tahoe', - state: 'CA', - lat: 39.31667, - lon: -120.13333, - }, - KCRQ: { - id: 'KCRQ', - city: 'Carlsbad, McClellan-Palomar Airport', - state: 'CA', - lat: 33.13, - lon: -117.27583, - }, - KDAG: { - id: 'KDAG', - city: 'Daggett, Barstow-Daggett Airport', - state: 'CA', - lat: 34.85361, - lon: -116.78667, - }, - KSCK: { - id: 'KSCK', - city: 'Stockton, Stockton Metropolitan Airport', - state: 'CA', - lat: 37.8897199, - lon: -121.22361, - }, - KUKI: { - id: 'KUKI', - city: 'Ukiah, Ukiah Municipal Airport', - state: 'CA', - lat: 39.12583, - lon: -123.20083, - }, - KVNY: { - id: 'KVNY', - city: 'Van Nuys, Van Nuys Airport', - state: 'CA', - lat: 34.2125, - lon: -118.49083, - }, - KEED: { - id: 'KEED', - city: 'Needles, Needles Airport', - state: 'CA', - lat: 34.76611, - lon: -114.62333, - }, - KCEC: { - id: 'KCEC', - city: 'Crescent City, Jack McNamara Field Airport', - state: 'CA', - lat: 41.78028, - lon: -124.23667, - }, - KSBP: { - id: 'KSBP', - city: 'San Luis Obispo, San Luis Obispo County-Mc Chesney Field', - state: 'CA', - lat: 35.2361099, - lon: -120.63611, - }, - KSJC: { - id: 'KSJC', - city: 'San Jose, San Jose International Airport', - state: 'CA', - lat: 37.35917, - lon: -121.92417, - }, - KNJK: { - id: 'KNJK', - city: 'El Centro, Naval Air Facility', - state: 'CA', - lat: 32.825, - lon: -115.66056, - }, - KSMX: { - id: 'KSMX', - city: 'Santa Maria, Santa Maria Public Airport', - state: 'CA', - lat: 34.89944, - lon: -120.44861, - }, - KBIH: { - id: 'KBIH', - city: 'Bishop, Bishop Airport', - state: 'CA', - lat: 37.37111, - lon: -118.35806, - }, - KNTD: { - id: 'KNTD', - city: 'Point Mugu, Naval Air Warfare Center', - state: 'CA', - lat: 34.12389, - lon: -119.12167, - }, - KLGB: { - id: 'KLGB', - city: 'Long Beach, Long Beach Airport', - state: 'CA', - lat: 33.81167, - lon: -118.14639, - }, - KBFL: { - id: 'KBFL', - city: 'Bakersfield, Meadows Field Airport', - state: 'CA', - lat: 35.43361, - lon: -119.05667, - }, - KRAL: { - id: 'KRAL', - city: 'Riverside Municipal Airport', - state: 'CA', - lat: 33.95299, - lon: -117.43491, - }, - KSNA: { - id: 'KSNA', - city: 'Santa Ana, John Wayne Airport-Orange County Airport', - state: 'CA', - lat: 33.68, - lon: -117.86639, - }, - KTVL: { - id: 'KTVL', - city: 'South Lake Tahoe, Lake Tahoe Airport', - state: 'CA', - lat: 38.8983599, - lon: -119.99615, - }, - KNLC: { - id: 'KNLC', - city: 'Lemoore, Naval Air Station', - state: 'CA', - lat: 36.30361, - lon: -119.93806, - }, - KMOD: { - id: 'KMOD', - city: 'Modesto, Modesto City-County-Sham Field', - state: 'CA', - lat: 37.62417, - lon: -120.95056, - }, - KNZY: { - id: 'KNZY', - city: 'San Diego, North Island, Naval Air Station', - state: 'CA', - lat: 32.69083, - lon: -117.20889, - }, - KPMD: { - id: 'KPMD', - city: 'Palmdale, Palmdale Production Flight Plant', - state: 'CA', - lat: 34.62972, - lon: -118.08139, - }, - KWJF: { - id: 'KWJF', - city: 'Lancaster, General William J. Fox Airfield Airport', - state: 'CA', - lat: 34.74083, - lon: -118.21889, - }, - KIPL: { - id: 'KIPL', - city: 'Imperial, Imperial County Airport', - state: 'CA', - lat: 32.83417, - lon: -115.57861, - }, - KSNS: { - id: 'KSNS', - city: 'Salinas, Salinas Municipal Airport', - state: 'CA', - lat: 36.66361, - lon: -121.60806, - }, - KSTS: { - id: 'KSTS', - city: 'Santa Rosa, Santa Rosa Sonoma County Airport', - state: 'CA', - lat: 38.5, - lon: -122.81667, - }, - KNXP: { - id: 'KNXP', - city: 'Twenty-Nine Palms, Marine Corps Air-Ground Combat Center', - state: 'CA', - lat: 34.29444, - lon: -116.145, - }, - KTRM: { - id: 'KTRM', - city: 'Palm Springs, Jacqueline Cochran Regional Airport', - state: 'CA', - lat: 33.62667, - lon: -116.15944, - }, - KBUR: { - id: 'KBUR', - city: 'Burbank - Bob Hope Airport', - state: 'CA', - lat: 34.19967, - lon: -118.36538, - }, - KPRB: { - id: 'KPRB', - city: 'Paso Robles, Paso Robles Municipal Airport', - state: 'CA', - lat: 35.67278, - lon: -120.62694, - }, - KRBL: { - id: 'KRBL', - city: 'Red Bluff, Red Bluff Municipal Airport', - state: 'CA', - lat: 40.15056, - lon: -122.25222, - }, - KBLH: { - id: 'KBLH', - city: 'Blythe, Blythe Airport', - state: 'CA', - lat: 33.6191699, - lon: -114.71694, - }, - KSBA: { - id: 'KSBA', - city: 'Santa Barbara, Santa Barbara Municipal Airport', - state: 'CA', - lat: 34.42611, - lon: -119.84361, - }, - KNFG: { - id: 'KNFG', - city: 'Oceanside, Camp Pendleton, Marine Corps Air Station', - state: 'CA', - lat: 33.30472, - lon: -117.35389, - }, - KSUU: { - id: 'KSUU', - city: 'Fairfield / Travis Air Force Base', - state: 'CA', - lat: 38.26667, - lon: -121.95, - }, - KBYS: { - id: 'KBYS', - city: 'Fort Irwin/Barstow, Bicycle Lake Army Airfield', - state: 'CA', - lat: 35.28333, - lon: -116.61667, - }, - WARR: { - id: 'WARR', - city: 'MT WARREN SUMMIT', - state: 'CA', - lat: 37.98972, - lon: -119.22361, - }, - LIPK: { - id: 'LIPK', - city: 'Mt. Lincoln', - state: 'CA', - lat: 39.28861, - lon: -120.32611, - }, - KSMO: { - id: 'KSMO', - city: 'Santa Monica, Santa Monica Municipal Airport', - state: 'CA', - lat: 34.01583, - lon: -118.45139, - }, - KMHR: { - id: 'KMHR', - city: 'Sacramento, Sacramento Mather Airport', - state: 'CA', - lat: 38.55, - lon: -121.3, - }, - KMAE: { - id: 'KMAE', - city: 'Madera, Madera Municipal Airport', - state: 'CA', - lat: 36.9866699, - lon: -120.11083, - }, - KCZZ: { - id: 'KCZZ', - city: 'Campo', - state: 'CA', - lat: 32.62611, - lon: -116.46833, - }, - KHHR: { - id: 'KHHR', - city: 'Hawthorne, Hawthorne Municipal Airport', - state: 'CA', - lat: 33.9236099, - lon: -118.33194, - }, - KNSI: { - id: 'KNSI', - city: 'San Nicholas Island', - state: 'CA', - lat: 33.23472, - lon: -119.45278, - }, - KPAO: { - id: 'KPAO', - city: 'Palo Alto Airport', - state: 'CA', - lat: 37.46667, - lon: -122.11667, - }, - KLVK: { - id: 'KLVK', - city: 'Livermore, Livermore Municipal Airport', - state: 'CA', - lat: 37.69278, - lon: -121.81444, - }, - KSDB: { - id: 'KSDB', - city: 'Sandberg', - state: 'CA', - lat: 34.7436099, - lon: -118.72444, - }, - KAPC: { - id: 'KAPC', - city: 'Napa, Napa County Airport', - state: 'CA', - lat: 38.2075, - lon: -122.27944, - }, - KCNO: { - id: 'KCNO', - city: 'Chino, Chino Airport', - state: 'CA', - lat: 33.97556, - lon: -117.62361, - }, - KMYF: { - id: 'KMYF', - city: 'San Diego, Montgomery Field', - state: 'CA', - lat: 32.81444, - lon: -117.13639, - }, - KTOA: { - id: 'KTOA', - city: 'Torrance, Zamperini Field Airport', - state: 'CA', - lat: 33.8, - lon: -118.33333, - }, - KSDM: { - id: 'KSDM', - city: 'San Diego, Brown Field Municipal Airport', - state: 'CA', - lat: 32.57528, - lon: -116.99306, - }, - KHJO: { - id: 'KHJO', - city: 'Hanford, Hanford Municipal Airport', - state: 'CA', - lat: 36.31861, - lon: -119.62889, - }, - KMMH: { - id: 'KMMH', - city: 'Mammoth Yosemite Airport', - state: 'CA', - lat: 37.6241, - lon: -118.8423, - }, - KMHV: { - id: 'KMHV', - city: 'Mojave', - state: 'CA', - lat: 35.06667, - lon: -118.15, - }, - KHWD: { - id: 'KHWD', - city: 'Hayward, Hayward Air Terminal', - state: 'CA', - lat: 37.66083, - lon: -122.11833, - }, - KNUC: { - id: 'KNUC', - city: 'San Clemente Island NALF', - state: 'CA', - lat: 33.0218, - lon: -118.58266, - }, - KOVE: { - id: 'KOVE', - city: 'Oroville, Oroville Municipal Airport', - state: 'CA', - lat: 39.49472, - lon: -121.62028, - }, - KMHS: { - id: 'KMHS', - city: 'Mount Shasta', - state: 'CA', - lat: 41.31494, - lon: -122.31702, - }, - KAAT: { - id: 'KAAT', - city: 'Alturas', - state: 'CA', - lat: 41.48362, - lon: -120.5615, - }, - KPTV: { - id: 'KPTV', - city: 'Porterville, Porterville Municipal Airport', - state: 'CA', - lat: 36.03333, - lon: -119.06667, - }, - KOXR: { - id: 'KOXR', - city: 'Oxnard, Oxnard Airport', - state: 'CA', - lat: 34.20056, - lon: -119.20306, - }, - KRNM: { - id: 'KRNM', - city: 'Ramona, Ramona Airport', - state: 'CA', - lat: 33.0375, - lon: -116.91583, - }, - KSVE: { - id: 'KSVE', - city: 'Susanville Municipal Airport', - state: 'CA', - lat: 40.37569, - lon: -120.57269, - }, - KBLU: { - id: 'KBLU', - city: 'Emigrant Gap, Blue Canyon Nyack Airport', - state: 'CA', - lat: 39.27611, - lon: -120.70806, - }, - KCQT: { - id: 'KCQT', - city: 'Los Angeles / USC Campus Downtown', - state: 'CA', - lat: 34.02355, - lon: -118.29122, - }, - KSQL: { - id: 'KSQL', - city: 'San Carlos Airport', - state: 'CA', - lat: 37.51667, - lon: -122.25, - }, - KPOC: { - id: 'KPOC', - city: 'La Verne / Brackett', - state: 'CA', - lat: 34.1, - lon: -117.78333, - }, - KSIY: { - id: 'KSIY', - city: 'Montague Siskiyou County Airport', - state: 'CA', - lat: 41.77375, - lon: -122.46817, - }, - KSLI: { - id: 'KSLI', - city: 'Los Alamitos U. S. Army Airfield', - state: 'CA', - lat: 33.78333, - lon: -118.05, - }, - KSEE: { - id: 'KSEE', - city: 'San Diego/El Cajon, Gillespie Field Airport', - state: 'CA', - lat: 32.82611, - lon: -116.97222, - }, - KCCR: { - id: 'KCCR', - city: 'Concord, Buchanan Field', - state: 'CA', - lat: 37.99167, - lon: -122.05194, - }, - KNUQ: { - id: 'KNUQ', - city: 'Mountain View, Moffett Field', - state: 'CA', - lat: 37.40583, - lon: -122.04806, - }, - KVCB: { - id: 'KVCB', - city: 'Vacaville Nut Tree Airport', - state: 'CA', - lat: 38.37755, - lon: -121.95853, - }, - KMYV: { - id: 'KMYV', - city: 'Marysville, Yuba County Airport', - state: 'CA', - lat: 39.09778, - lon: -121.56972, - }, - KVIS: { - id: 'KVIS', - city: 'Visalia, Visalia Municipal Airport', - state: 'CA', - lat: 36.31667, - lon: -119.4, - }, - KLPC: { - id: 'KLPC', - city: 'Lompoc, Lompoc Airport', - state: 'CA', - lat: 34.66667, - lon: -120.46667, - }, - KFUL: { - id: 'KFUL', - city: 'Fullerton, Fullerton Municipal Airport', - state: 'CA', - lat: 33.87194, - lon: -117.98472, - }, - KEMT: { - id: 'KEMT', - city: 'El Monte', - state: 'CA', - lat: 34.0833299, - lon: -118.03333, - }, - KCIC: { - id: 'KCIC', - city: 'Chico Municipal', - state: 'CA', - lat: 39.8, - lon: -121.85, - }, - KRHV: { - id: 'KRHV', - city: 'San Jose / Reid / Hillv', - state: 'CA', - lat: 37.3333299, - lon: -121.81667, - }, - KMCC: { - id: 'KMCC', - city: 'Sacramento, McClellan Airfield Airport', - state: 'CA', - lat: 38.66667, - lon: -121.4, - }, - KCMA: { - id: 'KCMA', - city: 'Camarillo, Camarillo Airport', - state: 'CA', - lat: 34.21667, - lon: -119.08333, - }, - KNRS: { - id: 'KNRS', - city: 'Imperial Beach, Naval Auxiliary Landing Field', - state: 'CA', - lat: 32.56306, - lon: -117.11, - }, - KOKB: { - id: 'KOKB', - city: 'Oceanside, Oceanside Municipal Airport', - state: 'CA', - lat: 33.21806, - lon: -117.35139, - }, - KRIV: { - id: 'KRIV', - city: 'Riverside / March Air Force Base', - state: 'CA', - lat: 33.9, - lon: -117.25, - }, - KWVI: { - id: 'KWVI', - city: 'Watsonville, Watsonville Municipal Airport', - state: 'CA', - lat: 36.93944, - lon: -121.78889, - }, - KIZA: { - id: 'KIZA', - city: 'Santa Ynez, Santa Ynez Airport', - state: 'CA', - lat: 34.60694, - lon: -120.07556, - }, - KAVX: { - id: 'KAVX', - city: 'Avalon Catalina Airport', - state: 'CA', - lat: 33.40421, - lon: -118.41456, - }, - KJAQ: { - id: 'KJAQ', - city: 'JACKSON', - state: 'CA', - lat: 38.37683, - lon: -120.794, - }, - KDVO: { - id: 'KDVO', - city: 'Novato / Gnoss Field', - state: 'CA', - lat: 38.14178, - lon: -122.55463, - }, - KMER: { - id: 'KMER', - city: 'Merced / Castle Air Force Base', - state: 'CA', - lat: 37.36667, - lon: -120.56667, - }, - KSBD: { - id: 'KSBD', - city: 'San Bernardino Intl. Airport', - state: 'CA', - lat: 34.0902699, - lon: -117.24705, - }, - KWHP: { - id: 'KWHP', - city: 'Los Angeles, Whiteman Airport', - state: 'CA', - lat: 34.25, - lon: -118.4, - }, - KVCV: { - id: 'KVCV', - city: 'Victorville, Southern California Logistics Airport', - state: 'CA', - lat: 34.59722, - lon: -117.38278, - }, - KAUN: { - id: 'KAUN', - city: 'Auburn Municipal Airport', - state: 'CA', - lat: 38.95535, - lon: -121.08636, - }, - KAPV: { - id: 'KAPV', - city: 'APPLE VALLEY', - state: 'CA', - lat: 34.57533, - lon: -117.18619, - }, - KAJO: { - id: 'KAJO', - city: 'Corona Airport', - state: 'CA', - lat: 33.8977, - lon: -117.6024, - }, - KREI: { - id: 'KREI', - city: 'REDLANDS', - state: 'CA', - lat: 34.08526, - lon: -117.14637, - }, - KHES: { - id: 'KHES', - city: 'HEALDSBURG', - state: 'CA', - lat: 38.65272, - lon: -122.89866, - }, - KEDU: { - id: 'KEDU', - city: 'University Airport', - state: 'CA', - lat: 38.5315, - lon: -121.7865, - }, - KHAF: { - id: 'KHAF', - city: 'Half Moon Bay Airport', - state: 'CA', - lat: 37.5135999, - lon: -122.4996, - }, - KCVH: { - id: 'KCVH', - city: 'Hollister, CA', - state: 'CA', - lat: 36.8933, - lon: -121.4103, - }, - KPVF: { - id: 'KPVF', - city: 'Placerville Airport', - state: 'CA', - lat: 38.7242, - lon: -120.7533, - }, - KLHM: { - id: 'KLHM', - city: 'Lincoln Regional Karl Harder Field', - state: 'CA', - lat: 38.9092, - lon: -121.3513, - }, - KNXF: { - id: 'KNXF', - city: 'Mcolf Camp Pendleton (Red Beach)', - state: 'CA', - lat: 33.2856, - lon: -117.4565, - }, - KTSP: { - id: 'KTSP', - city: 'Tehachapi Municipal Airport', - state: 'CA', - lat: 35.135, - lon: -118.4392, - }, - KFOT: { - id: 'KFOT', - city: 'Fortuna Rohnerville Airport', - state: 'CA', - lat: 40.55296, - lon: -124.13338, - }, - KGOO: { - id: 'KGOO', - city: 'Nevada County Air Park', - state: 'CA', - lat: 39.2240279, - lon: -121.003083, - }, - KBAN: { - id: 'KBAN', - city: 'MCMWTC BRIDGEPORT', - state: 'CA', - lat: 38.3557, - lon: -119.5188, - }, - KGXA: { - id: 'KGXA', - city: 'Gray Butte Field Airport', - state: 'CA', - lat: 34.5666, - lon: -117.6704, - }, - KRAP: { - id: 'KRAP', - city: 'Rapid City, Rapid City Regional Airport', - state: 'SD', - lat: 44.04556, - lon: -103.05389, - }, - KFSD: { - id: 'KFSD', - city: 'Sioux Falls, Foss Field', - state: 'SD', - lat: 43.57694, - lon: -96.75361, - }, - KABR: { - id: 'KABR', - city: 'Aberdeen, Aberdeen Regional Airport', - state: 'SD', - lat: 45.44333, - lon: -98.41306, - }, - KPIR: { - id: 'KPIR', - city: 'Pierre, Pierre Regional Airport', - state: 'SD', - lat: 44.3827799, - lon: -100.28583, - }, - KHON: { - id: 'KHON', - city: 'Huron, Huron Regional Airport', - state: 'SD', - lat: 44.38806, - lon: -98.22833, - }, - KRCA: { - id: 'KRCA', - city: 'Ellsworth Air Force Base', - state: 'SD', - lat: 44.15, - lon: -103.1, - }, - KMBG: { - id: 'KMBG', - city: 'Mobridge, Mobridge Municipal Airport', - state: 'SD', - lat: 45.55, - lon: -100.40861, - }, - KATY: { - id: 'KATY', - city: 'Watertown, Watertown Municipal Airport', - state: 'SD', - lat: 44.90472, - lon: -97.14944, - }, - KMHE: { - id: 'KMHE', - city: 'Mitchell, Mitchell Municipal Airport', - state: 'SD', - lat: 43.76667, - lon: -98.03333, - }, - KIEN: { - id: 'KIEN', - city: 'Pine Ridge, Pine Ridge Airport', - state: 'SD', - lat: 43.02556, - lon: -102.52306, - }, - KBKX: { - id: 'KBKX', - city: 'Brookings, Brookings Municipal Airport', - state: 'SD', - lat: 44.3, - lon: -96.81667, - }, - KPHP: { - id: 'KPHP', - city: 'Philip, Philip Airport', - state: 'SD', - lat: 44.05111, - lon: -101.60111, - }, - KYKN: { - id: 'KYKN', - city: 'Yankton, Chan Gurney Municipal Airport', - state: 'SD', - lat: 42.91667, - lon: -97.38333, - }, - KEFC: { - id: 'KEFC', - city: 'BELLE FOURCHE', - state: 'SD', - lat: 44.7342, - lon: -103.86199, - }, - KCUT: { - id: 'KCUT', - city: 'Custer, Custer County Airport', - state: 'SD', - lat: 43.73306, - lon: -103.6175, - }, - KICR: { - id: 'KICR', - city: 'Winner, Bob Wiley Field Airport', - state: 'SD', - lat: 43.39056, - lon: -99.8425, - }, - KSPF: { - id: 'KSPF', - city: 'Spearfish / Clyde Ice', - state: 'SD', - lat: 44.48333, - lon: -103.78333, - }, - KBTN: { - id: 'KBTN', - city: 'BRITTON', - state: 'SD', - lat: 45.8152199, - lon: -97.7431299, - }, - KVMR: { - id: 'KVMR', - city: 'VERMILLION', - state: 'SD', - lat: 42.76528, - lon: -96.93425, - }, - KMDS: { - id: 'KMDS', - city: 'Madison Municipal Airport', - state: 'SD', - lat: 44.0164147, - lon: -97.0855992, - }, - KHSR: { - id: 'KHSR', - city: 'HOTSPRINGS', - state: 'SD', - lat: 43.36824, - lon: -103.38813, - }, - KMKA: { - id: 'KMKA', - city: 'MILLERMUNC', - state: 'SD', - lat: 44.5252399, - lon: -98.95811, - }, - KUNR: { - id: 'KUNR', - city: 'Rapid City/WFO', - state: 'SD', - lat: 44.0727, - lon: -103.2108, - }, - KLEM: { - id: 'KLEM', - city: 'LEMMON', - state: 'SD', - lat: 45.91869, - lon: -102.10617, - }, - KPVD: { - id: 'KPVD', - city: 'Providence, Theodore Francis Green State Airport', - state: 'RI', - lat: 41.72249, - lon: -71.43247, - }, - KBID: { - id: 'KBID', - city: 'Block Island State Airport', - state: 'RI', - lat: 41.1694699, - lon: -71.5787299, - }, - KOQU: { - id: 'KOQU', - city: 'N. Kingston / Quonset', - state: 'RI', - lat: 41.6, - lon: -71.41667, - }, - KUUU: { - id: 'KUUU', - city: 'Newport, Newport State Airport', - state: 'RI', - lat: 41.53, - lon: -71.28361, - }, - KSFZ: { - id: 'KSFZ', - city: 'Pawtucket, North Central State Airport', - state: 'RI', - lat: 41.91667, - lon: -71.5, - }, - KWST: { - id: 'KWST', - city: 'Westerly, Westerly State Airport', - state: 'RI', - lat: 41.34972, - lon: -71.79889, - }, - KBIS: { - id: 'KBIS', - city: 'Bismarck, Bismarck Municipal Airport', - state: 'ND', - lat: 46.7825, - lon: -100.75722, - }, - KFAR: { - id: 'KFAR', - city: 'Fargo, Hector International Airport', - state: 'ND', - lat: 46.92528, - lon: -96.81111, - }, - KGFK: { - id: 'KGFK', - city: 'Grand Forks, Grand Forks International Airport', - state: 'ND', - lat: 47.94806, - lon: -97.1825, - }, - KRDR: { - id: 'KRDR', - city: 'Grand Forks Air Force Base', - state: 'ND', - lat: 47.96667, - lon: -97.4, - }, - KJMS: { - id: 'KJMS', - city: 'Jamestown, Jamestown Municipal Airport', - state: 'ND', - lat: 46.92972, - lon: -98.67833, - }, - KMIB: { - id: 'KMIB', - city: 'Minot Air Force Base', - state: 'ND', - lat: 48.41667, - lon: -101.35, - }, - KDIK: { - id: 'KDIK', - city: 'Dickinson, Dickinson Municipal Airport', - state: 'ND', - lat: 46.79722, - lon: -102.80194, - }, - KISN: { - id: 'KISN', - city: 'Williston, Sloulin Field International Airport', - state: 'ND', - lat: 48.17389, - lon: -103.63667, - }, - KMOT: { - id: 'KMOT', - city: 'Minot, Minot International Airport', - state: 'ND', - lat: 48.25944, - lon: -101.28028, - }, - KHEI: { - id: 'KHEI', - city: 'Hettinger, Hettinger Municipal Airport', - state: 'ND', - lat: 46.01056, - lon: -102.64972, - }, - KDVL: { - id: 'KDVL', - city: 'Devils Lake, Devils Lake Municipal Airport', - state: 'ND', - lat: 48.11667, - lon: -98.91667, - }, - KBWP: { - id: 'KBWP', - city: 'Wahpeton, Harry Stern Airport', - state: 'ND', - lat: 46.24389, - lon: -96.60722, - }, - KRUG: { - id: 'KRUG', - city: 'RUGBY', - state: 'ND', - lat: 48.38, - lon: -100.02, - }, - KGAF: { - id: 'KGAF', - city: 'GRAFTON', - state: 'ND', - lat: 48.4, - lon: -97.37, - }, - KGWR: { - id: 'KGWR', - city: 'Gwinner', - state: 'ND', - lat: 46.2187, - lon: -97.6435, - }, - KHZE: { - id: 'KHZE', - city: 'HAZEN', - state: 'ND', - lat: 47.28, - lon: -101.58, - }, - KBAC: { - id: 'KBAC', - city: 'Valley City', - state: 'ND', - lat: 46.9412, - lon: -98.018, - }, - KCHS: { - id: 'KCHS', - city: 'Charleston, Charleston Air Force Base', - state: 'SC', - lat: 32.89889, - lon: -80.04056, - }, - KCAE: { - id: 'KCAE', - city: 'Columbia, Columbia Metropolitan Airport', - state: 'SC', - lat: 33.94194, - lon: -81.11806, - }, - KGSP: { - id: 'KGSP', - city: 'Greer, Greenville-Spartanburg Airport', - state: 'SC', - lat: 34.88389, - lon: -82.22083, - }, - KGMU: { - id: 'KGMU', - city: 'Greenville, Greenville Downtown Airport', - state: 'SC', - lat: 34.84611, - lon: -82.34611, - }, - KAND: { - id: 'KAND', - city: 'Anderson, Anderson County Airport', - state: 'SC', - lat: 34.49778, - lon: -82.70972, - }, - KCRE: { - id: 'KCRE', - city: 'North Myrtle Beach Grand Strand Airport', - state: 'SC', - lat: 33.81619, - lon: -78.7204299, - }, - KMMT: { - id: 'KMMT', - city: 'McEntire Air National Guard Weather Facility Base', - state: 'SC', - lat: 33.91667, - lon: -80.8, - }, - KNBC: { - id: 'KNBC', - city: 'Beaufort, Marine Corps Air Station', - state: 'SC', - lat: 32.4936099, - lon: -80.7030599, - }, - KFLO: { - id: 'KFLO', - city: 'Florence - Florence Regional Airport', - state: 'SC', - lat: 34.1877799, - lon: -79.73083, - }, - KSSC: { - id: 'KSSC', - city: 'Shaw Air Force Base', - state: 'SC', - lat: 33.96667, - lon: -80.48333, - }, - KMYR: { - id: 'KMYR', - city: 'Myrtle Beach Air Force Base', - state: 'SC', - lat: 33.68333, - lon: -78.93333, - }, - KCEU: { - id: 'KCEU', - city: 'Clemson, Clemson-Oconee County Airport', - state: 'SC', - lat: 34.67222, - lon: -82.88139, - }, - KGRD: { - id: 'KGRD', - city: 'Greenwood, Greenwood County Airport', - state: 'SC', - lat: 34.24722, - lon: -82.15472, - }, - KCUB: { - id: 'KCUB', - city: 'Columbia - Jim Hamilton L.B. Owens Airport', - state: 'SC', - lat: 33.97083, - lon: -80.99444, - }, - KOGB: { - id: 'KOGB', - city: 'Orangeburg, Orangeburg Municipal Airport', - state: 'SC', - lat: 33.46389, - lon: -80.85361, - }, - KUZA: { - id: 'KUZA', - city: 'Rock Hill, Rock Hill - York County Airport', - state: 'SC', - lat: 34.98389, - lon: -81.05583, - }, - KUDG: { - id: 'KUDG', - city: 'Darlington, Darlington County Jetport Airport', - state: 'SC', - lat: 34.44917, - lon: -79.89028, - }, - KHXD: { - id: 'KHXD', - city: 'Hilton Head Island, Hilton Head Airport', - state: 'SC', - lat: 32.21667, - lon: -80.7, - }, - KGYH: { - id: 'KGYH', - city: 'Greenville-Donaldson Center Airport', - state: 'SC', - lat: 34.7583, - lon: -82.3764, - }, - KARW: { - id: 'KARW', - city: 'Beaufort County Airport', - state: 'SC', - lat: 32.412, - lon: -80.634, - }, - KMKS: { - id: 'KMKS', - city: 'Moncks Corner Berkeley County', - state: 'SC', - lat: 33.1855, - lon: -80.0361999, - }, - KSPA: { - id: 'KSPA', - city: 'Spartanburg Memorial', - state: 'SC', - lat: 34.91667, - lon: -81.95, - }, - KMNI: { - id: 'KMNI', - city: 'Manning / Cooper Regional', - state: 'SC', - lat: 33.5833299, - lon: -80.2166699, - }, - KGGE: { - id: 'KGGE', - city: 'Georgetown County Airport ', - state: 'SC', - lat: 33.3117, - lon: -79.3196, - }, - KEOE: { - id: 'KEOE', - city: 'Newberry County Airport', - state: 'SC', - lat: 34.309, - lon: -81.64, - }, - KSMS: { - id: 'KSMS', - city: 'Sumter Airport', - state: 'SC', - lat: 33.995, - lon: -80.361, - }, - KDCM: { - id: 'KDCM', - city: 'Chester Catawba Regional Airport', - state: 'SC', - lat: 34.789, - lon: -81.196, - }, - KCQW: { - id: 'KCQW', - city: 'Cheraw Municipal Lynch Bellinger Field', - state: 'SC', - lat: 34.713, - lon: -79.9569999, - }, - KLUX: { - id: 'KLUX', - city: 'Laurens County Airport', - state: 'SC', - lat: 34.507, - lon: -81.947, - }, - KAIK: { - id: 'KAIK', - city: 'Aiken Municipal Airport', - state: 'SC', - lat: 33.649, - lon: -81.685, - }, - KLKR: { - id: 'KLKR', - city: 'Lancaster County-mc Whirter Field', - state: 'SC', - lat: 34.723, - lon: -80.855, - }, - KMAO: { - id: 'KMAO', - city: 'Marion County Airport', - state: 'SC', - lat: 34.181, - lon: -79.3349999, - }, - KDYB: { - id: 'KDYB', - city: 'Summerville Airport', - state: 'SC', - lat: 33.063, - lon: -80.279, - }, - KFDW: { - id: 'KFDW', - city: 'Winnsboro/Fairfield County Airport', - state: 'SC', - lat: 34.315, - lon: -81.109, - }, - KLQK: { - id: 'KLQK', - city: 'Pickens County Airport', - state: 'SC', - lat: 34.80997, - lon: -82.70289, - }, - KLRO: { - id: 'KLRO', - city: 'Mount Pleasant Regional-Faison Field', - state: 'SC', - lat: 32.898, - lon: -79.783, - }, - KHYW: { - id: 'KHYW', - city: 'Conway Horry County Airport', - state: 'SC', - lat: 33.829, - lon: -79.122, - }, - KCKI: { - id: 'KCKI', - city: 'Kingstree Williamsburg Regional Airport', - state: 'SC', - lat: 33.717, - lon: -79.857, - }, - KBBP: { - id: 'KBBP', - city: 'Marlboro County Jetport', - state: 'SC', - lat: 34.622, - lon: -79.734, - }, - KJZI: { - id: 'KJZI', - city: 'Charleston Executive Airport', - state: 'SC', - lat: 32.701, - lon: -80.003, - }, - KHVS: { - id: 'KHVS', - city: 'Hartsville Regional Airport', - state: 'SC', - lat: 34.403, - lon: -80.119, - }, - KRBW: { - id: 'KRBW', - city: 'Walterboro Lowcountry Regional Airport', - state: 'SC', - lat: 32.921, - lon: -80.641, - }, - KAQX: { - id: 'KAQX', - city: 'Allendale County Airport', - state: 'SC', - lat: 32.9951, - lon: -81.2703, - }, - KMHT: { - id: 'KMHT', - city: 'Manchester Airport', - state: 'NH', - lat: 42.92964, - lon: -71.43559, - }, - KLEB: { - id: 'KLEB', - city: 'Lebanon Municipal Airport', - state: 'NH', - lat: 43.6271, - lon: -72.30537, - }, - KCON: { - id: 'KCON', - city: 'Concord Municipal Airport', - state: 'NH', - lat: 43.20489, - lon: -71.50257, - }, - KPSM: { - id: 'KPSM', - city: 'Pease Air Force Base / Portsmouth', - state: 'NH', - lat: 43.0833299, - lon: -70.81667, - }, - KEEN: { - id: 'KEEN', - city: 'Keene, Dillant-Hopkins Airport', - state: 'NH', - lat: 42.9, - lon: -72.26667, - }, - KAFN: { - id: 'KAFN', - city: 'Jaffrey Airport-Silver Ranch', - state: 'NH', - lat: 42.8066699, - lon: -72.00127, - }, - KDAW: { - id: 'KDAW', - city: 'Rochester - Skyhaven Airport', - state: 'NH', - lat: 43.27939, - lon: -70.92426, - }, - KBML: { - id: 'KBML', - city: 'Berlin, Berlin Municipal Airport', - state: 'NH', - lat: 44.57611, - lon: -71.17861, - }, - KHIE: { - id: 'KHIE', - city: 'Whitefield - Mount Washington Regional Airport', - state: 'NH', - lat: 44.36595, - lon: -71.55218, - }, - KASH: { - id: 'KASH', - city: 'Nashua - Boire Field Airport', - state: 'NH', - lat: 42.77981, - lon: -71.51409, - }, - KLCI: { - id: 'KLCI', - city: 'Laconia, Laconia Municipal Airport', - state: 'NH', - lat: 43.56667, - lon: -71.41667, - }, - KMWN: { - id: 'KMWN', - city: 'Mount Washington', - state: 'NH', - lat: 44.26667, - lon: -71.3, - }, - MRSO: { - id: 'MRSO', - city: 'MADRAS', - state: 'OR', - lat: 44.68, - lon: -121.14861, - }, - ONTO: { - id: 'ONTO', - city: 'ONTARIO', - state: 'OR', - lat: 43.97778, - lon: -117.01528, - }, - HRFO: { - id: 'HRFO', - city: 'HEREFORD', - state: 'OR', - lat: 44.48806, - lon: -118.02, - }, - BRKO: { - id: 'BRKO', - city: 'BROOKINGS', - state: 'OR', - lat: 42.03, - lon: -124.24083, - }, - WRDO: { - id: 'WRDO', - city: 'Worden', - state: 'OR', - lat: 42.01694, - lon: -121.78694, - }, - CHVO: { - id: 'CHVO', - city: 'CHRISTMAS VALLEY', - state: 'OR', - lat: 43.24139, - lon: -120.72806, - }, - PCYO: { - id: 'PCYO', - city: 'PRARIE CITY', - state: 'OR', - lat: 44.44083, - lon: -118.62778, - }, - HERO: { - id: 'HERO', - city: 'HERMISTON', - state: 'OR', - lat: 45.82111, - lon: -119.52139, - }, - HOXO: { - id: 'HOXO', - city: 'HOOD RIVER', - state: 'OR', - lat: 45.68444, - lon: -121.51806, - }, - ECHO: { - id: 'ECHO', - city: 'ECHO', - state: 'OR', - lat: 45.71861, - lon: -119.31111, - }, - BANO: { - id: 'BANO', - city: 'BANDON', - state: 'OR', - lat: 43.09111, - lon: -124.41722, - }, - IMBO: { - id: 'IMBO', - city: 'IMBLER', - state: 'OR', - lat: 45.43333, - lon: -117.96667, - }, - DEFO: { - id: 'DEFO', - city: 'DEE FLAT', - state: 'OR', - lat: 45.58639, - lon: -121.64056, - }, - PNGO: { - id: 'PNGO', - city: 'PINEGROVE', - state: 'OR', - lat: 45.65222, - lon: -121.50917, - }, - CRVO: { - id: 'CRVO', - city: 'CORVALLIS', - state: 'OR', - lat: 44.63417, - lon: -123.19, - }, - LAKO: { - id: 'LAKO', - city: 'LAKEVIEW', - state: 'OR', - lat: 42.12222, - lon: -120.52306, - }, - FOGO: { - id: 'FOGO', - city: 'FOREST GROVE', - state: 'OR', - lat: 45.55306, - lon: -123.08361, - }, - ARAO: { - id: 'ARAO', - city: 'AURORA', - state: 'OR', - lat: 45.28194, - lon: -122.75028, - }, - POBO: { - id: 'POBO', - city: 'POWELL BUTTE', - state: 'OR', - lat: 44.24833, - lon: -120.94972, - }, - HRMO: { - id: 'HRMO', - city: 'HERMISTON R&E', - state: 'OR', - lat: 45.81944, - lon: -119.28333, - }, - PARO: { - id: 'PARO', - city: 'PARKDALE', - state: 'OR', - lat: 45.54444, - lon: -121.61667, - }, - MDFO: { - id: 'MDFO', - city: 'MEDFORD', - state: 'OR', - lat: 42.33111, - lon: -122.93778, - }, - BEWO: { - id: 'BEWO', - city: 'Bend', - state: 'OR', - lat: 44.0475, - lon: -121.32028, - }, - DTRO: { - id: 'DTRO', - city: 'Detroit Lake', - state: 'OR', - lat: 44.7299999, - lon: -122.17917, - }, - LORO: { - id: 'LORO', - city: 'Lorella', - state: 'OR', - lat: 42.07778, - lon: -121.22417, - }, - BKVO: { - id: 'BKVO', - city: 'Baker Valley', - state: 'OR', - lat: 44.88194, - lon: -117.96361, - }, - AGKO: { - id: 'AGKO', - city: 'Agency Lake', - state: 'OR', - lat: 42.56528, - lon: -121.9825, - }, - BATO: { - id: 'BATO', - city: 'Beatty', - state: 'OR', - lat: 42.478, - lon: -121.27389, - }, - KJSY: { - id: 'KJSY', - city: 'Joseph State Airport AWOS', - state: 'OR', - lat: 45.355889, - lon: -117.254083, - }, - CPRA: { - id: 'CPRA', - city: 'Crane Prairie Reservoir nr. LaPine, OR', - state: 'OR', - lat: 43.7555555, - lon: -121.7833333, - }, - OCRO: { - id: 'OCRO', - city: 'Ochoco Cr. above Reservoir nr Prineville, OR', - state: 'OR', - lat: 44.3333333, - lon: -120.5827777, - }, - NPAO: { - id: 'NPAO', - city: 'N. Powder River bel Anthony Cr nr North Powder', - state: 'OR', - lat: 45.0127777, - lon: -118.0530555, - }, - ALNO: { - id: 'ALNO', - city: 'Allen Canal at Echo, OR', - state: 'OR', - lat: 45.7336111, - lon: -119.2041666, - }, - BCMO: { - id: 'BCMO', - city: 'Bear Creek at Mouth below Central Point, OR', - state: 'OR', - lat: 42.4263888, - lon: -122.9569444, - }, - CRRO: { - id: 'CRRO', - city: 'Castle Rock Ranch, OR', - state: 'OR', - lat: 43.9958333, - lon: -118.2269444, - }, - GRZO: { - id: 'GRZO', - city: 'Grizzly, OR', - state: 'OR', - lat: 44.5197222, - lon: -120.9386111, - }, - LBCO: { - id: 'LBCO', - city: 'Little Butte Creek at Lakecreek, OR', - state: 'OR', - lat: 42.4222222, - lon: -122.6222222, - }, - MYKO: { - id: 'MYKO', - city: 'Mckay Creek near Pilot Rock, OR', - state: 'OR', - lat: 45.5491666, - lon: -118.7733333, - }, - MAXO: { - id: 'MAXO', - city: 'Maxwell Canal near Hermiston, OR', - state: 'OR', - lat: 45.8047222, - lon: -119.3577777, - }, - WEIO: { - id: 'WEIO', - city: 'West Div Main Canal below WEID Pumps nr Umatilla OR', - state: 'OR', - lat: 45.8841666, - lon: -119.325, - }, - JDIO: { - id: 'JDIO', - city: 'South Fork John Day River above Izee Falls', - state: 'OR', - lat: 44.1236111, - lon: -119.4905555, - }, - BCTO: { - id: 'BCTO', - city: 'Bear Creek below Phoenix Diversion near Talent', - state: 'OR', - lat: 42.2536111, - lon: -122.7888888, - }, - SCLO: { - id: 'SCLO', - city: 'Scoggins Creek above Henry Hagg Lake, OR', - state: 'OR', - lat: 45.5016666, - lon: -123.2516666, - }, - WEPO: { - id: 'WEPO', - city: 'WEID Exchange Pump Plant near Hermiston, OR', - state: 'OR', - lat: 45.9197222, - lon: -119.3275, - }, - DRCO: { - id: 'DRCO', - city: 'Deer Creek above Phillips Lake', - state: 'OR', - lat: 44.6916666, - lon: -118.0638888, - }, - JDMO: { - id: 'JDMO', - city: 'John Day River at McDonald Ferry, OR', - state: 'OR', - lat: 45.5877777, - lon: -120.4083333, - }, - ROMO: { - id: 'ROMO', - city: 'Owyhee River near Rome, OR', - state: 'OR', - lat: 42.8663888, - lon: -117.6488888, - }, - PDTO: { - id: 'PDTO', - city: 'Umatilla River at Pendleton, OR', - state: 'OR', - lat: 45.6722222, - lon: -118.7916666, - }, - DLEO: { - id: 'DLEO', - city: 'Dillon Canal near Stanfield, OR', - state: 'OR', - lat: 45.7661111, - lon: -119.2161111, - }, - DEBO: { - id: 'DEBO', - city: 'Deschutes River Below Bend, OR', - state: 'OR', - lat: 44.0830555, - lon: -121.3066666, - }, - CKKO: { - id: 'CKKO', - city: 'Crooked Rver near Terrebonne, OR', - state: 'OR', - lat: 44.3583333, - lon: -121.1177777, - }, - LEFO: { - id: 'LEFO', - city: 'Tualatin River below Lee Falls nr Cherry Grove, OR', - state: 'OR', - lat: 45.5058333, - lon: -123.2183333, - }, - PILO: { - id: 'PILO', - city: 'Pilot Rock 11E, OR', - state: 'OR', - lat: 45.5019444, - lon: -118.6205555, - }, - EBCO: { - id: 'EBCO', - city: 'East Birch Creek at Pilot Rock, OR', - state: 'OR', - lat: 45.4841666, - lon: -118.8344444, - }, - BEUO: { - id: 'BEUO', - city: 'North Fork Malheur River at Beulah', - state: 'OR', - lat: 43.9088888, - lon: -118.1522222, - }, - NFLO: { - id: 'NFLO', - city: 'North Fork Little Butte Creek at 140, OR', - state: 'OR', - lat: 42.4027777, - lon: -122.5366666, - }, - PWDO: { - id: 'PWDO', - city: 'Powder River at Baker, OR', - state: 'OR', - lat: 44.7683333, - lon: -117.8305555, - }, - OCWO: { - id: 'OCWO', - city: 'Ochoco Ranger Station, OR', - state: 'OR', - lat: 44.3966666, - lon: -120.4266666, - }, - TRGO: { - id: 'TRGO', - city: 'Trout Creek at Clements Drive near Gateway, OR', - state: 'OR', - lat: 44.8013888, - lon: -121.065, - }, - EPTO: { - id: 'EPTO', - city: 'Antelope Creek near Eagle Point, OR', - state: 'OR', - lat: 42.4555555, - lon: -122.8266666, - }, - PRVO: { - id: 'PRVO', - city: 'Crooked River near Prineville, OR', - state: 'OR', - lat: 44.1138888, - lon: -120.7944444, - }, - CACO: { - id: 'CACO', - city: 'Cascade Canal near Fish Lake', - state: 'OR', - lat: 42.4055555, - lon: -122.2680555, - }, - YOKO: { - id: 'YOKO', - city: 'Umatilla River at Yoakum, OR', - state: 'OR', - lat: 45.6772222, - lon: -119.0358333, - }, - LBEO: { - id: 'LBEO', - city: 'Little Butte Creek below Eagle Point, OR', - state: 'OR', - lat: 42.4627777, - lon: -122.8152777, - }, - MADO: { - id: 'MADO', - city: 'Malheur River near Drewsey, OR', - state: 'OR', - lat: 43.7847222, - lon: -118.3305555, - }, - TRDO: { - id: 'TRDO', - city: 'Trout Creek, OR near Denio, NV', - state: 'OR', - lat: 42.1555555, - lon: -118.4538888, - }, - DANO: { - id: 'DANO', - city: 'Danner, OR', - state: 'OR', - lat: 42.9402777, - lon: -117.3402777, - }, - SQSO: { - id: 'SQSO', - city: 'Whychus Creek at Sisters, OR', - state: 'OR', - lat: 44.2877777, - lon: -121.5433333, - }, - SBEO: { - id: 'SBEO', - city: 'Stanfield Branch Exchange Canal near Hermiston, OR', - state: 'OR', - lat: 45.8677777, - lon: -119.1713888, - }, - ARNO: { - id: 'ARNO', - city: 'Arnold Canal', - state: 'OR', - lat: 43.9944444, - lon: -121.3777777, - }, - TUMO: { - id: 'TUMO', - city: 'Tumalo Creek nr Bend, OR', - state: 'OR', - lat: 44.0877777, - lon: -121.3716666, - }, - WEUO: { - id: 'WEUO', - city: 'West Division Main Canal near Umatilla, OR', - state: 'OR', - lat: 45.885, - lon: -119.3266666, - }, - TFCO: { - id: 'TFCO', - city: 'Tumalo Feed Canal (2 Flow Meters)', - state: 'OR', - lat: 44.0902777, - lon: -121.3686111, - }, - OCHO: { - id: 'OCHO', - city: 'Ochoco Creek below Ochoco Reservoir, OR', - state: 'OR', - lat: 44.2988888, - lon: -120.7277777, - }, - VALO: { - id: 'VALO', - city: 'Malheur River below Nevada Dam near Vale, OR', - state: 'OR', - lat: 43.9888888, - lon: -117.2194444, - }, - NMCO: { - id: 'NMCO', - city: 'North Unit Main Canal', - state: 'OR', - lat: 44.0772222, - lon: -121.3019444, - }, - CRSO: { - id: 'CRSO', - city: 'Crooked Riv at Smith Rock St. Park nr Terrebonne, OR', - state: 'OR', - lat: 44.3675, - lon: -121.1388888, - }, - FCSO: { - id: 'FCSO', - city: 'Umatilla Project Feed Canal near Hermiston, OR', - state: 'OR', - lat: 45.8538888, - lon: -119.1719444, - }, - BUSO: { - id: 'BUSO', - city: 'Silvies River near Burns, OR', - state: 'OR', - lat: 43.7152777, - lon: -119.1763888, - }, - MALO: { - id: 'MALO', - city: 'Malheur River at 36th St. Bridge near Ontario, OR', - state: 'OR', - lat: 44.0402777, - lon: -117.0205555, - }, - BIRO: { - id: 'BIRO', - city: 'Birch Creek near Reith, OR', - state: 'OR', - lat: 45.6513888, - lon: -118.8775, - }, - UMMO: { - id: 'UMMO', - city: 'Umatilla River above Butter Creek nr Hermiston', - state: 'OR', - lat: 45.7952777, - lon: -119.3227777, - }, - BENO: { - id: 'BENO', - city: 'Deschutes River at Benham Falls, OR', - state: 'OR', - lat: 43.9302777, - lon: -121.4108333, - }, - BASO: { - id: 'BASO', - city: 'Bear Creek below Ashland Cr. at Ashland, OR', - state: 'OR', - lat: 42.2161111, - lon: -122.7211111, - }, - CSAO: { - id: 'CSAO', - city: 'US A Line Canal at Cold Springs Res nr Hermiston OR', - state: 'OR', - lat: 45.8538888, - lon: -119.1719444, - }, - UBBO: { - id: 'UBBO', - city: 'Umatilla River below Butter Creek', - state: 'OR', - lat: 45.8288888, - lon: -119.3227777, - }, - PRIO: { - id: 'PRIO', - city: 'Prineville 4NW, OR', - state: 'OR', - lat: 44.3691666, - lon: -120.9377777, - }, - CRAO: { - id: 'CRAO', - city: 'Deschutes River below Crane Prairie Res., OR', - state: 'OR', - lat: 43.7536111, - lon: -121.7825, - }, - NCAO: { - id: 'NCAO', - city: 'North Canal near Bend, OR', - state: 'OR', - lat: 44.0772222, - lon: -121.3019444, - }, - DCMO: { - id: 'DCMO', - city: 'Deschutes County MID Canal', - state: 'OR', - lat: 44.0688888, - lon: -121.3125, - }, - SPBO: { - id: 'SPBO', - city: 'Sprague River near Beatty, OR', - state: 'OR', - lat: 42.4472222, - lon: -121.2375, - }, - ANTO: { - id: 'ANTO', - city: 'Antelope Creek and Diversion at Dam', - state: 'OR', - lat: 42.4111111, - lon: -122.7433333, - }, - MCKO: { - id: 'MCKO', - city: 'Mckay Creek near Pendleton, OR', - state: 'OR', - lat: 45.6094444, - lon: -118.7986111, - }, - WIWO: { - id: 'WIWO', - city: 'Wickiup Weather Station, OR', - state: 'OR', - lat: 43.6836111, - lon: -121.6888888, - }, - HPWO: { - id: 'HPWO', - city: 'Howard Prairie Dam Weather Station, OR', - state: 'OR', - lat: 42.215, - lon: -122.3719444, - }, - UMAO: { - id: 'UMAO', - city: 'Umatilla River near Umatilla, OR', - state: 'OR', - lat: 45.9, - lon: -119.3333333, - }, - CREO: { - id: 'CREO', - city: 'Crescent Creek at Crescent Lake, OR', - state: 'OR', - lat: 43.5030555, - lon: -121.9722222, - }, - DICO: { - id: 'DICO', - city: 'Dead Indian Collection Canal nr. Pinehurst, OR', - state: 'OR', - lat: 42.2638888, - lon: -122.4491666, - }, - WICO: { - id: 'WICO', - city: 'Deschutes River below Wickiup Res., OR', - state: 'OR', - lat: 43.6861111, - lon: -121.6869444, - }, - ALTO: { - id: 'ALTO', - city: 'A-Line Canal (Terminus) nr Hermiston, OR', - state: 'OR', - lat: 45.8136111, - lon: -119.3577777, - }, - PRHO: { - id: 'PRHO', - city: 'Powder River at Hudspeth Lane near Sumpter, OR', - state: 'OR', - lat: 44.6861111, - lon: -118.1, - }, - SCOO: { - id: 'SCOO', - city: 'Scoggins Creek below Henry Hagg Lake, Oregon', - state: 'OR', - lat: 45.4694444, - lon: -123.1988888, - }, - SILO: { - id: 'SILO', - city: 'Silver Creek near Silver Lake, OR', - state: 'OR', - lat: 43.1133333, - lon: -121.0675, - }, - UMDO: { - id: 'UMDO', - city: 'Umatilla River ar I84 near Stanfield, OR', - state: 'OR', - lat: 45.7766666, - lon: -119.2122222, - }, - DCIO: { - id: 'DCIO', - city: 'Deer Creek near Izee, OR', - state: 'OR', - lat: 44.1969444, - lon: -119.4686111, - }, - RIOO: { - id: 'RIOO', - city: 'Antelope Creek above Rio Canyon near Eagle Point, OR', - state: 'OR', - lat: 42.3502777, - lon: -122.6877777, - }, - MCDO: { - id: 'MCDO', - city: 'McDermitt, OR 26N', - state: 'OR', - lat: 42.4105555, - lon: -117.8627777, - }, - MABO: { - id: 'MABO', - city: 'North Fork Malheur River abv Beulah Res, OR', - state: 'OR', - lat: 43.9502777, - lon: -118.1744444, - }, - WARO: { - id: 'WARO', - city: 'Malheur River bel Warm Springs Res nr Riverside, OR', - state: 'OR', - lat: 43.5708333, - lon: -118.2013888, - }, - LAPO: { - id: 'LAPO', - city: 'Little Deschutes River near LaPine, OR', - state: 'OR', - lat: 43.6891666, - lon: -121.5016666, - }, - MCCO: { - id: 'MCCO', - city: 'McCullugh Ranch, OR', - state: 'OR', - lat: 44.1286111, - lon: -120.4216666, - }, - BJBO: { - id: 'BJBO', - city: 'Bear Creek at Jackson St. Bridge, Medford, OR', - state: 'OR', - lat: 42.3316666, - lon: -122.8694444, - }, - SDCO: { - id: 'SDCO', - city: 'Soda Creek at Howard Prairie Delivery Canal, OR', - state: 'OR', - lat: 42.1997222, - lon: -122.3583333, - }, - GSPO: { - id: 'GSPO', - city: 'Green Springs Powerplant near Ashland, OR', - state: 'OR', - lat: 42.1222222, - lon: -122.5463888, - }, - WCRO: { - id: 'WCRO', - city: 'Wildhorse Creek at Pendleton, OR', - state: 'OR', - lat: 45.6861111, - lon: -118.7455555, - }, - AFML: { - id: 'AFML', - city: 'Fourmile Lake near Ashland, OR', - state: 'OR', - lat: 42.4569444, - lon: -122.2416666, - }, - WBCO: { - id: 'WBCO', - city: 'West Birch Creek at Pilot Rock, OR', - state: 'OR', - lat: 45.4838888, - lon: -118.8355555, - }, - MLCO: { - id: 'MLCO', - city: 'Mill Creek nr Prineville, OR', - state: 'OR', - lat: 44.4072222, - lon: -120.6397222, - }, - FCEO: { - id: 'FCEO', - city: 'Umatilla Project Feed Canal near Echo, OR', - state: 'OR', - lat: 45.7294444, - lon: -119.1783333, - }, - SWCO: { - id: 'SWCO', - city: 'Swalley Canal', - state: 'OR', - lat: 44.0805555, - lon: -121.3, - }, - BCAO: { - id: 'BCAO', - city: 'Bear Creek above Ashland, OR', - state: 'OR', - lat: 42.195, - lon: -122.6686111, - }, - MFDO: { - id: 'MFDO', - city: 'Bear Creek at Medford, OR', - state: 'OR', - lat: 42.3308333, - lon: -122.8716666, - }, - DRSO: { - id: 'DRSO', - city: 'Drewsey, OR', - state: 'OR', - lat: 43.8077777, - lon: -118.3763888, - }, - GILO: { - id: 'GILO', - city: 'South Fork Little Butte Creek at Gilkey, OR', - state: 'OR', - lat: 42.3586111, - lon: -122.5086111, - }, - HPCO: { - id: 'HPCO', - city: 'Howard Prairie Delivery Canal & Keene Creek Dam, OR', - state: 'OR', - lat: 42.1288888, - lon: -122.4772222, - }, - BCSO: { - id: 'BCSO', - city: 'Beaver Creek and Beaver Siphon at Howard Prairie Can', - state: 'OR', - lat: 42.1505555, - lon: -122.3958333, - }, - CRPO: { - id: 'CRPO', - city: 'Crooked River above Prineville Reservoir, nr Post OR', - state: 'OR', - lat: 44.1791666, - lon: -120.5877777, - }, - BALO: { - id: 'BALO', - city: 'Baltzor Ranch near Sheaville, Oregon', - state: 'OR', - lat: 43.1069444, - lon: -117.0602777, - }, - UMUO: { - id: 'UMUO', - city: 'Umatilla River nr Echo, OR', - state: 'OR', - lat: 45.7208333, - lon: -119.1791666, - }, - CENO: { - id: 'CENO', - city: 'Central Oregon Canal', - state: 'OR', - lat: 44.0302777, - lon: -121.2947222, - }, - FURO: { - id: 'FURO', - city: 'Furnish Canal above Crayne-Lisle Canal near Echo, OR', - state: 'OR', - lat: 45.6911111, - lon: -119.1236111, - }, - WESO: { - id: 'WESO', - city: 'Westland Canal near Echo, OR', - state: 'OR', - lat: 45.7661111, - lon: -119.2161111, - }, - FRMO: { - id: 'FRMO', - city: 'Tualatin River at Farmington', - state: 'OR', - lat: 45.45, - lon: -122.95, - }, - FSHO: { - id: 'FSHO', - city: 'NF Little Butte Cr below Fish Lake', - state: 'OR', - lat: 42.3772222, - lon: -122.3594444, - }, - SFLO: { - id: 'SFLO', - city: 'South Fork Little Butte Creek at Mouth, OR', - state: 'OR', - lat: 42.4180555, - lon: -122.6125, - }, - EGSO: { - id: 'EGSO', - city: 'Emigrant Creek Above Green Springs Powerplant, OR', - state: 'OR', - lat: 42.1222222, - lon: -122.5463888, - }, - GSTO: { - id: 'GSTO', - city: 'Tualatin River at Gaston, Oregon', - state: 'OR', - lat: 45.4388888, - lon: -123.1397222, - }, - NPDO: { - id: 'NPDO', - city: 'Powder River abv Thief Valley Res nr. North Powder', - state: 'OR', - lat: 45.0575, - lon: -117.8408333, - }, - SLBO: { - id: 'SLBO', - city: 'South Fork Little Butte Cr. Collection Canal, OR', - state: 'OR', - lat: 42.2836111, - lon: -122.4002777, - }, - CRCO: { - id: 'CRCO', - city: 'Crooked River Feed Canal near Prineville, OR', - state: 'OR', - lat: 44.2388888, - lon: -120.8625, - }, - CSRO: { - id: 'CSRO', - city: 'Cold Springs Recharge Canal near Hermiston, OR', - state: 'OR', - lat: 45.8663888, - lon: -119.1672222, - }, - KMFR: { - id: 'KMFR', - city: 'Rogue Valley International Airport', - state: 'OR', - lat: 42.37503, - lon: -122.87696, - }, - KEUG: { - id: 'KEUG', - city: 'Eugene, Mahlon Sweet Field', - state: 'OR', - lat: 44.13333, - lon: -123.21444, - }, - KPDX: { - id: 'KPDX', - city: 'Portland, Portland International Airport', - state: 'OR', - lat: 45.59578, - lon: -122.60917, - }, - KPDT: { - id: 'KPDT', - city: 'Pendleton, Eastern Oregon Regional At Pendleton Airport', - state: 'OR', - lat: 45.69833, - lon: -118.83417, - }, - KSLE: { - id: 'KSLE', - city: 'Salem, McNary Field', - state: 'OR', - lat: 44.90778, - lon: -122.995, - }, - KAST: { - id: 'KAST', - city: 'Astoria, Astoria Regional Airport', - state: 'OR', - lat: 46.15694, - lon: -123.8825, - }, - KLMT: { - id: 'KLMT', - city: 'Klamath Falls International Airport', - state: 'OR', - lat: 42.14703, - lon: -121.72548, - }, - KLKV: { - id: 'KLKV', - city: 'Lakeview, Lake County Airport', - state: 'OR', - lat: 42.16667, - lon: -120.4, - }, - KONP: { - id: 'KONP', - city: 'Newport, Newport Municipal Airport', - state: 'OR', - lat: 44.58028, - lon: -124.05806, - }, - KHIO: { - id: 'KHIO', - city: 'Portland, Portland-Hillsboro Airport', - state: 'OR', - lat: 45.54806, - lon: -122.95444, - }, - KOTH: { - id: 'KOTH', - city: 'North Bend, North Bend Municipal Airport', - state: 'OR', - lat: 43.41667, - lon: -124.25, - }, - KBNO: { - id: 'KBNO', - city: 'Burns Municipal Airport', - state: 'OR', - lat: 43.59488, - lon: -118.95791, - }, - KTTD: { - id: 'KTTD', - city: 'Portland, Portland-Troutdale Airport', - state: 'OR', - lat: 45.55111, - lon: -122.40889, - }, - KBKE: { - id: 'KBKE', - city: 'Baker Municipal Airport', - state: 'OR', - lat: 44.84302, - lon: -117.80987, - }, - KRDM: { - id: 'KRDM', - city: 'Redmond Roberts Field', - state: 'OR', - lat: 44.25588, - lon: -121.14059, - }, - KREO: { - id: 'KREO', - city: 'Rome', - state: 'OR', - lat: 42.5901799, - lon: -117.86458, - }, - SBCO: { - id: 'SBCO', - city: 'Mud SPrings Creek near Gateway, OR', - state: 'OR', - lat: 44.8019444, - lon: -121.0602777, - }, - KUAO: { - id: 'KUAO', - city: 'Aurora, Aurora State Airport', - state: 'OR', - lat: 45.24889, - lon: -122.76556, - }, - KSXT: { - id: 'KSXT', - city: 'Sexton Summit', - state: 'OR', - lat: 42.6, - lon: -123.3656, - }, - KLGD: { - id: 'KLGD', - city: 'La Grande/Union County Airport', - state: 'OR', - lat: 45.29066, - lon: -118.00884, - }, - KSPB: { - id: 'KSPB', - city: 'Scappoose, Scappoose Industrial Airpark', - state: 'OR', - lat: 45.76917, - lon: -122.86222, - }, - KGCD: { - id: 'KGCD', - city: 'Grant County Regional Airport', - state: 'OR', - lat: 44.40287, - lon: -118.96715, - }, - KCVO: { - id: 'KCVO', - city: 'Corvallis, Corvallis Municipal Airport', - state: 'OR', - lat: 44.5, - lon: -123.28333, - }, - KONO: { - id: 'KONO', - city: 'Ontario Municipal Airport', - state: 'OR', - lat: 44.01424, - lon: -117.00808, - }, - KRBG: { - id: 'KRBG', - city: 'Roseburg, Roseburg Regional Airport', - state: 'OR', - lat: 43.23389, - lon: -123.35611, - }, - KMEH: { - id: 'KMEH', - city: 'Meacham', - state: 'OR', - lat: 45.51176, - lon: -118.42466, - }, - KHRI: { - id: 'KHRI', - city: 'Hermiston, Hermiston Municipal Airport', - state: 'OR', - lat: 45.82583, - lon: -119.26111, - }, - KMMV: { - id: 'KMMV', - city: 'McMinnville, McMinnville Municipal Airport', - state: 'OR', - lat: 45.19611, - lon: -123.13222, - }, - KTMK: { - id: 'KTMK', - city: 'Tillamook, Tillamook Airport', - state: 'OR', - lat: 45.4180599, - lon: -123.81444, - }, - KBOK: { - id: 'KBOK', - city: 'Brookings, Brookings Airport', - state: 'OR', - lat: 42.07444, - lon: -124.29, - }, - MUCO: { - id: 'MUCO', - city: 'Murderers Creek near Mouth', - state: 'OR', - lat: 44.3158333, - lon: -119.5341666, - }, - KPQR: { - id: 'KPQR', - city: 'Portland - NWS WFO', - state: 'OR', - lat: 45.56056, - lon: -122.53806, - }, - KBDN: { - id: 'KBDN', - city: 'Bend Airport AWOS', - state: 'OR', - lat: 44.0948, - lon: -121.2006, - }, - KDDC: { - id: 'KDDC', - city: 'Dodge City, Dodge City Regional Airport', - state: 'KS', - lat: 37.77278, - lon: -99.96972, - }, - KGLD: { - id: 'KGLD', - city: 'Goodland, Renner Field', - state: 'KS', - lat: 39.3675, - lon: -101.69306, - }, - KTOP: { - id: 'KTOP', - city: 'Topeka, Philip Billard Municipal Airport', - state: 'KS', - lat: 39.0725, - lon: -95.6258299, - }, - KICT: { - id: 'KICT', - city: 'Wichita - Wichita Dwight D. Eisenhower National Airport', - state: 'KS', - lat: 37.64722, - lon: -97.42944, - }, - KGCK: { - id: 'KGCK', - city: 'Garden City Regional Airport', - state: 'KS', - lat: 37.9275, - lon: -100.72444, - }, - KMHK: { - id: 'KMHK', - city: 'Manhattan, Manhattan Municipal Airport', - state: 'KS', - lat: 39.13528, - lon: -96.67778, - }, - KLBL: { - id: 'KLBL', - city: 'Liberal, Liberal Municipal Airport', - state: 'KS', - lat: 37.05, - lon: -100.9666699, - }, - KHYS: { - id: 'KHYS', - city: 'Hays, Hays Regional Airport', - state: 'KS', - lat: 38.85, - lon: -99.26667, - }, - KSLN: { - id: 'KSLN', - city: 'Salina, Salina Municipal Airport', - state: 'KS', - lat: 38.78, - lon: -97.64417, - }, - KHUT: { - id: 'KHUT', - city: 'Hutchinson, Hutchinson Municipal Airport', - state: 'KS', - lat: 38.06806, - lon: -97.86056, - }, - KEHA: { - id: 'KEHA', - city: 'Elkhart, Elkhart-Morton County Airport', - state: 'KS', - lat: 37, - lon: -101.88333, - }, - KRSL: { - id: 'KRSL', - city: 'Russell, Russell Municipal Airport', - state: 'KS', - lat: 38.87278, - lon: -98.8130599, - }, - KIAB: { - id: 'KIAB', - city: 'McConnell Air Force Base', - state: 'KS', - lat: 37.61667, - lon: -97.26667, - }, - KFRI: { - id: 'KFRI', - city: 'Fort Riley - Marshall AAF', - state: 'KS', - lat: 39.05586, - lon: -96.76166, - }, - KHLC: { - id: 'KHLC', - city: 'Hill City, Hill City Municipal Airport', - state: 'KS', - lat: 39.37472, - lon: -99.82972, - }, - KFOE: { - id: 'KFOE', - city: 'Topeka, Forbes Field', - state: 'KS', - lat: 38.94139, - lon: -95.65056, - }, - KCNU: { - id: 'KCNU', - city: 'Chanute, Chanute Martin Johnson Airport', - state: 'KS', - lat: 37.67028, - lon: -95.48417, - }, - KCFV: { - id: 'KCFV', - city: 'Coffeyville, Coffeyville Municipal Airport', - state: 'KS', - lat: 37.09111, - lon: -95.56639, - }, - KOJC: { - id: 'KOJC', - city: 'Olathe, Johnson County Executive Airport', - state: 'KS', - lat: 38.85, - lon: -94.73917, - }, - KGBD: { - id: 'KGBD', - city: 'Great Bend, Great Bend Municipal Airport', - state: 'KS', - lat: 38.35, - lon: -98.86667, - }, - KCNK: { - id: 'KCNK', - city: 'Concordia, Blosser Municipal Airport', - state: 'KS', - lat: 39.55139, - lon: -97.65056, - }, - KIXD: { - id: 'KIXD', - city: 'Olathe, New Century Aircenter', - state: 'KS', - lat: 38.82444, - lon: -94.88694, - }, - KPPF: { - id: 'KPPF', - city: 'Parsons, Tri-City Airport', - state: 'KS', - lat: 37.32778, - lon: -95.50417, - }, - KEWK: { - id: 'KEWK', - city: 'Newton, Newton City/County Airport', - state: 'KS', - lat: 38.05, - lon: -97.28333, - }, - KWLD: { - id: 'KWLD', - city: 'Winfield / Arkansas City, Strother Field', - state: 'KS', - lat: 37.1680599, - lon: -97.03694, - }, - KAAO: { - id: 'KAAO', - city: 'Wichita Jabara Airport', - state: 'KS', - lat: 37.74969, - lon: -97.21908, - }, - KLWC: { - id: 'KLWC', - city: 'Lawrence, Lawrence Municipal Airport', - state: 'KS', - lat: 39.00833, - lon: -95.21167, - }, - KEMP: { - id: 'KEMP', - city: 'Emporia, Emporia Municipal Airport', - state: 'KS', - lat: 38.32889, - lon: -96.19389, - }, - KMYZ: { - id: 'KMYZ', - city: 'Marysville Municipal Airport', - state: 'KS', - lat: 39.8553, - lon: -96.6306, - }, - KEQA: { - id: 'KEQA', - city: 'El Dorado Captain Jack Thomas Airport', - state: 'KS', - lat: 37.77534, - lon: -96.81449, - }, - KOWI: { - id: 'KOWI', - city: 'Ottawa Municipal Airport', - state: 'KS', - lat: 38.5409, - lon: -95.2542, - }, - KUKL: { - id: 'KUKL', - city: 'COFFEY', - state: 'KS', - lat: 38.3025, - lon: -95.725, - }, - KPTT: { - id: 'KPTT', - city: 'Pratt Municipal', - state: 'KS', - lat: 37.7, - lon: -98.75, - }, - KJHN: { - id: 'KJHN', - city: 'JOHNSON', - state: 'KS', - lat: 37.58266, - lon: -101.73283, - }, - KPTS: { - id: 'KPTS', - city: 'Atkinson Municipal Airport', - state: 'KS', - lat: 37.4494, - lon: -94.7311, - }, - KIDP: { - id: 'KIDP', - city: 'INDEPENDENCE', - state: 'KS', - lat: 37.1584, - lon: -95.7784, - }, - KOWP: { - id: 'KOWP', - city: 'SAND SPRINGS', - state: 'KS', - lat: 37.17527, - lon: -96.15183, - }, - KULS: { - id: 'KULS', - city: 'ULYSSES', - state: 'KS', - lat: 37.604, - lon: -101.3735, - }, - KFSK: { - id: 'KFSK', - city: 'FORT SCOTT', - state: 'KS', - lat: 37.79833, - lon: -94.76933, - }, - KMPR: { - id: 'KMPR', - city: 'MCPHERSON', - state: 'KS', - lat: 38.35244, - lon: -97.6913299, - }, - KHQG: { - id: 'KHQG', - city: 'HUGOTON', - state: 'KS', - lat: 37.1629999, - lon: -101.3705, - }, - KTQK: { - id: 'KTQK', - city: 'SCOTT CITY', - state: 'KS', - lat: 38.47433, - lon: -100.885, - }, - KPHG: { - id: 'KPHG', - city: 'PHILLIPSBURG', - state: 'KS', - lat: 39.735, - lon: -99.3171, - }, - KCBK: { - id: 'KCBK', - city: 'COLBY', - state: 'KS', - lat: 39.4275, - lon: -101.0465, - }, - KEGT: { - id: 'KEGT', - city: 'WELLINGTON', - state: 'KS', - lat: 37.32361, - lon: -97.38834, - }, - KOEL: { - id: 'KOEL', - city: 'LOGAN', - state: 'KS', - lat: 39.10166, - lon: -100.8165999, - }, - KNRN: { - id: 'KNRN', - city: 'NORTON', - state: 'KS', - lat: 39.8504099, - lon: -99.89466, - }, - KSYF: { - id: 'KSYF', - city: 'ST FRANCIS', - state: 'KS', - lat: 39.763884, - lon: -101.797861, - }, - KMEM: { - id: 'KMEM', - city: 'Memphis International Airport', - state: 'TN', - lat: 35.05644, - lon: -89.98634, - }, - KBNA: { - id: 'KBNA', - city: 'Nashville, Nashville International Airport', - state: 'TN', - lat: 36.11889, - lon: -86.68917, - }, - KCHA: { - id: 'KCHA', - city: 'Chattanooga, Lovell Field', - state: 'TN', - lat: 35.03333, - lon: -85.2, - }, - KTYS: { - id: 'KTYS', - city: 'Knoxville, McGhee Tyson Airport', - state: 'TN', - lat: 35.81806, - lon: -83.98583, - }, - KTRI: { - id: 'KTRI', - city: 'Bristol / Johnson / Kingsport, Tri-City Regional Airport', - state: 'TN', - lat: 36.47972, - lon: -82.39889, - }, - KNQA: { - id: 'KNQA', - city: 'Millington, Millington Municipal Airport', - state: 'TN', - lat: 35.35667, - lon: -89.8702799, - }, - KCSV: { - id: 'KCSV', - city: 'Crossville, Crossville Memorial-Whitson Field Airport', - state: 'TN', - lat: 35.95139, - lon: -85.0849999, - }, - KMKL: { - id: 'KMKL', - city: 'Jackson, McKellar-Sipes Regional Airport', - state: 'TN', - lat: 35.59306, - lon: -88.91667, - }, - KDYR: { - id: 'KDYR', - city: 'Dyersburg, Dyersburg Municipal Airport', - state: 'TN', - lat: 36, - lon: -89.4, - }, - KCKV: { - id: 'KCKV', - city: 'Clarksville Outlaw Field', - state: 'TN', - lat: 36.61689, - lon: -87.41174, - }, - KHZD: { - id: 'KHZD', - city: 'Huntingdon Carroll County Airport', - state: 'TN', - lat: 36.08896, - lon: -88.46538, - }, - KMQY: { - id: 'KMQY', - city: 'Smyrna, Smyrna Airport', - state: 'TN', - lat: 36.00889, - lon: -86.52, - }, - KUCY: { - id: 'KUCY', - city: 'Union City - Everett-Stewart Regional Airport', - state: 'TN', - lat: 36.38, - lon: -88.98, - }, - KSNH: { - id: 'KSNH', - city: 'SAVANNAH/HARDIN CO', - state: 'TN', - lat: 35.17, - lon: -88.22, - }, - KOQT: { - id: 'KOQT', - city: 'Oak Ridge', - state: 'TN', - lat: 36.02278, - lon: -84.23333, - }, - KPHT: { - id: 'KPHT', - city: 'Paris - Henry County Airport', - state: 'TN', - lat: 36.34, - lon: -88.38, - }, - KMMI: { - id: 'KMMI', - city: 'Athens McMinn County Airport', - state: 'TN', - lat: 35.3973, - lon: -84.5626, - }, - KRZR: { - id: 'KRZR', - city: 'Cleveland Regional Jetport', - state: 'TN', - lat: 35.2115, - lon: -84.7998, - }, - KPVE: { - id: 'KPVE', - city: 'Lexington-Parsons Beech River Regional Airport', - state: 'TN', - lat: 35.6564, - lon: -88.1954, - }, - KJAU: { - id: 'KJAU', - city: 'Jacksboro Campbell County Airport', - state: 'TN', - lat: 36.3341, - lon: -84.163, - }, - KMRC: { - id: 'KMRC', - city: 'Columbia / Maury County', - state: 'TN', - lat: 35.55, - lon: -87.18333, - }, - KDKX: { - id: 'KDKX', - city: 'Knoxville Downtown Airport', - state: 'TN', - lat: 35.96581, - lon: -83.87169, - }, - KBGF: { - id: 'KBGF', - city: 'Winchester Municipal Airport', - state: 'TN', - lat: 35.1775, - lon: -86.0662, - }, - KTHA: { - id: 'KTHA', - city: 'Tullahoma Regional Airport/William Northern Field', - state: 'TN', - lat: 35.38, - lon: -86.2467, - }, - KSRB: { - id: 'KSRB', - city: 'Sparta Upper Cumberland Regional Airport', - state: 'TN', - lat: 36.0559, - lon: -85.5307, - }, - KMOR: { - id: 'KMOR', - city: 'Morristown Moore-Murrell Airport', - state: 'TN', - lat: 36.1794, - lon: -83.3754, - }, - KSYI: { - id: 'KSYI', - city: 'Shelbyville Bomar Field & Shelbyville Municipal Airport', - state: 'TN', - lat: 35.5593999, - lon: -86.4425, - }, - KRNC: { - id: 'KRNC', - city: 'McMinnville Warren County Memorial Airport', - state: 'TN', - lat: 35.6991, - lon: -85.8402, - }, - KFYM: { - id: 'KFYM', - city: 'Fayetteville Municipal Airport', - state: 'TN', - lat: 35.0597, - lon: -86.5639999, - }, - KGKT: { - id: 'KGKT', - city: 'Sevierville Gatlinburg - Pigeon Forge Airport', - state: 'TN', - lat: 35.85681, - lon: -83.53334, - }, - KJWN: { - id: 'KJWN', - city: 'John C Tune Airport', - state: 'TN', - lat: 36.18521, - lon: -86.88331, - }, - KJAN: { - id: 'KJAN', - city: 'Jackson, Jackson International Airport', - state: 'MS', - lat: 32.3197199, - lon: -90.0775, - }, - KGWO: { - id: 'KGWO', - city: 'Greenwood, Greenwood-LeFlore Airport', - state: 'MS', - lat: 33.4925, - lon: -90.0836099, - }, - KTUP: { - id: 'KTUP', - city: 'Tupelo, Tupelo Regional Airport', - state: 'MS', - lat: 34.26806, - lon: -88.77, - }, - KGLH: { - id: 'KGLH', - city: 'Greenville, Mid Delta Regional Airport', - state: 'MS', - lat: 33.48278, - lon: -90.98556, - }, - KBIX: { - id: 'KBIX', - city: 'Keesler Air Force Base / Biloxi', - state: 'MS', - lat: 30.41667, - lon: -88.91667, - }, - KMCB: { - id: 'KMCB', - city: 'McComb, McComb / Pike County / John E Lewis Field Airport', - state: 'MS', - lat: 31.17833, - lon: -90.47194, - }, - KCBM: { - id: 'KCBM', - city: 'Columbus Air Force Base', - state: 'MS', - lat: 33.65, - lon: -88.45, - }, - KMEI: { - id: 'KMEI', - city: 'Meridian, Key Field', - state: 'MS', - lat: 32.33806, - lon: -88.74778, - }, - KGPT: { - id: 'KGPT', - city: 'Gulfport - Gulfport-Biloxi International Airport', - state: 'MS', - lat: 30.41194, - lon: -89.08083, - }, - KPIB: { - id: 'KPIB', - city: 'Hattiesburg/Laurel, Hattiesburg-Laurel Regional Airport', - state: 'MS', - lat: 31.46667, - lon: -89.33333, - }, - KNMM: { - id: 'KNMM', - city: 'Meridian, Meridian Naval Air Station - McCain Field', - state: 'MS', - lat: 32.55194, - lon: -88.55528, - }, - KGTR: { - id: 'KGTR', - city: 'Columbus/West Point/Starkville, Golden Triangle Regional Airport', - state: 'MS', - lat: 33.45, - lon: -88.58333, - }, - KHBG: { - id: 'KHBG', - city: 'Hattiesburg, Bobby L Chain Municipal Airport', - state: 'MS', - lat: 31.26945, - lon: -89.25613, - }, - KHKS: { - id: 'KHKS', - city: 'Jackson, Hawkins Field Airport', - state: 'MS', - lat: 32.33472, - lon: -90.2225, - }, - KHSA: { - id: 'KHSA', - city: 'Bay St. Louis, Stennis International Airport', - state: 'MS', - lat: 30.36778, - lon: -89.45472, - }, - KHEZ: { - id: 'KHEZ', - city: 'Natchez, Hardy-Anders Field Natchez-Adams County Airport', - state: 'MS', - lat: 31.61593, - lon: -91.29724, - }, - KPQL: { - id: 'KPQL', - city: 'Moss Point - Trent Lott International Airport', - state: 'MS', - lat: 30.46305, - lon: -88.53155, - }, - KOLV: { - id: 'KOLV', - city: 'Olive Branch, Olive Branch Airport', - state: 'MS', - lat: 34.97889, - lon: -89.78694, - }, - KRNV: { - id: 'KRNV', - city: 'Cleveland Municipal Airport', - state: 'MS', - lat: 33.7611, - lon: -90.7579, - }, - KMBO: { - id: 'KMBO', - city: 'Madison Bruce Campbell Field Airport', - state: 'MS', - lat: 32.4384, - lon: -90.1014, - }, - KPMU: { - id: 'KPMU', - city: 'Batesville Panola County', - state: 'MS', - lat: 34.3635, - lon: -89.8929, - }, - KLUL: { - id: 'KLUL', - city: 'LAUREL/NOBLE FIELD', - state: 'MS', - lat: 31.67, - lon: -89.17, - }, - KUOX: { - id: 'KUOX', - city: 'Oxford, University-Oxford Airport', - state: 'MS', - lat: 34.38444, - lon: -89.53556, - }, - KVKS: { - id: 'KVKS', - city: 'Vicksburg Municipal', - state: 'MS', - lat: 32.23333, - lon: -90.93333, - }, - KUTA: { - id: 'KUTA', - city: 'Tunica, Tunica Municipal Airport', - state: 'MS', - lat: 34.68083, - lon: -90.34639, - }, - KCRX: { - id: 'KCRX', - city: 'Corinth', - state: 'MS', - lat: 34.915, - lon: -88.6035, - }, - KCKM: { - id: 'KCKM', - city: 'Fletcher Field, Clarksdale', - state: 'MS', - lat: 34.2997, - lon: -90.5123, - }, - KSTF: { - id: 'KSTF', - city: 'George M Bryan Airport, Starkville', - state: 'MS', - lat: 33.4331, - lon: -88.8486, - }, - KJVW: { - id: 'KJVW', - city: 'JB Williams Airport', - state: 'MS', - lat: 32.30447, - lon: -90.41053, - }, - KIKT: { - id: 'KIKT', - city: 'Nakika Subsea Development Platform', - state: 'MS', - lat: 28.5208, - lon: -88.2889, - }, - KDLP: { - id: 'KDLP', - city: 'WEST DELTA OIL PLATFORM', - state: 'MS', - lat: 29.12, - lon: -89.55, - }, - KHOC: { - id: 'KHOC', - city: 'HILLSBORO', - state: 'OH', - lat: 39.18876, - lon: -83.53879, - }, - KLUK: { - id: 'KLUK', - city: 'Cincinnati, Cincinnati Municipal Airport Lunken Field', - state: 'OH', - lat: 39.10583, - lon: -84.41583, - }, - KILN: { - id: 'KILN', - city: 'Wilmington, Airborne Airpark Airport', - state: 'OH', - lat: 39.42833, - lon: -83.7791699, - }, - KCLE: { - id: 'KCLE', - city: 'Cleveland Hopkins International Airport', - state: 'OH', - lat: 41.40569, - lon: -81.85193, - }, - KCMH: { - id: 'KCMH', - city: 'Columbus - John Glenn Columbus International Airport', - state: 'OH', - lat: 39.995, - lon: -82.87639, - }, - KDAY: { - id: 'KDAY', - city: 'Dayton, Cox Dayton International Airport', - state: 'OH', - lat: 39.90611, - lon: -84.21861, - }, - KFFO: { - id: 'KFFO', - city: 'Dayton / Wright-Patterson Air Force Base', - state: 'OH', - lat: 39.8333299, - lon: -84.05, - }, - KCAK: { - id: 'KCAK', - city: 'Akron Canton Regional Airport', - state: 'OH', - lat: 40.91811, - lon: -81.44343, - }, - KMFD: { - id: 'KMFD', - city: 'Mansfield - Mansfield Lahm Regional Airport', - state: 'OH', - lat: 40.8202799, - lon: -82.51778, - }, - KFDY: { - id: 'KFDY', - city: 'Findlay, Findlay Airport', - state: 'OH', - lat: 41.01361, - lon: -83.66861, - }, - KZZV: { - id: 'KZZV', - city: 'Zanesville, Zanesville Municipal Airport', - state: 'OH', - lat: 39.94444, - lon: -81.89222, - }, - KTOL: { - id: 'KTOL', - city: 'Toledo - Toledo Express Airport', - state: 'OH', - lat: 41.58704, - lon: -83.80539, - }, - KYNG: { - id: 'KYNG', - city: 'Youngstown, Youngstown-Warren Regional Airport', - state: 'OH', - lat: 41.25444, - lon: -80.67389, - }, - KAOH: { - id: 'KAOH', - city: 'Lima, Lima Allen County Airport', - state: 'OH', - lat: 40.70806, - lon: -84.02139, - }, - KAKR: { - id: 'KAKR', - city: 'Akron, Akron Fulton International Airport', - state: 'OH', - lat: 41.0375, - lon: -81.46417, - }, - KLPR: { - id: 'KLPR', - city: 'Lorain / Elyria, Lorain County Regional Airport', - state: 'OH', - lat: 41.34611, - lon: -82.17944, - }, - KDFI: { - id: 'KDFI', - city: 'Defiance, Defiance Memorial Airport', - state: 'OH', - lat: 41.33639, - lon: -84.42944, - }, - KHZY: { - id: 'KHZY', - city: 'Ashtabula - Northeast Ohio Regional Airport', - state: 'OH', - lat: 41.77944, - lon: -80.69667, - }, - KLCK: { - id: 'KLCK', - city: 'Rickenbacker Air National Guard Base', - state: 'OH', - lat: 39.81667, - lon: -82.93333, - }, - KLNN: { - id: 'KLNN', - city: 'Willoughby', - state: 'OH', - lat: 41.68333, - lon: -81.38333, - }, - KBJJ: { - id: 'KBJJ', - city: 'Wooster, Wayne County Airport', - state: 'OH', - lat: 40.87306, - lon: -81.88667, - }, - KBKL: { - id: 'KBKL', - city: 'Cleveland, Burke Lakefront Airport', - state: 'OH', - lat: 41.52556, - lon: -81.66889, - }, - KCGF: { - id: 'KCGF', - city: 'Cleveland / Cuyahoga', - state: 'OH', - lat: 41.56667, - lon: -81.48333, - }, - KHAO: { - id: 'KHAO', - city: 'Butler County Regional Airport', - state: 'OH', - lat: 39.36121, - lon: -84.52061, - }, - KLHQ: { - id: 'KLHQ', - city: 'Lancaster, Fairfield County Airport', - state: 'OH', - lat: 39.7572199, - lon: -82.66333, - }, - KMGY: { - id: 'KMGY', - city: 'Dayton, Dayton-Wright Brothers Airport', - state: 'OH', - lat: 39.58889, - lon: -84.22472, - }, - KMNN: { - id: 'KMNN', - city: 'Marion, Marion Municipal Airport', - state: 'OH', - lat: 40.61667, - lon: -83.06833, - }, - KSGH: { - id: 'KSGH', - city: 'Springfield, Springfield-Beckley Municipal Airport', - state: 'OH', - lat: 39.84028, - lon: -83.84, - }, - KPHD: { - id: 'KPHD', - city: 'New Philadelphia, Harry Clever Field', - state: 'OH', - lat: 40.4719399, - lon: -81.42361, - }, - KVTA: { - id: 'KVTA', - city: 'Newark, Newark Heath Airport', - state: 'OH', - lat: 40.02278, - lon: -82.4625, - }, - KOSU: { - id: 'KOSU', - city: 'Columbus, Ohio State University Airport', - state: 'OH', - lat: 40.07806, - lon: -83.0780599, - }, - KTDZ: { - id: 'KTDZ', - city: 'Toledo - Toledo Executive Airport', - state: 'OH', - lat: 41.56306, - lon: -83.47639, - }, - LEBA: { - id: 'LEBA', - city: 'Lebanon', - state: 'OH', - lat: 39.43, - lon: -84.28, - }, - KPOV: { - id: 'KPOV', - city: 'Portage County Airport', - state: 'OH', - lat: 41.21, - lon: -81.252, - }, - KPCW: { - id: 'KPCW', - city: 'Port Clinton Carl R Keller Field Airport', - state: 'OH', - lat: 41.5163, - lon: -82.8687, - }, - KUYF: { - id: 'KUYF', - city: 'London Madison County Airport', - state: 'OH', - lat: 39.9326999, - lon: -83.462, - }, - KOWX: { - id: 'KOWX', - city: 'Ottawa Putnam County Airport', - state: 'OH', - lat: 41.0356, - lon: -83.982, - }, - KTZR: { - id: 'KTZR', - city: 'Columbus, Bolton Field Airport', - state: 'OH', - lat: 39.90083, - lon: -83.13722, - }, - KUNI: { - id: 'KUNI', - city: 'OHIO U/ATHEN-ALBANY', - state: 'OH', - lat: 39.22, - lon: -82.23, - }, - KAXV: { - id: 'KAXV', - city: 'WAPAKONETA', - state: 'OH', - lat: 40.49333, - lon: -84.299, - }, - KMWO: { - id: 'KMWO', - city: 'Hook Field Municipal Airport', - state: 'OH', - lat: 39.531, - lon: -84.3953, - }, - KEDJ: { - id: 'KEDJ', - city: 'Bellefontaine Regional Airport', - state: 'OH', - lat: 40.3723, - lon: -83.8192, - }, - KDLZ: { - id: 'KDLZ', - city: 'Delaware Municipal Airport', - state: 'OH', - lat: 40.2797, - lon: -83.1148, - }, - KVES: { - id: 'KVES', - city: 'Versailles Darke County Airport', - state: 'OH', - lat: 40.2044, - lon: -84.5318999, - }, - KMRT: { - id: 'KMRT', - city: 'Marysville Union County Airport', - state: 'OH', - lat: 40.2247, - lon: -83.3516, - }, - KUSE: { - id: 'KUSE', - city: 'Wauseon Fulton County Airport', - state: 'OH', - lat: 41.6101, - lon: -84.1272, - }, - KRZT: { - id: 'KRZT', - city: 'Chillicothe Ross County Airport', - state: 'OH', - lat: 39.4403999, - lon: -83.0231, - }, - KHTF: { - id: 'KHTF', - city: 'HORNELL', - state: 'NY', - lat: 42.38216, - lon: -77.68216, - }, - KGRU: { - id: 'KGRU', - city: 'Bethpage/Grumman', - state: 'NY', - lat: 40.75056, - lon: -73.50444, - }, - KBUF: { - id: 'KBUF', - city: 'Buffalo, Greater Buffalo International Airport', - state: 'NY', - lat: 42.93998, - lon: -78.73604, - }, - KJFK: { - id: 'KJFK', - city: 'New York, Kennedy International Airport', - state: 'NY', - lat: 40.63915, - lon: -73.76393, - }, - KLGA: { - id: 'KLGA', - city: 'New York, La Guardia Airport', - state: 'NY', - lat: 40.77917, - lon: -73.88, - }, - KBGM: { - id: 'KBGM', - city: 'Binghamton, Binghamton Regional Airport', - state: 'NY', - lat: 42.20778, - lon: -75.98139, - }, - KALB: { - id: 'KALB', - city: 'Albany International Airport', - state: 'NY', - lat: 42.74722, - lon: -73.79912, - }, - KSYR: { - id: 'KSYR', - city: 'Syracuse, Syracuse Hancock International Airport', - state: 'NY', - lat: 43.10917, - lon: -76.10333, - }, - KISP: { - id: 'KISP', - city: 'Islip, Long Island Mac Arthur Airport', - state: 'NY', - lat: 40.79389, - lon: -73.10167, - }, - KIAG: { - id: 'KIAG', - city: 'Niagara Falls, Niagara Falls International Airport', - state: 'NY', - lat: 43.1082899, - lon: -78.93818, - }, - KPOU: { - id: 'KPOU', - city: 'Poughkeepsie, Dutchess County Airport', - state: 'NY', - lat: 41.62667, - lon: -73.88417, - }, - KGTB: { - id: 'KGTB', - city: 'Fort Drum / Wheeler-Sack U. S. Army Airfield', - state: 'NY', - lat: 44.05, - lon: -75.73333, - }, - KJHW: { - id: 'KJHW', - city: 'Jamestown, Chautauqua County/Jamestown Airport', - state: 'NY', - lat: 42.15, - lon: -79.26667, - }, - KHTO: { - id: 'KHTO', - city: 'East Hampton, East Hampton Airport', - state: 'NY', - lat: 40.95944, - lon: -72.25194, - }, - KMSS: { - id: 'KMSS', - city: 'Massena, Massena International-Richards Field', - state: 'NY', - lat: 44.93583, - lon: -74.84556, - }, - KGFL: { - id: 'KGFL', - city: 'Glens Falls, Floyd Bennett Memorial Airport', - state: 'NY', - lat: 43.34111, - lon: -73.61056, - }, - KITH: { - id: 'KITH', - city: 'Ithaca, Ithaca Tompkins Regional Airport', - state: 'NY', - lat: 42.49083, - lon: -76.45833, - }, - KELM: { - id: 'KELM', - city: 'Elmira, Elmira / Corning Regional Airport', - state: 'NY', - lat: 42.15639, - lon: -76.90278, - }, - KART: { - id: 'KART', - city: 'Watertown, Watertown International Airport', - state: 'NY', - lat: 43.99194, - lon: -76.02167, - }, - KHPN: { - id: 'KHPN', - city: 'White Plains - Westchester County Airport', - state: 'NY', - lat: 41.06237, - lon: -73.70456, - }, - KSLK: { - id: 'KSLK', - city: 'Saranac Lake, Adirondack Regional Airport', - state: 'NY', - lat: 44.39306, - lon: -74.20278, - }, - KROC: { - id: 'KROC', - city: 'Rochester, Greater Rochester International Airport', - state: 'NY', - lat: 43.11667, - lon: -77.67667, - }, - KSWF: { - id: 'KSWF', - city: 'Newburgh / Stewart', - state: 'NY', - lat: 41.5, - lon: -74.1, - }, - KFOK: { - id: 'KFOK', - city: 'The Gabreski Airport', - state: 'NY', - lat: 40.85053, - lon: -72.61927, - }, - KDKK: { - id: 'KDKK', - city: 'Dunkirk, Chautauqua County / Dunkirk Airport', - state: 'NY', - lat: 42.49306, - lon: -79.27583, - }, - KFRG: { - id: 'KFRG', - city: 'Farmingdale - Republic Airport', - state: 'NY', - lat: 40.73443, - lon: -73.41639, - }, - KFZY: { - id: 'KFZY', - city: 'Fulton, Oswego County Airport', - state: 'NY', - lat: 43.35083, - lon: -76.38806, - }, - KELZ: { - id: 'KELZ', - city: 'Wellsville, Wellsville Municipal Airport', - state: 'NY', - lat: 42.1075, - lon: -77.98444, - }, - KMTP: { - id: 'KMTP', - city: 'Montauk, Montauk Airport', - state: 'NY', - lat: 41.07306, - lon: -71.92333, - }, - KMSV: { - id: 'KMSV', - city: 'Monticello, Sullivan County International Airport', - state: 'NY', - lat: 41.7, - lon: -74.8, - }, - KHWV: { - id: 'KHWV', - city: 'Shirley, Brookhaven Airport', - state: 'NY', - lat: 40.82167, - lon: -72.8688899, - }, - KDSV: { - id: 'KDSV', - city: 'Dansville, Dansville Municipal Airport', - state: 'NY', - lat: 42.56944, - lon: -77.71444, - }, - KMGJ: { - id: 'KMGJ', - city: 'Montgomery, Orange County Airport', - state: 'NY', - lat: 41.50917, - lon: -74.265, - }, - KOGS: { - id: 'KOGS', - city: 'OGDENSBURG', - state: 'NY', - lat: 44.68186, - lon: -75.4655, - }, - KPEO: { - id: 'KPEO', - city: 'Penn Yan, Penn Yan Airport', - state: 'NY', - lat: 42.64306, - lon: -77.04944, - }, - KNYC: { - id: 'KNYC', - city: 'New York City, Central Park', - state: 'NY', - lat: 40.78333, - lon: -73.9666699, - }, - KSCH: { - id: 'KSCH', - city: 'Schenectady Airport', - state: 'NY', - lat: 42.85, - lon: -73.93333, - }, - KRME: { - id: 'KRME', - city: 'Griffiss Air Force Base / Rome', - state: 'NY', - lat: 43.23333, - lon: -75.4, - }, - KOLE: { - id: 'KOLE', - city: 'CATTARAUGUS COUNTY-OLEAN', - state: 'NY', - lat: 42.23333, - lon: -78.36667, - }, - KPBG: { - id: 'KPBG', - city: 'Plattsburgh International Airport ', - state: 'NY', - lat: 44.65, - lon: -73.4666699, - }, - KOIC: { - id: 'KOIC', - city: 'NORWICH', - state: 'NY', - lat: 42.5665, - lon: -75.52416, - }, - KCZG: { - id: 'KCZG', - city: 'ENDICOTT', - state: 'NY', - lat: 42.0785, - lon: -76.09633, - }, - KVGC: { - id: 'KVGC', - city: 'HAMILTON', - state: 'NY', - lat: 42.82555, - lon: -75.54444, - }, - KPTD: { - id: 'KPTD', - city: 'POTSDAM', - state: 'NY', - lat: 44.67666, - lon: -74.9485, - }, - KSDC: { - id: 'KSDC', - city: 'WAYNE', - state: 'NY', - lat: 43.23461, - lon: -77.11947, - }, - KJRB: { - id: 'KJRB', - city: 'New York Downtown Manhattan', - state: 'NY', - lat: 40.7012, - lon: -74.009, - }, - KEWR: { - id: 'KEWR', - city: 'Newark, Newark International Airport', - state: 'NJ', - lat: 40.6825, - lon: -74.16944, - }, - KACY: { - id: 'KACY', - city: 'Atlantic City, Atlantic City International Airport', - state: 'NJ', - lat: 39.45202, - lon: -74.56699, - }, - KMIV: { - id: 'KMIV', - city: 'Millville, Millville Municipal Airport', - state: 'NJ', - lat: 39.36623, - lon: -75.0778, - }, - KTEB: { - id: 'KTEB', - city: 'Teterboro, Teterboro Airport', - state: 'NJ', - lat: 40.85889, - lon: -74.05667, - }, - KWRI: { - id: 'KWRI', - city: 'Mcguire Air Force Base', - state: 'NJ', - lat: 40.01667, - lon: -74.6, - }, - KCDW: { - id: 'KCDW', - city: 'Caldwell, Essex County Airport', - state: 'NJ', - lat: 40.87639, - lon: -74.28306, - }, - KMMU: { - id: 'KMMU', - city: 'Morristown Municipal', - state: 'NJ', - lat: 40.8, - lon: -74.41667, - }, - KBLM: { - id: 'KBLM', - city: 'Belmar-Farmingdale', - state: 'NJ', - lat: 40.18333, - lon: -74.13333, - }, - KFWN: { - id: 'KFWN', - city: 'Sussex, Sussex Airport', - state: 'NJ', - lat: 41.19925, - lon: -74.62594, - }, - KNEL: { - id: 'KNEL', - city: 'Lakehurst Naval Air Station', - state: 'NJ', - lat: 40.03661, - lon: -74.35251, - }, - KWWD: { - id: 'KWWD', - city: 'Wildwood, Cape May County Airport', - state: 'NJ', - lat: 39.01667, - lon: -74.91667, - }, - KTTN: { - id: 'KTTN', - city: 'Trenton, Mercer County Airport', - state: 'NJ', - lat: 40.27639, - lon: -74.81639, - }, - KVAY: { - id: 'KVAY', - city: 'Mount Holly, South Jersey Regional Airport', - state: 'NJ', - lat: 39.94076, - lon: -74.84071, - }, - KSMQ: { - id: 'KSMQ', - city: 'Somerville, Somerset Airport', - state: 'NJ', - lat: 40.6240499, - lon: -74.66898, - }, - KOBI: { - id: 'KOBI', - city: 'CAPE MAY', - state: 'NJ', - lat: 39.2191, - lon: -74.7948, - }, - KLDJ: { - id: 'KLDJ', - city: 'Linden Airport', - state: 'NJ', - lat: 40.6174, - lon: -74.2446, - }, - KMJX: { - id: 'KMJX', - city: 'Miller Air Park', - state: 'NJ', - lat: 39.927, - lon: -74.292, - }, - KMSP: { - id: 'KMSP', - city: 'Minneapolis, Minneapolis-St. Paul International Airport', - state: 'MN', - lat: 44.88306, - lon: -93.22889, - }, - KINL: { - id: 'KINL', - city: 'Falls International Airport', - state: 'MN', - lat: 48.55944, - lon: -93.39556, - }, - KSTP: { - id: 'KSTP', - city: 'Downtown Holman Field', - state: 'MN', - lat: 44.93237, - lon: -93.05588, - }, - KDLH: { - id: 'KDLH', - city: 'Duluth International Airport', - state: 'MN', - lat: 46.84347, - lon: -92.1866, - }, - KAXN: { - id: 'KAXN', - city: 'Alexandria, Chandler Field', - state: 'MN', - lat: 45.8686099, - lon: -95.39417, - }, - KANE: { - id: 'KANE', - city: 'Minneapolis / Blaine', - state: 'MN', - lat: 45.14258, - lon: -93.21272, - }, - KHIB: { - id: 'KHIB', - city: 'Chisholm-Hibbing Airport', - state: 'MN', - lat: 47.38039, - lon: -92.83245, - }, - KSTC: { - id: 'KSTC', - city: 'St. Cloud Regional Airport', - state: 'MN', - lat: 45.54415, - lon: -94.05165, - }, - KBRD: { - id: 'KBRD', - city: 'Brainerd - Crow Wing County Airport', - state: 'MN', - lat: 46.40205, - lon: -94.12734, - }, - KPKD: { - id: 'KPKD', - city: 'Park Rapids Municipal Airport', - state: 'MN', - lat: 46.8996799, - lon: -95.06681, - }, - KFRM: { - id: 'KFRM', - city: 'Fairmont, Fairmont Municipal Airport', - state: 'MN', - lat: 43.65, - lon: -94.41667, - }, - KBJI: { - id: 'KBJI', - city: 'Bemidji', - state: 'MN', - lat: 47.50762, - lon: -94.92783, - }, - KRRT: { - id: 'KRRT', - city: 'Warroad - Warroad International Memorial Airport', - state: 'MN', - lat: 48.94139, - lon: -95.34833, - }, - KRST: { - id: 'KRST', - city: 'Rochester, Rochester International Airport', - state: 'MN', - lat: 43.90417, - lon: -92.49167, - }, - KRWF: { - id: 'KRWF', - city: 'Redwood Falls Municipal Airport', - state: 'MN', - lat: 44.54828, - lon: -95.08042, - }, - KAIT: { - id: 'KAIT', - city: 'Aitkin Municipal Airport - Steve Kurtz Field', - state: 'MN', - lat: 46.54899, - lon: -93.67573, - }, - KCQM: { - id: 'KCQM', - city: 'Cook Municipal Airport', - state: 'MN', - lat: 47.81997, - lon: -92.68169, - }, - KHCD: { - id: 'KHCD', - city: 'Hutchinson, Hutchinson Municipal Airport-Butler Field', - state: 'MN', - lat: 44.85961, - lon: -94.38551, - }, - KMGG: { - id: 'KMGG', - city: 'Maple Lake, Maple Lake Municipal Airport', - state: 'MN', - lat: 45.2353499, - lon: -93.98959, - }, - KBFW: { - id: 'KBFW', - city: 'Silver Bay', - state: 'MN', - lat: 47.25206, - lon: -91.40983, - }, - KGYL: { - id: 'KGYL', - city: 'Glencoe Municipal Airport', - state: 'MN', - lat: 44.7588, - lon: -94.0905, - }, - KEVM: { - id: 'KEVM', - city: 'Eveleth-Virginia Municipal Airport', - state: 'MN', - lat: 47.4274, - lon: -92.49717, - }, - KFGN: { - id: 'KFGN', - city: 'Flag Island', - state: 'MN', - lat: 49.31667, - lon: -94.9, - }, - KCKC: { - id: 'KCKC', - city: 'Grand Marais/Cook County Airport', - state: 'MN', - lat: 47.83665, - lon: -90.3864399, - }, - KFBL: { - id: 'KFBL', - city: 'Faribault, Faribault Municipal Airport', - state: 'MN', - lat: 44.32983, - lon: -93.31186, - }, - KJKJ: { - id: 'KJKJ', - city: 'Moorhead Municipal Airport', - state: 'MN', - lat: 46.83916, - lon: -96.65543, - }, - KAUM: { - id: 'KAUM', - city: 'Austin Municipal', - state: 'MN', - lat: 43.66667, - lon: -92.93333, - }, - KCKN: { - id: 'KCKN', - city: 'Crookston Municipal Field', - state: 'MN', - lat: 47.84042, - lon: -96.6200999, - }, - KCBG: { - id: 'KCBG', - city: 'Cambridge Municipal Airport', - state: 'MN', - lat: 45.56275, - lon: -93.26436, - }, - KFOZ: { - id: 'KFOZ', - city: 'Bigfork, Bigfork Municipal Airport', - state: 'MN', - lat: 47.78278, - lon: -93.65028, - }, - KMKT: { - id: 'KMKT', - city: 'Mankato, Mankato Regional Airport', - state: 'MN', - lat: 44.21667, - lon: -93.91667, - }, - KMOX: { - id: 'KMOX', - city: 'Morris, Morris Municipal Airport', - state: 'MN', - lat: 45.56667, - lon: -95.9666699, - }, - KAEL: { - id: 'KAEL', - city: 'Albert Lea, Albert Lea Municipal Airport', - state: 'MN', - lat: 43.68333, - lon: -93.36667, - }, - KADC: { - id: 'KADC', - city: 'Wadena Municipal Airport', - state: 'MN', - lat: 46.45022, - lon: -95.21353, - }, - KCOQ: { - id: 'KCOQ', - city: 'Cloquet Carlton County Airport', - state: 'MN', - lat: 46.69869, - lon: -92.5034, - }, - KDXX: { - id: 'KDXX', - city: 'Madison, Madison-Lac Qui Parle County Airport', - state: 'MN', - lat: 44.9839399, - lon: -96.1788399, - }, - KHCO: { - id: 'KHCO', - city: 'Hallock Municipal Airport', - state: 'MN', - lat: 48.75245, - lon: -96.93759, - }, - KAQP: { - id: 'KAQP', - city: 'Appleton Municipal Airport', - state: 'MN', - lat: 45.22488, - lon: -96.00412, - }, - KBDE: { - id: 'KBDE', - city: 'Baudette International Airport', - state: 'MN', - lat: 48.72605, - lon: -94.61215, - }, - KLXL: { - id: 'KLXL', - city: 'Little Falls, Little Falls/Morrison County Airport-Lindbergh Field', - state: 'MN', - lat: 45.95, - lon: -94.35, - }, - KMJQ: { - id: 'KMJQ', - city: 'Jackson, Jackson Municipal Airport', - state: 'MN', - lat: 43.65, - lon: -94.98333, - }, - KMVE: { - id: 'KMVE', - city: 'Montevideo-Chippewa County Airport', - state: 'MN', - lat: 44.96749, - lon: -95.71159, - }, - KMWM: { - id: 'KMWM', - city: 'Windom Municipal Airport', - state: 'MN', - lat: 43.90999, - lon: -95.10723, - }, - KJYG: { - id: 'KJYG', - city: 'St. James Municipal Airport', - state: 'MN', - lat: 43.98558, - lon: -94.55299, - }, - KGNA: { - id: 'KGNA', - city: 'Grand Marais, The Bay of Grand Marais', - state: 'MN', - lat: 47.7472, - lon: -90.3443999, - }, - KGHW: { - id: 'KGHW', - city: 'Glenwood Municipal Airport', - state: 'MN', - lat: 45.64564, - lon: -95.31876, - }, - KLVN: { - id: 'KLVN', - city: 'Minneapolis, Airlake Airport', - state: 'MN', - lat: 44.62778, - lon: -93.22806, - }, - KMML: { - id: 'KMML', - city: 'Marshall, Southwest Minnesota Regional Airport - Marshall/Ryan Field', - state: 'MN', - lat: 44.45, - lon: -95.81667, - }, - KGPZ: { - id: 'KGPZ', - city: 'Grand Rapids, Grand Rapids/Itasca County Airport-Gordon Newstrom Field', - state: 'MN', - lat: 47.21667, - lon: -93.51667, - }, - KLJF: { - id: 'KLJF', - city: 'Litchfield Municipal Airport', - state: 'MN', - lat: 45.09485, - lon: -94.50837, - }, - KFCM: { - id: 'KFCM', - city: 'Minneapolis - Flying Cloud Airport', - state: 'MN', - lat: 44.83217, - lon: -93.47051, - }, - KETH: { - id: 'KETH', - city: 'Wheaton Municipal Airport', - state: 'MN', - lat: 45.78284, - lon: -96.54607, - }, - KJMR: { - id: 'KJMR', - city: 'Mora, Mora Municipal Airport', - state: 'MN', - lat: 45.88611, - lon: -93.27167, - }, - KBBB: { - id: 'KBBB', - city: 'Benson Municipal Airport', - state: 'MN', - lat: 45.3309799, - lon: -95.64692, - }, - KCDD: { - id: 'KCDD', - city: 'Crane Lake - Scotts Seaplane Base', - state: 'MN', - lat: 48.26014, - lon: -92.47485, - }, - KDTL: { - id: 'KDTL', - city: 'Detroit Lakes Airport-Wething Field', - state: 'MN', - lat: 46.8285399, - lon: -95.88567, - }, - KELO: { - id: 'KELO', - city: 'Ely, Ely Municipal Airport', - state: 'MN', - lat: 47.81667, - lon: -91.83333, - }, - KDYT: { - id: 'KDYT', - city: 'Duluth - Sky Harbor Airport', - state: 'MN', - lat: 46.72452, - lon: -92.0444799, - }, - KFSE: { - id: 'KFSE', - city: 'Fosston, Fosston Municipal Airport', - state: 'MN', - lat: 47.59278, - lon: -95.77333, - }, - KFFM: { - id: 'KFFM', - city: 'Fergus Falls Municipal Airport-Einar Mickel', - state: 'MN', - lat: 46.28655, - lon: -96.15338, - }, - KMIC: { - id: 'KMIC', - city: 'Minneapolis, Crystal Airport', - state: 'MN', - lat: 45.0625, - lon: -93.35083, - }, - KONA: { - id: 'KONA', - city: 'Winona, Winona Municipal Airport-Max Conrad Field', - state: 'MN', - lat: 44.0833299, - lon: -91.7, - }, - KOWA: { - id: 'KOWA', - city: 'Owatonna Degner Regional Airport', - state: 'MN', - lat: 44.11907, - lon: -93.25687, - }, - KROS: { - id: 'KROS', - city: 'Rush City, Rush City Regional Airport', - state: 'MN', - lat: 45.69806, - lon: -92.9530599, - }, - KULM: { - id: 'KULM', - city: 'New Ulm Municipal Airport', - state: 'MN', - lat: 44.32274, - lon: -94.50244, - }, - KOTG: { - id: 'KOTG', - city: 'Worthington, Worthington Municipal Airport', - state: 'MN', - lat: 43.65, - lon: -95.58333, - }, - KTOB: { - id: 'KTOB', - city: 'Dodge Center Airport', - state: 'MN', - lat: 44.02026, - lon: -92.8295, - }, - KTWM: { - id: 'KTWM', - city: 'Two Harbors', - state: 'MN', - lat: 47.05, - lon: -91.75, - }, - KVWU: { - id: 'KVWU', - city: 'Waskish Municipal Airport', - state: 'MN', - lat: 48.15014, - lon: -94.512, - }, - KSGS: { - id: 'KSGS', - city: 'South St. Paul Municipal-Richard E. Flemi', - state: 'MN', - lat: 44.86006, - lon: -93.03203, - }, - KTVF: { - id: 'KTVF', - city: 'Thief River Falls, Thief River Falls Regional Airport', - state: 'MN', - lat: 48.06667, - lon: -96.18333, - }, - KPQN: { - id: 'KPQN', - city: 'Pipestone Municipal Airport', - state: 'MN', - lat: 43.98542, - lon: -96.29764, - }, - KSAZ: { - id: 'KSAZ', - city: 'Staples, Staples Municipal Airport', - state: 'MN', - lat: 46.38083, - lon: -94.80667, - }, - KVVV: { - id: 'KVVV', - city: 'Ortonville, Ortonville Muncipal-Martinson Field Airport', - state: 'MN', - lat: 45.30556, - lon: -96.42444, - }, - KXVG: { - id: 'KXVG', - city: 'Longville, Longville Municipal Airport', - state: 'MN', - lat: 46.99028, - lon: -94.20389, - }, - KORB: { - id: 'KORB', - city: 'Orr', - state: 'MN', - lat: 48.01667, - lon: -92.86667, - }, - KROX: { - id: 'KROX', - city: 'Roseau, Roseau Municipal Airport/Rudy Billberg Field', - state: 'MN', - lat: 48.85, - lon: -95.7, - }, - KMZH: { - id: 'KMZH', - city: 'Moose Lake, Moose Lake Carlton County Airport', - state: 'MN', - lat: 46.41667, - lon: -92.8, - }, - KOVL: { - id: 'KOVL', - city: 'Olivia Regional Airport', - state: 'MN', - lat: 44.77923, - lon: -95.03033, - }, - KPNM: { - id: 'KPNM', - city: 'Princeton', - state: 'MN', - lat: 45.56425, - lon: -93.6080099, - }, - KPWC: { - id: 'KPWC', - city: 'Pine River Regional Airport', - state: 'MN', - lat: 46.72654, - lon: -94.38485, - }, - KCFE: { - id: 'KCFE', - city: 'Buffalo, Buffalo Municipal Airport', - state: 'MN', - lat: 45.15889, - lon: -93.84306, - }, - KHZX: { - id: 'KHZX', - city: 'Mc Gregor - Isedor Iverson Airport', - state: 'MN', - lat: 46.61904, - lon: -93.31267, - }, - KGDB: { - id: 'KGDB', - city: 'Granite Falls, Granite Falls Municipal Airport/Lenzen-Roe Memorial Field', - state: 'MN', - lat: 44.75306, - lon: -95.55583, - }, - KACQ: { - id: 'KACQ', - city: 'Waseca Municipal Airport', - state: 'MN', - lat: 44.07024, - lon: -93.55342, - }, - KFKA: { - id: 'KFKA', - city: 'Preston, Fillmore County Airport', - state: 'MN', - lat: 43.67701, - lon: -92.17422, - }, - KBDH: { - id: 'KBDH', - city: 'Willmar Municipal Airport - John L. Rice Field', - state: 'MN', - lat: 45.11113, - lon: -95.1258299, - }, - KDVP: { - id: 'KDVP', - city: 'Slayton Municipal Airport', - state: 'MN', - lat: 43.99055, - lon: -95.78102, - }, - KSYN: { - id: 'KSYN', - city: 'Stanton Airfield', - state: 'MN', - lat: 44.4736199, - lon: -93.01448, - }, - KTKC: { - id: 'KTKC', - city: 'Tracy, Tracy Municipal Airport', - state: 'MN', - lat: 44.24951, - lon: -95.61189, - }, - KLYV: { - id: 'KLYV', - city: 'Quentin Aanenson Field Airport', - state: 'MN', - lat: 43.62166, - lon: -96.2139399, - }, - KPEX: { - id: 'KPEX', - city: 'Paynesville, Paynesville Municipal Airport', - state: 'MN', - lat: 45.37247, - lon: -94.73878, - }, - KCNB: { - id: 'KCNB', - city: 'Canby Airfield', - state: 'MN', - lat: 44.7295, - lon: -96.266, - }, - VCEB: { - id: 'VCEB', - city: 'Cebollita Spring (Valles Caldera)', - state: 'NM', - lat: 35.83111, - lon: -106.72083, - }, - VJEM: { - id: 'VJEM', - city: 'Jemez Springs (Valles Caldera)', - state: 'NM', - lat: 35.77972, - lon: -106.68889, - }, - VRDD: { - id: 'VRDD', - city: 'Redondo (Valles Caldera)', - state: 'NM', - lat: 35.88389, - lon: -106.55361, - }, - VVLL: { - id: 'VVLL', - city: 'Valle Toledo (Valles Caldera)', - state: 'NM', - lat: 35.97389, - lon: -106.46472, - }, - VSNT: { - id: 'VSNT', - city: 'San Antonio (Valles Caldera)', - state: 'NM', - lat: 35.9805599, - lon: -106.57083, - }, - VCNJ: { - id: 'VCNJ', - city: 'Conejos (Valles Caldera)', - state: 'NM', - lat: 35.71805, - lon: -106.58611, - }, - VHVC: { - id: 'VHVC', - city: 'Headquarters (Valles Caldera)', - state: 'NM', - lat: 35.85278, - lon: -106.5211099, - }, - VHVY: { - id: 'VHVY', - city: 'Hidden Valley (Valles Caldera)', - state: 'NM', - lat: 35.8408299, - lon: -106.5005599, - }, - KABQ: { - id: 'KABQ', - city: 'Albuquerque, Albuquerque International Airport', - state: 'NM', - lat: 35.04167, - lon: -106.61472, - }, - KSAF: { - id: 'KSAF', - city: 'Santa Fe County Municipal Airport', - state: 'NM', - lat: 35.61097, - lon: -106.09573, - }, - KLVS: { - id: 'KLVS', - city: 'Las Vegas, Las Vegas Municipal Airport', - state: 'NM', - lat: 35.65417, - lon: -105.1425, - }, - KROW: { - id: 'KROW', - city: 'Roswell, Roswell Industrial Air Center Airport', - state: 'NM', - lat: 33.30806, - lon: -104.50778, - }, - KCVS: { - id: 'KCVS', - city: 'Cannon Air Force Base / Clovis', - state: 'NM', - lat: 34.38333, - lon: -103.31667, - }, - KLAM: { - id: 'KLAM', - city: 'Los Alamos Airport', - state: 'NM', - lat: 35.87891, - lon: -106.26205, - }, - KHMN: { - id: 'KHMN', - city: 'Holloman Air Force Base', - state: 'NM', - lat: 32.85, - lon: -106.1, - }, - KDMN: { - id: 'KDMN', - city: 'Deming, Deming Municipal Airport', - state: 'NM', - lat: 32.26222, - lon: -107.72056, - }, - KTCC: { - id: 'KTCC', - city: 'Tucumcari Municipal Airport', - state: 'NM', - lat: 35.18053, - lon: -103.60145, - }, - KALM: { - id: 'KALM', - city: 'Alamogordo-White', - state: 'NM', - lat: 32.8333299, - lon: -105.98333, - }, - KTCS: { - id: 'KTCS', - city: 'Truth Or Consequences, Truth Or Consequences Municipal Airport', - state: 'NM', - lat: 33.2366699, - lon: -107.26806, - }, - ESPA: { - id: 'ESPA', - city: 'ESPANOLA', - state: 'NM', - lat: 36.15, - lon: -105.99, - }, - KFMN: { - id: 'KFMN', - city: 'Farmington, Four Corners Regional Airport', - state: 'NM', - lat: 36.7436099, - lon: -108.22917, - }, - KGUP: { - id: 'KGUP', - city: 'Gallup, Gallup Municipal Airport', - state: 'NM', - lat: 35.51111, - lon: -108.78944, - }, - KHOB: { - id: 'KHOB', - city: 'Hobbs / Lea County', - state: 'NM', - lat: 32.68333, - lon: -103.2166699, - }, - KCNM: { - id: 'KCNM', - city: 'Carlsbad, Cavern City Air Terminal Airport', - state: 'NM', - lat: 32.3375, - lon: -104.26333, - }, - KGNT: { - id: 'KGNT', - city: 'Grants, Grants-Milan Municipal Airport', - state: 'NM', - lat: 35.16528, - lon: -107.90222, - }, - KCAO: { - id: 'KCAO', - city: 'Clayton Municipal Airpark', - state: 'NM', - lat: 36.44834, - lon: -103.15367, - }, - KRTN: { - id: 'KRTN', - city: 'Raton Municipal - Crews Field Airport', - state: 'NM', - lat: 36.741528, - lon: -104.502183, - }, - KATS: { - id: 'KATS', - city: 'Artesia, Artesia Municipal Airport', - state: 'NM', - lat: 32.8525, - lon: -104.4675, - }, - KCQC: { - id: 'KCQC', - city: 'Clines Corners', - state: 'NM', - lat: 35, - lon: -105.66667, - }, - KSKX: { - id: 'KSKX', - city: 'Taos, Taos Regional Airport', - state: 'NM', - lat: 36.45, - lon: -105.66667, - }, - KCVN: { - id: 'KCVN', - city: 'Clovis Municipal Airport', - state: 'NM', - lat: 34.42274, - lon: -103.0802, - }, - KLRU: { - id: 'KLRU', - city: 'Las Cruces, Las Cruces International Airport', - state: 'NM', - lat: 32.28944, - lon: -106.92194, - }, - KAEG: { - id: 'KAEG', - city: 'Albuquerque, Double Eagle II Airport', - state: 'NM', - lat: 35.145, - lon: -106.795, - }, - KSRR: { - id: 'KSRR', - city: 'Ruidoso Regional', - state: 'NM', - lat: 33.46667, - lon: -105.53333, - }, - VLPS: { - id: 'VLPS', - city: 'Los Posos (Valles Caldera)', - state: 'NM', - lat: 35.91583, - lon: -106.42278, - }, - KSVC: { - id: 'KSVC', - city: 'Silver City / Grant', - state: 'NM', - lat: 32.63333, - lon: -108.15, - }, - KONM: { - id: 'KONM', - city: 'Socorro Municipal Airport', - state: 'NM', - lat: 34.02633, - lon: -106.90372, - }, - KAXX: { - id: 'KAXX', - city: 'Angel Fire Airport', - state: 'NM', - lat: 36.42586, - lon: -105.29028, - }, - KVTN: { - id: 'KVTN', - city: 'Valentine, Miller Field', - state: 'NE', - lat: 42.85861, - lon: -100.55139, - }, - KOMA: { - id: 'KOMA', - city: 'Omaha - Eppley Airfield', - state: 'NE', - lat: 41.3119, - lon: -95.90185, - }, - KLBF: { - id: 'KLBF', - city: 'North Platte, North Platte Regional Airport', - state: 'NE', - lat: 41.12194, - lon: -100.66833, - }, - KLNK: { - id: 'KLNK', - city: 'Lincoln, Lincoln Municipal Airport', - state: 'NE', - lat: 40.83111, - lon: -96.7644399, - }, - KOFF: { - id: 'KOFF', - city: 'Omaha / Offutt Air Force Base', - state: 'NE', - lat: 41.11667, - lon: -95.9, - }, - KSNY: { - id: 'KSNY', - city: 'Sidney, Sidney Municipal Airport', - state: 'NE', - lat: 41.09944, - lon: -102.98556, - }, - KONL: { - id: 'KONL', - city: 'O\'Neill / Baker Field', - state: 'NE', - lat: 42.46667, - lon: -98.68333, - }, - KBFF: { - id: 'KBFF', - city: 'Scottsbluff, Heilig Field', - state: 'NE', - lat: 41.86694, - lon: -103.58583, - }, - KMCK: { - id: 'KMCK', - city: 'McCook, McCook Municipal Airport', - state: 'NE', - lat: 40.20306, - lon: -100.58833, - }, - KOFK: { - id: 'KOFK', - city: 'Norfolk, Stefan Memorial Airport', - state: 'NE', - lat: 41.9805599, - lon: -97.43694, - }, - KCDR: { - id: 'KCDR', - city: 'Chadron, Chadron Municipal Airport', - state: 'NE', - lat: 42.8375, - lon: -103.09528, - }, - KANW: { - id: 'KANW', - city: 'Ainsworth Regional Airport', - state: 'NE', - lat: 42.57484, - lon: -99.99832, - }, - KGRI: { - id: 'KGRI', - city: 'Grand Island, Central Nebraska Regional Airport', - state: 'NE', - lat: 40.9583299, - lon: -98.3125, - }, - KHDE: { - id: 'KHDE', - city: 'Brewster Field Airport', - state: 'NE', - lat: 40.45, - lon: -99.33333, - }, - KLXN: { - id: 'KLXN', - city: 'Lexington, Jim Kelly Field Airport', - state: 'NE', - lat: 40.79111, - lon: -99.77722, - }, - KODX: { - id: 'KODX', - city: 'Ord, Evelyn Sharp Field Airport', - state: 'NE', - lat: 41.62417, - lon: -98.9525, - }, - KBBW: { - id: 'KBBW', - city: 'Broken Bow, Broken Bow Municipal Airport', - state: 'NE', - lat: 41.43333, - lon: -99.65, - }, - KAUH: { - id: 'KAUH', - city: 'Aurora, Aurora Municipal Airport', - state: 'NE', - lat: 40.89389, - lon: -97.99444, - }, - KAIA: { - id: 'KAIA', - city: 'Alliance, Alliance Municipal Airport', - state: 'NE', - lat: 42.05722, - lon: -102.8, - }, - KOLU: { - id: 'KOLU', - city: 'Columbus, Columbus Municipal Airport', - state: 'NE', - lat: 41.45, - lon: -97.33333, - }, - KFET: { - id: 'KFET', - city: 'Fremont Municipal Airport', - state: 'NE', - lat: 41.45, - lon: -96.51667, - }, - KOGA: { - id: 'KOGA', - city: 'Ogallala, Searle Field Airport', - state: 'NE', - lat: 41.11972, - lon: -101.76889, - }, - KFNB: { - id: 'KFNB', - city: 'Falls City, Brenner Field Airport', - state: 'NE', - lat: 40.07889, - lon: -95.5919399, - }, - KHSI: { - id: 'KHSI', - city: 'Hastings, Hastings Municipal Airport', - state: 'NE', - lat: 40.60056, - lon: -98.42583, - }, - KTQE: { - id: 'KTQE', - city: 'Tekamah, Tekamah Municipal Airport', - state: 'NE', - lat: 41.76694, - lon: -96.17778, - }, - KEAR: { - id: 'KEAR', - city: 'Kearney, Kearney Municipal Airport', - state: 'NE', - lat: 40.73333, - lon: -99, - }, - KBIE: { - id: 'KBIE', - city: 'Beatrice Municipal', - state: 'NE', - lat: 40.3, - lon: -96.75, - }, - KIML: { - id: 'KIML', - city: 'Imperial, Imperial Municipal Airport', - state: 'NE', - lat: 40.51667, - lon: -101.61667, - }, - KMLE: { - id: 'KMLE', - city: 'Omaha, Millard Airport', - state: 'NE', - lat: 41.19583, - lon: -96.1122199, - }, - KIBM: { - id: 'KIBM', - city: 'Kimball, Kimball Municipal Airport/Robert E Arraj Field', - state: 'NE', - lat: 41.18333, - lon: -103.66667, - }, - KHJH: { - id: 'KHJH', - city: 'Hebron, Hebron Municipal Airport', - state: 'NE', - lat: 40.15222, - lon: -97.58694, - }, - KJYR: { - id: 'KJYR', - city: 'York, York Municipal Airport', - state: 'NE', - lat: 40.89667, - lon: -97.62278, - }, - KTIF: { - id: 'KTIF', - city: 'Thedford, Thomas County Airport', - state: 'NE', - lat: 41.96194, - lon: -100.56889, - }, - KLCG: { - id: 'KLCG', - city: 'Wayne, Wayne Municipal Airport', - state: 'NE', - lat: 42.24167, - lon: -96.98139, - }, - KAHQ: { - id: 'KAHQ', - city: 'Wahoo', - state: 'NE', - lat: 41.2406, - lon: -96.5946, - }, - KAFK: { - id: 'KAFK', - city: 'Nebraska City, Nebraska City Municipal Airport', - state: 'NE', - lat: 40.6, - lon: -95.85, - }, - KBVN: { - id: 'KBVN', - city: 'Albion Municipal Airport', - state: 'NE', - lat: 41.73016, - lon: -98.05453, - }, - KPMV: { - id: 'KPMV', - city: 'Plattsmouth, Plattsmouth Municipal Airport', - state: 'NE', - lat: 40.95, - lon: -95.9177799, - }, - KBTA: { - id: 'KBTA', - city: 'Blair Municipal Airport', - state: 'NE', - lat: 41.4148, - lon: -96.109, - }, - KOKC: { - id: 'KOKC', - city: 'Oklahoma City, Will Rogers World Airport', - state: 'OK', - lat: 35.38861, - lon: -97.60028, - }, - KOUN: { - id: 'KOUN', - city: 'Norman / Max Westheimer', - state: 'OK', - lat: 35.2435, - lon: -97.4708, - }, - KTUL: { - id: 'KTUL', - city: 'Tulsa, Tulsa International Airport', - state: 'OK', - lat: 36.1975, - lon: -95.88639, - }, - KADM: { - id: 'KADM', - city: 'Ardmore, Ardmore Municipal Airport', - state: 'OK', - lat: 34.30306, - lon: -97.01944, - }, - KEND: { - id: 'KEND', - city: 'Vance Air Force Base / Enid', - state: 'OK', - lat: 36.3333299, - lon: -97.91667, - }, - KFDR: { - id: 'KFDR', - city: 'Frederick, Frederick Municipal Airport', - state: 'OK', - lat: 34.34444, - lon: -98.98306, - }, - KLTS: { - id: 'KLTS', - city: 'Altus Air Force Base', - state: 'OK', - lat: 34.65, - lon: -99.26667, - }, - KMLC: { - id: 'KMLC', - city: 'McAlester, McAlester Regional Airport', - state: 'OK', - lat: 34.8822199, - lon: -95.78306, - }, - KGAG: { - id: 'KGAG', - city: 'Gage, Gage Airport', - state: 'OK', - lat: 36.29667, - lon: -99.76889, - }, - KHBR: { - id: 'KHBR', - city: 'Hobart, Hobart Municipal Airport', - state: 'OK', - lat: 34.98944, - lon: -99.0525, - }, - KPNC: { - id: 'KPNC', - city: 'Ponca City, Ponca City Municipal Airport', - state: 'OK', - lat: 36.7305599, - lon: -97.09972, - }, - KRVS: { - id: 'KRVS', - city: 'Tulsa - Jones Jr. Airport', - state: 'OK', - lat: 36.04255, - lon: -95.99005, - }, - KTIK: { - id: 'KTIK', - city: 'Tinker Air Force Base', - state: 'OK', - lat: 35.41667, - lon: -97.38333, - }, - KGUY: { - id: 'KGUY', - city: 'Guymon / Guymon Municipal Airport', - state: 'OK', - lat: 36.6816699, - lon: -101.50528, - }, - KCHK: { - id: 'KCHK', - city: 'Chickasha, Chickasha Municipal Airport', - state: 'OK', - lat: 35.09611, - lon: -97.96611, - }, - KCQB: { - id: 'KCQB', - city: 'Chandler, Chandler Municipal Airport', - state: 'OK', - lat: 35.72389, - lon: -96.82028, - }, - KBVO: { - id: 'KBVO', - city: 'Bartlesville, Bartlesville Municipal Airport', - state: 'OK', - lat: 36.76833, - lon: -96.02611, - }, - KFSI: { - id: 'KFSI', - city: 'Fort Sill', - state: 'OK', - lat: 34.6, - lon: -98.4, - }, - KLAW: { - id: 'KLAW', - city: 'Lawton, Lawton Municipal Airport', - state: 'OK', - lat: 34.5575, - lon: -98.41667, - }, - KMKO: { - id: 'KMKO', - city: 'Muskogee, Davis Field', - state: 'OK', - lat: 35.65694, - lon: -95.35972, - }, - KJSV: { - id: 'KJSV', - city: 'Sallisaw, Sallisaw Municipal Airport', - state: 'OK', - lat: 35.43806, - lon: -94.80278, - }, - KAQR: { - id: 'KAQR', - city: 'Atoka, Atoka Municipal Airport', - state: 'OK', - lat: 34.39833, - lon: -96.14806, - }, - KCSM: { - id: 'KCSM', - city: 'Clinton, Clinton-Sherman Airport', - state: 'OK', - lat: 35.35667, - lon: -99.20361, - }, - KGCM: { - id: 'KGCM', - city: 'Claremore, Claremore Regional Airport', - state: 'OK', - lat: 36.29444, - lon: -95.47972, - }, - KJWG: { - id: 'KJWG', - city: 'Watonga, Watonga Airport', - state: 'OK', - lat: 35.86472, - lon: -98.42083, - }, - KDUC: { - id: 'KDUC', - city: 'Duncan, Halliburton Field Airport', - state: 'OK', - lat: 34.47083, - lon: -97.9599999, - }, - KADH: { - id: 'KADH', - city: 'Ada, Ada Municipal Airport', - state: 'OK', - lat: 34.80444, - lon: -96.67139, - }, - KDUA: { - id: 'KDUA', - city: 'Durant, Eaker Field Airport', - state: 'OK', - lat: 33.94222, - lon: -96.39444, - }, - KGOK: { - id: 'KGOK', - city: 'Guthrie, Guthrie Municipal Airport', - state: 'OK', - lat: 35.85194, - lon: -97.4075, - }, - KAVK: { - id: 'KAVK', - city: 'Alva, Alva Regional Airport', - state: 'OK', - lat: 36.77306, - lon: -98.67, - }, - KGMJ: { - id: 'KGMJ', - city: 'Grove, Grove Municipal Airport', - state: 'OK', - lat: 36.60528, - lon: -94.73861, - }, - KPVJ: { - id: 'KPVJ', - city: 'Pauls Valley, Pauls Valley Municipal Airport', - state: 'OK', - lat: 34.71111, - lon: -97.22333, - }, - KSWO: { - id: 'KSWO', - city: 'Stillwater, Stillwater Regional Airport', - state: 'OK', - lat: 36.16222, - lon: -97.08917, - }, - KRKR: { - id: 'KRKR', - city: 'Poteau, Robert S Kerr Airport', - state: 'OK', - lat: 35.02167, - lon: -94.62139, - }, - KTQH: { - id: 'KTQH', - city: 'Tahlequah, Tahlequah Municipal Airport', - state: 'OK', - lat: 35.92889, - lon: -95.00444, - }, - KWDG: { - id: 'KWDG', - city: 'Enid, Enid Woodring Regional Airport', - state: 'OK', - lat: 36.37917, - lon: -97.79111, - }, - KPWA: { - id: 'KPWA', - city: 'Oklahoma City, Wiley Post Airport', - state: 'OK', - lat: 35.54111, - lon: -97.64667, - }, - KWWR: { - id: 'KWWR', - city: 'Woodward, West Woodward Airport', - state: 'OK', - lat: 36.43667, - lon: -99.5211099, - }, - KOKM: { - id: 'KOKM', - city: 'Okmulgee, Okmulgee Municipal Airport', - state: 'OK', - lat: 35.6680599, - lon: -95.94861, - }, - KSNL: { - id: 'KSNL', - city: 'Shawnee, Shawnee Municipal Airport', - state: 'OK', - lat: 35.35722, - lon: -96.94278, - }, - KOJA: { - id: 'KOJA', - city: 'Weatherford, Thomas P Stafford Airport', - state: 'OK', - lat: 35.54472, - lon: -98.66833, - }, - KCUH: { - id: 'KCUH', - city: 'Cushing, Cushing Municipal Airport', - state: 'OK', - lat: 35.94972, - lon: -96.77278, - }, - KAXS: { - id: 'KAXS', - city: 'Altus, Altus/Quartz Mountain Regional Airport', - state: 'OK', - lat: 34.69861, - lon: -99.33806, - }, - KHMY: { - id: 'KHMY', - city: 'MULDROWARMY', - state: 'OK', - lat: 35.02638, - lon: -97.23163, - }, - KRCE: { - id: 'KRCE', - city: 'Clarence E Page Municipal Airport', - state: 'OK', - lat: 35.4880799, - lon: -97.82356, - }, - KGZL: { - id: 'KGZL', - city: 'Stigler', - state: 'OK', - lat: 35.2891, - lon: -95.0939, - }, - KCLK: { - id: 'KCLK', - city: 'Clinton, Clinton Regional Airport', - state: 'OK', - lat: 35.53806, - lon: -98.92139, - }, - KHHW: { - id: 'KHHW', - city: 'Hugo Stan Stamper Municipal Airport', - state: 'OK', - lat: 34.0348, - lon: -95.5419, - }, - KELK: { - id: 'KELK', - city: 'Elk City Regional Business Airport', - state: 'OK', - lat: 35.4308, - lon: -99.3943, - }, - KIND: { - id: 'KIND', - city: 'Indianapolis International Airport', - state: 'IN', - lat: 39.72518, - lon: -86.2816, - }, - KFWA: { - id: 'KFWA', - city: 'Fort Wayne International Airport', - state: 'IN', - lat: 40.97251, - lon: -85.20637, - }, - KGYY: { - id: 'KGYY', - city: 'Gary Regional Airport', - state: 'IN', - lat: 41.61212, - lon: -87.40908, - }, - KLAF: { - id: 'KLAF', - city: 'Lafayette, Purdue University Airport', - state: 'IN', - lat: 40.4125, - lon: -86.9475, - }, - KEVV: { - id: 'KEVV', - city: 'Evansville, Evansville Regional Airport', - state: 'IN', - lat: 38.0430599, - lon: -87.52028, - }, - KSBN: { - id: 'KSBN', - city: 'South Bend, South Bend Regional Airport', - state: 'IN', - lat: 41.7088899, - lon: -86.31861, - }, - KGUS: { - id: 'KGUS', - city: 'Grissom Air Force Base / Peru', - state: 'IN', - lat: 40.65, - lon: -86.15, - }, - KHUF: { - id: 'KHUF', - city: 'Terre Haute International Airport - Hulman Field', - state: 'IN', - lat: 39.4429, - lon: -87.32207, - }, - KGSH: { - id: 'KGSH', - city: 'Goshen, Goshen Municipal Airport', - state: 'IN', - lat: 41.52611, - lon: -85.78667, - }, - KAID: { - id: 'KAID', - city: 'Anderson Municipal Airport', - state: 'IN', - lat: 40.10612, - lon: -85.60977, - }, - KEKM: { - id: 'KEKM', - city: 'Elkhart Municipal', - state: 'IN', - lat: 41.71667, - lon: -86, - }, - KBAK: { - id: 'KBAK', - city: 'Columbus / Bakalar', - state: 'IN', - lat: 39.26667, - lon: -85.9, - }, - KBMG: { - id: 'KBMG', - city: 'Bloomington, Monroe County Airport', - state: 'IN', - lat: 39.14306, - lon: -86.61667, - }, - KGEZ: { - id: 'KGEZ', - city: 'Shelbyville Municipal Airport', - state: 'IN', - lat: 39.58546, - lon: -85.79982, - }, - KHNB: { - id: 'KHNB', - city: 'Huntingburg', - state: 'IN', - lat: 38.25, - lon: -86.95, - }, - KMIE: { - id: 'KMIE', - city: 'Muncie, Delaware County-Johnson Field', - state: 'IN', - lat: 40.23417, - lon: -85.39361, - }, - KVPZ: { - id: 'KVPZ', - city: 'Valparaiso Porter County Municipal Airport', - state: 'IN', - lat: 41.45349, - lon: -86.99805, - }, - KMCX: { - id: 'KMCX', - city: 'Monticello White County Airport', - state: 'IN', - lat: 40.7087999, - lon: -86.7668, - }, - KHHG: { - id: 'KHHG', - city: 'Huntington Municipal Airport', - state: 'IN', - lat: 40.8529, - lon: -85.4571, - }, - KFKR: { - id: 'KFKR', - city: 'Frankfort Municipal Airport', - state: 'IN', - lat: 40.2734, - lon: -86.5622, - }, - KCFJ: { - id: 'KCFJ', - city: 'Crawfordsville Municipal Airport', - state: 'IN', - lat: 39.9756, - lon: -86.9199, - }, - KOKK: { - id: 'KOKK', - city: 'Kokomo, Kokomo Municipal Airport', - state: 'IN', - lat: 40.53333, - lon: -86.06667, - }, - KASW: { - id: 'KASW', - city: 'Warsaw, Warsaw Municipal Airport', - state: 'IN', - lat: 41.27444, - lon: -85.84, - }, - KTYQ: { - id: 'KTYQ', - city: 'INDIANAPOLIS', - state: 'IN', - lat: 40.03066, - lon: -86.2514999, - }, - KMQJ: { - id: 'KMQJ', - city: 'INDIANAPOLIS', - state: 'IN', - lat: 39.8435, - lon: -85.897, - }, - KRZL: { - id: 'KRZL', - city: 'Rensselaer Jasper County Airport', - state: 'IN', - lat: 40.94789, - lon: -87.18258, - }, - KMZZ: { - id: 'KMZZ', - city: 'Marion Municipal Airport', - state: 'IN', - lat: 40.49, - lon: -85.68, - }, - KRCR: { - id: 'KRCR', - city: 'Rochester Fulton County Airport', - state: 'IN', - lat: 41.06553, - lon: -86.18169, - }, - KGGP: { - id: 'KGGP', - city: 'Logansport/Cass County Airport', - state: 'IN', - lat: 40.711, - lon: -86.373, - }, - KOXI: { - id: 'KOXI', - city: 'Starke County Airport', - state: 'IN', - lat: 41.33, - lon: -86.665, - }, - KGWB: { - id: 'KGWB', - city: 'Auburn De Kalb County Airport', - state: 'IN', - lat: 41.307, - lon: -85.0639999, - }, - KPPO: { - id: 'KPPO', - city: 'La Porte Municipal Airport', - state: 'IN', - lat: 41.5725, - lon: -86.7345, - }, - KMGC: { - id: 'KMGC', - city: 'Michigan City Municipal Airport', - state: 'IN', - lat: 41.7033, - lon: -86.8212, - }, - KHBE: { - id: 'KHBE', - city: 'Himsel Army Airfield', - state: 'IN', - lat: 39.34167, - lon: -86.0305, - }, - KDCY: { - id: 'KDCY', - city: 'Daviess County Airport', - state: 'IN', - lat: 38.7004, - lon: -87.1297, - }, - KANQ: { - id: 'KANQ', - city: 'Angola Tri-State Steuben County Airport', - state: 'IN', - lat: 41.6404, - lon: -85.0851, - }, - KIMS: { - id: 'KIMS', - city: 'Madison Municipal Airport', - state: 'IN', - lat: 38.7589, - lon: -85.4655, - }, - DYER: { - id: 'DYER', - city: 'DYER - WALLACE FARMS', - state: 'NV', - lat: 37.6061, - lon: -117.98861, - }, - FREY: { - id: 'FREY', - city: 'FREY RANCH - FALLON', - state: 'NV', - lat: 39.3861, - lon: -118.7761, - }, - NNSC: { - id: 'NNSC', - city: 'DRI - NNSC', - state: 'NV', - lat: 39.57083, - lon: -119.80167, - }, - UNRC: { - id: 'UNRC', - city: 'UNR CAMPUS', - state: 'NV', - lat: 39.53917, - lon: -119.80583, - }, - FALN: { - id: 'FALN', - city: 'Fallon', - state: 'NV', - lat: 39.45806, - lon: -118.77694, - }, - EURN: { - id: 'EURN', - city: 'Eureka', - state: 'NV', - lat: 39.68528, - lon: -115.97861, - }, - VAPK: { - id: 'VAPK', - city: 'VIRGINIA PEAK (KRGX)', - state: 'NV', - lat: 39.75417, - lon: -119.46222, - }, - DUCK: { - id: 'DUCK', - city: 'DUCKWATER', - state: 'NV', - lat: 38.92167, - lon: -115.70111, - }, - WRUN: { - id: 'WRUN', - city: 'SOUTH RENO - WOLF RUN GOLF COURSE', - state: 'NV', - lat: 39.41639, - lon: -119.80139, - }, - KSPZ: { - id: 'KSPZ', - city: 'SILVER SPRINGS', - state: 'NV', - lat: 39.40302, - lon: -119.25119, - }, - NSMV: { - id: 'NSMV', - city: 'Smith Valley', - state: 'NV', - lat: 38.7513999, - lon: -119.3356, - }, - NANV: { - id: 'NANV', - city: 'Antelope Valley', - state: 'NV', - lat: 40.09389, - lon: -117.16889, - }, - NSWM: { - id: 'NSWM', - city: 'Steptoe Valley WMA', - state: 'NV', - lat: 39.19556, - lon: -114.81028, - }, - NPWL: { - id: 'NPWL', - city: 'Pahranagat NWR', - state: 'NV', - lat: 37.24556, - lon: -115.10639, - }, - NBNG: { - id: 'NBNG', - city: 'Bango', - state: 'NV', - lat: 39.49722, - lon: -119.03333, - }, - NSNA: { - id: 'NSNA', - city: 'Snake Valley', - state: 'NV', - lat: 39.02111, - lon: -114.08972, - }, - NSTV: { - id: 'NSTV', - city: 'Steptoe Valley (North)', - state: 'NV', - lat: 40.08417, - lon: -114.65139, - }, - NROG: { - id: 'NROG', - city: 'Rogers Spring', - state: 'NV', - lat: 36.47833, - lon: -116.33083, - }, - NBSV: { - id: 'NBSV', - city: 'Badger Spring Valley', - state: 'NV', - lat: 37.31083, - lon: -115.27694, - }, - NTIK: { - id: 'NTIK', - city: 'Tikaboo Peak', - state: 'NV', - lat: 37.34417, - lon: -115.35889, - }, - NMAS: { - id: 'NMAS', - city: 'Mason Valley WR', - state: 'NV', - lat: 39.10667, - lon: -119.14722, - }, - TIMB: { - id: 'TIMB', - city: 'Timber Mountain', - state: 'NV', - lat: 37.05917, - lon: -116.46444, - }, - SMYC: { - id: 'SMYC', - city: 'Spring Mountain Youth Camp', - state: 'NV', - lat: 36.31833, - lon: -115.58361, - }, - NNSV: { - id: 'NNSV', - city: 'North Spring Valley', - state: 'NV', - lat: 39.45806, - lon: -114.50667, - }, - NCVA: { - id: 'NCVA', - city: 'Carson Valley', - state: 'NV', - lat: 38.99278, - lon: -119.80389, - }, - NSSV: { - id: 'NSSV', - city: 'Sand Spring Valley', - state: 'NV', - lat: 37.64667, - lon: -115.7975, - }, - NCLV: { - id: 'NCLV', - city: 'Clover Valley', - state: 'NV', - lat: 40.86833, - lon: -114.96944, - }, - NSPA: { - id: 'NSPA', - city: 'Sparks - UNR Ag. Exp. Farm', - state: 'NV', - lat: 39.50306, - lon: -119.73778, - }, - NHUA: { - id: 'NHUA', - city: 'Hualapai Flat', - state: 'NV', - lat: 40.90111, - lon: -119.33306, - }, - NREE: { - id: 'NREE', - city: 'Reese River Valley', - state: 'NV', - lat: 39.23417, - lon: -117.29806, - }, - NLAZ: { - id: 'NLAZ', - city: 'Lazy 5 Park', - state: 'NV', - lat: 39.62139, - lon: -119.71583, - }, - MOCN: { - id: 'MOCN', - city: 'Mountain City Ranger Station, NV', - state: 'NV', - lat: 41.8388888, - lon: -115.9661111, - }, - OWYN: { - id: 'OWYN', - city: 'Owyhee, NV', - state: 'NV', - lat: 41.9455555, - lon: -116.0980555, - }, - WLDN: { - id: 'WLDN', - city: 'Owyhee River bel Wildhorse Dam nr Gold Creek, NV', - state: 'NV', - lat: 41.6875, - lon: -115.8605555, - }, - KTPH: { - id: 'KTPH', - city: 'Tonopah, Tonopah Airport', - state: 'NV', - lat: 38.06028, - lon: -117.08722, - }, - KRNO: { - id: 'KRNO', - city: 'Reno, Reno Tahoe International Airport', - state: 'NV', - lat: 39.50776, - lon: -119.76819, - }, - KLAS: { - id: 'KLAS', - city: 'Las Vegas, McCarran International Airport', - state: 'NV', - lat: 36.07188, - lon: -115.1634, - }, - KELY: { - id: 'KELY', - city: 'Ely, Ely Airport', - state: 'NV', - lat: 39.295, - lon: -114.84528, - }, - KWMC: { - id: 'KWMC', - city: 'Winnemucca, Winnemucca Municipal Airport', - state: 'NV', - lat: 40.90194, - lon: -117.80722, - }, - KEKO: { - id: 'KEKO', - city: 'Elko, Elko Regional Airport', - state: 'NV', - lat: 40.8240399, - lon: -115.78635, - }, - KDRA: { - id: 'KDRA', - city: 'Mercury, Desert Rock Airport', - state: 'NV', - lat: 36.6207, - lon: -116.02868, - }, - KNFL: { - id: 'KNFL', - city: 'Fallon, Naval Air Station', - state: 'NV', - lat: 39.43222, - lon: -118.68556, - }, - KVGT: { - id: 'KVGT', - city: 'Las Vegas, North Las Vegas Airport', - state: 'NV', - lat: 36.21205, - lon: -115.19395, - }, - KLSV: { - id: 'KLSV', - city: 'Nellis Air Force Base', - state: 'NV', - lat: 36.23333, - lon: -115.03333, - }, - KLOL: { - id: 'KLOL', - city: 'Lovelock, Derby Field Airport', - state: 'NV', - lat: 40.0683999, - lon: -118.57017, - }, - KHND: { - id: 'KHND', - city: 'Las Vegas - Henderson Executive Airport', - state: 'NV', - lat: 35.97665, - lon: -115.13221, - }, - KMEV: { - id: 'KMEV', - city: 'Minden-Tahoe Airport', - state: 'NV', - lat: 38.9963, - lon: -119.75, - }, - KHTH: { - id: 'KHTH', - city: 'Hawthorne Municipal Airport', - state: 'NV', - lat: 38.54482, - lon: -118.63137, - }, - KINS: { - id: 'KINS', - city: 'Nellis AFB - Indian Springs Auxiliary Airfield', - state: 'NV', - lat: 36.58573, - lon: -115.69008, - }, - KCXP: { - id: 'KCXP', - city: 'Carson City Airport', - state: 'NV', - lat: 39.19056, - lon: -119.73191, - }, - KBVU: { - id: 'KBVU', - city: 'Boulder City Municipal Airport', - state: 'NV', - lat: 35.9475, - lon: -114.8611, - }, - KRTS: { - id: 'KRTS', - city: 'Reno/Stead', - state: 'NV', - lat: 39.6682, - lon: -119.8764, - }, - KORD: { - id: 'KORD', - city: 'Chicago, Chicago-O\'Hare International Airport', - state: 'IL', - lat: 41.97972, - lon: -87.9044399, - }, - KMDW: { - id: 'KMDW', - city: 'Chicago, Chicago Midway Airport', - state: 'IL', - lat: 41.78417, - lon: -87.75528, - }, - KBLV: { - id: 'KBLV', - city: 'Belleville, Scott AFB/MidAmerica Airport', - state: 'IL', - lat: 38.55, - lon: -89.85, - }, - KDEC: { - id: 'KDEC', - city: 'Decatur Airport', - state: 'IL', - lat: 39.8308, - lon: -88.87192, - }, - KRFD: { - id: 'KRFD', - city: 'Rockford, Greater Rockford Airport', - state: 'IL', - lat: 42.19278, - lon: -89.09333, - }, - KPIA: { - id: 'KPIA', - city: 'Peoria - General Downing-Peoria International Airport', - state: 'IL', - lat: 40.6674999, - lon: -89.68389, - }, - KLOT: { - id: 'KLOT', - city: 'Lewis University Airport', - state: 'IL', - lat: 41.60307, - lon: -88.10164, - }, - KCMI: { - id: 'KCMI', - city: 'University of Illinois - Willard', - state: 'IL', - lat: 40.03245, - lon: -88.27547, - }, - KMLI: { - id: 'KMLI', - city: 'Moline, Quad-City Airport', - state: 'IL', - lat: 41.45139, - lon: -90.51472, - }, - KJOT: { - id: 'KJOT', - city: 'Joliet Regional Airport', - state: 'IL', - lat: 41.51755, - lon: -88.17903, - }, - KDPA: { - id: 'KDPA', - city: 'Chicago / West Chicago, Dupage Airport', - state: 'IL', - lat: 41.8963899, - lon: -88.25111, - }, - KUIN: { - id: 'KUIN', - city: 'Quincy Regional Airport-Baldwin Field', - state: 'IL', - lat: 39.9371, - lon: -91.19659, - }, - KSPI: { - id: 'KSPI', - city: 'Springfield - Abraham Lincoln Capital Airport', - state: 'IL', - lat: 39.84527, - lon: -89.68405, - }, - KARR: { - id: 'KARR', - city: 'Aurora Municipal Airport', - state: 'IL', - lat: 41.77132, - lon: -88.48147, - }, - KHSB: { - id: 'KHSB', - city: 'Harrisburg-Raleigh Airport', - state: 'IL', - lat: 37.81281, - lon: -88.54486, - }, - KIKK: { - id: 'KIKK', - city: 'Greater Kankakee Airport', - state: 'IL', - lat: 41.06871, - lon: -87.85372, - }, - KALN: { - id: 'KALN', - city: 'St. Louis Regional Airport', - state: 'IL', - lat: 38.88968, - lon: -90.03163, - }, - KMVN: { - id: 'KMVN', - city: 'Mount Vernon, Mount Vernon Airport', - state: 'IL', - lat: 38.31667, - lon: -88.86667, - }, - KGBG: { - id: 'KGBG', - city: 'Galesburg Municipal Airport', - state: 'IL', - lat: 40.9328999, - lon: -90.43339, - }, - KIGQ: { - id: 'KIGQ', - city: 'Lansing Municipal Airport', - state: 'IL', - lat: 41.54125, - lon: -87.52822, - }, - KLWV: { - id: 'KLWV', - city: 'Lawrenceville-Vincennes International Airport', - state: 'IL', - lat: 38.76046, - lon: -87.59903, - }, - KFWC: { - id: 'KFWC', - city: 'Fairfield, Fairfield Municipal Airport', - state: 'IL', - lat: 38.37861, - lon: -88.41278, - }, - KMWA: { - id: 'KMWA', - city: 'Marion - Williamson County Regional Airport', - state: 'IL', - lat: 37.76671, - lon: -89.00993, - }, - KAAA: { - id: 'KAAA', - city: 'Logan County Airport', - state: 'IL', - lat: 40.15885, - lon: -89.33891, - }, - KBMI: { - id: 'KBMI', - city: 'Bloomington/Normal, Central Illinois Regional Airport at Bloomington-Normal', - state: 'IL', - lat: 40.47694, - lon: -88.91583, - }, - KDNV: { - id: 'KDNV', - city: 'Danville, Vermilion County Airport', - state: 'IL', - lat: 40.19944, - lon: -87.59556, - }, - KFOA: { - id: 'KFOA', - city: 'Flora Municipal Airport', - state: 'IL', - lat: 38.66726, - lon: -88.4526999, - }, - KMTO: { - id: 'KMTO', - city: 'Mattoon / Charleston, Coles County Memorial Airport', - state: 'IL', - lat: 39.47806, - lon: -88.2791699, - }, - KFEP: { - id: 'KFEP', - city: 'Albertus Airport', - state: 'IL', - lat: 42.24751, - lon: -89.58104, - }, - KIJX: { - id: 'KIJX', - city: 'Jacksonville Municipal Airport', - state: 'IL', - lat: 39.7740099, - lon: -90.24187, - }, - KMQB: { - id: 'KMQB', - city: 'Macomb Municipal Airport', - state: 'IL', - lat: 40.5176299, - lon: -90.64807, - }, - KCPS: { - id: 'KCPS', - city: 'St. Louis Downtown Airport', - state: 'IL', - lat: 38.56403, - lon: -90.14871, - }, - KDKB: { - id: 'KDKB', - city: 'De Kalb Taylor Municipal Airport', - state: 'IL', - lat: 41.93381, - lon: -88.70657, - }, - KMDH: { - id: 'KMDH', - city: 'Southern Illinois Airport', - state: 'IL', - lat: 37.78328, - lon: -89.24532, - }, - KENL: { - id: 'KENL', - city: 'Centralia Municipal Airport', - state: 'IL', - lat: 38.50951, - lon: -89.08996, - }, - KPWK: { - id: 'KPWK', - city: 'Chicago / Wheeling, Pal-Waukee Airport', - state: 'IL', - lat: 42.12083, - lon: -87.90472, - }, - KPPQ: { - id: 'KPPQ', - city: 'Pittsfield, Pittsfield Penstone Municipal Airport', - state: 'IL', - lat: 39.63889, - lon: -90.77833, - }, - KSQI: { - id: 'KSQI', - city: 'Sterling Rockfalls', - state: 'IL', - lat: 41.75, - lon: -89.66667, - }, - KRPJ: { - id: 'KRPJ', - city: 'Rochelle, Rochelle Municipal-Koritz Field Airport', - state: 'IL', - lat: 41.8905699, - lon: -89.08175, - }, - KPRG: { - id: 'KPRG', - city: 'Edgar County Airport', - state: 'IL', - lat: 39.69817, - lon: -87.6669, - }, - KUGN: { - id: 'KUGN', - city: 'Chicago/Waukegan Regional Airport', - state: 'IL', - lat: 42.42546, - lon: -87.86339, - }, - KVYS: { - id: 'KVYS', - city: 'Illinois Valley Regional Airport', - state: 'IL', - lat: 41.35175, - lon: -89.14963, - }, - KTIP: { - id: 'KTIP', - city: 'Rantoul National Aviation Center Airport', - state: 'IL', - lat: 40.28952, - lon: -88.1473, - }, - KSAR: { - id: 'KSAR', - city: 'Sparta Community-Hunter Field Airport', - state: 'IL', - lat: 38.14624, - lon: -89.70243, - }, - KOLY: { - id: 'KOLY', - city: 'Olney-Noble Airport', - state: 'IL', - lat: 38.72133, - lon: -88.1799, - }, - KTAZ: { - id: 'KTAZ', - city: 'Taylorville, Taylorville Municipal Airport', - state: 'IL', - lat: 39.53417, - lon: -89.32778, - }, - KSLO: { - id: 'KSLO', - city: 'Salem, Salem-Leckrone Airport', - state: 'IL', - lat: 38.64278, - lon: -88.96417, - }, - KPNT: { - id: 'KPNT', - city: 'Pontiac Municipal Airport', - state: 'IL', - lat: 40.92327, - lon: -88.6213, - }, - KRSV: { - id: 'KRSV', - city: 'Robinson Municipal Airport', - state: 'IL', - lat: 39.01361, - lon: -87.64846, - }, - KAJG: { - id: 'KAJG', - city: 'Mount Carmel, Mount Carmel Municipal Airport', - state: 'IL', - lat: 38.60928, - lon: -87.72508, - }, - KCUL: { - id: 'KCUL', - city: 'Carmi Municipal Airport', - state: 'IL', - lat: 38.08875, - lon: -88.12125, - }, - KSFY: { - id: 'KSFY', - city: 'Tri-Township Airport', - state: 'IL', - lat: 42.04544, - lon: -90.11009, - }, - KCIR: { - id: 'KCIR', - city: 'Cairo Regional Airport', - state: 'IL', - lat: 37.06388, - lon: -89.2232, - }, - KMCI: { - id: 'KMCI', - city: 'Kansas City, Kansas City International Airport', - state: 'MO', - lat: 39.29722, - lon: -94.73056, - }, - KSTL: { - id: 'KSTL', - city: 'St. Louis, Lambert-St. Louis International Airport', - state: 'MO', - lat: 38.7525, - lon: -90.37361, - }, - KMKC: { - id: 'KMKC', - city: 'Kansas City, Kansas City Downtown Airport', - state: 'MO', - lat: 39.12083, - lon: -94.59694, - }, - KSUS: { - id: 'KSUS', - city: 'St. Louis, Spirit Of St. Louis Airport', - state: 'MO', - lat: 38.65722, - lon: -90.65583, - }, - KCOU: { - id: 'KCOU', - city: 'Columbia, Columbia Regional Airport', - state: 'MO', - lat: 38.81694, - lon: -92.21833, - }, - KSTJ: { - id: 'KSTJ', - city: 'St. Joseph, Rosecrans Memorial Airport', - state: 'MO', - lat: 39.76806, - lon: -94.90917, - }, - KSGF: { - id: 'KSGF', - city: 'Springfield, Springfield Regional Airport', - state: 'MO', - lat: 37.23972, - lon: -93.38972, - }, - KIRK: { - id: 'KIRK', - city: 'Kirksville, Kirksville Regional Airport', - state: 'MO', - lat: 40.09722, - lon: -92.54333, - }, - KFAM: { - id: 'KFAM', - city: 'Farmington Airport', - state: 'MO', - lat: 37.76667, - lon: -90.43333, - }, - KCGI: { - id: 'KCGI', - city: 'Cape Girardeau, Cape Girardeau Regional Airport', - state: 'MO', - lat: 37.22556, - lon: -89.5783299, - }, - KJLN: { - id: 'KJLN', - city: 'Joplin, Joplin Regional Airport', - state: 'MO', - lat: 37.15611, - lon: -94.5005599, - }, - KPOF: { - id: 'KPOF', - city: 'Poplar Bluff, Poplar Bluff Municipal Airport', - state: 'MO', - lat: 36.77056, - lon: -90.32222, - }, - KSZL: { - id: 'KSZL', - city: 'Whiteman Air Force Base', - state: 'MO', - lat: 38.73333, - lon: -93.55, - }, - KLXT: { - id: 'KLXT', - city: 'Lee\'s Summit, Lee\'s Summit Municipal Airport', - state: 'MO', - lat: 38.95972, - lon: -94.37167, - }, - KDMO: { - id: 'KDMO', - city: 'Sedalia, Sedalia Memorial Airport', - state: 'MO', - lat: 38.71222, - lon: -93.17444, - }, - KJEF: { - id: 'KJEF', - city: 'Jefferson City, Jefferson City Memorial Airport', - state: 'MO', - lat: 38.59444, - lon: -92.15583, - }, - KCDJ: { - id: 'KCDJ', - city: 'Chillicothe, Chillicothe Agri-Science Center', - state: 'MO', - lat: 39.81667, - lon: -93.58333, - }, - KAIZ: { - id: 'KAIZ', - city: 'Kaiser Lake Ozark, Lee C Fine Memorial Airport', - state: 'MO', - lat: 38.1, - lon: -92.55, - }, - KTBN: { - id: 'KTBN', - city: 'Fort Leonard Wood', - state: 'MO', - lat: 37.73333, - lon: -92.13333, - }, - KUNO: { - id: 'KUNO', - city: 'West Plains, West Plains Municipal Airport', - state: 'MO', - lat: 36.87917, - lon: -91.905, - }, - KSET: { - id: 'KSET', - city: 'St. Charles, St. Charles County Smartt Airport', - state: 'MO', - lat: 38.93056, - lon: -90.4325, - }, - KVIH: { - id: 'KVIH', - city: 'Rolla / Vichy, Rolla National Airport', - state: 'MO', - lat: 38.13194, - lon: -91.76528, - }, - KBBG: { - id: 'KBBG', - city: 'Branson', - state: 'MO', - lat: 36.5321, - lon: -93.2005, - }, - KVER: { - id: 'KVER', - city: 'Jesse Viertel Memorial Airport', - state: 'MO', - lat: 38.94672, - lon: -92.68267, - }, - KGPH: { - id: 'KGPH', - city: 'Mosby Midwest National Air Center Airport', - state: 'MO', - lat: 39.3325, - lon: -94.3096, - }, - KFWB: { - id: 'KFWB', - city: 'Branson West Muni - Emerson Field', - state: 'MO', - lat: 36.6985, - lon: -93.4021999, - }, - KHAE: { - id: 'KHAE', - city: 'HANNIBAL', - state: 'MO', - lat: 39.7245, - lon: -91.44366, - }, - KSIK: { - id: 'KSIK', - city: 'SIKESTON', - state: 'MO', - lat: 36.8988299, - lon: -89.56184, - }, - KMHL: { - id: 'KMHL', - city: 'MARSHALL', - state: 'MO', - lat: 39.09583, - lon: -93.20284, - }, - KMYJ: { - id: 'KMYJ', - city: 'MEXICO', - state: 'MO', - lat: 39.1575, - lon: -91.81834, - }, - KRCM: { - id: 'KRCM', - city: 'Skyhaven Airport', - state: 'MO', - lat: 38.7842, - lon: -93.8028999, - }, - KEOS: { - id: 'KEOS', - city: 'NEOSHO AIRPORT', - state: 'MO', - lat: 36.8108, - lon: -94.39169, - }, - KHFJ: { - id: 'KHFJ', - city: 'Monett', - state: 'MO', - lat: 36.9062, - lon: -94.0128, - }, - KGLY: { - id: 'KGLY', - city: 'Clinton, MO', - state: 'MO', - lat: 38.3566, - lon: -93.6842, - }, - KOZS: { - id: 'KOZS', - city: 'Camdenton Memorial Airport', - state: 'MO', - lat: 37.9739999, - lon: -92.6912, - }, - KFYG: { - id: 'KFYG', - city: 'Washington Regional Airport', - state: 'MO', - lat: 38.5876, - lon: -90.9937999, - }, - KTKX: { - id: 'KTKX', - city: 'Kennett - Kennett Memorial Airport', - state: 'MO', - lat: 36.22256, - lon: -90.03671, - }, - KBTV: { - id: 'KBTV', - city: 'Burlington, Burlington International Airport', - state: 'VT', - lat: 44.46806, - lon: -73.15028, - }, - KMPV: { - id: 'KMPV', - city: 'Barre / Montpelier, Knapp State Airport', - state: 'VT', - lat: 44.20472, - lon: -72.56611, - }, - KDDH: { - id: 'KDDH', - city: 'Bennington Morse State Airport', - state: 'VT', - lat: 42.89355, - lon: -73.2486, - }, - KMVL: { - id: 'KMVL', - city: 'Morrisville-Stowe State Airport', - state: 'VT', - lat: 44.53589, - lon: -72.6162499, - }, - KVSF: { - id: 'KVSF', - city: 'Springfield, Hartness State Springfield Airport', - state: 'VT', - lat: 43.3425, - lon: -72.52167, - }, - KRUT: { - id: 'KRUT', - city: 'Rutland-Southern Vermont Regional Airport', - state: 'VT', - lat: 43.53333, - lon: -72.95, - }, - KEFK: { - id: 'KEFK', - city: 'NEWPORT', - state: 'VT', - lat: 44.93, - lon: -72.2, - }, - KFSO: { - id: 'KFSO', - city: 'Franklin County State Airport', - state: 'VT', - lat: 44.9402807, - lon: -73.09746, - }, - KCDA: { - id: 'KCDA', - city: 'Caledonia County Airport', - state: 'VT', - lat: 44.5691142, - lon: -72.0179789, - }, - KLIT: { - id: 'KLIT', - city: 'Little Rock, Adams Field', - state: 'AR', - lat: 34.72667, - lon: -92.23611, - }, - KLRF: { - id: 'KLRF', - city: 'Little Rock Air Force Base', - state: 'AR', - lat: 34.91667, - lon: -92.15, - }, - KFSM: { - id: 'KFSM', - city: 'Fort Smith, Fort Smith Regional Airport', - state: 'AR', - lat: 35.33361, - lon: -94.365, - }, - KFYV: { - id: 'KFYV', - city: 'Fayetteville, Drake Field', - state: 'AR', - lat: 36.01028, - lon: -94.1677799, - }, - KAWM: { - id: 'KAWM', - city: 'West Memphis, West Memphis Municipal Airport', - state: 'AR', - lat: 35.13333, - lon: -90.23333, - }, - KHOT: { - id: 'KHOT', - city: 'Hot Springs, Memorial Field Airport', - state: 'AR', - lat: 34.47806, - lon: -93.09611, - }, - KELD: { - id: 'KELD', - city: 'El Dorado, South Arkansas Regional at Goodwin Field Airport', - state: 'AR', - lat: 33.22083, - lon: -92.8133299, - }, - KHRO: { - id: 'KHRO', - city: 'Harrison, Boone County Airport', - state: 'AR', - lat: 36.26167, - lon: -93.15472, - }, - KJBR: { - id: 'KJBR', - city: 'Jonesboro, Jonesboro Municipal Airport', - state: 'AR', - lat: 35.83722, - lon: -90.64306, - }, - KARG: { - id: 'KARG', - city: 'Walnut Ridge, Walnut Ridge Regional Airport', - state: 'AR', - lat: 36.13333, - lon: -90.91667, - }, - KXNA: { - id: 'KXNA', - city: 'Fayetteville/Springdale, Northwest Arkansas Regional Airport', - state: 'AR', - lat: 36.28194, - lon: -94.30694, - }, - KTXK: { - id: 'KTXK', - city: 'Texarkana, Texarkana Regional-Webb Field', - state: 'AR', - lat: 33.45611, - lon: -93.9875, - }, - KPBF: { - id: 'KPBF', - city: 'Pine Bluff, Grider Field Airport', - state: 'AR', - lat: 34.175, - lon: -91.93472, - }, - KLLQ: { - id: 'KLLQ', - city: 'Monticello, Monticello Municipal Airport/Ellis Field', - state: 'AR', - lat: 33.63833, - lon: -91.75111, - }, - KDEQ: { - id: 'KDEQ', - city: 'De Queen, J Lynn Helms Sevier County Airport', - state: 'AR', - lat: 34.04694, - lon: -94.39944, - }, - KBYH: { - id: 'KBYH', - city: 'Eaker Air Force Base', - state: 'AR', - lat: 35.96667, - lon: -89.95, - }, - KBVX: { - id: 'KBVX', - city: 'Batesville, Batesville Regional Airport', - state: 'AR', - lat: 35.73333, - lon: -91.65, - }, - KFLP: { - id: 'KFLP', - city: 'Flippin, Marion County Regional Airport', - state: 'AR', - lat: 36.3, - lon: -92.58333, - }, - KASG: { - id: 'KASG', - city: 'Springdale Municipal', - state: 'AR', - lat: 36.18333, - lon: -94.11667, - }, - KBPK: { - id: 'KBPK', - city: 'Mountain Home, Baxter County Regional Airport', - state: 'AR', - lat: 36.37056, - lon: -92.47194, - }, - KHKA: { - id: 'KHKA', - city: 'Blytheville, Blytheville Municipal Airport', - state: 'AR', - lat: 35.93889, - lon: -89.8325, - }, - KSRC: { - id: 'KSRC', - city: 'Searcy, Searcy Municipal Airport', - state: 'AR', - lat: 35.21194, - lon: -91.7372199, - }, - KMWT: { - id: 'KMWT', - city: 'Mount Ida', - state: 'AR', - lat: 34.55, - lon: -93.58333, - }, - KSGT: { - id: 'KSGT', - city: 'Stuttgart, Stuttgart Municipal Airport', - state: 'AR', - lat: 34.6, - lon: -91.56667, - }, - KRUE: { - id: 'KRUE', - city: 'Russellville, Russellville Regional Airport', - state: 'AR', - lat: 35.25889, - lon: -93.09333, - }, - KSLG: { - id: 'KSLG', - city: 'Siloam Springs, Smith Field Airport', - state: 'AR', - lat: 36.2, - lon: -94.48333, - }, - KROG: { - id: 'KROG', - city: 'Rogers - Rogers Executive Airport - Carter Field', - state: 'AR', - lat: 36.36667, - lon: -94.1, - }, - KVBT: { - id: 'KVBT', - city: 'Bentonville, Bentonville Municipal Airport/Louise M Thaden Field', - state: 'AR', - lat: 36.35, - lon: -94.2166699, - }, - KCDH: { - id: 'KCDH', - city: 'Camden / Harrell Field', - state: 'AR', - lat: 33.61667, - lon: -92.76667, - }, - KMEZ: { - id: 'KMEZ', - city: 'Mena, Mena Intermountain Municipal Airport', - state: 'AR', - lat: 34.54528, - lon: -94.2025, - }, - KCCA: { - id: 'KCCA', - city: 'Clinton Memorial Airfield', - state: 'AR', - lat: 35.598, - lon: -92.4516, - }, - KADF: { - id: 'KADF', - city: 'Dexter B Florence Memorial Field', - state: 'AR', - lat: 34.0998, - lon: -93.0661, - }, - KMGW: { - id: 'KMGW', - city: 'Morgantown Municipal-Hart Field', - state: 'WV', - lat: 39.64985, - lon: -79.92065, - }, - KHTS: { - id: 'KHTS', - city: 'Huntington, Tri-State Airport', - state: 'WV', - lat: 38.365, - lon: -82.555, - }, - KEKN: { - id: 'KEKN', - city: 'Elkins, Elkins-Randolph County-Jennings Randolph Field', - state: 'WV', - lat: 38.88528, - lon: -79.85278, - }, - KCKB: { - id: 'KCKB', - city: 'Clarksburg, Clarksburg Benedum Airport', - state: 'WV', - lat: 39.3, - lon: -80.22472, - }, - KMRB: { - id: 'KMRB', - city: 'Eastern WV Regional Airport/Shepherd Field', - state: 'WV', - lat: 39.40372, - lon: -77.975, - }, - KLWB: { - id: 'KLWB', - city: 'Lewisburg / Greenbrier', - state: 'WV', - lat: 37.86667, - lon: -80.4, - }, - KCRW: { - id: 'KCRW', - city: 'Charleston, Yeager Airport', - state: 'WV', - lat: 38.37944, - lon: -81.59139, - }, - KHLG: { - id: 'KHLG', - city: 'Wheeling, Wheeling Ohio County Airport', - state: 'WV', - lat: 40.17028, - lon: -80.64444, - }, - KBLF: { - id: 'KBLF', - city: 'Bluefield, Mercer County Airport', - state: 'WV', - lat: 37.29583, - lon: -81.20778, - }, - KBKW: { - id: 'KBKW', - city: 'Beckley, Raleigh County Memorial Airport', - state: 'WV', - lat: 37.795, - lon: -81.12472, - }, - KPKB: { - id: 'KPKB', - city: 'Parkersburg, Mid-Ohio Valley Regional Airport', - state: 'WV', - lat: 39.345, - lon: -81.43917, - }, - KCBE: { - id: 'KCBE', - city: 'Cumberland, Greater Cumberland Regional Airport', - state: 'WV', - lat: 39.61528, - lon: -78.76083, - }, - KDSM: { - id: 'KDSM', - city: 'Des Moines, Des Moines International Airport', - state: 'IA', - lat: 41.53778, - lon: -93.66611, - }, - KDVN: { - id: 'KDVN', - city: 'Davenport, Davenport Municipal Airport', - state: 'IA', - lat: 41.61389, - lon: -90.59139, - }, - KSUX: { - id: 'KSUX', - city: 'Sioux City, Sioux Gateway Airport', - state: 'IA', - lat: 42.4025, - lon: -96.38444, - }, - KALO: { - id: 'KALO', - city: 'Waterloo, Waterloo Municipal Airport', - state: 'IA', - lat: 42.55444, - lon: -92.40111, - }, - KCID: { - id: 'KCID', - city: 'Cedar Rapids, The Eastern Iowa Airport', - state: 'IA', - lat: 41.88444, - lon: -91.71056, - }, - KDBQ: { - id: 'KDBQ', - city: 'Dubuque, Dubuque Regional Airport', - state: 'IA', - lat: 42.39778, - lon: -90.70361, - }, - KBRL: { - id: 'KBRL', - city: 'Burlington, Burlington Regional Airport', - state: 'IA', - lat: 40.77278, - lon: -91.12528, - }, - KFOD: { - id: 'KFOD', - city: 'Fort Dodge', - state: 'IA', - lat: 42.55, - lon: -94.18333, - }, - KMCW: { - id: 'KMCW', - city: 'Mason City, Mason City Municipal Airport', - state: 'IA', - lat: 43.15778, - lon: -93.33139, - }, - KIOW: { - id: 'KIOW', - city: 'Iowa City, Iowa City Municipal Airport', - state: 'IA', - lat: 41.6327799, - lon: -91.54306, - }, - KOTM: { - id: 'KOTM', - city: 'Ottumwa, Ottumwa Industrial Airport', - state: 'IA', - lat: 41.10667, - lon: -92.44806, - }, - KSPW: { - id: 'KSPW', - city: 'Spencer, Spencer Municipal Airport', - state: 'IA', - lat: 43.16556, - lon: -95.20278, - }, - KAMW: { - id: 'KAMW', - city: 'Ames, Ames Municipal Airport', - state: 'IA', - lat: 41.99056, - lon: -93.6188899, - }, - KLWD: { - id: 'KLWD', - city: 'Lamoni, Lamoni Municipal Airport', - state: 'IA', - lat: 40.63056, - lon: -93.90083, - }, - KEST: { - id: 'KEST', - city: 'Estherville, Estherville Municipal Airport', - state: 'IA', - lat: 43.40111, - lon: -94.74722, - }, - KMIW: { - id: 'KMIW', - city: 'Marshalltown, Marshalltown Municipal Airport', - state: 'IA', - lat: 42.11056, - lon: -92.91611, - }, - KIFA: { - id: 'KIFA', - city: 'Iowa Falls Municipal Airport', - state: 'IA', - lat: 42.4709999, - lon: -93.27, - }, - KAIO: { - id: 'KAIO', - city: 'Atlantic', - state: 'IA', - lat: 41.4, - lon: -95.05, - }, - KFSW: { - id: 'KFSW', - city: 'Fort Madison', - state: 'IA', - lat: 40.66667, - lon: -91.33333, - }, - KAXA: { - id: 'KAXA', - city: 'Algona', - state: 'IA', - lat: 43.0833299, - lon: -94.26667, - }, - KEBS: { - id: 'KEBS', - city: 'Webster City', - state: 'IA', - lat: 42.43333, - lon: -93.86667, - }, - KCCY: { - id: 'KCCY', - city: 'Charles City', - state: 'IA', - lat: 43.06667, - lon: -92.61667, - }, - KIKV: { - id: 'KIKV', - city: 'Ankeny, Ankeny Regional Airport', - state: 'IA', - lat: 41.69, - lon: -93.56583, - }, - KMUT: { - id: 'KMUT', - city: 'Muscatine', - state: 'IA', - lat: 41.36667, - lon: -91.15, - }, - KAWG: { - id: 'KAWG', - city: 'Washington', - state: 'IA', - lat: 41.28333, - lon: -91.66667, - }, - KCSQ: { - id: 'KCSQ', - city: 'Creston', - state: 'IA', - lat: 41.01667, - lon: -94.36667, - }, - KEOK: { - id: 'KEOK', - city: 'Keokuk Municipal', - state: 'IA', - lat: 40.46667, - lon: -91.43333, - }, - KCIN: { - id: 'KCIN', - city: 'Carroll', - state: 'IA', - lat: 42.05, - lon: -94.78333, - }, - KDEH: { - id: 'KDEH', - city: 'Decorah', - state: 'IA', - lat: 43.28333, - lon: -91.73333, - }, - KCWI: { - id: 'KCWI', - city: 'Clinton, Clinton Municipal Airport', - state: 'IA', - lat: 41.8333299, - lon: -90.33333, - }, - KFFL: { - id: 'KFFL', - city: 'Fairfield - Fairfield Municipal Airport', - state: 'IA', - lat: 41.05, - lon: -91.98333, - }, - KLRJ: { - id: 'KLRJ', - city: 'Le Mars, Le Mars Municipal Airport', - state: 'IA', - lat: 42.77806, - lon: -96.19361, - }, - KCAV: { - id: 'KCAV', - city: 'Clarion', - state: 'IA', - lat: 42.75, - lon: -93.76667, - }, - KCBF: { - id: 'KCBF', - city: 'Council Bluffs', - state: 'IA', - lat: 41.26667, - lon: -95.76667, - }, - KHNR: { - id: 'KHNR', - city: 'Harlan, Harlan Municipal Airport', - state: 'IA', - lat: 41.58444, - lon: -95.33972, - }, - KDNS: { - id: 'KDNS', - city: 'Denison', - state: 'IA', - lat: 41.98333, - lon: -95.38333, - }, - KBNW: { - id: 'KBNW', - city: 'Boone Municipal', - state: 'IA', - lat: 42.05, - lon: -93.85, - }, - KCNC: { - id: 'KCNC', - city: 'Chariton', - state: 'IA', - lat: 41.03333, - lon: -93.36667, - }, - KICL: { - id: 'KICL', - city: 'Clarinda', - state: 'IA', - lat: 40.71667, - lon: -95.03333, - }, - KADU: { - id: 'KADU', - city: 'Audubon, Audubon County Airport', - state: 'IA', - lat: 41.70111, - lon: -94.92028, - }, - KMPZ: { - id: 'KMPZ', - city: 'Mount Pleasant, Mount Pleasant Municipal Airport', - state: 'IA', - lat: 40.94667, - lon: -91.51111, - }, - KSDA: { - id: 'KSDA', - city: 'Shenandoah Municipal', - state: 'IA', - lat: 40.75, - lon: -95.41667, - }, - KOLZ: { - id: 'KOLZ', - city: 'Oelwein, Oelwein Municipal Airport', - state: 'IA', - lat: 42.68083, - lon: -91.97444, - }, - KPEA: { - id: 'KPEA', - city: 'Pella, Pella Municipal Airport', - state: 'IA', - lat: 41.4, - lon: -92.93333, - }, - KTNU: { - id: 'KTNU', - city: 'Newton Municipal', - state: 'IA', - lat: 41.68333, - lon: -93.01667, - }, - KOXV: { - id: 'KOXV', - city: 'Knoxville', - state: 'IA', - lat: 41.3, - lon: -93.11667, - }, - KMXO: { - id: 'KMXO', - city: 'Monticello Municipal', - state: 'IA', - lat: 42.23333, - lon: -91.16667, - }, - KRDK: { - id: 'KRDK', - city: 'Red Oak', - state: 'IA', - lat: 41.01667, - lon: -95.26667, - }, - KORC: { - id: 'KORC', - city: 'Orange City', - state: 'IA', - lat: 42.98333, - lon: -96.06667, - }, - KSLB: { - id: 'KSLB', - city: 'Storm Lake', - state: 'IA', - lat: 42.6, - lon: -95.23333, - }, - KSHL: { - id: 'KSHL', - city: 'Sheldon', - state: 'IA', - lat: 43.21667, - lon: -95.83333, - }, - KOOA: { - id: 'KOOA', - city: 'Oskaloosa, Oskaloosa Municipal Airport', - state: 'IA', - lat: 41.22611, - lon: -92.49361, - }, - KCKP: { - id: 'KCKP', - city: 'Cherokee, Cherokee Municipal Airport', - state: 'IA', - lat: 42.73167, - lon: -95.55583, - }, - KVTI: { - id: 'KVTI', - city: 'Vinton, Vinton Veterans Memorial Airpark Airport', - state: 'IA', - lat: 42.21861, - lon: -92.02583, - }, - KIIB: { - id: 'KIIB', - city: 'Independence, Independence Municipal Airport', - state: 'IA', - lat: 42.45, - lon: -91.93333, - }, - KGGI: { - id: 'KGGI', - city: 'Grinnell Municipal Airfield', - state: 'IA', - lat: 41.7092, - lon: -92.7349, - }, - KPRO: { - id: 'KPRO', - city: 'Perry Municipal Airport', - state: 'IA', - lat: 41.828, - lon: -94.1598999, - }, - KTVK: { - id: 'KTVK', - city: 'Centerville Municipal Airport', - state: 'IA', - lat: 40.6839, - lon: -92.901, - }, - KFXY: { - id: 'KFXY', - city: 'Forest City Municipal Airport', - state: 'IA', - lat: 43.235, - lon: -93.624, - }, - KEET: { - id: 'KEET', - city: 'Alabaster, Shelby County Airport', - state: 'AL', - lat: 33.17833, - lon: -86.78167, - }, - KMOB: { - id: 'KMOB', - city: 'Mobile, Mobile Regional Airport', - state: 'AL', - lat: 30.68833, - lon: -88.24556, - }, - KBHM: { - id: 'KBHM', - city: 'Birmingham, Birmingham International Airport', - state: 'AL', - lat: 33.56556, - lon: -86.745, - }, - KMGM: { - id: 'KMGM', - city: 'Montgomery, Dannelly Field', - state: 'AL', - lat: 32.30028, - lon: -86.40611, - }, - KHSV: { - id: 'KHSV', - city: 'Huntsville, Huntsville International / Jones Field', - state: 'AL', - lat: 34.64361, - lon: -86.78556, - }, - KANB: { - id: 'KANB', - city: 'Anniston Metro Airport', - state: 'AL', - lat: 33.59045, - lon: -85.84789, - }, - KDHN: { - id: 'KDHN', - city: 'Dothan, Dothan Regional Airport', - state: 'AL', - lat: 31.32139, - lon: -85.44972, - }, - KMSL: { - id: 'KMSL', - city: 'Muscle Shoals, North West Alabama Regional Airport', - state: 'AL', - lat: 34.74389, - lon: -87.59944, - }, - KMXF: { - id: 'KMXF', - city: 'Maxwell Air Force Base / Montgomery', - state: 'AL', - lat: 32.38333, - lon: -86.36667, - }, - KTCL: { - id: 'KTCL', - city: 'Tuscaloosa Regional Airport', - state: 'AL', - lat: 33.21215, - lon: -87.61554, - }, - KOZR: { - id: 'KOZR', - city: 'Cairns Army Air Field / Ozark', - state: 'AL', - lat: 31.27672, - lon: -85.71099, - }, - KLOR: { - id: 'KLOR', - city: 'Fort Rucker, Lowe Army Heliport', - state: 'AL', - lat: 31.35889, - lon: -85.74833, - }, - KBFM: { - id: 'KBFM', - city: 'Mobile, Mobile Downtown Airport', - state: 'AL', - lat: 30.61389, - lon: -88.0633299, - }, - KGZH: { - id: 'KGZH', - city: 'Evergreen, Middleton Field', - state: 'AL', - lat: 31.41889, - lon: -87.04806, - }, - KAUO: { - id: 'KAUO', - city: 'Auburn-Opelika Airport', - state: 'AL', - lat: 32.61667, - lon: -85.43333, - }, - KGAD: { - id: 'KGAD', - city: 'Gadsden, Gadsden Municipal Airport', - state: 'AL', - lat: 33.96667, - lon: -86.08333, - }, - KDCU: { - id: 'KDCU', - city: 'Decatur, Pryor Field', - state: 'AL', - lat: 34.65806, - lon: -86.94333, - }, - KTOI: { - id: 'KTOI', - city: 'Troy, Troy Municipal Airport', - state: 'AL', - lat: 31.86056, - lon: -86.01222, - }, - KSEM: { - id: 'KSEM', - city: 'Craig Field / Selma', - state: 'AL', - lat: 32.35, - lon: -86.98333, - }, - KALX: { - id: 'KALX', - city: 'Alexander City, Thomas C Russell Field Airport', - state: 'AL', - lat: 32.91472, - lon: -85.96278, - }, - KCMD: { - id: 'KCMD', - city: 'Cullman Regional Folsom Field', - state: 'AL', - lat: 34.2687, - lon: -86.858, - }, - KJKA: { - id: 'KJKA', - city: 'Jack Edwards Airport', - state: 'AL', - lat: 30.2896, - lon: -87.6718, - }, - KDYA: { - id: 'KDYA', - city: 'Demopolis Municipal Airport', - state: 'AL', - lat: 32.4638, - lon: -87.9541, - }, - KSCD: { - id: 'KSCD', - city: 'Merkel Field Sylacauga Municipal Airport', - state: 'AL', - lat: 33.1718, - lon: -86.3055, - }, - KPLR: { - id: 'KPLR', - city: 'St Clair County Airport', - state: 'AL', - lat: 33.5588, - lon: -86.2491, - }, - KEKY: { - id: 'KEKY', - city: 'Bessemer Airport', - state: 'AL', - lat: 33.3126, - lon: -86.9263, - }, - KMDQ: { - id: 'KMDQ', - city: 'Huntsville, Madison County Executive Airport', - state: 'AL', - lat: 34.86139, - lon: -86.55722, - }, - KHEY: { - id: 'KHEY', - city: 'Hanchey AHP / Ozark', - state: 'AL', - lat: 31.35, - lon: -85.66667, - }, - KPRN: { - id: 'KPRN', - city: 'Mac Crenshaw Mememorial Airport', - state: 'AL', - lat: 31.8457, - lon: -86.6107, - }, - KHUA: { - id: 'KHUA', - city: 'Redstone Airfield', - state: 'AL', - lat: 34.6786, - lon: -86.6847, - }, - KEUF: { - id: 'KEUF', - city: 'Eufaula Municipal Airport', - state: 'AL', - lat: 31.951, - lon: -85.129, - }, - KCQF: { - id: 'KCQF', - city: 'Sonny Callahan Airport', - state: 'AL', - lat: 30.461, - lon: -87.877, - }, - KJFX: { - id: 'KJFX', - city: 'Jasper Walker County Airport & Bevill Field', - state: 'AL', - lat: 33.902, - lon: -87.31417, - }, - KASN: { - id: 'KASN', - city: 'Talladega Municipal Airport', - state: 'AL', - lat: 33.5695, - lon: -86.0512, - }, - AFTY: { - id: 'AFTY', - city: 'AFTON', - state: 'WY', - lat: 42.73333, - lon: -110.93583, - }, - KEVS: { - id: 'KEVS', - city: 'EVANSTON/BURNS', - state: 'WY', - lat: 41.27, - lon: -111.01, - }, - KREC: { - id: 'KREC', - city: 'Red Canyon WYO 28 tween Riverton&S.Pass', - state: 'WY', - lat: 42.6166, - lon: -108.60859, - }, - KSOU: { - id: 'KSOU', - city: 'South Pass WYO 28 near South Pass', - state: 'WY', - lat: 42.47752, - lon: -108.84441, - }, - KTET: { - id: 'KTET', - city: 'Teton Pass WYO 22 west of Jackson', - state: 'WY', - lat: 43.49873, - lon: -110.9562, - }, - KPER: { - id: 'KPER', - city: 'Peru Hill I-80 west of Green River', - state: 'WY', - lat: 41.53186, - lon: -109.45995, - }, - KVED: { - id: 'KVED', - city: 'Vedauwoo', - state: 'WY', - lat: 41.1571799, - lon: -105.4019299, - }, - KWYH: { - id: 'KWYH', - city: 'Wyo Hill I-25 south of Cheyenne', - state: 'WY', - lat: 41.04746, - lon: -104.8901, - }, - JHRV: { - id: 'JHRV', - city: 'JACKSON HOLE-RENDEZVOUS BOWL ', - state: 'WY', - lat: 43.590858, - lon: -110.872558, - }, - AGRS: { - id: 'AGRS', - city: 'Grassy Lake near Moran, WY', - state: 'WY', - lat: 44.1291666, - lon: -110.8180555, - }, - PCKY: { - id: 'PCKY', - city: 'Pacific Creek at Moran, WY', - state: 'WY', - lat: 43.8502777, - lon: -110.5177777, - }, - BONY: { - id: 'BONY', - city: 'Bondurant 3NW', - state: 'WY', - lat: 43.2158333, - lon: -110.4236111, - }, - ALPY: { - id: 'ALPY', - city: 'Snake River above Reservoir near Alpine, WY', - state: 'WY', - lat: 43.1961111, - lon: -110.8894444, - }, - FLGY: { - id: 'FLGY', - city: 'Snake River near Flagg Ranch, WY', - state: 'WY', - lat: 44.0988888, - lon: -110.6672222, - }, - JKSY: { - id: 'JKSY', - city: 'Snake River below Flat Creek near Jackson, WY', - state: 'WY', - lat: 43.3722222, - lon: -110.7386111, - }, - ALTY: { - id: 'ALTY', - city: 'Alta Wyoming Weather Station', - state: 'WY', - lat: 43.7725, - lon: -111.0330555, - }, - SALY: { - id: 'SALY', - city: 'Salt River above Reservoir near Etna, WY', - state: 'WY', - lat: 43.0797222, - lon: -111.0372222, - }, - JKNY: { - id: 'JKNY', - city: 'Jackson WY Weather Station', - state: 'WY', - lat: 43.4836111, - lon: -110.7602777, - }, - SKRY: { - id: 'SKRY', - city: 'Snake River Station, WY', - state: 'WY', - lat: 44.1333333, - lon: -110.6666666, - }, - HKBY: { - id: 'HKBY', - city: 'Huckleberry Divide, WY', - state: 'WY', - lat: 44.1333333, - lon: -110.6688888, - }, - BFKY: { - id: 'BFKY', - city: 'Buffalo Fork above Lava Creek near Moran, WY', - state: 'WY', - lat: 43.8380555, - lon: -110.4411111, - }, - GCKY: { - id: 'GCKY', - city: 'Glade Creek', - state: 'WY', - lat: 44.0997222, - lon: -110.7366666, - }, - GREY: { - id: 'GREY', - city: 'Greys River above Reservoir near Alpine, WY', - state: 'WY', - lat: 43.1427777, - lon: -110.9766666, - }, - KSHR: { - id: 'KSHR', - city: 'Sheridan County Airport', - state: 'WY', - lat: 44.7603099, - lon: -106.97411, - }, - KRIW: { - id: 'KRIW', - city: 'Riverton, Riverton Regional Airport', - state: 'WY', - lat: 43.06194, - lon: -108.44639, - }, - KCOD: { - id: 'KCOD', - city: 'Cody', - state: 'WY', - lat: 44.51667, - lon: -109.01667, - }, - KCYS: { - id: 'KCYS', - city: 'Cheyenne, Cheyenne Airport', - state: 'WY', - lat: 41.15789, - lon: -104.80812, - }, - KRKS: { - id: 'KRKS', - city: 'Rock Springs, Rock Springs-Sweetwater County Airport', - state: 'WY', - lat: 41.59417, - lon: -109.06528, - }, - KCPR: { - id: 'KCPR', - city: 'Casper, Natrona County International Airport', - state: 'WY', - lat: 42.8975, - lon: -106.47306, - }, - KLAR: { - id: 'KLAR', - city: 'Laramie Regional Airport', - state: 'WY', - lat: 41.3165, - lon: -105.67287, - }, - KRWL: { - id: 'KRWL', - city: 'Rawlins, Rawlins Municipal Airport', - state: 'WY', - lat: 41.80556, - lon: -107.19972, - }, - KWRL: { - id: 'KWRL', - city: 'Worland, Worland Municipal Airport', - state: 'WY', - lat: 43.9658299, - lon: -107.95083, - }, - KGCC: { - id: 'KGCC', - city: 'Gillette, Gillette-Campbell County Airport', - state: 'WY', - lat: 44.33944, - lon: -105.54194, - }, - KLND: { - id: 'KLND', - city: 'Lander', - state: 'WY', - lat: 42.81472, - lon: -108.72806, - }, - KJAC: { - id: 'KJAC', - city: 'Jackson, Jackson Hole Airport', - state: 'WY', - lat: 43.6, - lon: -110.73333, - }, - KBPI: { - id: 'KBPI', - city: 'Big Piney, Big Piney-Marbleton Airport', - state: 'WY', - lat: 42.57889, - lon: -110.10306, - }, - KGEY: { - id: 'KGEY', - city: 'South Big Horn County Airport', - state: 'WY', - lat: 44.5174, - lon: -108.0752, - }, - KBYG: { - id: 'KBYG', - city: 'Buffalo, Buffalo Johnson County Airport', - state: 'WY', - lat: 44.38139, - lon: -106.71889, - }, - KTOR: { - id: 'KTOR', - city: 'Torrington Municipal Airport', - state: 'WY', - lat: 42.0645, - lon: -104.1527, - }, - KDGW: { - id: 'KDGW', - city: 'Douglas, Converse County Airport', - state: 'WY', - lat: 42.79417, - lon: -105.38194, - }, - KEVW: { - id: 'KEVW', - city: 'Evanston, Evanston-Uinta County Burns Field', - state: 'WY', - lat: 41.27306, - lon: -111.03056, - }, - KDUB: { - id: 'KDUB', - city: 'Dubois Municipal Airport', - state: 'WY', - lat: 43.5484, - lon: -109.6903, - }, - KDWX: { - id: 'KDWX', - city: 'Dixon Airport', - state: 'WY', - lat: 41.03704, - lon: -107.49976, - }, - KGUR: { - id: 'KGUR', - city: 'Camp Guernsey', - state: 'WY', - lat: 42.2597, - lon: -104.7283, - }, - KPOY: { - id: 'KPOY', - city: 'Powell Municipal Airport', - state: 'WY', - lat: 44.8671999, - lon: -108.7934, - }, - KPNA: { - id: 'KPNA', - city: 'Pinedale, Ralph Wenz Field Airport', - state: 'WY', - lat: 42.79528, - lon: -109.80694, - }, - KAFO: { - id: 'KAFO', - city: 'Afton WY', - state: 'WY', - lat: 42.7113299, - lon: -110.94217, - }, - KECS: { - id: 'KECS', - city: 'Mondell Field', - state: 'WY', - lat: 43.8854, - lon: -104.3179, - }, - KFEW: { - id: 'KFEW', - city: 'Francis E Warren Air Force Base Heliport', - state: 'WY', - lat: 41.13332, - lon: -104.8671899, - }, - KTBX: { - id: 'KTBX', - city: 'Boysen', - state: 'WY', - lat: 43.4667, - lon: -108.2333, - }, - KEHY: { - id: 'KEHY', - city: 'Elk Mountain AWOS', - state: 'WY', - lat: 41.7253, - lon: -106.4594, - }, - KHSG: { - id: 'KHSG', - city: 'Hot Springs County Airport', - state: 'WY', - lat: 43.7136, - lon: -108.3897, - }, - KBFU: { - id: 'KBFU', - city: 'Belle Fourche US 59 south of Gillette', - state: 'WY', - lat: 43.9325, - lon: -105.4467, - }, - KSKL: { - id: 'KSKL', - city: 'Skyline 230 WYO 230 SE of Encampment', - state: 'WY', - lat: 41.13753, - lon: -106.57687, - }, - KIKA: { - id: 'KIKA', - city: 'Inyan Kara I-90 west of Sundance', - state: 'WY', - lat: 44.29414, - lon: -104.62926, - }, - KBIT: { - id: 'KBIT', - city: 'Bitter Creek I-80 east of Rock Springs', - state: 'WY', - lat: 41.64599, - lon: -108.5836, - }, - KDRC: { - id: 'KDRC', - city: 'Deer Creek I-25 east of Casper', - state: 'WY', - lat: 42.83687, - lon: -105.86063, - }, - KTMH: { - id: 'KTMH', - city: 'Twenty Mile Hill I-25 north of Casper', - state: 'WY', - lat: 43.12271, - lon: -106.33705, - }, - KMTR: { - id: 'KMTR', - city: 'Meeteetse US 120 north of Meeteetsie', - state: 'WY', - lat: 44.27011, - lon: -108.87343, - }, - KBVR: { - id: 'KBVR', - city: 'Beaver Rim US 287/WYO 789 SE of Lander', - state: 'WY', - lat: 42.58565, - lon: -108.28199, - }, - KARL: { - id: 'KARL', - city: 'Arlington I-80 west of Laramie', - state: 'WY', - lat: 41.5980599, - lon: -106.21487, - }, - KVDW: { - id: 'KVDW', - city: 'Vedauwoo I-80 between Cheyenne&Laramie', - state: 'WY', - lat: 41.15688, - lon: -105.40237, - }, - KHLD: { - id: 'KHLD', - city: 'Hiland US 20/26 between Casper&Shoshoni', - state: 'WY', - lat: 43.0923, - lon: -107.32198, - }, - KCTD: { - id: 'KCTD', - city: 'Continental Divide I-80 west of Rawlins', - state: 'WY', - lat: 41.71586, - lon: -107.78256, - }, - KFIR: { - id: 'KFIR', - city: 'First Divide I-80 east of Evanston', - state: 'WY', - lat: 41.27649, - lon: -110.80067, - }, - KDHS: { - id: 'KDHS', - city: 'Dead Horse I-90 tween Buffalo&Gillette', - state: 'WY', - lat: 44.21906, - lon: -106.10477, - }, - KPUM: { - id: 'KPUM', - city: 'Pumpkin Vine US 287 south of Laramie', - state: 'WY', - lat: 41.05218, - lon: -105.4691, - }, - KWTR: { - id: 'KWTR', - city: 'Whitaker I-25 north of Cheyenne', - state: 'WY', - lat: 41.41772, - lon: -104.87502, - }, - KIDV: { - id: 'KIDV', - city: 'I-25 Divide I-25 north of Kaycee', - state: 'WY', - lat: 43.89864, - lon: -106.63833, - }, - KCMS: { - id: 'KCMS', - city: 'Peru Hill I-80 at Green River Tunnel', - state: 'WY', - lat: 41.54958, - lon: -109.60197, - }, - KPAT: { - id: 'KPAT', - city: 'Pathfinder Hill US 220 south of Alcova', - state: 'WY', - lat: 42.55811, - lon: -106.8453399, - }, - KPIN: { - id: 'KPIN', - city: 'Piney Creek I-90 tween Buffalo&Sheridan', - state: 'WY', - lat: 44.53356, - lon: -106.80509, - }, - KBRX: { - id: 'KBRX', - city: 'Bordeaux I-25 south of Wheatland', - state: 'WY', - lat: 41.93066, - lon: -104.9436, - }, - KFBR: { - id: 'KFBR', - city: 'Fort Bridger WY', - state: 'WY', - lat: 41.392, - lon: -110.40683, - }, - KSAA: { - id: 'KSAA', - city: 'Saratoga WY', - state: 'WY', - lat: 41.44483, - lon: -106.8235, - }, - KEMM: { - id: 'KEMM', - city: 'KEMMERER', - state: 'WY', - lat: 41.82, - lon: -110.56, - }, - KSHC: { - id: 'KSHC', - city: 'Shute Creek WYO 372 Grn. River-La Barge', - state: 'WY', - lat: 41.94409, - lon: -110.00399, - }, - KCHJ: { - id: 'KCHJ', - city: 'Chief Joseph WYO 296 north of Cody', - state: 'WY', - lat: 44.73997, - lon: -109.38088, - }, - KSGE: { - id: 'KSGE', - city: 'Sage Junction US 30 west of Kemmerer', - state: 'WY', - lat: 41.82447, - lon: -110.90764, - }, - KRIM: { - id: 'KRIM', - city: 'Rim US 191 between Pinedale & Bondurant', - state: 'WY', - lat: 43.1047, - lon: -110.17098, - }, - KGUN: { - id: 'KGUN', - city: 'Gun Barrel US 85 northeast of Cheyenne', - state: 'WY', - lat: 41.44368, - lon: -104.34428, - }, - KAJL: { - id: 'KAJL', - city: 'Lava Mountain', - state: 'WY', - lat: 43.674, - lon: -110.031, - }, - KLSK: { - id: 'KLSK', - city: 'Lusk Municipal Airport', - state: 'WY', - lat: 42.7538, - lon: -104.4046, - }, - KANJ: { - id: 'KANJ', - city: 'Sault Ste. Marie', - state: 'MI', - lat: 46.4794399, - lon: -84.35722, - }, - KDTW: { - id: 'KDTW', - city: 'Detroit, Detroit Metropolitan Wayne County Airport', - state: 'MI', - lat: 42.23139, - lon: -83.33083, - }, - KPTK: { - id: 'KPTK', - city: 'Pontiac, Oakland County International Airport', - state: 'MI', - lat: 42.66306, - lon: -83.41, - }, - KGRR: { - id: 'KGRR', - city: 'Grand Rapids, Gerald R. Ford International Airport', - state: 'MI', - lat: 42.88083, - lon: -85.52278, - }, - KDET: { - id: 'KDET', - city: 'Detroit, Detroit City Airport', - state: 'MI', - lat: 42.40917, - lon: -83.01, - }, - KGLR: { - id: 'KGLR', - city: 'Gaylord, Otsego County Airport', - state: 'MI', - lat: 45.01639, - lon: -84.68889, - }, - KAPN: { - id: 'KAPN', - city: 'Alpena, Alpena County Regional Airport', - state: 'MI', - lat: 45.07167, - lon: -83.56444, - }, - KLAN: { - id: 'KLAN', - city: 'Lansing, Capital City Airport', - state: 'MI', - lat: 42.78028, - lon: -84.57889, - }, - KFNT: { - id: 'KFNT', - city: 'Flint, Bishop International Airport', - state: 'MI', - lat: 42.96667, - lon: -83.74944, - }, - KMKG: { - id: 'KMKG', - city: 'Muskegon, Muskegon County Airport', - state: 'MI', - lat: 43.17111, - lon: -86.23667, - }, - KMBS: { - id: 'KMBS', - city: 'MBS International Airport', - state: 'MI', - lat: 43.53167, - lon: -84.07724, - }, - KCMX: { - id: 'KCMX', - city: 'Hancock, Houghton County Memorial Airport', - state: 'MI', - lat: 47.16833, - lon: -88.48889, - }, - KJXN: { - id: 'KJXN', - city: 'Jackson, Jackson County-Reynolds Field Airport', - state: 'MI', - lat: 42.25972, - lon: -84.45944, - }, - KBTL: { - id: 'KBTL', - city: 'Battle Creek, Kellogg Airport', - state: 'MI', - lat: 42.3125, - lon: -85.24083, - }, - KMTC: { - id: 'KMTC', - city: 'Selfridge Air National Guard Base', - state: 'MI', - lat: 42.61667, - lon: -82.83333, - }, - KAZO: { - id: 'KAZO', - city: 'Kalamazoo, Kalamazoo / Battle Creek International Airport', - state: 'MI', - lat: 42.22917, - lon: -85.54639, - }, - KPLN: { - id: 'KPLN', - city: 'Pellston, Pellston Regional Airport of Emmet County Airport', - state: 'MI', - lat: 45.57083, - lon: -84.79667, - }, - KTVC: { - id: 'KTVC', - city: 'Traverse City, Cherry Capital Airport', - state: 'MI', - lat: 44.7366699, - lon: -85.5699999, - }, - KESC: { - id: 'KESC', - city: 'Escanaba', - state: 'MI', - lat: 45.75, - lon: -87.03333, - }, - KJYM: { - id: 'KJYM', - city: 'Hillsdale, Hillsdale Municipal Airport', - state: 'MI', - lat: 41.92139, - lon: -84.58583, - }, - KCVX: { - id: 'KCVX', - city: 'Charlevoix, Charlevoix Municipal Airport', - state: 'MI', - lat: 45.30472, - lon: -85.27472, - }, - KIMT: { - id: 'KIMT', - city: 'Iron Mountain / Kingsford, Ford Airport', - state: 'MI', - lat: 45.81417, - lon: -88.10889, - }, - KMBL: { - id: 'KMBL', - city: 'Manistee, Manistee County-Blacker Airport', - state: 'MI', - lat: 44.26667, - lon: -86.25, - }, - KAMN: { - id: 'KAMN', - city: 'Alma, Gratiot Community Airport', - state: 'MI', - lat: 43.32194, - lon: -84.68778, - }, - KARB: { - id: 'KARB', - city: 'Ann Arbor, Ann Arbor Municipal Airport', - state: 'MI', - lat: 42.22389, - lon: -83.74, - }, - KIRS: { - id: 'KIRS', - city: 'Sturgis, Kirsch Municipal Airport', - state: 'MI', - lat: 41.8127799, - lon: -85.43917, - }, - KCAD: { - id: 'KCAD', - city: 'Cadillac / Wexford County', - state: 'MI', - lat: 44.28333, - lon: -85.41667, - }, - KMOP: { - id: 'KMOP', - city: 'Mount Pleasant, Mount Pleasant Municipal Airport', - state: 'MI', - lat: 43.61667, - lon: -84.73333, - }, - KDUH: { - id: 'KDUH', - city: 'Lambertville, Toledo Suburban Airport', - state: 'MI', - lat: 41.73583, - lon: -83.65528, - }, - KHTL: { - id: 'KHTL', - city: 'Houghton Lake, Roscommon County Airport', - state: 'MI', - lat: 44.35111, - lon: -84.67417, - }, - KACB: { - id: 'KACB', - city: 'Bellaire, Antrim County Airport', - state: 'MI', - lat: 44.98833, - lon: -85.19833, - }, - KADG: { - id: 'KADG', - city: 'Adrian, Lenawee County Airport', - state: 'MI', - lat: 41.86778, - lon: -84.07944, - }, - KCIU: { - id: 'KCIU', - city: 'Sault Ste Marie, Chippewa County International Airport', - state: 'MI', - lat: 46.25, - lon: -84.4666699, - }, - KBAX: { - id: 'KBAX', - city: 'Bad Axe, Huron County Memorial Airport', - state: 'MI', - lat: 43.78083, - lon: -82.98556, - }, - KMGN: { - id: 'KMGN', - city: 'Harbor Springs, Harbor Springs Airport', - state: 'MI', - lat: 45.42556, - lon: -84.91333, - }, - KBIV: { - id: 'KBIV', - city: 'Holland - West Michigan Regional Airport', - state: 'MI', - lat: 42.74611, - lon: -86.09667, - }, - KBEH: { - id: 'KBEH', - city: 'Benton Harbor, Southwest Michigan Regional Airport', - state: 'MI', - lat: 42.12861, - lon: -86.42833, - }, - KIWD: { - id: 'KIWD', - city: 'Ironwood, Gogebic-Iron County Airport', - state: 'MI', - lat: 46.53333, - lon: -90.13333, - }, - KERY: { - id: 'KERY', - city: 'Newberry, Luce County Airport', - state: 'MI', - lat: 46.31111, - lon: -85.45722, - }, - KMCD: { - id: 'KMCD', - city: 'Mackinac Island - Mackinac Island Airport', - state: 'MI', - lat: 45.865, - lon: -84.63722, - }, - KMNM: { - id: 'KMNM', - city: 'Menominee, Menominee-Marinette Twin County Airport', - state: 'MI', - lat: 45.13333, - lon: -87.63333, - }, - KHYX: { - id: 'KHYX', - city: 'Saginaw, Saginaw County H.W. Browne Airport', - state: 'MI', - lat: 43.43333, - lon: -83.8625, - }, - KISQ: { - id: 'KISQ', - city: 'Manistique, Schoolcraft County Airport', - state: 'MI', - lat: 45.97472, - lon: -86.17194, - }, - KLDM: { - id: 'KLDM', - city: 'Ludington, Mason County Airport', - state: 'MI', - lat: 43.96667, - lon: -86.4, - }, - KGOV: { - id: 'KGOV', - city: 'Grayling, Grayling Army Airfield', - state: 'MI', - lat: 44.68028, - lon: -84.72889, - }, - KYIP: { - id: 'KYIP', - city: 'Detroit, Willow Run Airport', - state: 'MI', - lat: 42.2366699, - lon: -83.52611, - }, - KTTF: { - id: 'KTTF', - city: 'Monroe, Custer Airport', - state: 'MI', - lat: 41.94, - lon: -83.43472, - }, - KOZW: { - id: 'KOZW', - city: 'Howell, Livingston County Airport', - state: 'MI', - lat: 42.62944, - lon: -83.98417, - }, - KOEB: { - id: 'KOEB', - city: 'Coldwater, Branch County Memorial Airport', - state: 'MI', - lat: 41.93333, - lon: -85.0525, - }, - KONZ: { - id: 'KONZ', - city: 'Detroit/Grosse Ile, Grosse Ile Airport', - state: 'MI', - lat: 42.09861, - lon: -83.1611099, - }, - KOSC: { - id: 'KOSC', - city: 'Oscoda, Oscoda-Wurtsmith Airport', - state: 'MI', - lat: 44.45, - lon: -83.36667, - }, - KRMY: { - id: 'KRMY', - city: 'Marshall, Brooks Field Airport', - state: 'MI', - lat: 42.25111, - lon: -84.95556, - }, - KRQB: { - id: 'KRQB', - city: 'Big Rapids, Roben-Hood Airport', - state: 'MI', - lat: 43.7224999, - lon: -85.50417, - }, - KTEW: { - id: 'KTEW', - city: 'Mason, Mason Jewett Field Airport', - state: 'MI', - lat: 42.56583, - lon: -84.42333, - }, - KPHN: { - id: 'KPHN', - city: 'St. Clair County International', - state: 'MI', - lat: 42.91667, - lon: -82.53333, - }, - KSJX: { - id: 'KSJX', - city: 'Beaver Island, Beaver Island Airport', - state: 'MI', - lat: 45.69222, - lon: -85.56639, - }, - KSLH: { - id: 'KSLH', - city: 'Cheboygan, Cheboygan County Airport', - state: 'MI', - lat: 45.65361, - lon: -84.51917, - }, - KFPK: { - id: 'KFPK', - city: 'Charlotte, Fitch H Beach Airport', - state: 'MI', - lat: 42.57444, - lon: -84.81139, - }, - KHAI: { - id: 'KHAI', - city: 'Haines Memorial Airport', - state: 'MI', - lat: 41.9598, - lon: -85.5934, - }, - KDRM: { - id: 'KDRM', - city: 'Drummond Island Airport', - state: 'MI', - lat: 46.0072, - lon: -83.7427, - }, - KSAW: { - id: 'KSAW', - city: 'Marquette, Sawyer International Airport', - state: 'MI', - lat: 46.35361, - lon: -87.39528, - }, - KVLL: { - id: 'KVLL', - city: 'Troy, Oakland/Troy Airport', - state: 'MI', - lat: 42.54278, - lon: -83.17778, - }, - KCFS: { - id: 'KCFS', - city: 'Caro, Tuscola Area Airport', - state: 'MI', - lat: 43.45861, - lon: -83.44528, - }, - KLWA: { - id: 'KLWA', - city: 'South Haven, South Haven Area Regional Airport', - state: 'MI', - lat: 42.35083, - lon: -86.25611, - }, - KPZQ: { - id: 'KPZQ', - city: 'Rogers City, Presque Isle County Airport', - state: 'MI', - lat: 45.40694, - lon: -83.81278, - }, - KFKS: { - id: 'KFKS', - city: 'Frankfort, Frankfort Dow Memorial Field Airport', - state: 'MI', - lat: 44.625, - lon: -86.20056, - }, - KRNP: { - id: 'KRNP', - city: 'Owosso, Owosso Community Airport', - state: 'MI', - lat: 42.99278, - lon: -84.13889, - }, - KFFX: { - id: 'KFFX', - city: 'Fremont Municipal Airport', - state: 'MI', - lat: 43.43933, - lon: -85.9948299, - }, - KIKW: { - id: 'KIKW', - city: 'Jack Barstow Airport', - state: 'MI', - lat: 43.6624, - lon: -84.26213, - }, - GFMT: { - id: 'GFMT', - city: 'GREENFIELDS', - state: 'MT', - lat: 47.65833, - lon: -111.8125, - }, - DRLM: { - id: 'DRLM', - city: 'DEER LODGE', - state: 'MT', - lat: 46.33556, - lon: -112.76667, - }, - COVM: { - id: 'COVM', - city: 'CORVALLIS', - state: 'MT', - lat: 46.3333299, - lon: -114.08333, - }, - BFAM: { - id: 'BFAM', - city: 'BLACKFEET', - state: 'MT', - lat: 48.675, - lon: -112.58889, - }, - RDBM: { - id: 'RDBM', - city: 'ROUND BUTTE', - state: 'MT', - lat: 47.53944, - lon: -114.28056, - }, - CRSM: { - id: 'CRSM', - city: 'CRESTON', - state: 'MT', - lat: 48.1875, - lon: -114.12778, - }, - HRLM: { - id: 'HRLM', - city: 'HARLEM', - state: 'MT', - lat: 48.54333, - lon: -108.83472, - }, - SIGM: { - id: 'SIGM', - city: 'ST. IGNATIUS', - state: 'MT', - lat: 47.31333, - lon: -114.09806, - }, - TOSM: { - id: 'TOSM', - city: 'TOSTON', - state: 'MT', - lat: 46.12222, - lon: -111.49472, - }, - DLNM: { - id: 'DLNM', - city: 'DILLON', - state: 'MT', - lat: 45.3333299, - lon: -112.50917, - }, - BOZM: { - id: 'BOZM', - city: 'BOZEMAN', - state: 'MT', - lat: 45.6736099, - lon: -111.15, - }, - BRTM: { - id: 'BRTM', - city: 'BUFFALO RAPIDS/TERRY', - state: 'MT', - lat: 46.77806, - lon: -105.29944, - }, - MATM: { - id: 'MATM', - city: 'MALTA', - state: 'MT', - lat: 48.37361, - lon: -107.77639, - }, - GLGM: { - id: 'GLGM', - city: 'GLASGOW', - state: 'MT', - lat: 48.14333, - lon: -106.60917, - }, - RBYM: { - id: 'RBYM', - city: 'RUBY VALLEY', - state: 'MT', - lat: 45.345, - lon: -112.15028, - }, - BRGM: { - id: 'BRGM', - city: 'BUFFALO RAPIDS/GLEND', - state: 'MT', - lat: 46.98778, - lon: -104.80306, - }, - HVMT: { - id: 'HVMT', - city: 'HELENA VALLEY', - state: 'MT', - lat: 46.67917, - lon: -111.98333, - }, - WSSM: { - id: 'WSSM', - city: 'White Sulphur Springs', - state: 'MT', - lat: 46.55333, - lon: -110.94667, - }, - JVWM: { - id: 'JVWM', - city: 'Jefferson River Valley', - state: 'MT', - lat: 45.79778, - lon: -112.16528, - }, - UMHM: { - id: 'UMHM', - city: 'Upper Musselshell', - state: 'MT', - lat: 46.44722, - lon: -109.94, - }, - BFTM: { - id: 'BFTM', - city: 'Big Flat / Turner', - state: 'MT', - lat: 48.83556, - lon: -108.56389, - }, - TRFM: { - id: 'TRFM', - city: 'Teton River', - state: 'MT', - lat: 47.90056, - lon: -112.15972, - }, - MWSM: { - id: 'MWSM', - city: 'Moccasin', - state: 'MT', - lat: 47.05889, - lon: -109.95083, - }, - SVWM: { - id: 'SVWM', - city: 'Shields River Valley', - state: 'MT', - lat: 46.04667, - lon: -110.65278, - }, - KTHM: { - id: 'KTHM', - city: 'THOMPSON FALLS', - state: 'MT', - lat: 47.5735, - lon: -115.28066, - }, - SWLM: { - id: 'SWLM', - city: 'Swan Lake', - state: 'MT', - lat: 47.9330555, - lon: -113.8486111, - }, - HGWM: { - id: 'HGWM', - city: 'Hungry Horse Dam Weather Station, MT', - state: 'MT', - lat: 48.3422222, - lon: -114.0188888, - }, - SELM: { - id: 'SELM', - city: 'Seeley Lake Ranger Station', - state: 'MT', - lat: 47.2136111, - lon: -113.5197222, - }, - SUMM: { - id: 'SUMM', - city: 'Summit, MT', - state: 'MT', - lat: 48.3175, - lon: -113.3527777, - }, - GDMM: { - id: 'GDMM', - city: 'Gibson Dam Weather Station', - state: 'MT', - lat: 47.6016666, - lon: -112.7616666, - }, - FCFM: { - id: 'FCFM', - city: 'North Fork Flathead River near Columbia Falls, MT', - state: 'MT', - lat: 48.4955555, - lon: -114.1266666, - }, - CFMM: { - id: 'CFMM', - city: 'Flathead River at Columbia Falls, MT', - state: 'MT', - lat: 48.3619444, - lon: -114.1838888, - }, - HGHM: { - id: 'HGHM', - city: 'S.Fk. Flathead Riv nr Columbia Falls at Hungry Horse', - state: 'MT', - lat: 48.3566666, - lon: -114.0366666, - }, - WGLM: { - id: 'WGLM', - city: 'West Glacier, MT', - state: 'MT', - lat: 48.5011111, - lon: -113.985, - }, - WGCM: { - id: 'WGCM', - city: 'Middle Fork Flathead River near West Glacier, MT', - state: 'MT', - lat: 48.4952777, - lon: -114.0091666, - }, - KCII: { - id: 'KCII', - city: 'Choteau Airport', - state: 'MT', - lat: 47.8283, - lon: -112.1683, - }, - KGTF: { - id: 'KGTF', - city: 'Great Falls, Great Falls International Airport', - state: 'MT', - lat: 47.47333, - lon: -111.38222, - }, - KGGW: { - id: 'KGGW', - city: 'Glasgow, Glasgow International Airport', - state: 'MT', - lat: 48.21389, - lon: -106.62139, - }, - KHVR: { - id: 'KHVR', - city: 'Havre, Havre City-County Airport', - state: 'MT', - lat: 48.54278, - lon: -109.76333, - }, - KMSO: { - id: 'KMSO', - city: 'Missoula, Missoula International Airport', - state: 'MT', - lat: 46.92083, - lon: -114.0925, - }, - KCTB: { - id: 'KCTB', - city: 'Cut Bank, Cut Bank Municipal Airport', - state: 'MT', - lat: 48.60833, - lon: -112.37611, - }, - KHLN: { - id: 'KHLN', - city: 'Helena Regional Airport', - state: 'MT', - lat: 46.60445, - lon: -111.9892, - }, - KMLS: { - id: 'KMLS', - city: 'Miles City, Frank Wiley Field Airport', - state: 'MT', - lat: 46.42806, - lon: -105.88639, - }, - KBZN: { - id: 'KBZN', - city: 'Bozeman, Gallatin Field', - state: 'MT', - lat: 45.78806, - lon: -111.16083, - }, - KBIL: { - id: 'KBIL', - city: 'Billings, Billings Logan International Airport', - state: 'MT', - lat: 45.80694, - lon: -108.54222, - }, - KGDV: { - id: 'KGDV', - city: 'Glendive, Dawson Community Airport', - state: 'MT', - lat: 47.13333, - lon: -104.8, - }, - KBTM: { - id: 'KBTM', - city: 'Butte, Bert Mooney Airport', - state: 'MT', - lat: 45.95472, - lon: -112.4975, - }, - KMLP: { - id: 'KMLP', - city: 'Mullan Pass, Mullan Pass Vor', - state: 'MT', - lat: 47.45417, - lon: -115.66972, - }, - KDLN: { - id: 'KDLN', - city: 'Dillon, Dillon Airport', - state: 'MT', - lat: 45.2575, - lon: -112.55444, - }, - KSDY: { - id: 'KSDY', - city: 'Sidney-Richland', - state: 'MT', - lat: 47.7, - lon: -104.2, - }, - KLWT: { - id: 'KLWT', - city: 'Lewistown, Lewistown Municipal Airport', - state: 'MT', - lat: 47.0491699, - lon: -109.46639, - }, - KOLF: { - id: 'KOLF', - city: 'Wolf Point, Clayton Airport', - state: 'MT', - lat: 48.09444, - lon: -105.57722, - }, - KLVM: { - id: 'KLVM', - city: 'Livingston, Mission Field Airport', - state: 'MT', - lat: 45.69944, - lon: -110.44833, - }, - SARC: { - id: 'SARC', - city: 'SOUTHERN AG. RESEARCH CENTER', - state: 'MT', - lat: 45.92278, - lon: -108.24528, - }, - KGPI: { - id: 'KGPI', - city: 'Kalispell, Glacier Park International Airport', - state: 'MT', - lat: 48.30417, - lon: -114.26361, - }, - KBHK: { - id: 'KBHK', - city: 'Baker, Baker Municipal Airport', - state: 'MT', - lat: 46.34778, - lon: -104.2574999, - }, - KGFA: { - id: 'KGFA', - city: 'Malmstrom Air Force Base', - state: 'MT', - lat: 47.5, - lon: -111.18333, - }, - KJDN: { - id: 'KJDN', - city: 'Jordan, Jordan Airport', - state: 'MT', - lat: 47.32583, - lon: -106.9475, - }, - LMMM: { - id: 'LMMM', - city: 'Lower Musselshell', - state: 'MT', - lat: 46.5627799, - lon: -108.00583, - }, - KPWD: { - id: 'KPWD', - city: 'PLENTYWOOD', - state: 'MT', - lat: 48.78863, - lon: -104.5231699, - }, - KWYS: { - id: 'KWYS', - city: 'West Yellowstone', - state: 'MT', - lat: 44.68333, - lon: -111.11667, - }, - KRPX: { - id: 'KRPX', - city: 'ROUNDUP', - state: 'MT', - lat: 46.47499, - lon: -108.54339, - }, - KEKS: { - id: 'KEKS', - city: 'Ennis - Big Sky Airport', - state: 'MT', - lat: 45.27436, - lon: -111.64886, - }, - KMVH: { - id: 'KMVH', - city: 'N BAR Ranch Airport', - state: 'MT', - lat: 46.8381, - lon: -108.9368, - }, - KCVG: { - id: 'KCVG', - city: 'Cincinnati/Northern Kentucky International Airport', - state: 'KY', - lat: 39.04456, - lon: -84.67229, - }, - KLOU: { - id: 'KLOU', - city: 'Louisville, Bowman Field Airport', - state: 'KY', - lat: 38.22778, - lon: -85.66361, - }, - KPAH: { - id: 'KPAH', - city: 'Paducah, Barkley Regional Airport', - state: 'KY', - lat: 37.05639, - lon: -88.77389, - }, - KBWG: { - id: 'KBWG', - city: 'Bowling Green, Bowling Green-Warren County Regional Airport', - state: 'KY', - lat: 36.96444, - lon: -86.41944, - }, - KLEX: { - id: 'KLEX', - city: 'Lexington Blue Grass Airport', - state: 'KY', - lat: 38.0339, - lon: -84.6114599, - }, - KJKL: { - id: 'KJKL', - city: 'Jackson, Carroll Airport', - state: 'KY', - lat: 37.5913899, - lon: -83.31444, - }, - KHOP: { - id: 'KHOP', - city: 'Fort Campbell U. S. Army Airfield', - state: 'KY', - lat: 36.66667, - lon: -87.5, - }, - KLOZ: { - id: 'KLOZ', - city: 'London, London-Corbin Airport-Magee Field', - state: 'KY', - lat: 37.08944, - lon: -84.06861, - }, - KFTK: { - id: 'KFTK', - city: 'Fort Knox', - state: 'KY', - lat: 37.9, - lon: -85.9666699, - }, - KSDF: { - id: 'KSDF', - city: 'Louisville, Standiford Field', - state: 'KY', - lat: 38.17722, - lon: -85.72972, - }, - KEHR: { - id: 'KEHR', - city: 'Henderson City', - state: 'KY', - lat: 37.81667, - lon: -87.68333, - }, - KFFT: { - id: 'KFFT', - city: 'Frankfort, Capital City Airport', - state: 'KY', - lat: 38.18472, - lon: -84.90333, - }, - KOWB: { - id: 'KOWB', - city: 'Owensboro, Owensboro-Daviess County Airport', - state: 'KY', - lat: 37.74, - lon: -87.16667, - }, - KSME: { - id: 'KSME', - city: 'Somerset, Somerset-Pulaski County - J.T. Wilson Field Airport', - state: 'KY', - lat: 37.05417, - lon: -84.615, - }, - KEKQ: { - id: 'KEKQ', - city: 'Monticello, Wayne County Airport', - state: 'KY', - lat: 36.85528, - lon: -84.85611, - }, - KFGX: { - id: 'KFGX', - city: 'Flemingsburg Fleming-Mason Airport', - state: 'KY', - lat: 38.5418, - lon: -83.7434, - }, - KPBX: { - id: 'KPBX', - city: 'Pikeville Pike County Airport and Hatcher Field', - state: 'KY', - lat: 37.5587, - lon: -82.5674, - }, - KGLW: { - id: 'KGLW', - city: 'Glasgow, Glasgow Municipal Airport', - state: 'KY', - lat: 37.03167, - lon: -85.95361, - }, - KCEY: { - id: 'KCEY', - city: 'Murray Kyle Oakley Field, KY', - state: 'KY', - lat: 36.6646, - lon: -88.3728, - }, - KDVK: { - id: 'KDVK', - city: 'Stuart Powell Field Airport', - state: 'KY', - lat: 37.5775751, - lon: -84.7694978, - }, - KIOB: { - id: 'KIOB', - city: 'Mount Sterling-Montgomery County Airport', - state: 'KY', - lat: 38.0575, - lon: -83.9829, - }, - KSJS: { - id: 'KSJS', - city: 'Big Sandy Regional Airport', - state: 'KY', - lat: 37.751, - lon: -82.6367, - }, - KDWU: { - id: 'KDWU', - city: 'Ashland Regional Airport', - state: 'KY', - lat: 38.5545, - lon: -82.738, - }, - KBYL: { - id: 'KBYL', - city: 'Williamsburg-Whitley County Airport', - state: 'KY', - lat: 36.7954099, - lon: -84.2012699, - }, - KSYM: { - id: 'KSYM', - city: 'Clyde A. Thomas Regional Airport', - state: 'KY', - lat: 38.215, - lon: -83.5874, - }, - KLZD: { - id: 'KLZD', - city: 'DANIELSON', - state: 'CT', - lat: 41.8197, - lon: -71.90096, - }, - KBDR: { - id: 'KBDR', - city: 'Bridgeport, Sikorsky Memorial Airport', - state: 'CT', - lat: 41.16421, - lon: -73.12663, - }, - KHFD: { - id: 'KHFD', - city: 'Hartford, Hartford-Brainard Airport', - state: 'CT', - lat: 41.735, - lon: -72.65167, - }, - KBDL: { - id: 'KBDL', - city: 'Windsor Locks, Bradley International Airport', - state: 'CT', - lat: 41.93806, - lon: -72.6825, - }, - KGON: { - id: 'KGON', - city: 'Groton / New London, Groton / New London Airport', - state: 'CT', - lat: 41.3275, - lon: -72.04944, - }, - KHVN: { - id: 'KHVN', - city: 'New Haven, Tweed-New Haven Airport', - state: 'CT', - lat: 41.26389, - lon: -72.88722, - }, - KMMK: { - id: 'KMMK', - city: 'Meriden, Meriden Markham Municipal Airport', - state: 'CT', - lat: 41.50972, - lon: -72.82778, - }, - KIJD: { - id: 'KIJD', - city: 'Willimantic, Windham Airport', - state: 'CT', - lat: 41.74194, - lon: -72.18361, - }, - KDXR: { - id: 'KDXR', - city: 'Danbury, Danbury Municipal Airport', - state: 'CT', - lat: 41.37167, - lon: -73.48444, - }, - KOXC: { - id: 'KOXC', - city: 'Oxford, Waterbury-Oxford Airport', - state: 'CT', - lat: 41.48333, - lon: -73.13333, - }, - KSNC: { - id: 'KSNC', - city: 'Chester, Chester Airport', - state: 'CT', - lat: 41.38389, - lon: -72.50583, - }, - PHTO: { - id: 'PHTO', - city: 'Hilo, Hilo International Airport', - state: 'HI', - lat: 19.72222, - lon: -155.0558299, - }, - PHLI: { - id: 'PHLI', - city: 'Lihue, Lihue Airport', - state: 'HI', - lat: 21.98389, - lon: -159.3411099, - }, - PHNL: { - id: 'PHNL', - city: 'Honolulu, Honolulu International Airport', - state: 'HI', - lat: 21.3275, - lon: -157.94306, - }, - PHNY: { - id: 'PHNY', - city: 'Lanai City, Lanai Airport', - state: 'HI', - lat: 20.78556, - lon: -156.95139, - }, - PHKO: { - id: 'PHKO', - city: 'Kailua / Kona, Keahole Airport', - state: 'HI', - lat: 19.74083, - lon: -156.05056, - }, - PHMK: { - id: 'PHMK', - city: 'Kaunakakai, Molokai Airport', - state: 'HI', - lat: 21.15, - lon: -157.1, - }, - PHOG: { - id: 'PHOG', - city: 'Kahului, Kahului Airport', - state: 'HI', - lat: 20.8924999, - lon: -156.43694, - }, - PHJH: { - id: 'PHJH', - city: 'Lahaina - West Maui', - state: 'HI', - lat: 20.9630699, - lon: -156.67466, - }, - PHJR: { - id: 'PHJR', - city: 'Oahu, Kalaeloa Airport', - state: 'HI', - lat: 21.30833, - lon: -158.06806, - }, - PHHI: { - id: 'PHHI', - city: 'Wheeler Air Force Base / Oahu', - state: 'HI', - lat: 21.48333, - lon: -158.03333, - }, - PHSF: { - id: 'PHSF', - city: 'Bradshaw Army Air Field / Hawaii', - state: 'HI', - lat: 19.78333, - lon: -155.55, - }, - PMDY: { - id: 'PMDY', - city: 'Sand Island, Henderson Field Airport', - state: 'HI', - lat: 28.21667, - lon: -177.36667, - }, - PHNG: { - id: 'PHNG', - city: 'Kaneohe, Marine Corps Air Station', - state: 'HI', - lat: 21.45389, - lon: -157.76556, - }, - PHBK: { - id: 'PHBK', - city: 'Kekaha, Pacific Missile Test Facility Barking Sands', - state: 'HI', - lat: 22.03639, - lon: -159.78639, - }, - PHHN: { - id: 'PHHN', - city: 'HANA', - state: 'HI', - lat: 20.79563, - lon: -156.01444, - }, - PHMU: { - id: 'PHMU', - city: 'KAMUELA', - state: 'HI', - lat: 20.00133, - lon: -155.66817, - }, - AHTI: { - id: 'AHTI', - city: 'ASHTON', - state: 'ID', - lat: 44.025, - lon: -111.46667, - }, - GFRI: { - id: 'GFRI', - city: 'GLENNS FERRY', - state: 'ID', - lat: 42.86667, - lon: -115.35694, - }, - TWFI: { - id: 'TWFI', - city: 'TWIN FALLS', - state: 'ID', - lat: 42.54611, - lon: -114.34528, - }, - GDVI: { - id: 'GDVI', - city: 'GRAND VIEW', - state: 'ID', - lat: 42.9125, - lon: -116.05611, - }, - RPTI: { - id: 'RPTI', - city: 'RUPERT', - state: 'ID', - lat: 42.595, - lon: -113.83806, - }, - FAFI: { - id: 'FAFI', - city: 'FAIRFIELD', - state: 'ID', - lat: 43.30833, - lon: -114.825, - }, - BOII: { - id: 'BOII', - city: 'BOISE', - state: 'ID', - lat: 43.60028, - lon: -116.17667, - }, - RXGI: { - id: 'RXGI', - city: 'REXBURG', - state: 'ID', - lat: 43.85, - lon: -111.76667, - }, - FTHI: { - id: 'FTHI', - city: 'FORT HALL', - state: 'ID', - lat: 43.07139, - lon: -112.43111, - }, - PMAI: { - id: 'PMAI', - city: 'PARMA', - state: 'ID', - lat: 43.8, - lon: -116.93333, - }, - NMPI: { - id: 'NMPI', - city: 'NAMPA', - state: 'ID', - lat: 43.44167, - lon: -116.63694, - }, - PICI: { - id: 'PICI', - city: 'PICABO', - state: 'ID', - lat: 43.31167, - lon: -114.16583, - }, - MALI: { - id: 'MALI', - city: 'MALTA', - state: 'ID', - lat: 42.4375, - lon: -113.41389, - }, - KTBI: { - id: 'KTBI', - city: 'Kettle Butte', - state: 'ID', - lat: 43.5486099, - lon: -112.32583, - }, - DENI: { - id: 'DENI', - city: 'Dworshak - Dent Acres', - state: 'ID', - lat: 46.62333, - lon: -116.22056, - }, - ABEI: { - id: 'ABEI', - city: 'Aberdeen', - state: 'ID', - lat: 42.95333, - lon: -112.82667, - }, - MNTI: { - id: 'MNTI', - city: 'Monteview', - state: 'ID', - lat: 44.015, - lon: -112.53583, - }, - KETI: { - id: 'KETI', - city: 'Ketchum Ranger Station', - state: 'ID', - lat: 43.6816666, - lon: -114.3627777, - }, - FRCI: { - id: 'FRCI', - city: 'Fall River Canal', - state: 'ID', - lat: 43.9991666, - lon: -111.5280555, - }, - PAYI: { - id: 'PAYI', - city: 'North Fork Payette River at McCall, Idaho', - state: 'ID', - lat: 44.9083333, - lon: -116.1194444, - }, - HENI: { - id: 'HENI', - city: 'Henrys Fork near Lake, ID', - state: 'ID', - lat: 44.595, - lon: -111.35, - }, - DRYI: { - id: 'DRYI', - city: 'Dry Bed near Ririe, ID', - state: 'ID', - lat: 43.6391666, - lon: -111.7152777, - }, - MRYI: { - id: 'MRYI', - city: 'Marysville Canal near Squirrel, ID', - state: 'ID', - lat: 44.0616666, - lon: -111.3283333, - }, - WACI: { - id: 'WACI', - city: 'Watson Canal', - state: 'ID', - lat: 43.1958333, - lon: -112.4, - }, - TITI: { - id: 'TITI', - city: 'Teton Island Feeder Canal near Teton, ID', - state: 'ID', - lat: 43.8911111, - lon: -111.6969444, - }, - BTSI: { - id: 'BTSI', - city: 'Boise River near Twin Springs, Idaho', - state: 'ID', - lat: 43.6586111, - lon: -115.7272222, - }, - FHPI: { - id: 'FHPI', - city: 'Fort Hall Michaud Pump', - state: 'ID', - lat: 43.9283333, - lon: -112.5666666, - }, - HLSI: { - id: 'HLSI', - city: 'Hailey Ranger Station, ID', - state: 'ID', - lat: 43.5147222, - lon: -114.3066666, - }, - MIII: { - id: 'MIII', - city: 'Milner-Gooding Canal', - state: 'ID', - lat: 42.5275, - lon: -114.0102777, - }, - CCPI: { - id: 'CCPI', - city: 'Canyon Creek Lateral Pump', - state: 'ID', - lat: 43.9033333, - lon: -111.5380555, - }, - BPPI: { - id: 'BPPI', - city: 'Bob Parkinson Pump', - state: 'ID', - lat: 43.9194444, - lon: -111.4594444, - }, - PRKI: { - id: 'PRKI', - city: 'Parks and Lewisville Canal near Rigby, ID', - state: 'ID', - lat: 43.6888888, - lon: -111.8661111, - }, - HRSI: { - id: 'HRSI', - city: 'Payette River near Horseshoe Bend, ID', - state: 'ID', - lat: 43.945, - lon: -116.1969444, - }, - DRII: { - id: 'DRII', - city: 'Deadwood River above Deadwood Reservoir, ID', - state: 'ID', - lat: 44.3483333, - lon: -115.6497222, - }, - TICI: { - id: 'TICI', - city: 'Teton Irrigation Weir', - state: 'ID', - lat: 43.8916666, - lon: -111.6672222, - }, - ANTI: { - id: 'ANTI', - city: 'Henrys Fork at St. Anthony, ID', - state: 'ID', - lat: 43.9666666, - lon: -111.6722222, - }, - WLWI: { - id: 'WLWI', - city: 'Willow Creek near Bellevue, ID', - state: 'ID', - lat: 43.3230555, - lon: -114.3236111, - }, - ASCI: { - id: 'ASCI', - city: 'Aberdeen-Springfield Canal', - state: 'ID', - lat: 43.2805555, - lon: -112.2569444, - }, - WILI: { - id: 'WILI', - city: 'Willow Creek Floodway Channel nr Ukon, ID', - state: 'ID', - lat: 43.5763888, - lon: -111.9130555, - }, - RDWI: { - id: 'RDWI', - city: 'Reid Weir', - state: 'ID', - lat: 43.7155555, - lon: -111.8141666, - }, - DNCI: { - id: 'DNCI', - city: 'Danskin Canal', - state: 'ID', - lat: 43.2208333, - lon: -112.3541666, - }, - RXRI: { - id: 'RXRI', - city: 'Rexburg Irrigation Canal near Rexburg, ID', - state: 'ID', - lat: 43.8363888, - lon: -111.7638888, - }, - VLVI: { - id: 'VLVI', - city: 'Valley View', - state: 'ID', - lat: 44.6458333, - lon: -111.3291666, - }, - GWCI: { - id: 'GWCI', - city: 'Great Western Canal near Lewisville, ID', - state: 'ID', - lat: 43.5875, - lon: -112.0611111, - }, - HFAI: { - id: 'HFAI', - city: 'Henrys Fork near Ashton, ID', - state: 'ID', - lat: 44.0697222, - lon: -111.5105555, - }, - SUCI: { - id: 'SUCI', - city: 'Salem Union Weir', - state: 'ID', - lat: 43.9708333, - lon: -111.6505555, - }, - WIFI: { - id: 'WIFI', - city: 'Sand Creek above Willow Creek Diversion nr Ukon, ID', - state: 'ID', - lat: 43.5741666, - lon: -111.895, - }, - JRPI: { - id: 'JRPI', - city: 'J. Ricks Pipeline (Teton River)', - state: 'ID', - lat: 43.8513888, - lon: -111.2533333, - }, - SNAI: { - id: 'SNAI', - city: 'Snake River at Blackfoot, ID', - state: 'ID', - lat: 43.1975, - lon: -112.3691666, - }, - SNDI: { - id: 'SNDI', - city: 'Sand Creek at Wolverine Road', - state: 'ID', - lat: 43.2827777, - lon: -112.1508333, - }, - PLCI: { - id: 'PLCI', - city: 'Palisades Canal near Irwin, ID', - state: 'ID', - lat: 43.7458333, - lon: -112.1027777, - }, - TEAI: { - id: 'TEAI', - city: 'Teton River near St. Anthony, ID', - state: 'ID', - lat: 43.9272222, - lon: -111.6152777, - }, - PRLI: { - id: 'PRLI', - city: 'South Fork Payette River at Lowman, ID', - state: 'ID', - lat: 44.0847222, - lon: -115.6027777, - }, - PALI: { - id: 'PALI', - city: 'Snake River near Irwin, ID', - state: 'ID', - lat: 43.3508333, - lon: -111.2183333, - }, - CHEI: { - id: 'CHEI', - city: 'Falls River near Chester, ID', - state: 'ID', - lat: 44.0183333, - lon: -111.5666666, - }, - ELCI: { - id: 'ELCI', - city: 'Eagle Rock Canal near Hwy 26', - state: 'ID', - lat: 43.6041666, - lon: -111.7977777, - }, - MILI: { - id: 'MILI', - city: 'Snake River at Milner, Idaho', - state: 'ID', - lat: 42.5283333, - lon: -114.0183333, - }, - OSCI: { - id: 'OSCI', - city: 'Osgood Canal', - state: 'ID', - lat: 43.6291666, - lon: -112.0791666, - }, - PARI: { - id: 'PARI', - city: 'Boise River near Parma, ID', - state: 'ID', - lat: 43.7816666, - lon: -116.9713888, - }, - RICI: { - id: 'RICI', - city: 'Riverside Canal', - state: 'ID', - lat: 43.2636111, - lon: -112.3013888, - }, - SPPI: { - id: 'SPPI', - city: 'South Pipeline (Teton River)', - state: 'ID', - lat: 43.8413888, - lon: -111.2438888, - }, - IDCI: { - id: 'IDCI', - city: 'Idaho Canal near Lewisville, ID', - state: 'ID', - lat: 43.6138888, - lon: -112.0527777, - }, - IDHI: { - id: 'IDHI', - city: 'Idaho City', - state: 'ID', - lat: 43.8361111, - lon: -115.8347222, - }, - RIWI: { - id: 'RIWI', - city: 'Ririe Dam Weather Station', - state: 'ID', - lat: 43.5825, - lon: -111.7386111, - }, - CRMI: { - id: 'CRMI', - city: 'Craters of the Moon, ID', - state: 'ID', - lat: 43.4622222, - lon: -113.5613888, - }, - PRPI: { - id: 'PRPI', - city: 'Payette River near Payette, ID', - state: 'ID', - lat: 44.0424999, - lon: -116.9241666, - }, - WODI: { - id: 'WODI', - city: 'Little Wood River near Carey, ID', - state: 'ID', - lat: 43.39, - lon: -114, - }, - HEII: { - id: 'HEII', - city: 'Snake River near Heise, ID', - state: 'ID', - lat: 43.6125, - lon: -111.66, - }, - MCGI: { - id: 'MCGI', - city: 'Mann Creek at Mann Creek Guard Station, ID', - state: 'ID', - lat: 44.5013888, - lon: -116.9491666, - }, - LWOI: { - id: 'LWOI', - city: 'Little Wood River above High Five Creek, ID', - state: 'ID', - lat: 43.4930555, - lon: -114.0572222, - }, - TRCI: { - id: 'TRCI', - city: 'Trego Canal near Blackfoot, ID', - state: 'ID', - lat: 43.2013888, - lon: -112.3666666, - }, - ERCI: { - id: 'ERCI', - city: 'Eagle Rock Canal near Heise, ID', - state: 'ID', - lat: 43.6305555, - lon: -111.6875, - }, - LORI: { - id: 'LORI', - city: 'Snake River at Lorenzo, ID', - state: 'ID', - lat: 43.7352777, - lon: -111.8780555, - }, - AFCI: { - id: 'AFCI', - city: 'St. Anthony Union Feeder Canal', - state: 'ID', - lat: 43.9602777, - lon: -111.6980555, - }, - BMCI: { - id: 'BMCI', - city: 'Butte and Market Lake Canal', - state: 'ID', - lat: 43.7458333, - lon: -112.1027777, - }, - DFWI: { - id: 'DFWI', - city: 'Deer Flat Upper Embankment Warning System', - state: 'ID', - lat: 43.5611111, - lon: -116.6591666, - }, - BDDI: { - id: 'BDDI', - city: 'Boise River below Diversion Dam near Boise', - state: 'ID', - lat: 43.5397222, - lon: -116.0936111, - }, - BIGI: { - id: 'BIGI', - city: 'Boise River at Glenwood Bridge', - state: 'ID', - lat: 43.6602777, - lon: -116.2783333, - }, - DEDI: { - id: 'DEDI', - city: 'Deadwood River below Deadwood Dam', - state: 'ID', - lat: 44.2961111, - lon: -115.6455555, - }, - FARI: { - id: 'FARI', - city: 'Farmers Friend Canal near St. Anthony, ID', - state: 'ID', - lat: 43.9738888, - lon: -111.6380555, - }, - EGCI: { - id: 'EGCI', - city: 'Egin Canal', - state: 'ID', - lat: 43.9652777, - lon: -111.6861111, - }, - LACI: { - id: 'LACI', - city: 'East Labelle Weir', - state: 'ID', - lat: 43.6733333, - lon: -111.8041666, - }, - INCI: { - id: 'INCI', - city: 'Independent Canal', - state: 'ID', - lat: 43.9588888, - lon: -111.7011111, - }, - CNCI: { - id: 'CNCI', - city: 'Council Weather Station', - state: 'ID', - lat: 44.7305555, - lon: -116.4322222, - }, - MPCI: { - id: 'MPCI', - city: 'Minidoka North Side Pump Canal near Burley, ID', - state: 'ID', - lat: 42.5336111, - lon: -113.9469444, - }, - RGCI: { - id: 'RGCI', - city: 'Rigby Weir', - state: 'ID', - lat: 43.6855555, - lon: -111.8538888, - }, - MDNI: { - id: 'MDNI', - city: 'Main Drain North near Heyburn, ID', - state: 'ID', - lat: 42.5505555, - lon: -113.8663888, - }, - MING: { - id: 'MING', - city: 'Minidoka Dam and Lake Walcott, ID', - state: 'ID', - lat: 42.6708333, - lon: -113.4833333, - }, - BFTI: { - id: 'BFTI', - city: 'Snake River near Blackfoot, ID', - state: 'ID', - lat: 43.1252777, - lon: -112.5183333, - }, - ENTI: { - id: 'ENTI', - city: 'Enterprize Canal', - state: 'ID', - lat: 43.6305555, - lon: -111.6847222, - }, - TCNI: { - id: 'TCNI', - city: 'Twin Falls North Side Canal', - state: 'ID', - lat: 42.5263888, - lon: -114.0097222, - }, - BRFI: { - id: 'BRFI', - city: 'South Fork Boise River near Featherville', - state: 'ID', - lat: 43.4958333, - lon: -115.3075, - }, - BKPI: { - id: 'BKPI', - city: 'Boelky Pump', - state: 'ID', - lat: 43.8636111, - lon: -111.2544444, - }, - RJPI: { - id: 'RJPI', - city: 'Ray and John Brown Pump', - state: 'ID', - lat: 43.9099999, - lon: -111.2844444, - }, - HUKI: { - id: 'HUKI', - city: 'Huckleberry Creek Weather Station, ID', - state: 'ID', - lat: 44.0430555, - lon: -115.5636111, - }, - REXI: { - id: 'REXI', - city: 'Henrys Fork near Rexburg, ID', - state: 'ID', - lat: 43.8258333, - lon: -111.905, - }, - CRCI: { - id: 'CRCI', - city: 'Crosscut Canal at End', - state: 'ID', - lat: 43.9205555, - lon: -111.6119444, - }, - WTXI: { - id: 'WTXI', - city: 'Willow Creek below Tex Creek near Ririe, ID', - state: 'ID', - lat: 43.4416666, - lon: -111.7283333, - }, - VSPI: { - id: 'VSPI', - city: 'Val Schwiendiman Pump near Newdale, ID', - state: 'ID', - lat: 43.9144444, - lon: -111.4652777, - }, - MCII: { - id: 'MCII', - city: 'Mann Creek bel Adams Cr abv Reservoir', - state: 'ID', - lat: 44.4802777, - lon: -116.9325, - }, - PLEI: { - id: 'PLEI', - city: 'Payette River near Letha, ID', - state: 'ID', - lat: 43.8963888, - lon: -116.6258333, - }, - RSDI: { - id: 'RSDI', - city: 'Reservation Drop', - state: 'ID', - lat: 43.2444444, - lon: -112.1844444, - }, - TGCI: { - id: 'TGCI', - city: 'Twin Groves Canal near St. Anthony, ID', - state: 'ID', - lat: 43.975, - lon: -111.6416666, - }, - NLCI: { - id: 'NLCI', - city: 'New Lavaside Canal', - state: 'ID', - lat: 43.2991666, - lon: -112.225, - }, - VLCI: { - id: 'VLCI', - city: 'Snake River Valley Canal', - state: 'ID', - lat: 43.4536111, - lon: -112.0880555, - }, - CBCI: { - id: 'CBCI', - city: 'Corbett Canal', - state: 'ID', - lat: 43.2533333, - lon: -112.2716666, - }, - GRSI: { - id: 'GRSI', - city: 'Grouse, ID', - state: 'ID', - lat: 43.6775, - lon: -113.635, - }, - AUCI: { - id: 'AUCI', - city: 'St. Anthony Union Canal', - state: 'ID', - lat: 43.975, - lon: -111.65, - }, - ISLI: { - id: 'ISLI', - city: 'Henrys Fork near Island Park, ID', - state: 'ID', - lat: 44.4163888, - lon: -111.3947222, - }, - LABI: { - id: 'LABI', - city: 'West Labelle and Long Island Canal near Rigby, ID', - state: 'ID', - lat: 43.6905555, - lon: -111.8555555, - }, - CVPI: { - id: 'CVPI', - city: 'Clementsville Pump', - state: 'ID', - lat: 43.8747222, - lon: -111.2472222, - }, - CFCI: { - id: 'CFCI', - city: 'Consolidated Farmers Weir', - state: 'ID', - lat: 43.94, - lon: -111.7275, - }, - RRPI: { - id: 'RRPI', - city: 'R. Brent Ricks Pipeline (Teton River)', - state: 'ID', - lat: 43.9191666, - lon: -111.5147222, - }, - ATLI: { - id: 'ATLI', - city: 'Atlanta 3 Weather Station', - state: 'ID', - lat: 43.8047222, - lon: -115.1272222, - }, - POCI: { - id: 'POCI', - city: 'Porter Canal', - state: 'ID', - lat: 43.5030555, - lon: -112.0480555, - }, - SHYI: { - id: 'SHYI', - city: 'Snake River near Shelley, ID', - state: 'ID', - lat: 43.4133333, - lon: -112.1341666, - }, - CECI: { - id: 'CECI', - city: 'Clark and Edwards Canal', - state: 'ID', - lat: 43.6569444, - lon: -111.7833333, - }, - IDFI: { - id: 'IDFI', - city: 'Idaho Falls 16SE', - state: 'ID', - lat: 43.3458333, - lon: -111.7869444, - }, - GAVI: { - id: 'GAVI', - city: 'Garden Valley Ranger Station, ID', - state: 'ID', - lat: 44.0630555, - lon: -115.9216666, - }, - FFCI: { - id: 'FFCI', - city: 'Farmers Friend Canal near Heise, ID', - state: 'ID', - lat: 43.6305555, - lon: -111.6888888, - }, - BFCI: { - id: 'BFCI', - city: 'Blackfoot Canal', - state: 'ID', - lat: 43.3208333, - lon: -112.1719444, - }, - BOOI: { - id: 'BOOI', - city: 'Rudy Canal', - state: 'ID', - lat: 43.6541666, - lon: -111.7775, - }, - WBFI: { - id: 'WBFI', - city: 'Willow Creek Below Floodway Channel nr. Ukon, ID', - state: 'ID', - lat: 43.5758333, - lon: -111.9119444, - }, - WVCI: { - id: 'WVCI', - city: 'Woodville Canal', - state: 'ID', - lat: 43.4338888, - lon: -112.0980555, - }, - AMFI: { - id: 'AMFI', - city: 'Snake River at Neeley, ID', - state: 'ID', - lat: 42.7683333, - lon: -112.8783333, - }, - MORI: { - id: 'MORI', - city: 'Mores Creek above Robie Creek, ID', - state: 'ID', - lat: 43.6480555, - lon: -115.9888888, - }, - PECI: { - id: 'PECI', - city: 'Peoples Canal', - state: 'ID', - lat: 43.2841666, - lon: -112.25, - }, - MLCI: { - id: 'MLCI', - city: 'Milner Irrigation Canal near Milner, ID', - state: 'ID', - lat: 42.5194444, - lon: -114.01, - }, - DRMI: { - id: 'DRMI', - city: 'Deadwood River at Mouth near Lowman, ID', - state: 'ID', - lat: 44.0861111, - lon: -115.6611111, - }, - TCSI: { - id: 'TCSI', - city: 'Twin Falls South Side Canal', - state: 'ID', - lat: 42.5227777, - lon: -114.0130555, - }, - BURI: { - id: 'BURI', - city: 'Burgess Canal near Ririe, ID', - state: 'ID', - lat: 43.6561111, - lon: -111.7825, - }, - MINI: { - id: 'MINI', - city: 'Snake River near Minidoka, ID', - state: 'ID', - lat: 42.6730555, - lon: -113.4994444, - }, - PNRI: { - id: 'PNRI', - city: 'PN Region USBR Hydromet Test Site - Boise, ID', - state: 'ID', - lat: 43.6225, - lon: -116.1933333, - }, - WAFI: { - id: 'WAFI', - city: 'Lake Waha Feeder Canal, ID', - state: 'ID', - lat: 46.2055555, - lon: -116.8291666, - }, - HARI: { - id: 'HARI', - city: 'Harrison Canal near Ririe, ID', - state: 'ID', - lat: 43.6441666, - lon: -111.7644444, - }, - ANDI: { - id: 'ANDI', - city: 'South Fork Boise River at Anderson Ranch Dam', - state: 'ID', - lat: 43.3416666, - lon: -115.4777777, - }, - BILI: { - id: 'BILI', - city: 'Billingsly Creek near Haggerman at Hwy 30', - state: 'ID', - lat: 42.8352777, - lon: -114.8938888, - }, - CSCI: { - id: 'CSCI', - city: 'North Fork Payette River at Cascade, Idaho', - state: 'ID', - lat: 44.5288888, - lon: -116.0477777, - }, - MXCI: { - id: 'MXCI', - city: 'North Side X-Cut Diversion from Gooding, ID', - state: 'ID', - lat: 42.5586111, - lon: -114.0513888, - }, - WFCI: { - id: 'WFCI', - city: 'Wilford Canal', - state: 'ID', - lat: 43.9055555, - lon: -111.6277777, - }, - ANCI: { - id: 'ANCI', - city: 'Anderson Canal near Ririe, ID', - state: 'ID', - lat: 43.6222222, - lon: -111.6694444, - }, - ISCI: { - id: 'ISCI', - city: 'Island Canal', - state: 'ID', - lat: 43.6916666, - lon: -111.8541666, - }, - BNWI: { - id: 'BNWI', - city: 'Bone, ID', - state: 'ID', - lat: 43.395, - lon: -111.8258333, - }, - CXCI: { - id: 'CXCI', - city: 'Crosscut Canal near Chester, ID', - state: 'ID', - lat: 44.0166666, - lon: -111.5833333, - }, - TLCI: { - id: 'TLCI', - city: 'Texas and Liberty Weir', - state: 'ID', - lat: 43.7202777, - lon: -111.8272222, - }, - BSKI: { - id: 'BSKI', - city: 'Big Smokey RS Weather Station', - state: 'ID', - lat: 43.6194444, - lon: -114.8675, - }, - RECI: { - id: 'RECI', - city: 'Reservation Canal', - state: 'ID', - lat: 43.3722222, - lon: -112.15, - }, - ACSC: { - id: 'ACSC', - city: 'Cascade Dam and Lake Cascade at Cascade, Idaho', - state: 'ID', - lat: 44.525, - lon: -116.05, - }, - BSEI: { - id: 'BSEI', - city: 'New York Canal Diversion from Boise River', - state: 'ID', - lat: 43.5494444, - lon: -116.1091666, - }, - KBOI: { - id: 'KBOI', - city: 'Boise Air Terminal', - state: 'ID', - lat: 43.56704, - lon: -116.24053, - }, - KPIH: { - id: 'KPIH', - city: 'Pocatello, Pocatello Regional Airport', - state: 'ID', - lat: 42.92028, - lon: -112.57111, - }, - KCOE: { - id: 'KCOE', - city: 'Coeur d\'Alene Airport - Pappy Boyington Field', - state: 'ID', - lat: 47.76667, - lon: -116.81667, - }, - KSUN: { - id: 'KSUN', - city: 'Hailey, Friedman Memorial Airport', - state: 'ID', - lat: 43.5, - lon: -114.3, - }, - KBYI: { - id: 'KBYI', - city: 'Burley Municipal Airport', - state: 'ID', - lat: 42.54525, - lon: -113.7686, - }, - KSMN: { - id: 'KSMN', - city: 'Salmon, Lemhi County Airport', - state: 'ID', - lat: 45.11667, - lon: -113.88333, - }, - KMYL: { - id: 'KMYL', - city: 'McCall Airport', - state: 'ID', - lat: 44.89425, - lon: -116.09978, - }, - KIDA: { - id: 'KIDA', - city: 'Idaho Falls Regional Airport', - state: 'ID', - lat: 43.5208299, - lon: -112.06611, - }, - KLWS: { - id: 'KLWS', - city: 'Lewiston, Lewiston-Nez Perce County Airport', - state: 'ID', - lat: 46.37472, - lon: -117.01444, - }, - KTWF: { - id: 'KTWF', - city: 'Joslin Field - Magic Valley Regional Airport', - state: 'ID', - lat: 42.4784999, - lon: -114.47739, - }, - KMUO: { - id: 'KMUO', - city: 'Mountain Home Air Force Base', - state: 'ID', - lat: 43.05, - lon: -115.86667, - }, - KEUL: { - id: 'KEUL', - city: 'Caldwell - Caldwell Industrial Airport', - state: 'ID', - lat: 43.64055, - lon: -116.63017, - }, - KJER: { - id: 'KJER', - city: 'Jerome County Airport', - state: 'ID', - lat: 42.72736, - lon: -114.45469, - }, - KSNT: { - id: 'KSNT', - city: 'Stanley, Stanley Ranger Station', - state: 'ID', - lat: 44.20861, - lon: -114.93444, - }, - KGIC: { - id: 'KGIC', - city: 'Grangeville - Idaho County Airport', - state: 'ID', - lat: 45.94111, - lon: -116.13257, - }, - KRXE: { - id: 'KRXE', - city: 'Rexburg, Rexburg-Madison County Airport', - state: 'ID', - lat: 43.83167, - lon: -111.80611, - }, - KLLJ: { - id: 'KLLJ', - city: 'Challis - Challis Airport', - state: 'ID', - lat: 44.523, - lon: -114.21611, - }, - KSZT: { - id: 'KSZT', - city: 'Sandpoint, Sandpoint Airport', - state: 'ID', - lat: 48.29944, - lon: -116.56, - }, - KDIJ: { - id: 'KDIJ', - city: 'Driggs, Driggs-Reed Memorial Airport', - state: 'ID', - lat: 43.74167, - lon: -111.09778, - }, - ETSI: { - id: 'ETSI', - city: 'Emmett I.D. Southside Canal', - state: 'ID', - lat: 43.925, - lon: -116.4402777, - }, - KMAN: { - id: 'KMAN', - city: 'Nampa Municipal Airport', - state: 'ID', - lat: 43.5813, - lon: -116.5231, - }, - FALI: { - id: 'FALI', - city: 'Falls River near Squirrel, ID', - state: 'ID', - lat: 44.0686111, - lon: -111.2402777, - }, - LPPI: { - id: 'LPPI', - city: 'PA Lateral (Pumping Plant) near Milner, ID', - state: 'ID', - lat: 42.5333333, - lon: -113.9666666, - }, - KILG: { - id: 'KILG', - city: 'Wilmington, New Castle County Airport', - state: 'DE', - lat: 39.67442, - lon: -75.60567, - }, - KDOV: { - id: 'KDOV', - city: 'Dover Air Force Base', - state: 'DE', - lat: 39.13333, - lon: -75.4666699, - }, - KGED: { - id: 'KGED', - city: 'Georgetown - Delaware Coastal Airport', - state: 'DE', - lat: 38.68974, - lon: -75.36245, - }, - KGRB: { - id: 'KGRB', - city: 'Green Bay, Austin Straubel International Airport', - state: 'WI', - lat: 44.4794399, - lon: -88.13667, - }, - KMKE: { - id: 'KMKE', - city: 'Milwaukee, General Mitchell International Airport', - state: 'WI', - lat: 42.955, - lon: -87.9044399, - }, - KMSN: { - id: 'KMSN', - city: 'Madison, Dane County Regional-Truax Field', - state: 'WI', - lat: 43.14056, - lon: -89.34528, - }, - KEAU: { - id: 'KEAU', - city: 'Eau Claire, Chippewa Valley Regional Airport', - state: 'WI', - lat: 44.86528, - lon: -91.485, - }, - KLSE: { - id: 'KLSE', - city: 'La Crosse - La Crosse Regional Airport', - state: 'WI', - lat: 43.87944, - lon: -91.25667, - }, - KCWA: { - id: 'KCWA', - city: 'Mosinee', - state: 'WI', - lat: 44.77944, - lon: -89.67098, - }, - KAUW: { - id: 'KAUW', - city: 'Wausau, Wausau Downtown Airport', - state: 'WI', - lat: 44.92861, - lon: -89.62667, - }, - KHYR: { - id: 'KHYR', - city: 'Hayward, Hayward Municipal Airport', - state: 'WI', - lat: 46.02056, - lon: -91.45028, - }, - KDLL: { - id: 'KDLL', - city: 'Baraboo Wisconsin Dells Airport', - state: 'WI', - lat: 43.52372, - lon: -89.77345, - }, - KOSH: { - id: 'KOSH', - city: 'Wittman Regional Airport', - state: 'WI', - lat: 43.98938, - lon: -88.55894, - }, - KRHI: { - id: 'KRHI', - city: 'Rhinelander, Rhinelander-Oneida County Airport', - state: 'WI', - lat: 45.63167, - lon: -89.48222, - }, - KCLI: { - id: 'KCLI', - city: 'Clintonville Municipal Airport', - state: 'WI', - lat: 44.61526, - lon: -88.73129, - }, - KEGV: { - id: 'KEGV', - city: 'Eagle River Union Airport', - state: 'WI', - lat: 45.9309299, - lon: -89.26702, - }, - KARV: { - id: 'KARV', - city: 'Minocqua/Woodruff, Lakeland Airport/Noble F. Lee Memorial Field', - state: 'WI', - lat: 45.93333, - lon: -89.73333, - }, - KCMY: { - id: 'KCMY', - city: 'Sparta, Sparta / Fort McCoy Airport', - state: 'WI', - lat: 43.9583299, - lon: -90.73778, - }, - KFLD: { - id: 'KFLD', - city: 'Fond Du Lac, Fond Du Lac County Airport', - state: 'WI', - lat: 43.77, - lon: -88.48639, - }, - KMDZ: { - id: 'KMDZ', - city: 'Taylor County Airport', - state: 'WI', - lat: 45.10462, - lon: -90.30253, - }, - KMRJ: { - id: 'KMRJ', - city: 'Iowa County Airport', - state: 'WI', - lat: 42.88754, - lon: -90.23147, - }, - KJVL: { - id: 'KJVL', - city: 'Janesville-Rock County', - state: 'WI', - lat: 42.62135, - lon: -89.04186, - }, - KAIG: { - id: 'KAIG', - city: 'Langlade County Airport', - state: 'WI', - lat: 45.15659, - lon: -89.11144, - }, - KETB: { - id: 'KETB', - city: 'West Bend Municipal Airport', - state: 'WI', - lat: 43.42256, - lon: -88.1326, - }, - KATW: { - id: 'KATW', - city: 'Appleton-Outagamie', - state: 'WI', - lat: 44.2595, - lon: -88.51567, - }, - KMFI: { - id: 'KMFI', - city: 'Marshfield, Marshfield Municipal Airport', - state: 'WI', - lat: 44.63806, - lon: -90.1875, - }, - KMTW: { - id: 'KMTW', - city: 'Manitowoc, Manitowoc County Airport', - state: 'WI', - lat: 44.13333, - lon: -87.68333, - }, - KMWC: { - id: 'KMWC', - city: 'Milwaukee-Timmerman', - state: 'WI', - lat: 43.10961, - lon: -88.03048, - }, - KBUU: { - id: 'KBUU', - city: 'Burlington Municipal Airport', - state: 'WI', - lat: 42.69088, - lon: -88.308, - }, - KISW: { - id: 'KISW', - city: 'Wisconsin Rapids, Alexander Field South Wood County Airport', - state: 'WI', - lat: 44.35917, - lon: -89.83694, - }, - KASX: { - id: 'KASX', - city: 'Ashland, Kennedy Memorial Airport', - state: 'WI', - lat: 46.54972, - lon: -90.91833, - }, - KENW: { - id: 'KENW', - city: 'Kenosha, Kenosha Regional Airport', - state: 'WI', - lat: 42.595, - lon: -87.9380599, - }, - KEFT: { - id: 'KEFT', - city: 'Monroe Municipal Airport', - state: 'WI', - lat: 42.61959, - lon: -89.59309, - }, - KLNR: { - id: 'KLNR', - city: 'Lone Rock Tri-County Regional Airport', - state: 'WI', - lat: 43.21108, - lon: -90.18735, - }, - KRGK: { - id: 'KRGK', - city: 'Red Wing - Red Wing Regional Airport', - state: 'WI', - lat: 44.5926, - lon: -92.48439, - }, - KVOK: { - id: 'KVOK', - city: 'Volk / Camp Douglas', - state: 'WI', - lat: 43.93333, - lon: -90.26667, - }, - KSUE: { - id: 'KSUE', - city: 'Sturgeon Bay', - state: 'WI', - lat: 44.85, - lon: -87.41667, - }, - KUNU: { - id: 'KUNU', - city: 'Juneau, Dodge County Airport', - state: 'WI', - lat: 43.42667, - lon: -88.7033299, - }, - KPDC: { - id: 'KPDC', - city: 'Prairie Du Chien Municipal Airport', - state: 'WI', - lat: 43.01938, - lon: -91.12112, - }, - KRNH: { - id: 'KRNH', - city: 'New Richmond Municipal Airport', - state: 'WI', - lat: 45.14762, - lon: -92.53349, - }, - KSUW: { - id: 'KSUW', - city: 'Richard I. Bong Airport', - state: 'WI', - lat: 46.68335, - lon: -92.09254, - }, - KOEO: { - id: 'KOEO', - city: 'L O Simenstad Municipal Airport', - state: 'WI', - lat: 45.31084, - lon: -92.6948, - }, - KRYV: { - id: 'KRYV', - city: 'Watertown', - state: 'WI', - lat: 43.17016, - lon: -88.72497, - }, - KRZN: { - id: 'KRZN', - city: 'Siren, Burnett County Airport', - state: 'WI', - lat: 45.82278, - lon: -92.3725, - }, - KOVS: { - id: 'KOVS', - city: 'Boscobel, Boscobel Airport', - state: 'WI', - lat: 43.15611, - lon: -90.6775, - }, - KPBH: { - id: 'KPBH', - city: 'Phillips / Price County', - state: 'WI', - lat: 45.7, - lon: -90.4, - }, - KRAC: { - id: 'KRAC', - city: 'Racine, Batten International Airport', - state: 'WI', - lat: 42.75861, - lon: -87.81778, - }, - KSTE: { - id: 'KSTE', - city: 'Stevens Point Municipal Airport', - state: 'WI', - lat: 44.54371, - lon: -89.53468, - }, - KRRL: { - id: 'KRRL', - city: 'Merrill, Merrill Municipal Airport', - state: 'WI', - lat: 45.19844, - lon: -89.70996, - }, - KSBM: { - id: 'KSBM', - city: 'Sheboygan, Sheboygan County Memorial Airport', - state: 'WI', - lat: 43.77639, - lon: -87.84972, - }, - KRPD: { - id: 'KRPD', - city: 'Rice Lake, Rice Lake Regional-Carl\'s Field Airport', - state: 'WI', - lat: 45.4180599, - lon: -91.77361, - }, - KUES: { - id: 'KUES', - city: 'Waukesha County Airport', - state: 'WI', - lat: 43.04245, - lon: -88.24607, - }, - KTKV: { - id: 'KTKV', - city: 'Tomahawk Regional Airport', - state: 'WI', - lat: 45.46801, - lon: -89.80962, - }, - KUBE: { - id: 'KUBE', - city: 'Cumberland', - state: 'WI', - lat: 45.506, - lon: -91.9811, - }, - KOCQ: { - id: 'KOCQ', - city: 'Oconto J. Douglas Bake Memorial Airport', - state: 'WI', - lat: 44.8742, - lon: -87.9096, - }, - KRCX: { - id: 'KRCX', - city: 'Ladysmith - Rusk County Airport', - state: 'WI', - lat: 45.4935, - lon: -90.9985, - }, - KPCZ: { - id: 'KPCZ', - city: 'Waupaca Municipal Airport', - state: 'WI', - lat: 44.33425, - lon: -89.02023, - }, - KLUM: { - id: 'KLUM', - city: 'Menomonie Municipal Airport-Score Field', - state: 'WI', - lat: 44.89363, - lon: -91.86652, - }, - KLNL: { - id: 'KLNL', - city: 'Land O\' Lakes, Kings Land O\' Lakes Airport', - state: 'WI', - lat: 46.1538899, - lon: -89.21194, - }, - KBCK: { - id: 'KBCK', - city: 'Black River Falls Area Airport', - state: 'WI', - lat: 44.24996, - lon: -90.84999, - }, - KEZS: { - id: 'KEZS', - city: 'Shawano Municipal Airport', - state: 'WI', - lat: 44.787, - lon: -88.56, - }, - KPVB: { - id: 'KPVB', - city: 'Platteville Municipal Airport', - state: 'WI', - lat: 42.69092, - lon: -90.4412399, - }, - KOLG: { - id: 'KOLG', - city: 'Solon Springs Municipal Airport', - state: 'WI', - lat: 46.3148, - lon: -91.8164, - }, - KMSY: { - id: 'KMSY', - city: 'New Orleans, New Orleans International Airport', - state: 'LA', - lat: 29.99278, - lon: -90.2508299, - }, - KNEW: { - id: 'KNEW', - city: 'New Orleans, New Orleans Lakefront Airport', - state: 'LA', - lat: 30.04944, - lon: -90.02889, - }, - KASD: { - id: 'KASD', - city: 'Slidell, Slidell Airport', - state: 'LA', - lat: 30.34306, - lon: -89.82194, - }, - KLCH: { - id: 'KLCH', - city: 'Lake Charles, Lake Charles Regional Airport', - state: 'LA', - lat: 30.12611, - lon: -93.22333, - }, - KSHV: { - id: 'KSHV', - city: 'Shreveport, Shreveport Regional Airport', - state: 'LA', - lat: 32.44694, - lon: -93.82417, - }, - KBTR: { - id: 'KBTR', - city: 'Baton Rouge, Baton Rouge Metropolitan, Ryan Field', - state: 'LA', - lat: 30.53722, - lon: -91.14694, - }, - KPOE: { - id: 'KPOE', - city: 'Fort Polk, Polk AAF Ft Polk', - state: 'LA', - lat: 31.05, - lon: -93.19389, - }, - KAEX: { - id: 'KAEX', - city: 'Alexandria, Alexandria International Airport', - state: 'LA', - lat: 31.33472, - lon: -92.55861, - }, - KBAD: { - id: 'KBAD', - city: 'Barksdale Air Force Base', - state: 'LA', - lat: 32.5, - lon: -93.66667, - }, - KDTN: { - id: 'KDTN', - city: 'Shreveport, Shreveport Downtown Airport', - state: 'LA', - lat: 32.5424999, - lon: -93.74472, - }, - KLFT: { - id: 'KLFT', - city: 'Lafayette, Lafayette Regional Airport', - state: 'LA', - lat: 30.20222, - lon: -91.99306, - }, - KMLU: { - id: 'KMLU', - city: 'Monroe Regional Airport', - state: 'LA', - lat: 32.5155699, - lon: -92.02995, - }, - KESF: { - id: 'KESF', - city: 'Alexandria Esler Regional Airport', - state: 'LA', - lat: 31.39634, - lon: -92.28273, - }, - KNBG: { - id: 'KNBG', - city: 'New Orleans, Naval Air Station - Alvin Callender Field', - state: 'LA', - lat: 29.82528, - lon: -90.035, - }, - KARA: { - id: 'KARA', - city: 'New Iberia, Acadiana Regional Airport', - state: 'LA', - lat: 30.02889, - lon: -91.88444, - }, - KIER: { - id: 'KIER', - city: 'Natchitoches, Natchitoches Regional Airport', - state: 'LA', - lat: 31.73583, - lon: -93.09917, - }, - KAXO: { - id: 'KAXO', - city: 'Grand Isle Supplementary Aviation Weather Reporting Station', - state: 'LA', - lat: 29.25, - lon: -89.9666699, - }, - KHDC: { - id: 'KHDC', - city: 'Hammond, Hammond Municipal Airport', - state: 'LA', - lat: 30.52083, - lon: -90.4175, - }, - KHUM: { - id: 'KHUM', - city: 'Houma-Terrebonne', - state: 'LA', - lat: 29.56667, - lon: -90.66667, - }, - KCVW: { - id: 'KCVW', - city: 'Cameron', - state: 'LA', - lat: 29.78333, - lon: -93.3, - }, - KCWF: { - id: 'KCWF', - city: 'Chenault Airpark', - state: 'LA', - lat: 30.21667, - lon: -93.15, - }, - KRSN: { - id: 'KRSN', - city: 'Ruston, Ruston Regional Airport', - state: 'LA', - lat: 32.51444, - lon: -92.58833, - }, - KTVR: { - id: 'KTVR', - city: 'Vicksburg, Vicksburg / Tallulah Regional Airport', - state: 'LA', - lat: 32.3480599, - lon: -91.03, - }, - KPTN: { - id: 'KPTN', - city: 'Patterson Memorial', - state: 'LA', - lat: 29.71667, - lon: -91.33333, - }, - KAUD: { - id: 'KAUD', - city: 'Audubon Park', - state: 'LA', - lat: 29.93333, - lon: -90.13333, - }, - KACP: { - id: 'KACP', - city: 'Oakdale, Allen Parish Airport', - state: 'LA', - lat: 30.75056, - lon: -92.68861, - }, - KBVE: { - id: 'KBVE', - city: 'Boothville', - state: 'LA', - lat: 29.33333, - lon: -89.4, - }, - KBKB: { - id: 'KBKB', - city: 'Ft. Polk - Fullerton Landing Strip', - state: 'LA', - lat: 31.0217, - lon: -92.9107, - }, - KAQV: { - id: 'KAQV', - city: 'Ft. Polk - Peason Ridge', - state: 'LA', - lat: 31.4, - lon: -93.2833, - }, - KGAO: { - id: 'KGAO', - city: 'Galliano, South Lafourche Airport', - state: 'LA', - lat: 29.44472, - lon: -90.26111, - }, - KDRI: { - id: 'KDRI', - city: 'De Ridder, Beauregard Parish Airport', - state: 'LA', - lat: 30.83167, - lon: -93.33972, - }, - KBQP: { - id: 'KBQP', - city: 'Bastrop, Morehouse Memorial Airport', - state: 'LA', - lat: 32.75583, - lon: -91.88056, - }, - KBXA: { - id: 'KBXA', - city: 'Bogalusa, George R Carr Memorial Air Field', - state: 'LA', - lat: 30.81361, - lon: -89.86472, - }, - KUXL: { - id: 'KUXL', - city: 'Southland Field', - state: 'LA', - lat: 30.1314, - lon: -93.3760999, - }, - KGHB: { - id: 'KGHB', - city: 'GB172/Salsa (Shell E-P)', - state: 'LA', - lat: 27.84, - lon: -91.988, - }, - KATP: { - id: 'KATP', - city: 'Green Canyon 787 Atlantis', - state: 'LA', - lat: 27.195, - lon: -90.027, - }, - KXIH: { - id: 'KXIH', - city: 'High Island 179A (Apache Corp)', - state: 'LA', - lat: 29.18, - lon: -94.521, - }, - KXPY: { - id: 'KXPY', - city: 'Port Fourchon', - state: 'LA', - lat: 29.123, - lon: -90.202, - }, - KEIR: { - id: 'KEIR', - city: 'Eugene Island', - state: 'LA', - lat: 28.634, - lon: -91.489, - }, - KMNE: { - id: 'KMNE', - city: 'Minden Airport', - state: 'LA', - lat: 32.64603, - lon: -93.29808, - }, - KIYA: { - id: 'KIYA', - city: 'Abbeville Chris Crusta Memorial Airport', - state: 'LA', - lat: 29.97578, - lon: -92.08422, - }, - KVKY: { - id: 'KVKY', - city: 'Main Pass 289C (Apache Corp)', - state: 'LA', - lat: 29.248, - lon: -88.441, - }, - KVQT: { - id: 'KVQT', - city: 'Vermilion 331 (Energy Resource Technology)', - state: 'LA', - lat: 28.27, - lon: -92.264, - }, - KMIS: { - id: 'KMIS', - city: 'Main Pass 140B (Apache Corp)', - state: 'LA', - lat: 29.296, - lon: -88.842, - }, - KGRY: { - id: 'KGRY', - city: 'Green Canyon 338 Front Runner', - state: 'LA', - lat: 27.625, - lon: -90.441, - }, - KHZR: { - id: 'KHZR', - city: 'New Roads False River Regional Airport', - state: 'LA', - lat: 30.7183, - lon: -91.4787, - }, - KOPL: { - id: 'KOPL', - city: 'Opelousas St Landry Parish Airport', - state: 'LA', - lat: 30.5584, - lon: -92.0994, - }, - KSQE: { - id: 'KSQE', - city: 'GOMEX Ship Shoal 354 Fieldwood Energy', - state: 'LA', - lat: 28.083, - lon: -90.819, - }, - KGBK: { - id: 'KGBK', - city: 'MAGNOLIA OIL PLATFORM', - state: 'LA', - lat: 27.2, - lon: -92.2, - }, - KSCF: { - id: 'KSCF', - city: 'S MARSH268 OIL PLATFORM', - state: 'LA', - lat: 29.12, - lon: -91.87, - }, - KMDJ: { - id: 'KMDJ', - city: 'MISS CANYON OIL PLATFORM', - state: 'LA', - lat: 28.65, - lon: -89.8, - }, - KSPR: { - id: 'KSPR', - city: 'SHIP SHOAL OIL PLATFORM', - state: 'LA', - lat: 28.6, - lon: -91.2, - }, - KEHC: { - id: 'KEHC', - city: 'E CAMERON278 OIL PLATFORM', - state: 'LA', - lat: 28.43, - lon: -92.88, - }, - KVBS: { - id: 'KVBS', - city: 'SABINE 13B OIL PLATFORM', - state: 'LA', - lat: 29.48, - lon: -93.63, - }, - KVOA: { - id: 'KVOA', - city: 'VK 786/Petronius (Chevron)', - state: 'LA', - lat: 29.229, - lon: -87.781, - }, - KPIT: { - id: 'KPIT', - city: 'Pittsburgh, Pittsburgh International Airport', - state: 'PA', - lat: 40.50389, - lon: -80.26639, - }, - KPHL: { - id: 'KPHL', - city: 'Philadelphia, Philadelphia International Airport', - state: 'PA', - lat: 39.87327, - lon: -75.22678, - }, - KUNV: { - id: 'KUNV', - city: 'State College - University Park Airport', - state: 'PA', - lat: 40.85344, - lon: -77.8401, - }, - KERI: { - id: 'KERI', - city: 'Erie, Erie International Airport', - state: 'PA', - lat: 42.08, - lon: -80.1825, - }, - KPNE: { - id: 'KPNE', - city: 'Philadelphia, Northeast Philadelphia Airport', - state: 'PA', - lat: 40.07889, - lon: -75.01361, - }, - KAGC: { - id: 'KAGC', - city: 'Pittsburgh - Allegheny County Airport', - state: 'PA', - lat: 40.35521, - lon: -79.92144, - }, - KJST: { - id: 'KJST', - city: 'Johnstown - Cambria County Airport', - state: 'PA', - lat: 40.3149, - lon: -78.83074, - }, - KDUJ: { - id: 'KDUJ', - city: 'Du Bois - Jefferson County Airport', - state: 'PA', - lat: 41.17948, - lon: -78.89326, - }, - KMUI: { - id: 'KMUI', - city: 'Muir Army Air Field / Indiantown', - state: 'PA', - lat: 40.43808, - lon: -76.56434, - }, - KIPT: { - id: 'KIPT', - city: 'Williamsport - Lycoming County Airport', - state: 'PA', - lat: 41.24298, - lon: -76.92173, - }, - KABE: { - id: 'KABE', - city: 'Allentown, Lehigh Valley International Airport', - state: 'PA', - lat: 40.64985, - lon: -75.44771, - }, - KLBE: { - id: 'KLBE', - city: 'Latrobe / Westmorland', - state: 'PA', - lat: 40.28333, - lon: -79.4, - }, - KAVP: { - id: 'KAVP', - city: 'Wilkes-Barre - Scranton, Wilkes-Barre / Scranton International Airport', - state: 'PA', - lat: 41.33889, - lon: -75.72667, - }, - KAOO: { - id: 'KAOO', - city: 'Altoona - Blair County Airport', - state: 'PA', - lat: 40.29994, - lon: -78.3168, - }, - KMDT: { - id: 'KMDT', - city: 'Harrisburg, Harrisburg International Airport', - state: 'PA', - lat: 40.19361, - lon: -76.76333, - }, - KBVI: { - id: 'KBVI', - city: 'Beaver Falls Airport', - state: 'PA', - lat: 40.76667, - lon: -80.4, - }, - KBFD: { - id: 'KBFD', - city: 'Bradford Regional Airport', - state: 'PA', - lat: 41.79838, - lon: -78.63539, - }, - KFKL: { - id: 'KFKL', - city: 'Franklin, Venango Regional Airport', - state: 'PA', - lat: 41.38333, - lon: -79.86667, - }, - KRDG: { - id: 'KRDG', - city: 'Reading, Reading Regional Airport', - state: 'PA', - lat: 40.37333, - lon: -75.95944, - }, - KGKJ: { - id: 'KGKJ', - city: 'Port Meadville Airport', - state: 'PA', - lat: 41.6258399, - lon: -80.21231, - }, - KMQS: { - id: 'KMQS', - city: 'Chester County Airport', - state: 'PA', - lat: 39.98333, - lon: -75.86667, - }, - KIDI: { - id: 'KIDI', - city: 'Indiana / Stewart Field', - state: 'PA', - lat: 40.63333, - lon: -79.1, - }, - KDYL: { - id: 'KDYL', - city: 'Doylestown, Doylestown Airport', - state: 'PA', - lat: 40.33016, - lon: -75.12286, - }, - KMPO: { - id: 'KMPO', - city: 'Mount Pocono, Pocono Mountains Municipal Airport', - state: 'PA', - lat: 41.13821, - lon: -75.37971, - }, - KLNS: { - id: 'KLNS', - city: 'Lancaster, Lancaster Airport', - state: 'PA', - lat: 40.1205799, - lon: -76.29446, - }, - KFIG: { - id: 'KFIG', - city: 'Clearfield, Clearfield-Lawrence Airport', - state: 'PA', - lat: 41.04667, - lon: -78.41167, - }, - KCXY: { - id: 'KCXY', - city: 'Harrisburg, Capital City Airport', - state: 'PA', - lat: 40.21843, - lon: -76.8552, - }, - KAFJ: { - id: 'KAFJ', - city: 'Washington, Washington County Airport', - state: 'PA', - lat: 40.13333, - lon: -80.28333, - }, - KBTP: { - id: 'KBTP', - city: 'Butler, Butler County Airport/K W Scholter Field', - state: 'PA', - lat: 40.78333, - lon: -79.95, - }, - KPTW: { - id: 'KPTW', - city: 'Pottstown, Pottstown Limerick Airport', - state: 'PA', - lat: 40.23802, - lon: -75.5548699, - }, - KTHV: { - id: 'KTHV', - city: 'York, York Airport', - state: 'PA', - lat: 39.91944, - lon: -76.87694, - }, - KSEG: { - id: 'KSEG', - city: 'Selinsgrove Penn Valley Airport', - state: 'PA', - lat: 40.81929, - lon: -76.86582, - }, - KHMZ: { - id: 'KHMZ', - city: 'Bedford, Bedford County Airport', - state: 'PA', - lat: 40.08528, - lon: -78.51222, - }, - KUKT: { - id: 'KUKT', - city: 'Quakertown Airport', - state: 'PA', - lat: 40.4368, - lon: -75.38016, - }, - KLOM: { - id: 'KLOM', - city: 'Philadelphia - Wings Field Airport', - state: 'PA', - lat: 40.13758, - lon: -75.2684, - }, - KCKZ: { - id: 'KCKZ', - city: 'PERKASIE', - state: 'PA', - lat: 40.3891599, - lon: -75.2905, - }, - KOQN: { - id: 'KOQN', - city: 'WEST CHESTER', - state: 'PA', - lat: 39.99016, - lon: -75.58183, - }, - KHZL: { - id: 'KHZL', - city: 'Hazleton Municipal Airport', - state: 'PA', - lat: 40.98447, - lon: -75.99005, - }, - KUCP: { - id: 'KUCP', - city: 'New Castle, New Castle Municipal Airport', - state: 'PA', - lat: 41.02528, - lon: -80.41333, - }, - KRYT: { - id: 'KRYT', - city: 'Fountain Dale', - state: 'PA', - lat: 39.7341399, - lon: -77.43042, - }, - KXLL: { - id: 'KXLL', - city: 'Allentown Queen City Municipal Airport', - state: 'PA', - lat: 40.57, - lon: -75.488, - }, - KBOS: { - id: 'KBOS', - city: 'Boston, Logan International Airport', - state: 'MA', - lat: 42.36056, - lon: -71.01056, - }, - KACK: { - id: 'KACK', - city: 'Nantucket, Nantucket Memorial Airport', - state: 'MA', - lat: 41.25389, - lon: -70.05972, - }, - KBED: { - id: 'KBED', - city: 'Bedford, Hanscom Field', - state: 'MA', - lat: 42.46833, - lon: -71.29444, - }, - KBAF: { - id: 'KBAF', - city: 'Westfield, Barnes Municipal Airport', - state: 'MA', - lat: 42.15972, - lon: -72.71278, - }, - KHYA: { - id: 'KHYA', - city: 'Hyannis, Barnstable Municipal-Boardman Airport', - state: 'MA', - lat: 41.67194, - lon: -70.26972, - }, - KORH: { - id: 'KORH', - city: 'Worcester, Worcester Regional Airport', - state: 'MA', - lat: 42.27056, - lon: -71.87306, - }, - KAQW: { - id: 'KAQW', - city: 'North Adams Harriman-and-West Airport', - state: 'MA', - lat: 42.69731, - lon: -73.16955, - }, - KBVY: { - id: 'KBVY', - city: 'Beverly, Beverly Municipal Airport', - state: 'MA', - lat: 42.58361, - lon: -70.91639, - }, - KCQX: { - id: 'KCQX', - city: 'Chatham, Chatham Municipal Airport', - state: 'MA', - lat: 41.6875, - lon: -69.99333, - }, - KFMH: { - id: 'KFMH', - city: 'Otis Air National Guard Base', - state: 'MA', - lat: 41.65, - lon: -70.51667, - }, - KMVY: { - id: 'KMVY', - city: 'Vineyard Haven, Marthas Vineyard Airport', - state: 'MA', - lat: 41.39222, - lon: -70.61667, - }, - KLWM: { - id: 'KLWM', - city: 'Lawrence, Lawrence Municipal Airport', - state: 'MA', - lat: 42.71306, - lon: -71.1258299, - }, - KCEF: { - id: 'KCEF', - city: 'Chicopee Falls / Westover Air Force Base', - state: 'MA', - lat: 42.2, - lon: -72.53333, - }, - KFIT: { - id: 'KFIT', - city: 'Fitchburg, Fitchburg Municipal Airport', - state: 'MA', - lat: 42.55194, - lon: -71.75583, - }, - KMQE: { - id: 'KMQE', - city: 'East Milton', - state: 'MA', - lat: 42.21222, - lon: -71.11472, - }, - KEWB: { - id: 'KEWB', - city: 'New Bedford, New Bedford Regional Airport', - state: 'MA', - lat: 41.67528, - lon: -70.95694, - }, - KORE: { - id: 'KORE', - city: 'Orange, Orange Municipal Airport', - state: 'MA', - lat: 42.57167, - lon: -72.2775, - }, - KPSF: { - id: 'KPSF', - city: 'Pittsfield Municipal Airport', - state: 'MA', - lat: 42.42691, - lon: -73.28897, - }, - KTAN: { - id: 'KTAN', - city: 'Taunton, Taunton Municipal Airport', - state: 'MA', - lat: 41.87556, - lon: -71.0211099, - }, - KPVC: { - id: 'KPVC', - city: 'Provincetown, Provincetown Municipal Airport', - state: 'MA', - lat: 42.06667, - lon: -70.2166699, - }, - KPYM: { - id: 'KPYM', - city: 'Plymouth, Plymouth Municipal Airport', - state: 'MA', - lat: 41.90861, - lon: -70.72806, - }, - KOWD: { - id: 'KOWD', - city: 'Norwood, Norwood Memorial Airport', - state: 'MA', - lat: 42.19083, - lon: -71.17389, - }, - KGHG: { - id: 'KGHG', - city: 'Marshfield Airport', - state: 'MA', - lat: 42.0983, - lon: -70.6722, - }, - FARM: { - id: 'FARM', - city: 'Farmington Bench', - state: 'UT', - lat: 41.004, - lon: -111.8907, - }, - TRJO: { - id: 'TRJO', - city: 'Trans-Jordan Landfill', - state: 'UT', - lat: 40.556805, - lon: -112.06094, - }, - KKNB: { - id: 'KKNB', - city: 'KANAB MUNICIPAL AIRPORT', - state: 'UT', - lat: 37.01, - lon: -112.53, - }, - KRIF: { - id: 'KRIF', - city: 'RICHFIELD MUNICPAL AIRPORT', - state: 'UT', - lat: 38.74, - lon: -112.1, - }, - EYSC: { - id: 'EYSC', - city: 'Eyring Science Center', - state: 'UT', - lat: 40.24715, - lon: -111.65001, - }, - WPOE: { - id: 'WPOE', - city: 'Wendover Port of Entry', - state: 'UT', - lat: 40.7459, - lon: -113.991, - }, - PCSL: { - id: 'PCSL', - city: 'PARK CITY - SILVERLODE TOP', - state: 'UT', - lat: 40.628, - lon: -111.529, - }, - MOAB: { - id: 'MOAB', - city: 'USGS/NPS Building, Moab', - state: 'UT', - lat: 38.537356, - lon: -109.510439, - }, - PCPD: { - id: 'PCPD', - city: 'PARK CITY - PAYDAY TOP', - state: 'UT', - lat: 40.635, - lon: -111.508, - }, - KFOM: { - id: 'KFOM', - city: 'Fillmore', - state: 'UT', - lat: 38.95814, - lon: -112.36314, - }, - NHMU: { - id: 'NHMU', - city: 'Natural History Museum Utah', - state: 'UT', - lat: 40.764306, - lon: -111.822855, - }, - DRRD: { - id: 'DRRD', - city: 'Dry Ridge', - state: 'UT', - lat: 40.5839, - lon: -110.6169, - }, - GSLM: { - id: 'GSLM', - city: 'Great Salt Lake Minerals', - state: 'UT', - lat: 41.296997, - lon: -112.269075, - }, - KSLC: { - id: 'KSLC', - city: 'Salt Lake City, Salt Lake City International Airport', - state: 'UT', - lat: 40.77069, - lon: -111.96503, - }, - KOGD: { - id: 'KOGD', - city: 'Ogden-Hinckley Airport', - state: 'UT', - lat: 41.19406, - lon: -112.01681, - }, - KDPG: { - id: 'KDPG', - city: 'Dugway Proving Grounds', - state: 'UT', - lat: 40.16667, - lon: -112.93333, - }, - KCDC: { - id: 'KCDC', - city: 'Cedar City Municipal Airport', - state: 'UT', - lat: 37.70675, - lon: -113.09695, - }, - KENV: { - id: 'KENV', - city: 'Wendover / Air Force Auxillary Field', - state: 'UT', - lat: 40.72056, - lon: -114.03583, - }, - KBCE: { - id: 'KBCE', - city: 'Bryce Canyon Airport', - state: 'UT', - lat: 37.7012799, - lon: -112.14897, - }, - KPVU: { - id: 'KPVU', - city: 'Provo, Provo Municipal Airport', - state: 'UT', - lat: 40.21667, - lon: -111.71667, - }, - KVEL: { - id: 'KVEL', - city: 'Vernal Airport', - state: 'UT', - lat: 40.44295, - lon: -109.51273, - }, - KLGU: { - id: 'KLGU', - city: 'Logan-Cache Airport', - state: 'UT', - lat: 41.78652, - lon: -111.85187, - }, - KHIF: { - id: 'KHIF', - city: 'Hill Air Force Base', - state: 'UT', - lat: 41.11112, - lon: -111.96229, - }, - KSGU: { - id: 'KSGU', - city: 'St George Municipal Airport', - state: 'UT', - lat: 37.0451, - lon: -113.50561, - }, - SANT: { - id: 'SANT', - city: 'SANTAQUIN', - state: 'UT', - lat: 39.99, - lon: -111.78, - }, - KPUC: { - id: 'KPUC', - city: 'Price - Carbon County Regional Airport', - state: 'UT', - lat: 39.60886, - lon: -110.75548, - }, - KBMC: { - id: 'KBMC', - city: 'BRIGHAM CITY AIRPORT', - state: 'UT', - lat: 41.51, - lon: -112.05, - }, - KMLF: { - id: 'KMLF', - city: 'Milford Municipal Airport', - state: 'UT', - lat: 38.42252, - lon: -113.01089, - }, - KBDG: { - id: 'KBDG', - city: 'BLANDING', - state: 'UT', - lat: 37.62, - lon: -109.47, - }, - KCNY: { - id: 'KCNY', - city: 'Moab, Canyonlands Field', - state: 'UT', - lat: 38.76, - lon: -109.74472, - }, - SLCO: { - id: 'SLCO', - city: 'OLYPMPUS JHS', - state: 'UT', - lat: 40.67, - lon: -111.82, - }, - KTVY: { - id: 'KTVY', - city: 'Bolinder Field-Tooele Valley Airport', - state: 'UT', - lat: 40.61269, - lon: -112.35362, - }, - KDTA: { - id: 'KDTA', - city: 'Delta, Delta Municipal Airport', - state: 'UT', - lat: 39.38333, - lon: -112.50967, - }, - KHVE: { - id: 'KHVE', - city: 'Hanksville', - state: 'UT', - lat: 38.418037, - lon: -110.704038, - }, - NWTC: { - id: 'NWTC', - city: 'Rocky Flats Nat Wind Tech Ctr', - state: 'CO', - lat: 39.9106499, - lon: -105.2348, - }, - SRRL: { - id: 'SRRL', - city: 'Solar Radiation Research Lab', - state: 'CO', - lat: 39.74, - lon: -105.18, - }, - SPMD: { - id: 'SPMD', - city: 'South Park Mountain Data (NREL)', - state: 'CO', - lat: 39.27, - lon: -105.62, - }, - CDSK: { - id: 'CDSK', - city: 'Durango Mountain Resort', - state: 'CO', - lat: 37.61806, - lon: -107.85306, - }, - RMEX: { - id: 'RMEX', - city: 'Mexican Cut', - state: 'CO', - lat: 39.0283299, - lon: -107.06361, - }, - KDEN: { - id: 'KDEN', - city: 'Denver, Denver International Airport', - state: 'CO', - lat: 39.84658, - lon: -104.65622, - }, - KBJC: { - id: 'KBJC', - city: 'Broomfield / Jeffco', - state: 'CO', - lat: 39.90085, - lon: -105.10417, - }, - KGJT: { - id: 'KGJT', - city: 'Grand Junction Regional Airport', - state: 'CO', - lat: 39.13389, - lon: -108.53861, - }, - KBKF: { - id: 'KBKF', - city: 'Buckley Air Force Base Airport', - state: 'CO', - lat: 39.71331, - lon: -104.75806, - }, - KPUB: { - id: 'KPUB', - city: 'Pueblo Memorial Airport', - state: 'CO', - lat: 38.28869, - lon: -104.5057, - }, - KCOS: { - id: 'KCOS', - city: 'City Of Colorado Springs Municipal Airport', - state: 'CO', - lat: 38.80948, - lon: -104.68872, - }, - KLIC: { - id: 'KLIC', - city: 'Limon Municipal Airport', - state: 'CO', - lat: 39.27334, - lon: -103.66738, - }, - KLAA: { - id: 'KLAA', - city: 'Lamar Municipal Airport', - state: 'CO', - lat: 38.0717799, - lon: -102.68745, - }, - KCAG: { - id: 'KCAG', - city: 'Craig-Moffat Airport', - state: 'CO', - lat: 40.49297, - lon: -107.52394, - }, - KAKO: { - id: 'KAKO', - city: 'Akron-Washington County Airport', - state: 'CO', - lat: 40.17428, - lon: -103.21459, - }, - KGXY: { - id: 'KGXY', - city: 'Greeley, Greeley-Weld County Airport', - state: 'CO', - lat: 40.43333, - lon: -104.63333, - }, - KDRO: { - id: 'KDRO', - city: 'Durango-La Plata County Airport', - state: 'CO', - lat: 37.14312, - lon: -107.76023, - }, - KASE: { - id: 'KASE', - city: 'Aspen-Pitkin County Airport', - state: 'CO', - lat: 39.22992, - lon: -106.87051, - }, - KAPA: { - id: 'KAPA', - city: 'Denver - Centennial Airport', - state: 'CO', - lat: 39.55991, - lon: -104.84841, - }, - KAFF: { - id: 'KAFF', - city: 'Air Force Academy', - state: 'CO', - lat: 38.96667, - lon: -104.81667, - }, - KFCS: { - id: 'KFCS', - city: 'Fort Carson', - state: 'CO', - lat: 38.7, - lon: -104.76667, - }, - KEGE: { - id: 'KEGE', - city: 'Eagle County Regional', - state: 'CO', - lat: 39.65, - lon: -106.91667, - }, - KALS: { - id: 'KALS', - city: 'San Luis Valley Regional Airport', - state: 'CO', - lat: 37.43933, - lon: -105.8618, - }, - KMTJ: { - id: 'KMTJ', - city: 'Montrose, Montrose Regional Airport', - state: 'CO', - lat: 38.505, - lon: -107.8975, - }, - KGUC: { - id: 'KGUC', - city: 'Gunnison, Gunnison-Crested Butte Regional Airport', - state: 'CO', - lat: 38.53333, - lon: -106.93333, - }, - KHDN: { - id: 'KHDN', - city: 'Hayden, Yampa Valley Airport', - state: 'CO', - lat: 40.48333, - lon: -107.2166699, - }, - KSBS: { - id: 'KSBS', - city: 'Steamboat Springs', - state: 'CO', - lat: 40.5153, - lon: -106.86767, - }, - KRIL: { - id: 'KRIL', - city: 'Rifle, Garfield County Regional Airport', - state: 'CO', - lat: 39.525, - lon: -107.72722, - }, - KEEO: { - id: 'KEEO', - city: 'Meeker Airport', - state: 'CO', - lat: 40.0444, - lon: -107.88832, - }, - KLHX: { - id: 'KLHX', - city: 'La Junta Municipal Airport', - state: 'CO', - lat: 38.04949, - lon: -103.51334, - }, - KCEZ: { - id: 'KCEZ', - city: 'Cortez-Montezuma County Airport', - state: 'CO', - lat: 37.30706, - lon: -108.62644, - }, - KTAD: { - id: 'KTAD', - city: 'Perry Stokes Airport', - state: 'CO', - lat: 37.26218, - lon: -104.33184, - }, - KSPD: { - id: 'KSPD', - city: 'Springfield, Comanche National Grassland', - state: 'CO', - lat: 37.28333, - lon: -102.61667, - }, - KLXV: { - id: 'KLXV', - city: 'Leadville, Lake County Airport', - state: 'CO', - lat: 39.22806, - lon: -106.31611, - }, - KFNL: { - id: 'KFNL', - city: 'Fort Collins/Loveland, Fort Collins-Loveland Municipal Airport', - state: 'CO', - lat: 40.45, - lon: -105.01667, - }, - KTEX: { - id: 'KTEX', - city: 'Telluride, Telluride Regional Airport', - state: 'CO', - lat: 37.95389, - lon: -107.90861, - }, - KITR: { - id: 'KITR', - city: 'Burlington - Carson County Airport', - state: 'CO', - lat: 39.24149, - lon: -102.2818999, - }, - KMYP: { - id: 'KMYP', - city: 'Salida Mountain, Monarch Pass', - state: 'CO', - lat: 38.48444, - lon: -106.31694, - }, - KVTP: { - id: 'KVTP', - city: 'La Veta Mountain, La Veta Pass', - state: 'CO', - lat: 37.50111, - lon: -105.16694, - }, - KCCU: { - id: 'KCCU', - city: 'Copper Mountain - Red Cliff Pass', - state: 'CO', - lat: 39.47523, - lon: -106.15228, - }, - KMNH: { - id: 'KMNH', - city: 'Elbert Mountain, Monument Pass', - state: 'CO', - lat: 39.21667, - lon: -104.6338899, - }, - KCPW: { - id: 'KCPW', - city: 'Pagosa Springs, Wolf Creek Pass', - state: 'CO', - lat: 37.45139, - lon: -106.80028, - }, - KFLY: { - id: 'KFLY', - city: 'Meadow Lake Airport', - state: 'CO', - lat: 38.9439, - lon: -104.56838, - }, - KAIB: { - id: 'KAIB', - city: 'Nucla Hopkins Field Airport', - state: 'CO', - lat: 38.23875, - lon: -108.563277, - }, - KRCV: { - id: 'KRCV', - city: 'Astronaut Kent Rominger - Del Norte', - state: 'CO', - lat: 37.7138, - lon: -106.352, - }, - KFTG: { - id: 'KFTG', - city: 'Denver Nexrad', - state: 'CO', - lat: 39.78333, - lon: -104.55, - }, - KABH: { - id: 'KABH', - city: 'ELLICOTT-B AFA', - state: 'CO', - lat: 38.7578, - lon: -104.3013, - }, - KEIK: { - id: 'KEIK', - city: 'Erie Municipal Airport', - state: 'CO', - lat: 40.01169, - lon: -105.05033, - }, - KPSO: { - id: 'KPSO', - city: 'Stevens Field, Pagosa Springs', - state: 'CO', - lat: 37.2862, - lon: -107.056, - }, - KBDU: { - id: 'KBDU', - city: 'Boulder Municipal Airport', - state: 'CO', - lat: 40.0394297, - lon: -105.2258217, - }, - KSTK: { - id: 'KSTK', - city: 'Sterling Municipal Airport', - state: 'CO', - lat: 40.61331, - lon: -103.26109, - }, - KHEQ: { - id: 'KHEQ', - city: 'Holyoke Airport', - state: 'CO', - lat: 40.57155, - lon: -102.27676, - }, - KAEJ: { - id: 'KAEJ', - city: 'Central Colorado Regional Airport', - state: 'CO', - lat: 38.81416, - lon: -106.12069, - }, - KANK: { - id: 'KANK', - city: 'Harriet Alexander Field Airport', - state: 'CO', - lat: 38.53828, - lon: -106.04864, - }, - KAJZ: { - id: 'KAJZ', - city: 'Delta/Blake Field Airport', - state: 'CO', - lat: 38.7868799, - lon: -108.06584, - }, - KLMO: { - id: 'KLMO', - city: 'Vance Brand Airport', - state: 'CO', - lat: 40.16115, - lon: -105.16042, - }, - KFMM: { - id: 'KFMM', - city: 'Fort Morgan Municipal Airport', - state: 'CO', - lat: 40.33148, - lon: -103.80704, - }, - KCWN: { - id: 'KCWN', - city: 'Cheyenne Mountain', - state: 'CO', - lat: 38.75, - lon: -104.85, - }, - LIDW: { - id: 'LIDW', - city: 'LIND', - state: 'WA', - lat: 46.86722, - lon: -118.73944, - }, - MASW: { - id: 'MASW', - city: 'MANSON', - state: 'WA', - lat: 47.9169399, - lon: -120.12444, - }, - LEGW: { - id: 'LEGW', - city: 'LEGRO', - state: 'WA', - lat: 46.20528, - lon: -118.93611, - }, - HEOC: { - id: 'HEOC', - city: 'Hanford Emergency Operations Center', - state: 'WA', - lat: 46.392, - lon: -119.537, - }, - ODSW: { - id: 'ODSW', - city: 'ODESSA', - state: 'WA', - lat: 47.30889, - lon: -118.87861, - }, - GERW: { - id: 'GERW', - city: 'GEORGE', - state: 'WA', - lat: 47.04389, - lon: -119.64222, - }, - QHMS: { - id: 'QHMS', - city: 'Hanford', - state: 'WA', - lat: 46.56667, - lon: -119.6, - }, - OMAW: { - id: 'OMAW', - city: 'OMAK', - state: 'WA', - lat: 48.4025, - lon: -119.57611, - }, - HRHW: { - id: 'HRHW', - city: 'HARRA', - state: 'WA', - lat: 46.38472, - lon: -120.57444, - }, - GOLW: { - id: 'GOLW', - city: 'GOLDENDALE', - state: 'WA', - lat: 45.81194, - lon: -120.82444, - }, - HHMS: { - id: 'HHMS', - city: 'Hanford', - state: 'WA', - lat: 46.563, - lon: -119.599, - }, - HPFP: { - id: 'HPFP', - city: 'Hanford 200 West Area #2', - state: 'WA', - lat: 46.545, - lon: -119.633, - }, - GCDW: { - id: 'GCDW', - city: 'Grand Coulee Dam', - state: 'WA', - lat: 47.9452799, - lon: -118.95361, - }, - SILW: { - id: 'SILW', - city: 'Silcott Island', - state: 'WA', - lat: 46.41861, - lon: -117.18472, - }, - KFLW: { - id: 'KFLW', - city: 'Kettle Falls', - state: 'WA', - lat: 48.595, - lon: -118.12417, - }, - CJDW: { - id: 'CJDW', - city: 'Chief Joseph Dam', - state: 'WA', - lat: 47.99083, - lon: -119.63556, - }, - BNDW: { - id: 'BNDW', - city: 'Bonneville Dam', - state: 'WA', - lat: 45.64778, - lon: -121.93111, - }, - LBRW: { - id: 'LBRW', - city: 'Lake Bryan - Rice Bar', - state: 'WA', - lat: 46.6975, - lon: -117.65417, - }, - SBMW: { - id: 'SBMW', - city: 'Seven Bays Marina', - state: 'WA', - lat: 47.85528, - lon: -118.34111, - }, - RCLE: { - id: 'RCLE', - city: 'Cle Elum Reservoir', - state: 'WA', - lat: 47.2456, - lon: -121.0733, - }, - RBUM: { - id: 'RBUM', - city: 'Bumping Reservoir', - state: 'WA', - lat: 46.8686, - lon: -121.2989, - }, - RKEE: { - id: 'RKEE', - city: 'Keechelus Reservoir', - state: 'WA', - lat: 47.3222, - lon: -121.3389, - }, - RRIM: { - id: 'RRIM', - city: 'Rimrock Reservoir', - state: 'WA', - lat: 46.6528, - lon: -121.125, - }, - CHAW: { - id: 'CHAW', - city: 'Chamokane, WA', - state: 'WA', - lat: 48.03132, - lon: -117.73922, - }, - RKAC: { - id: 'RKAC', - city: 'Kachess Reservoir', - state: 'WA', - lat: 47.2647, - lon: -121.2044, - }, - YGVW: { - id: 'YGVW', - city: 'YAKIMA RIVER AT EUCLID RD. BR. NEAR GRANDVIEW,WA.', - state: 'WA', - lat: 46.2172222, - lon: -119.9169444, - }, - DRYW: { - id: 'DRYW', - city: 'Dry Falls Dam Weather Station at Coulee City, WA', - state: 'WA', - lat: 47.6141666, - lon: -119.2991666, - }, - RBDW: { - id: 'RBDW', - city: 'YAKIMA RIVER BELOW ROZA DAM', - state: 'WA', - lat: 46.75, - lon: -120.4666666, - }, - TIEW: { - id: 'TIEW', - city: 'TIETON CANAL', - state: 'WA', - lat: 46.6694444, - lon: -121.0055555, - }, - TNAW: { - id: 'TNAW', - city: 'TEANAWAY RIVER AT FORKS NEAR CLE ELUM, WA', - state: 'WA', - lat: 47.2463888, - lon: -120.8611111, - }, - NSCW: { - id: 'NSCW', - city: 'NACHES SELAH CANAL', - state: 'WA', - lat: 46.7466666, - lon: -120.7688888, - }, - YRWW: { - id: 'YRWW', - city: 'YAKIMA RIVER NEAR HORLICK ,WA.', - state: 'WA', - lat: 47.1241666, - lon: -120.7391666, - }, - CSPW: { - id: 'CSPW', - city: 'CASH PRAIRIE', - state: 'WA', - lat: 46.7138888, - lon: -121.1505555, - }, - YRPW: { - id: 'YRPW', - city: 'YAKIMA RIVER NEAR PROSSER ,WA.', - state: 'WA', - lat: 46.2175, - lon: -119.7463888, - }, - LNRW: { - id: 'LNRW', - city: 'LITTLE NACHES RIVER NEAR NILE, WA', - state: 'WA', - lat: 46.9875, - lon: -121.0986111, - }, - YRCW: { - id: 'YRCW', - city: 'YAKIMA RIVER AT CRYSTAL SPRINGS', - state: 'WA', - lat: 47.3086111, - lon: -121.3141666, - }, - RSCW: { - id: 'RSCW', - city: 'NEW RESERVATION CANAL', - state: 'WA', - lat: 46.5194444, - lon: -120.4777777, - }, - FDRW: { - id: 'FDRW', - city: 'Grand Coulee Dam Forebay Water Quality', - state: 'WA', - lat: 47.9563888, - lon: -118.9769444, - }, - CIBW: { - id: 'CIBW', - city: 'Columbia River at International Boundary', - state: 'WA', - lat: 48.9713888, - lon: -117.6469444, - }, - ACFS: { - id: 'ACFS', - city: 'Chandler Fish Screen Weather Station', - state: 'WA', - lat: 46.2166666, - lon: -119.7577777, - }, - GCGW: { - id: 'GCGW', - city: 'Columbia River below Grand Coulee Dam near Barry, WA', - state: 'WA', - lat: 48.0333333, - lon: -118.9766666, - }, - DEPW: { - id: 'DEPW', - city: 'DEEP CREEK BELOW COPPER CREEK', - state: 'WA', - lat: 46.8325, - lon: -121.3177777, - }, - SWLW: { - id: 'SWLW', - city: 'SWAMP LAKE CR. NR CRYSTAL SPRINGS CAMPGROUND', - state: 'WA', - lat: 47.3066666, - lon: -121.3094444, - }, - TEAW: { - id: 'TEAW', - city: 'TEANAWAY RIVER BELOW LAMBERT ROAD', - state: 'WA', - lat: 47.19, - lon: -120.8222222, - }, - NRYW: { - id: 'NRYW', - city: 'NACHES RIVER NEAR YAKIMA, WA', - state: 'WA', - lat: 46.6283333, - lon: -120.5194444, - }, - SOUW: { - id: 'SOUW', - city: 'SOUTH NACHES CHANNEL COMPANY CANAL', - state: 'WA', - lat: 46.7330555, - lon: -120.7163888, - }, - YUMW: { - id: 'YUMW', - city: 'YAKIMA RIVER AT CLE ELUM , WA.', - state: 'WA', - lat: 47.1919444, - lon: -120.9455555, - }, - ROZW: { - id: 'ROZW', - city: 'ROZA CANAL AT 11.0 MILE', - state: 'WA', - lat: 46.6166666, - lon: -120.4833333, - }, - SUCW: { - id: 'SUCW', - city: 'SULPHUR CREEK AT HOLIDAY ROAD NEAR SUNNYSIDE', - state: 'WA', - lat: 46.2511111, - lon: -120.02, - }, - SNCW: { - id: 'SNCW', - city: 'SUNNYSIDE CANAL', - state: 'WA', - lat: 46.4944444, - lon: -120.4277777, - }, - ELNW: { - id: 'ELNW', - city: 'YAKIMA RIVER NEAR ELLENSBURG ,WA.', - state: 'WA', - lat: 47, - lon: -120.6, - }, - BICW: { - id: 'BICW', - city: 'Moxee Drain at Birchfield Road', - state: 'WA', - lat: 46.5461111, - lon: -120.4369444, - }, - UMTW: { - id: 'UMTW', - city: 'YAKIMA RIVER NEAR UMTANUM ,WA.', - state: 'WA', - lat: 46.8636111, - lon: -120.4794444, - }, - PARW: { - id: 'PARW', - city: 'YAKIMA RIVER NEAR PARKER, WA.', - state: 'WA', - lat: 46.5061111, - lon: -120.4519444, - }, - WONW: { - id: 'WONW', - city: 'WILSON CREEK (THRALL RD.,KITTITAS VAL)', - state: 'WA', - lat: 46.9261111, - lon: -120.5011111, - }, - KNCW: { - id: 'KNCW', - city: 'KENNEWICK CANAL', - state: 'WA', - lat: 46.2652777, - lon: -119.5694444, - }, - KTCW: { - id: 'KTCW', - city: 'KITTITAS CANAL', - state: 'WA', - lat: 47.2388888, - lon: -121.1833333, - }, - CLYW: { - id: 'CLYW', - city: 'CLEAR LAKE OUTFLOW (N FORK TIETON R. BLW CLEAR LAKE)', - state: 'WA', - lat: 46.6308333, - lon: -121.2677777, - }, - QSPW: { - id: 'QSPW', - city: 'QUARTZ MTN', - state: 'WA', - lat: 47.0672222, - lon: -121.0788888, - }, - CLFW: { - id: 'CLFW', - city: 'NACHES RIVER NEAR CLIFFDELL ,WA.', - state: 'WA', - lat: 46.9005555, - lon: -120.0180555, - }, - TICW: { - id: 'TICW', - city: 'TIETON RIVER NEAR TIETON CANAL HEADWORKS', - state: 'WA', - lat: 46.6711111, - lon: -121, - }, - CHCW: { - id: 'CHCW', - city: 'CHANDLER - PROSSER POWER CANAL', - state: 'WA', - lat: 46.2327777, - lon: -119.6744444, - }, - CHRW: { - id: 'CHRW', - city: 'CHERRY CREEK (THRALL RD.,KITTITAS VAL)', - state: 'WA', - lat: 46.9258333, - lon: -120.5002777, - }, - AUGW: { - id: 'AUGW', - city: 'Ahtanum Creek at Union Gap', - state: 'WA', - lat: 46.5352777, - lon: -120.4716666, - }, - CPPW: { - id: 'CPPW', - city: 'COOPER PASS', - state: 'WA', - lat: 47.4297222, - lon: -121.2108333, - }, - EASW: { - id: 'EASW', - city: 'YAKIMA RIVER AT EASTON WA.', - state: 'WA', - lat: 47.2388888, - lon: -121.1777777, - }, - NACW: { - id: 'NACW', - city: 'NACHES RIVER NEAR NACHES,WA.', - state: 'WA', - lat: 46.7455555, - lon: -120.7680555, - }, - ETCW: { - id: 'ETCW', - city: 'Ellensburg Town Canal', - state: 'WA', - lat: 47.3383333, - lon: -120.5963888, - }, - YRTW: { - id: 'YRTW', - city: 'YAKIMA RIVER AT TERRACE HEIGHTS BRIDGE', - state: 'WA', - lat: 46.6058333, - lon: -120.4741666, - }, - RFSW: { - id: 'RFSW', - city: 'Roza Fish Screen Weather Station', - state: 'WA', - lat: 46.7494444, - lon: -120.4666666, - }, - WOPW: { - id: 'WOPW', - city: 'WAPATOX POWER CANAL', - state: 'WA', - lat: 46.7488888, - lon: -120.7786111, - }, - WESW: { - id: 'WESW', - city: 'WESTSIDE CANAL', - state: 'WA', - lat: 47.0863888, - lon: -120.6938888, - }, - RZCW: { - id: 'RZCW', - city: 'ROZA CANAL AT HEADWORKS', - state: 'WA', - lat: 46.75, - lon: -120.4666666, - }, - KSEA: { - id: 'KSEA', - city: 'Seattle, Seattle-Tacoma International Airport', - state: 'WA', - lat: 47.4447199, - lon: -122.31361, - }, - KBFI: { - id: 'KBFI', - city: 'Seattle, Seattle Boeing Field', - state: 'WA', - lat: 47.54583, - lon: -122.31361, - }, - KGEG: { - id: 'KGEG', - city: 'Spokane, Spokane International Airport', - state: 'WA', - lat: 47.62139, - lon: -117.52778, - }, - KUIL: { - id: 'KUIL', - city: 'Quillayute, Quillayute State Airport', - state: 'WA', - lat: 47.9375, - lon: -124.555, - }, - KDLS: { - id: 'KDLS', - city: 'The Dalles Municipal Airport', - state: 'WA', - lat: 45.61901, - lon: -121.16572, - }, - KSMP: { - id: 'KSMP', - city: 'Stampede Pass', - state: 'WA', - lat: 47.27648, - lon: -121.33817, - }, - KYKM: { - id: 'KYKM', - city: 'Yakima, Yakima Air Terminal', - state: 'WA', - lat: 46.56417, - lon: -120.53361, - }, - KHQM: { - id: 'KHQM', - city: 'Hoquiam, Bowerman Airport', - state: 'WA', - lat: 46.97111, - lon: -123.92, - }, - KALW: { - id: 'KALW', - city: 'Walla Walla Regional Airport', - state: 'WA', - lat: 46.09462, - lon: -118.2858, - }, - KMWH: { - id: 'KMWH', - city: 'Grant County Airport', - state: 'WA', - lat: 47.19299, - lon: -119.31451, - }, - KBLI: { - id: 'KBLI', - city: 'Bellingham, Bellingham International Airport', - state: 'WA', - lat: 48.79911, - lon: -122.54064, - }, - KNUW: { - id: 'KNUW', - city: 'Whidbey Island, Naval Air Station', - state: 'WA', - lat: 48.34917, - lon: -122.65056, - }, - KOLM: { - id: 'KOLM', - city: 'Olympia, Olympia Airport', - state: 'WA', - lat: 46.97333, - lon: -122.90333, - }, - KEPH: { - id: 'KEPH', - city: 'Ephrata, Ephrata Municipal Airport', - state: 'WA', - lat: 47.3075, - lon: -119.51583, - }, - KSFF: { - id: 'KSFF', - city: 'Spokane, Felts Field', - state: 'WA', - lat: 47.68556, - lon: -117.32028, - }, - KEAT: { - id: 'KEAT', - city: 'Wenatchee, Pangborn Memorial Airport', - state: 'WA', - lat: 47.39889, - lon: -120.20694, - }, - KCLM: { - id: 'KCLM', - city: 'Port Angeles Fairchild International Airport', - state: 'WA', - lat: 48.12194, - lon: -123.50661, - }, - KPAE: { - id: 'KPAE', - city: 'Everett Snohomish County', - state: 'WA', - lat: 47.92331, - lon: -122.28305, - }, - KPSC: { - id: 'KPSC', - city: 'Pasco, Tri-Cities Airport', - state: 'WA', - lat: 46.26972, - lon: -119.11667, - }, - KGRF: { - id: 'KGRF', - city: 'Fort Lewis / Gray U. S. Army Airfield', - state: 'WA', - lat: 47.11667, - lon: -122.55, - }, - KTCM: { - id: 'KTCM', - city: 'Tacoma / McChord Air Force Base', - state: 'WA', - lat: 47.15, - lon: -122.48333, - }, - KSKA: { - id: 'KSKA', - city: 'Fairchild Air Force Base', - state: 'WA', - lat: 47.61667, - lon: -117.65, - }, - KAWO: { - id: 'KAWO', - city: 'Arlington Municipal', - state: 'WA', - lat: 48.16667, - lon: -122.16667, - }, - KRNT: { - id: 'KRNT', - city: 'Renton, Renton Municipal Airport', - state: 'WA', - lat: 47.49444, - lon: -122.21278, - }, - KKLS: { - id: 'KKLS', - city: 'Kelso, Kelso-Longview Airport', - state: 'WA', - lat: 46.11667, - lon: -122.9, - }, - KPUW: { - id: 'KPUW', - city: 'Pullman / Moscow Regional Airport', - state: 'WA', - lat: 46.74377, - lon: -117.11579, - }, - KTIW: { - id: 'KTIW', - city: 'Tacoma, Tacoma Narrows Airport', - state: 'WA', - lat: 47.2675, - lon: -122.57611, - }, - KELN: { - id: 'KELN', - city: 'Ellensburg, Ellensburg Bowers Field', - state: 'WA', - lat: 47.0337699, - lon: -120.53132, - }, - KSHN: { - id: 'KSHN', - city: 'Shelton, Shelton Sanderson Field', - state: 'WA', - lat: 47.23806, - lon: -123.14083, - }, - KPWT: { - id: 'KPWT', - city: 'Bremerton, Bremerton National Airport', - state: 'WA', - lat: 47.5, - lon: -122.75, - }, - KDEW: { - id: 'KDEW', - city: 'Deer Park, Deer Park Airport', - state: 'WA', - lat: 47.97417, - lon: -117.42833, - }, - KFHR: { - id: 'KFHR', - city: 'Friday Harbor, Friday Harbor Airport', - state: 'WA', - lat: 48.52028, - lon: -123.02528, - }, - KOMK: { - id: 'KOMK', - city: 'Omak, Omak Airport', - state: 'WA', - lat: 48.46417, - lon: -119.51806, - }, - KORS: { - id: 'KORS', - city: 'Eastsound, Orcas Island Airport', - state: 'WA', - lat: 48.70806, - lon: -122.91028, - }, - KBVS: { - id: 'KBVS', - city: 'Burlington/Mount Vernon, Skagit Regional Airport', - state: 'WA', - lat: 48.47083, - lon: -122.42083, - }, - KRLD: { - id: 'KRLD', - city: 'Richland Airport', - state: 'WA', - lat: 46.30859, - lon: -119.3058, - }, - KVUO: { - id: 'KVUO', - city: 'Pearson Airfield', - state: 'WA', - lat: 45.62103, - lon: -122.65419, - }, - KNOW: { - id: 'KNOW', - city: 'Port Angeles Coast Guard Air Station', - state: 'WA', - lat: 48.13333, - lon: -123.4, - }, - KCLS: { - id: 'KCLS', - city: 'Chehalis-Centralia Airport', - state: 'WA', - lat: 46.677, - lon: -122.9827, - }, - KPLU: { - id: 'KPLU', - city: 'Pierce County-Thun Field', - state: 'WA', - lat: 47.104, - lon: -122.287, - }, - KOTX: { - id: 'KOTX', - city: 'Spokane NWS', - state: 'WA', - lat: 47.6811999, - lon: -117.6268, - }, - KANP: { - id: 'KANP', - city: 'LEE AIRPORT', - state: 'MD', - lat: 38.94287, - lon: -76.5683899, - }, - KVKX: { - id: 'KVKX', - city: 'POTOMAC', - state: 'MD', - lat: 38.74761, - lon: -76.95719, - }, - KEDG: { - id: 'KEDG', - city: 'WEIDE', - state: 'MD', - lat: 39.39205, - lon: -76.29106, - }, - KBWI: { - id: 'KBWI', - city: 'Baltimore, Baltimore-Washington International Airport', - state: 'MD', - lat: 39.17329, - lon: -76.68404, - }, - KSBY: { - id: 'KSBY', - city: 'Salisbury, Salisbury-Ocean City Wicomico County Regional Airport', - state: 'MD', - lat: 38.34056, - lon: -75.51028, - }, - KMTN: { - id: 'KMTN', - city: 'Baltimore / Martin', - state: 'MD', - lat: 39.3333299, - lon: -76.41667, - }, - KADW: { - id: 'KADW', - city: 'Camp Springs / Andrews Air Force Base', - state: 'MD', - lat: 38.81667, - lon: -76.85, - }, - KNHK: { - id: 'KNHK', - city: 'Patuxent River, Naval Air Station', - state: 'MD', - lat: 38.27861, - lon: -76.41389, - }, - KFDK: { - id: 'KFDK', - city: 'Frederick Municipal Airport', - state: 'MD', - lat: 39.41775, - lon: -77.36982, - }, - KHGR: { - id: 'KHGR', - city: 'Hagerstown, Washington County Regional Airport', - state: 'MD', - lat: 39.70583, - lon: -77.73, - }, - KDMH: { - id: 'KDMH', - city: 'Baltimore, Inner Harbor', - state: 'MD', - lat: 39.28333, - lon: -76.61667, - }, - KOXB: { - id: 'KOXB', - city: 'Ocean City, Ocean City Municipal Airport', - state: 'MD', - lat: 38.31056, - lon: -75.12389, - }, - KNAK: { - id: 'KNAK', - city: 'Annapolis, United States Naval Academy', - state: 'MD', - lat: 38.99125, - lon: -76.48907, - }, - KFME: { - id: 'KFME', - city: 'Fort Meade / Tipton', - state: 'MD', - lat: 39.0833299, - lon: -76.76667, - }, - KAPG: { - id: 'KAPG', - city: 'Phillips Army Air Field / Aberdeen', - state: 'MD', - lat: 39.46667, - lon: -76.16667, - }, - KESN: { - id: 'KESN', - city: 'Easton / Newman Field', - state: 'MD', - lat: 38.8, - lon: -76.06667, - }, - KNUI: { - id: 'KNUI', - city: 'St. Inigoes, Webster Field, Naval Electronic Systems Engineering Activity', - state: 'MD', - lat: 38.14889, - lon: -76.42, - }, - KRSP: { - id: 'KRSP', - city: 'Camp David', - state: 'MD', - lat: 39.645, - lon: -77.468, - }, - KCGS: { - id: 'KCGS', - city: 'College Park Airport', - state: 'MD', - lat: 38.9806, - lon: -76.9223, - }, - KCGE: { - id: 'KCGE', - city: 'Cambridge-Dorchester Airport', - state: 'MD', - lat: 38.5393, - lon: -76.0304, - }, - KGAI: { - id: 'KGAI', - city: 'Gaithersburg - Montgomery County Airport', - state: 'MD', - lat: 39.16957, - lon: -77.16551, - }, - KDMW: { - id: 'KDMW', - city: 'Carroll County Regional Jack B Poage Field', - state: 'MD', - lat: 39.6083, - lon: -77.0077, - }, - BALM: { - id: 'BALM', - city: 'Balm', - state: 'FL', - lat: 27.76, - lon: -82.223, - }, - LXWS: { - id: 'LXWS', - city: 'LXWS', - state: 'FL', - lat: 26.4989, - lon: -80.2222, - }, - SVWX: { - id: 'SVWX', - city: 'SVWX', - state: 'FL', - lat: 27.2903, - lon: -80.2537, - }, - JDWX: { - id: 'JDWX', - city: 'JDWX', - state: 'FL', - lat: 27.0287, - lon: -80.1653, - }, - FPWX: { - id: 'FPWX', - city: 'FPWX', - state: 'FL', - lat: 26.433, - lon: -81.723, - }, - WRWX: { - id: 'WRWX', - city: 'WRWX', - state: 'FL', - lat: 28.0483, - lon: -81.3994, - }, - KJAX: { - id: 'KJAX', - city: 'Jacksonville, Jacksonville International Airport', - state: 'FL', - lat: 30.49444, - lon: -81.69333, - }, - KMIA: { - id: 'KMIA', - city: 'Miami, Miami International Airport', - state: 'FL', - lat: 25.79056, - lon: -80.31639, - }, - KCRG: { - id: 'KCRG', - city: 'Jacksonville Craig Municipal Airport', - state: 'FL', - lat: 30.33709, - lon: -81.51275, - }, - KOPF: { - id: 'KOPF', - city: 'Miami, Opa Locka Airport', - state: 'FL', - lat: 25.91, - lon: -80.28306, - }, - KEYW: { - id: 'KEYW', - city: 'Key West International Airport', - state: 'FL', - lat: 24.55707, - lon: -81.75539, - }, - KMCO: { - id: 'KMCO', - city: 'Orlando International Airport', - state: 'FL', - lat: 28.41826, - lon: -81.32413, - }, - KDAB: { - id: 'KDAB', - city: 'Daytona Beach International Airport', - state: 'FL', - lat: 29.17354, - lon: -81.07186, - }, - KTPA: { - id: 'KTPA', - city: 'Tampa, Tampa International Airport', - state: 'FL', - lat: 27.96139, - lon: -82.54028, - }, - KTLH: { - id: 'KTLH', - city: 'Tallahassee - Tallahassee International Airport', - state: 'FL', - lat: 30.39306, - lon: -84.35333, - }, - KPBI: { - id: 'KPBI', - city: 'West Palm Beach - Palm Beach International Airport', - state: 'FL', - lat: 26.6850999, - lon: -80.0991899, - }, - KMLB: { - id: 'KMLB', - city: 'Melbourne International Airport', - state: 'FL', - lat: 28.09973, - lon: -80.6356, - }, - KGNV: { - id: 'KGNV', - city: 'Gainesville, Gainesville Regional Airport', - state: 'FL', - lat: 29.69194, - lon: -82.27556, - }, - KVRB: { - id: 'KVRB', - city: 'Vero Beach, Vero Beach Municipal Airport', - state: 'FL', - lat: 27.65556, - lon: -80.41806, - }, - KAPF: { - id: 'KAPF', - city: 'Naples, Naples Municipal Airport', - state: 'FL', - lat: 26.15, - lon: -81.76667, - }, - KCTY: { - id: 'KCTY', - city: 'Cross City Airport', - state: 'FL', - lat: 29.633326, - lon: -83.105458, - }, - KCEW: { - id: 'KCEW', - city: 'Crestview, Sikes Airport', - state: 'FL', - lat: 30.77222, - lon: -86.52, - }, - KHRT: { - id: 'KHRT', - city: 'Hurlburt Field', - state: 'FL', - lat: 30.41667, - lon: -86.68333, - }, - KMCF: { - id: 'KMCF', - city: 'Macdill Air Force Base, Fl.', - state: 'FL', - lat: 27.85, - lon: -82.5, - }, - KFLL: { - id: 'KFLL', - city: 'Fort Lauderdale, Fort Lauderdale / Hollywood International Airport', - state: 'FL', - lat: 26.06806, - lon: -80.1525, - }, - KCOF: { - id: 'KCOF', - city: 'Cocoa - Patrick Air Force Base', - state: 'FL', - lat: 28.24219, - lon: -80.60799, - }, - KHST: { - id: 'KHST', - city: 'Homestead Air Force Base', - state: 'FL', - lat: 25.48333, - lon: -80.38333, - }, - KFMY: { - id: 'KFMY', - city: 'Fort Myers, Page Field', - state: 'FL', - lat: 26.58417, - lon: -81.8625, - }, - KSRQ: { - id: 'KSRQ', - city: 'Sarasota / Bradenton, Sarasota-Bradenton International Airport', - state: 'FL', - lat: 27.40139, - lon: -82.55861, - }, - KORL: { - id: 'KORL', - city: 'Orlando Executive Airport', - state: 'FL', - lat: 28.54655, - lon: -81.33543, - }, - KPAM: { - id: 'KPAM', - city: 'Tyndall Air Force Base', - state: 'FL', - lat: 30.06667, - lon: -85.58333, - }, - KSFB: { - id: 'KSFB', - city: 'Orlando / Sanford Airport', - state: 'FL', - lat: 28.78333, - lon: -81.25, - }, - KNRB: { - id: 'KNRB', - city: 'Mayport, Mayport Naval Station, Adm David L. McDonald Field', - state: 'FL', - lat: 30.39583, - lon: -81.4225, - }, - KNPA: { - id: 'KNPA', - city: 'Pensacola Naval Air Station', - state: 'FL', - lat: 30.35641, - lon: -87.32326, - }, - KNQX: { - id: 'KNQX', - city: 'Key West Naval Air Station', - state: 'FL', - lat: 24.5800899, - lon: -81.68293, - }, - KRSW: { - id: 'KRSW', - city: 'Fort Myers, Southwest Florida International Airport', - state: 'FL', - lat: 26.52694, - lon: -81.76639, - }, - KNIP: { - id: 'KNIP', - city: 'Jacksonville Naval Air Station', - state: 'FL', - lat: 30.23468, - lon: -81.67462, - }, - KVPS: { - id: 'KVPS', - city: 'Valparaiso / Eglin Air Force Base', - state: 'FL', - lat: 30.48333, - lon: -86.51667, - }, - KPIE: { - id: 'KPIE', - city: 'St. Petersburg/Clearwater Airport', - state: 'FL', - lat: 27.91259, - lon: -82.68554, - }, - KPNS: { - id: 'KPNS', - city: 'Pensacola - Pensacola International Airport', - state: 'FL', - lat: 30.47806, - lon: -87.18694, - }, - KECP: { - id: 'KECP', - city: 'Panama City - Northwest Florida Beaches International Airport', - state: 'FL', - lat: 30.3582, - lon: -85.7955999, - }, - KBOW: { - id: 'KBOW', - city: 'Bartow Municipal', - state: 'FL', - lat: 27.95, - lon: -81.78333, - }, - KBCT: { - id: 'KBCT', - city: 'Boca Raton, Boca Raton Airport', - state: 'FL', - lat: 26.3786099, - lon: -80.10778, - }, - KBKV: { - id: 'KBKV', - city: 'Brooksville, Hernando County Airport', - state: 'FL', - lat: 28.47361, - lon: -82.45444, - }, - KAAF: { - id: 'KAAF', - city: 'Apalachicola, Apalachicola', - state: 'FL', - lat: 29.72694, - lon: -85.02472, - }, - KHWO: { - id: 'KHWO', - city: 'Hollywood, North Perry Airport', - state: 'FL', - lat: 25.99889, - lon: -80.24111, - }, - KMTH: { - id: 'KMTH', - city: 'Marathon, Marathon Airport', - state: 'FL', - lat: 24.7258299, - lon: -81.04778, - }, - KMAI: { - id: 'KMAI', - city: 'Marianna, Marianna Municipal Airport', - state: 'FL', - lat: 30.83667, - lon: -85.18361, - }, - KEGI: { - id: 'KEGI', - city: 'Duke Field / Eglin Auxiliary', - state: 'FL', - lat: 30.65, - lon: -86.51667, - }, - KISM: { - id: 'KISM', - city: 'Orlando, Kissimmee Municipal Airport', - state: 'FL', - lat: 28.28972, - lon: -81.43722, - }, - KFPR: { - id: 'KFPR', - city: 'Fort Pierce, St. Lucie County International Airport', - state: 'FL', - lat: 27.49806, - lon: -80.37667, - }, - KLAL: { - id: 'KLAL', - city: 'Lakeland Regional', - state: 'FL', - lat: 27.98333, - lon: -82.01667, - }, - KFXE: { - id: 'KFXE', - city: 'Fort Lauderdale, Fort Lauderdale Executive Airport', - state: 'FL', - lat: 26.2, - lon: -80.18333, - }, - KDTS: { - id: 'KDTS', - city: 'Destin, Destin-Ft. Walton Beach Airport', - state: 'FL', - lat: 30.39333, - lon: -86.4675, - }, - KLEE: { - id: 'KLEE', - city: 'Leesburg Regional Airport', - state: 'FL', - lat: 28.82142, - lon: -81.80964, - }, - KGIF: { - id: 'KGIF', - city: 'Winter Havens Gilbert Airport', - state: 'FL', - lat: 28.06138, - lon: -81.75684, - }, - KVDF: { - id: 'KVDF', - city: 'Tampa, Vandenberg Airport', - state: 'FL', - lat: 28.01983, - lon: -82.3415, - }, - KSUA: { - id: 'KSUA', - city: 'Stuart, Witham Field Airport', - state: 'FL', - lat: 27.18167, - lon: -80.22111, - }, - KPMP: { - id: 'KPMP', - city: 'Pompano Beach, Pompano Beach Airpark', - state: 'FL', - lat: 26.24556, - lon: -80.11139, - }, - KPGD: { - id: 'KPGD', - city: 'Punta Gorda, Charlotte County Airport', - state: 'FL', - lat: 26.91778, - lon: -81.99361, - }, - KVVG: { - id: 'KVVG', - city: 'The Villages', - state: 'FL', - lat: 28.96667, - lon: -81.9666699, - }, - KNSE: { - id: 'KNSE', - city: 'Milton - Whiting Field Naval Air Station North', - state: 'FL', - lat: 30.72848, - lon: -87.02192, - }, - KVQQ: { - id: 'KVQQ', - city: 'Jacksonville, Cecil Field Airport', - state: 'FL', - lat: 30.21861, - lon: -81.87667, - }, - KTTS: { - id: 'KTTS', - city: 'Titusville, NASA Shuttle Landing Facility', - state: 'FL', - lat: 28.61667, - lon: -80.7, - }, - KSGJ: { - id: 'KSGJ', - city: 'St. Augustine, St. Augustine Airport', - state: 'FL', - lat: 29.95917, - lon: -81.33972, - }, - KTMB: { - id: 'KTMB', - city: 'Miami, Kendall-Tamiami Executive Airport', - state: 'FL', - lat: 25.64194, - lon: -80.43472, - }, - KTIX: { - id: 'KTIX', - city: 'Titusville', - state: 'FL', - lat: 28.51667, - lon: -80.8, - }, - KOCF: { - id: 'KOCF', - city: 'Ocala, Ocala International Airport-Jim Taylor Field', - state: 'FL', - lat: 29.16667, - lon: -82.2166699, - }, - KSPG: { - id: 'KSPG', - city: 'St. Petersburg Whitted Airport', - state: 'FL', - lat: 27.7676, - lon: -82.62633, - }, - KPCM: { - id: 'KPCM', - city: 'Plant City, Plant City Municipal Airport', - state: 'FL', - lat: 28, - lon: -82.15, - }, - KTDR: { - id: 'KTDR', - city: 'Tyndall Drone Runway', - state: 'FL', - lat: 30.0333, - lon: -85.5333, - }, - KFHB: { - id: 'KFHB', - city: 'Fernandina Beach Municipal Airport', - state: 'FL', - lat: 30.61183, - lon: -81.46119, - }, - KDED: { - id: 'KDED', - city: 'DeLand Municipal Airport', - state: 'FL', - lat: 29.067, - lon: -81.2837, - }, - KZPH: { - id: 'KZPH', - city: 'Zephyrhills Airport', - state: 'FL', - lat: 28.2281, - lon: -82.1559, - }, - KLCQ: { - id: 'KLCQ', - city: 'Lake City Municipal Airport', - state: 'FL', - lat: 30.1821, - lon: -82.5769, - }, - KCLW: { - id: 'KCLW', - city: 'Clearwater Air Park', - state: 'FL', - lat: 27.9742, - lon: -82.7563, - }, - KXMR: { - id: 'KXMR', - city: 'Cocoa Beach, Cape Canaveral Air Force Station Skid Strip', - state: 'FL', - lat: 28.46667, - lon: -80.56667, - }, - KTPF: { - id: 'KTPF', - city: 'Tampa, Peter O Knight Airport', - state: 'FL', - lat: 27.91556, - lon: -82.44917, - }, - KNDZ: { - id: 'KNDZ', - city: 'Milton, Whiting Field South', - state: 'FL', - lat: 30.69722, - lon: -87.02, - }, - KEVB: { - id: 'KEVB', - city: 'New Smyrna Beach Municipal Airport', - state: 'FL', - lat: 29.05687, - lon: -80.94909, - }, - KOMN: { - id: 'KOMN', - city: 'Ormond Beach, Ormond Beach Municipal Airport', - state: 'FL', - lat: 29.30111, - lon: -81.11361, - }, - KOBE: { - id: 'KOBE', - city: 'Okeechobee County Airport', - state: 'FL', - lat: 27.2628, - lon: -80.8498, - }, - KINF: { - id: 'KINF', - city: 'Inverness Airport', - state: 'FL', - lat: 28.8086, - lon: -82.3165, - }, - KCGC: { - id: 'KCGC', - city: 'Crystal River Airport', - state: 'FL', - lat: 28.8673, - lon: -82.5712999, - }, - KVNC: { - id: 'KVNC', - city: 'Venice Municipal Airport', - state: 'FL', - lat: 27.0716, - lon: -82.44033, - }, - KFIN: { - id: 'KFIN', - city: 'Flagler County Airport', - state: 'FL', - lat: 29.4657, - lon: -81.20872, - }, - KMKY: { - id: 'KMKY', - city: 'Marco Island Airport', - state: 'FL', - lat: 25.995, - lon: -81.6725, - }, - KBXM: { - id: 'KBXM', - city: 'BRUNSWICK', - state: 'ME', - lat: 43.8923599, - lon: -69.93883, - }, - KCAR: { - id: 'KCAR', - city: 'Caribou, Caribou Municipal Airport', - state: 'ME', - lat: 46.86722, - lon: -68.01333, - }, - KHUL: { - id: 'KHUL', - city: 'Houlton, Houlton International Airport', - state: 'ME', - lat: 46.12306, - lon: -67.79194, - }, - KBGR: { - id: 'KBGR', - city: 'Bangor, Bangor International Airport', - state: 'ME', - lat: 44.79722, - lon: -68.81861, - }, - KPWM: { - id: 'KPWM', - city: 'Portland, Portland International Jetport', - state: 'ME', - lat: 43.64222, - lon: -70.30444, - }, - KAUG: { - id: 'KAUG', - city: 'Augusta, Augusta State Airport', - state: 'ME', - lat: 44.32056, - lon: -69.79722, - }, - KMLT: { - id: 'KMLT', - city: 'Millinocket, Millinocket Municipal Airport', - state: 'ME', - lat: 45.64778, - lon: -68.69194, - }, - KPQI: { - id: 'KPQI', - city: 'Presque Isle', - state: 'ME', - lat: 46.68333, - lon: -68.05, - }, - KGNR: { - id: 'KGNR', - city: 'Greenville', - state: 'ME', - lat: 45.4646199, - lon: -69.5538, - }, - KFVE: { - id: 'KFVE', - city: 'Frenchville, Northern Aroostook Regional Airport', - state: 'ME', - lat: 47.2849999, - lon: -68.30722, - }, - KBHB: { - id: 'KBHB', - city: 'Bar Harbor, Hancock County-Bar Harbor Airport', - state: 'ME', - lat: 44.45, - lon: -68.36667, - }, - KIWI: { - id: 'KIWI', - city: 'Wiscasset Airport', - state: 'ME', - lat: 43.96401, - lon: -69.7107599, - }, - KIZG: { - id: 'KIZG', - city: 'Fryeburg, Eastern Slopes Regional Airport', - state: 'ME', - lat: 43.98917, - lon: -70.95028, - }, - KLEW: { - id: 'KLEW', - city: 'Auburn-Lewiston', - state: 'ME', - lat: 44.05, - lon: -70.28333, - }, - KRKD: { - id: 'KRKD', - city: 'Rockland, Knox County Regional Airport', - state: 'ME', - lat: 44.06667, - lon: -69.1, - }, - KSFM: { - id: 'KSFM', - city: 'Sanford, Sanford Regional Airport', - state: 'ME', - lat: 43.4, - lon: -70.7166699, - }, - KWVL: { - id: 'KWVL', - city: 'Waterville, Waterville Robert LaFleur Airport', - state: 'ME', - lat: 44.53333, - lon: -69.68333, - }, - KABY: { - id: 'KABY', - city: 'Albany', - state: 'GA', - lat: 31.5333, - lon: -84.2, - }, - KACJ: { - id: 'KACJ', - city: 'Americus', - state: 'GA', - lat: 32.1166, - lon: -84.1833, - }, - KPZD: { - id: 'KPZD', - city: 'Pecan (Albany)', - state: 'GA', - lat: 31.65, - lon: -84.3, - }, - KAMG: { - id: 'KAMG', - city: 'Alma', - state: 'GA', - lat: 31.5333, - lon: -82.5, - }, - KAHN: { - id: 'KAHN', - city: 'Athens', - state: 'GA', - lat: 33.95, - lon: -83.3333, - }, - KATL: { - id: 'KATL', - city: 'Atlanta', - state: 'GA', - lat: 33.6333, - lon: -84.45, - }, - KFTY: { - id: 'KFTY', - city: 'Atlanta/Fulton', - state: 'GA', - lat: 33.7833, - lon: -84.5166, - }, - KPUJ: { - id: 'KPUJ', - city: 'Atlanta/Paulding', - state: 'GA', - lat: 33.9166, - lon: -84.9333, - }, - KATR: { - id: 'KATR', - city: 'Atlanta/Rfc', - state: 'GA', - lat: 33.3666, - lon: -84.5666, - }, - KZTL: { - id: 'KZTL', - city: 'Atlanta/Artcc', - state: 'GA', - lat: 33.3833, - lon: -84.3333, - }, - K6A2: { - id: 'K6A2', - city: 'Griffin-Spalding', - state: 'GA', - lat: 33.2333, - lon: -84.2666, - }, - KDNL: { - id: 'KDNL', - city: 'Augusta/Daniel', - state: 'GA', - lat: 33.4666, - lon: -82.0333, - }, - KAGS: { - id: 'KAGS', - city: 'Augusta/Bush', - state: 'GA', - lat: 33.3666, - lon: -81.9666, - }, - KBGE: { - id: 'KBGE', - city: 'Bainbridge', - state: 'GA', - lat: 30.9666, - lon: -84.6333, - }, - KDZJ: { - id: 'KDZJ', - city: 'Blairsville', - state: 'GA', - lat: 34.85, - lon: -84, - }, - KBIJ: { - id: 'KBIJ', - city: 'Blakely Early C', - state: 'GA', - lat: 31.4, - lon: -84.9, - }, - KSSI: { - id: 'KSSI', - city: 'Brunswick', - state: 'GA', - lat: 31.15, - lon: -81.3833, - }, - KBQK: { - id: 'KBQK', - city: 'Brunswick/Glynco', - state: 'GA', - lat: 31.25, - lon: -81.4666, - }, - K6A1: { - id: 'K6A1', - city: 'Butler', - state: 'GA', - lat: 32.5666, - lon: -84.25, - }, - KCNI: { - id: 'KCNI', - city: 'Canton/Cherokee', - state: 'GA', - lat: 34.3166, - lon: -84.4166, - }, - KCTJ: { - id: 'KCTJ', - city: 'Carrollton/Gray', - state: 'GA', - lat: 33.6333, - lon: -85.15, - }, - KVPC: { - id: 'KVPC', - city: 'Cartersville', - state: 'GA', - lat: 34.1333, - lon: -84.85, - }, - KCWV: { - id: 'KCWV', - city: 'Claxton/Evans Co', - state: 'GA', - lat: 32.2, - lon: -81.8666, - }, - KCSG: { - id: 'KCSG', - city: 'Columbus', - state: 'GA', - lat: 32.5166, - lon: -84.95, - }, - KCKF: { - id: 'KCKF', - city: 'Cordele', - state: 'GA', - lat: 31.9833, - lon: -83.7666, - }, - K9A1: { - id: 'K9A1', - city: 'Covington', - state: 'GA', - lat: 33.6333, - lon: -83.85, - }, - KDNN: { - id: 'KDNN', - city: 'Dalton', - state: 'GA', - lat: 34.7166, - lon: -84.8666, - }, - KMGE: { - id: 'KMGE', - city: 'Dobbins Afb/Mari', - state: 'GA', - lat: 33.9166, - lon: -84.5166, - }, - KDQH: { - id: 'KDQH', - city: 'Douglas Muni', - state: 'GA', - lat: 31.4833, - lon: -82.8666, - }, - KDBN: { - id: 'KDBN', - city: 'Dublin', - state: 'GA', - lat: 32.5666, - lon: -82.9833, - }, - KEZM: { - id: 'KEZM', - city: 'Eastman', - state: 'GA', - lat: 32.2166, - lon: -83.1333, - }, - K27A: { - id: 'K27A', - city: 'Elberton Patz F', - state: 'GA', - lat: 34.1, - lon: -82.8166, - }, - KFZG: { - id: 'KFZG', - city: 'Fitzgerald', - state: 'GA', - lat: 31.6833, - lon: -83.2666, - }, - KLSF: { - id: 'KLSF', - city: 'Ft Benning/Colum', - state: 'GA', - lat: 32.3166, - lon: -84.9666, - }, - KLHW: { - id: 'KLHW', - city: 'Ft Stewart/Wrigh', - state: 'GA', - lat: 31.8666, - lon: -81.5666, - }, - KGVL: { - id: 'KGVL', - city: 'Gainesville', - state: 'GA', - lat: 34.2666, - lon: -83.8333, - }, - K3J7: { - id: 'K3J7', - city: 'Greensboro', - state: 'GA', - lat: 33.6, - lon: -83.1333, - }, - KAZE: { - id: 'KAZE', - city: 'Hazelhurst', - state: 'GA', - lat: 31.8833, - lon: -82.65, - }, - KHOE: { - id: 'KHOE', - city: 'Homerville', - state: 'GA', - lat: 31.05, - lon: -82.7833, - }, - K19A: { - id: 'K19A', - city: 'Jefferson', - state: 'GA', - lat: 34.1833, - lon: -83.5666, - }, - KJES: { - id: 'KJES', - city: 'Jesup/Wayne Cty', - state: 'GA', - lat: 31.55, - lon: -81.8833, - }, - KLGC: { - id: 'KLGC', - city: 'La Grange', - state: 'GA', - lat: 33, - lon: -85.0666, - }, - KLZU: { - id: 'KLZU', - city: 'Lawrenceville', - state: 'GA', - lat: 33.9833, - lon: -83.9666, - }, - KMCN: { - id: 'KMCN', - city: 'Macon', - state: 'GA', - lat: 32.6833, - lon: -83.65, - }, - KRYY: { - id: 'KRYY', - city: 'Marietta Mccolum', - state: 'GA', - lat: 34.0166, - lon: -84.6, - }, - KHQU: { - id: 'KHQU', - city: 'Mcduffie/Thomson', - state: 'GA', - lat: 33.5333, - lon: -82.5166, - }, - KMLJ: { - id: 'KMLJ', - city: 'Milledgeville', - state: 'GA', - lat: 33.15, - lon: -83.2333, - }, - KVAD: { - id: 'KVAD', - city: 'Moody Afb/Valdos', - state: 'GA', - lat: 30.9666, - lon: -83.2, - }, - KVAX: { - id: 'KVAX', - city: 'Moody Afb/88D', - state: 'GA', - lat: 30.8833, - lon: -83, - }, - KMGR: { - id: 'KMGR', - city: 'Moultrie Muni', - state: 'GA', - lat: 31.0833, - lon: -83.8, - }, - KMUL: { - id: 'KMUL', - city: 'Moultrie/Spence', - state: 'GA', - lat: 31.1333, - lon: -83.7, - }, - KCCO: { - id: 'KCCO', - city: 'Newnan', - state: 'GA', - lat: 33.3166, - lon: -84.7666, - }, - KPDK: { - id: 'KPDK', - city: 'Peachtree/Dekalb', - state: 'GA', - lat: 33.8833, - lon: -84.3, - }, - KFFC: { - id: 'KFFC', - city: 'Peachtree City', - state: 'GA', - lat: 33.35, - lon: -84.5666, - }, - KALR: { - id: 'KALR', - city: 'Atlanta Rfc', - state: 'GA', - lat: 33.3666, - lon: -84.5666, - }, - KJGX: { - id: 'KJGX', - city: 'Robins Afb/88D', - state: 'GA', - lat: 32.6833, - lon: -83.35, - }, - KRMG: { - id: 'KRMG', - city: 'Rome', - state: 'GA', - lat: 34.35, - lon: -85.1666, - }, - KSAV: { - id: 'KSAV', - city: 'Savannah', - state: 'GA', - lat: 32.1166, - lon: -81.2, - }, - KSVN: { - id: 'KSVN', - city: 'Savannah/Hunter', - state: 'GA', - lat: 32.0166, - lon: -81.15, - }, - KTBR: { - id: 'KTBR', - city: 'Statesboro', - state: 'GA', - lat: 32.4833, - lon: -81.7333, - }, - KSBO: { - id: 'KSBO', - city: 'Swainsboro', - state: 'GA', - lat: 32.6166, - lon: -82.3666, - }, - KJYL: { - id: 'KJYL', - city: 'Sylvania', - state: 'GA', - lat: 32.65, - lon: -81.6, - }, - KTMA: { - id: 'KTMA', - city: 'Tifton', - state: 'GA', - lat: 31.4333, - lon: -83.4833, - }, - KOPN: { - id: 'KOPN', - city: 'Thomaston Upson', - state: 'GA', - lat: 32.95, - lon: -84.2666, - }, - KTVI: { - id: 'KTVI', - city: 'Thomasville', - state: 'GA', - lat: 30.9, - lon: -83.8833, - }, - KTOC: { - id: 'KTOC', - city: 'Toccoa', - state: 'GA', - lat: 34.6, - lon: -83.3, - }, - KODF: { - id: 'KODF', - city: 'Toccoa Vor', - state: 'GA', - lat: 34.7, - lon: -83.3, - }, - KVLD: { - id: 'KVLD', - city: 'Valdosta Regiona', - state: 'GA', - lat: 30.7833, - lon: -83.2666, - }, - KVDI: { - id: 'KVDI', - city: 'Vidalia Muni', - state: 'GA', - lat: 32.2, - lon: -82.3666, - }, - KWRB: { - id: 'KWRB', - city: 'Warner Robins Af', - state: 'GA', - lat: 32.6166, - lon: -83.5833, - }, - KIIY: { - id: 'KIIY', - city: 'Washington', - state: 'GA', - lat: 33.7833, - lon: -82.8166, - }, - KAYS: { - id: 'KAYS', - city: 'Waycross/Ware Co', - state: 'GA', - lat: 31.25, - lon: -82.4, - }, - KWDR: { - id: 'KWDR', - city: 'Winder/Barrow', - state: 'GA', - lat: 33.9833, - lon: -83.6666, - }, - TJSJ: { - id: 'TJSJ', - city: 'San Juan, Luis Munoz Marin International Airport', - state: 'PR', - lat: 18.45, - lon: -66, - }, - TJBQ: { - id: 'TJBQ', - city: 'Aquadilla, Rafael Hernandez Airport', - state: 'PR', - lat: 18.5, - lon: -67.13333, - }, - TJPS: { - id: 'TJPS', - city: 'Ponce, Mercedita Airport', - state: 'PR', - lat: 18.01667, - lon: -66.56667, - }, - TJNR: { - id: 'TJNR', - city: 'Roosevelt Roads, Roosevelt Roads Naval Station, Ofstie Field', - state: 'PR', - lat: 18.25528, - lon: -65.64333, - }, - TJMZ: { - id: 'TJMZ', - city: 'Mayaguez, Eugenio Maria de Hostos Airport', - state: 'PR', - lat: 18.26667, - lon: -67.15, - }, - TJIG: { - id: 'TJIG', - city: 'San Juan Fernando Luis Ribas Dominicci', - state: 'PR', - lat: 18.4568, - lon: -66.0981, - }, - KILM: { - id: 'KILM', - city: 'Wilmington International Airport', - state: 'NC', - lat: 34.26681, - lon: -77.89987, - }, - KHSE: { - id: 'KHSE', - city: 'Hatteras, Mitchell Field', - state: 'NC', - lat: 35.23222, - lon: -75.6225, - }, - KRDU: { - id: 'KRDU', - city: 'Raleigh / Durham, Raleigh-Durham International Airport', - state: 'NC', - lat: 35.89223, - lon: -78.78185, - }, - KGSO: { - id: 'KGSO', - city: 'Greensboro, Piedmont Triad International Airport', - state: 'NC', - lat: 36.0974999, - lon: -79.94361, - }, - KNKT: { - id: 'KNKT', - city: 'Cherry Point Marine Corps Air Station', - state: 'NC', - lat: 34.89719, - lon: -76.88135, - }, - KAVL: { - id: 'KAVL', - city: 'Asheville, Asheville Regional Airport', - state: 'NC', - lat: 35.43194, - lon: -82.5375, - }, - KINT: { - id: 'KINT', - city: 'Winston Salem, Smith Reynolds Airport', - state: 'NC', - lat: 36.13333, - lon: -80.22472, - }, - KFAY: { - id: 'KFAY', - city: 'Fayetteville, Fayetteville Regional Airport', - state: 'NC', - lat: 34.98944, - lon: -78.88, - }, - KCLT: { - id: 'KCLT', - city: 'Charlotte, Charlotte / Douglas International Airport', - state: 'NC', - lat: 35.21333, - lon: -80.94861, - }, - KFBG: { - id: 'KFBG', - city: 'Fort Bragg / Simmons Army Airfield', - state: 'NC', - lat: 35.1314, - lon: -78.93158, - }, - KHKY: { - id: 'KHKY', - city: 'Hickory, Hickory Regional Airport', - state: 'NC', - lat: 35.74222, - lon: -81.38222, - }, - KGSB: { - id: 'KGSB', - city: 'Seymour-Johnson Air Force Base', - state: 'NC', - lat: 35.34457, - lon: -77.94583, - }, - KECG: { - id: 'KECG', - city: 'Elizabeth City C/G Regional Airport', - state: 'NC', - lat: 36.25771, - lon: -76.1716, - }, - KEWN: { - id: 'KEWN', - city: 'New Bern, Craven County Regional Airport', - state: 'NC', - lat: 35.0675, - lon: -77.04722, - }, - KNCA: { - id: 'KNCA', - city: 'MCAS New River', - state: 'NC', - lat: 34.70627, - lon: -77.44066, - }, - KPOB: { - id: 'KPOB', - city: 'Pope Air Force Base', - state: 'NC', - lat: 35.17531, - lon: -79.00771, - }, - KRWI: { - id: 'KRWI', - city: 'Rocky Mount, Rocky Mount-Wilson Regional Airport', - state: 'NC', - lat: 35.8549999, - lon: -77.89306, - }, - KHBI: { - id: 'KHBI', - city: 'Asheboro, Asheboro Municipal Airport', - state: 'NC', - lat: 35.6538899, - lon: -79.895, - }, - KJQF: { - id: 'KJQF', - city: 'Concord Regional Airport', - state: 'NC', - lat: 35.3896299, - lon: -80.70735, - }, - KDPL: { - id: 'KDPL', - city: 'Duplin County Airport', - state: 'NC', - lat: 34.99942, - lon: -77.97995, - }, - KHFF: { - id: 'KHFF', - city: 'Mackall U. S. Army Airfield', - state: 'NC', - lat: 35.03333, - lon: -79.5, - }, - KHRJ: { - id: 'KHRJ', - city: 'Erwin, Harnett County Airport', - state: 'NC', - lat: 35.37861, - lon: -78.73361, - }, - KBUY: { - id: 'KBUY', - city: 'Burlington Alamance Regional Airport', - state: 'NC', - lat: 36.04753, - lon: -79.47375, - }, - KAKH: { - id: 'KAKH', - city: 'Gastonia Municipal Airport', - state: 'NC', - lat: 35.1968699, - lon: -81.15545, - }, - KFQD: { - id: 'KFQD', - city: 'Rutherfordton, Rutherford County-Marchman Field Airport', - state: 'NC', - lat: 35.42833, - lon: -81.935, - }, - KIPJ: { - id: 'KIPJ', - city: 'Lincolnton, Lincolnton-Lincoln County Regional Airport', - state: 'NC', - lat: 35.48306, - lon: -81.16139, - }, - KISO: { - id: 'KISO', - city: 'Kinston, Kinston Regional Jetport at Stallings Field', - state: 'NC', - lat: 35.3333299, - lon: -77.61667, - }, - KMQI: { - id: 'KMQI', - city: 'Manteo / Dare County Regional', - state: 'NC', - lat: 35.91667, - lon: -75.7, - }, - KGEV: { - id: 'KGEV', - city: 'Jefferson, Ashe County Airport', - state: 'NC', - lat: 36.43333, - lon: -81.41667, - }, - KASJ: { - id: 'KASJ', - city: 'Ahoskie, Tri-County Airport', - state: 'NC', - lat: 36.2975, - lon: -77.17083, - }, - KMEB: { - id: 'KMEB', - city: 'Laurinburg Maxton Airport', - state: 'NC', - lat: 34.79132, - lon: -79.3683, - }, - KMRN: { - id: 'KMRN', - city: 'Morganton-Lenoir Airport', - state: 'NC', - lat: 35.81922, - lon: -81.60971, - }, - KEXX: { - id: 'KEXX', - city: 'Lexington, Davidson County Airport', - state: 'NC', - lat: 35.78111, - lon: -80.30389, - }, - KCTZ: { - id: 'KCTZ', - city: 'Sampson County Airport', - state: 'NC', - lat: 34.97522, - lon: -78.36276, - }, - KEDE: { - id: 'KEDE', - city: 'Edenton, Northeastern Regional Airport', - state: 'NC', - lat: 36.02778, - lon: -76.56722, - }, - KEQY: { - id: 'KEQY', - city: 'Monroe, Monroe Airport', - state: 'NC', - lat: 35.01694, - lon: -80.62056, - }, - KIGX: { - id: 'KIGX', - city: 'Chapel Hill, Williams Airport', - state: 'NC', - lat: 35.9336, - lon: -79.0605999, - }, - KMRH: { - id: 'KMRH', - city: 'Beaufort Smith Field', - state: 'NC', - lat: 34.73259, - lon: -76.6566, - }, - KMWK: { - id: 'KMWK', - city: 'Mount Airy/Surry County Airport', - state: 'NC', - lat: 36.45675, - lon: -80.55483, - }, - KJNX: { - id: 'KJNX', - city: 'Smithfield, Johnston County Airport', - state: 'NC', - lat: 35.54083, - lon: -78.39028, - }, - KLBT: { - id: 'KLBT', - city: 'Lumberton Municipal Airport', - state: 'NC', - lat: 34.60817, - lon: -79.059, - }, - KOAJ: { - id: 'KOAJ', - city: 'Jacksonville, Albert J Ellis Airport', - state: 'NC', - lat: 34.8333299, - lon: -77.61667, - }, - KNJM: { - id: 'KNJM', - city: 'Bogue Field Marine Corps Auxiliary Field', - state: 'NC', - lat: 34.69403, - lon: -77.02945, - }, - KSOP: { - id: 'KSOP', - city: 'Pinehurst/Southern Pines, Moore County Airport', - state: 'NC', - lat: 35.23333, - lon: -79.4, - }, - KRHP: { - id: 'KRHP', - city: 'Andrews-Murphy Airport', - state: 'NC', - lat: 35.19394, - lon: -83.86182, - }, - KSUT: { - id: 'KSUT', - city: 'Brunswick County Airport', - state: 'NC', - lat: 33.92921, - lon: -78.07223, - }, - KSVH: { - id: 'KSVH', - city: 'Statesville Municipal Airport', - state: 'NC', - lat: 35.76362, - lon: -80.9473, - }, - KTNB: { - id: 'KTNB', - city: 'Watauga County Hospital Heliport', - state: 'NC', - lat: 36.19856, - lon: -81.65171, - }, - KTDF: { - id: 'KTDF', - city: 'Roxboro, Person County Airport', - state: 'NC', - lat: 36.2849999, - lon: -78.98417, - }, - KTTA: { - id: 'KTTA', - city: 'Sanford, Sanford-Lee County Regional Airport', - state: 'NC', - lat: 35.5825, - lon: -79.10139, - }, - KOCW: { - id: 'KOCW', - city: 'Washington, Warren Field Airport', - state: 'NC', - lat: 35.57056, - lon: -77.0497199, - }, - KPGV: { - id: 'KPGV', - city: 'Pitt-Greenville Airport', - state: 'NC', - lat: 35.63742, - lon: -77.38506, - }, - KUKF: { - id: 'KUKF', - city: 'North Wilkesboro, Wilkes County Airport', - state: 'NC', - lat: 36.21667, - lon: -81.08333, - }, - KVUJ: { - id: 'KVUJ', - city: 'Albemarle, Stanly County Airport', - state: 'NC', - lat: 35.41667, - lon: -80.15083, - }, - KRUQ: { - id: 'KRUQ', - city: 'Rowan County Airport', - state: 'NC', - lat: 35.64417, - lon: -80.52359, - }, - KONX: { - id: 'KONX', - city: 'Currituck, Currituck County Airport', - state: 'NC', - lat: 36.39889, - lon: -76.01611, - }, - KLHZ: { - id: 'KLHZ', - city: 'Franklin County Airport', - state: 'NC', - lat: 36.02288, - lon: -78.33405, - }, - KEHO: { - id: 'KEHO', - city: 'Shelby Municipal Airport', - state: 'NC', - lat: 35.2556299, - lon: -81.59858, - }, - KRCZ: { - id: 'KRCZ', - city: 'Rockingham-Hamlet Airport', - state: 'NC', - lat: 34.8954499, - lon: -79.75755, - }, - KFFA: { - id: 'KFFA', - city: 'Kill Devil Hills, First Flight Airport', - state: 'NC', - lat: 36.01667, - lon: -75.66667, - }, - KAFP: { - id: 'KAFP', - city: 'Anson County Airport', - state: 'NC', - lat: 35.01944, - lon: -80.07836, - }, - KGWW: { - id: 'KGWW', - city: 'Goldsboro, Goldsboro-Wayne Municipal Airport', - state: 'NC', - lat: 35.46056, - lon: -77.965, - }, - KCPC: { - id: 'KCPC', - city: 'Whiteville, Columbus County Municipal Airport', - state: 'NC', - lat: 34.27278, - lon: -78.715, - }, - KHNZ: { - id: 'KHNZ', - city: 'Henderson-Oxford Airport', - state: 'NC', - lat: 36.36352, - lon: -78.52889, - }, - KNBT: { - id: 'KNBT', - city: 'Piney Island, Bt-11 Bombing Range', - state: 'NC', - lat: 35.02222, - lon: -76.4625, - }, - KEYF: { - id: 'KEYF', - city: 'Curtis L Brown Jr. Field Airport', - state: 'NC', - lat: 34.60418, - lon: -78.57902, - }, - KSIF: { - id: 'KSIF', - city: 'Reidsville, Rockingham County NC Shiloh Airport', - state: 'NC', - lat: 36.43722, - lon: -79.85083, - }, - KETC: { - id: 'KETC', - city: 'Tarboro-Edgecombe Airport', - state: 'NC', - lat: 35.9373, - lon: -77.54648, - }, - KIXA: { - id: 'KIXA', - city: 'Halifax-Northampton Regional Airport', - state: 'NC', - lat: 36.33, - lon: -77.635, - }, - KSCR: { - id: 'KSCR', - city: 'Siler City Municipal Airport', - state: 'NC', - lat: 35.7043, - lon: -79.5043, - }, - NEFD: { - id: 'NEFD', - city: 'NASA Ellington Field', - state: 'TX', - lat: 29.595778, - lon: -95.168233, - }, - KLBB: { - id: 'KLBB', - city: 'Lubbock, Lubbock International Airport', - state: 'TX', - lat: 33.6674999, - lon: -101.8213899, - }, - KBRO: { - id: 'KBRO', - city: 'Brownsville, Brownsville / South Padre Island International Airport', - state: 'TX', - lat: 25.91417, - lon: -97.42306, - }, - KDFW: { - id: 'KDFW', - city: 'Dallas/Fort Worth International Airport', - state: 'TX', - lat: 32.89743, - lon: -97.02196, - }, - KSAT: { - id: 'KSAT', - city: 'San Antonio, San Antonio International Airport', - state: 'TX', - lat: 29.53278, - lon: -98.46361, - }, - KDAL: { - id: 'KDAL', - city: 'Dallas Love Field', - state: 'TX', - lat: 32.85416, - lon: -96.85506, - }, - KDRT: { - id: 'KDRT', - city: 'Del Rio, Del Rio International Airport', - state: 'TX', - lat: 29.37472, - lon: -100.92361, - }, - KELP: { - id: 'KELP', - city: 'El Paso, El Paso International Airport', - state: 'TX', - lat: 31.81111, - lon: -106.3758299, - }, - KIAH: { - id: 'KIAH', - city: 'Houston Intercontinental Airport', - state: 'TX', - lat: 29.9844, - lon: -95.36074, - }, - KFTW: { - id: 'KFTW', - city: 'Fort Worth, Meacham International Airport', - state: 'TX', - lat: 32.82528, - lon: -97.36417, - }, - KCRP: { - id: 'KCRP', - city: 'Corpus Christi, Corpus Christi International Airport', - state: 'TX', - lat: 27.77306, - lon: -97.51278, - }, - KAMA: { - id: 'KAMA', - city: 'Amarillo, Amarillo International Airport', - state: 'TX', - lat: 35.22, - lon: -101.71722, - }, - KCDS: { - id: 'KCDS', - city: 'Childress, Childress Municipal Airport', - state: 'TX', - lat: 34.4275, - lon: -100.28333, - }, - KAUS: { - id: 'KAUS', - city: 'Austin-Bergstrom International Airport', - state: 'TX', - lat: 30.18304, - lon: -97.6798699, - }, - KMWL: { - id: 'KMWL', - city: 'Mineral Wells, Mineral Wells Airport', - state: 'TX', - lat: 32.78167, - lon: -98.06028, - }, - KHOU: { - id: 'KHOU', - city: 'Houston, Houston Hobby Airport', - state: 'TX', - lat: 29.6375, - lon: -95.2825, - }, - KLRD: { - id: 'KLRD', - city: 'Laredo, Laredo International Airport', - state: 'TX', - lat: 27.54361, - lon: -99.46139, - }, - KCLL: { - id: 'KCLL', - city: 'College Station, Easterwood Field', - state: 'TX', - lat: 30.58222, - lon: -96.36167, - }, - KGGG: { - id: 'KGGG', - city: 'Longview - East Texas Regional Airport', - state: 'TX', - lat: 32.39056, - lon: -94.71389, - }, - KABI: { - id: 'KABI', - city: 'Abilene, Abilene Regional Airport', - state: 'TX', - lat: 32.41028, - lon: -99.68167, - }, - KSPS: { - id: 'KSPS', - city: 'Wichita Falls, Sheppard Air Force Base', - state: 'TX', - lat: 33.97861, - lon: -98.49278, - }, - KTYR: { - id: 'KTYR', - city: 'Tyler, Tyler Pounds Field', - state: 'TX', - lat: 32.35861, - lon: -95.40389, - }, - KMAF: { - id: 'KMAF', - city: 'Midland, Midland International Airport', - state: 'TX', - lat: 31.94778, - lon: -102.2086099, - }, - KSJT: { - id: 'KSJT', - city: 'San Angelo, Mathis Field', - state: 'TX', - lat: 31.35139, - lon: -100.4938899, - }, - KGRK: { - id: 'KGRK', - city: 'Fort Hood, Robert Gray AAF Ft Hood', - state: 'TX', - lat: 31.06667, - lon: -97.81667, - }, - KINK: { - id: 'KINK', - city: 'Wink, Winkler County Airport', - state: 'TX', - lat: 31.77972, - lon: -103.20139, - }, - KFST: { - id: 'KFST', - city: 'Fort Stockton, Fort Stockton-Pecos County Airport', - state: 'TX', - lat: 30.91194, - lon: -102.91667, - }, - KDLF: { - id: 'KDLF', - city: 'Laughlin Air Force Base Auxiliary Airfield', - state: 'TX', - lat: 29.36652, - lon: -100.78469, - }, - KMRF: { - id: 'KMRF', - city: 'Marfa', - state: 'TX', - lat: 30.36667, - lon: -104.01667, - }, - KDHT: { - id: 'KDHT', - city: 'Dalhart, Dalhart Municipal Airport', - state: 'TX', - lat: 36.02333, - lon: -102.54722, - }, - KACT: { - id: 'KACT', - city: 'Waco, Waco Regional Airport', - state: 'TX', - lat: 31.61722, - lon: -97.22778, - }, - KBPT: { - id: 'KBPT', - city: 'Beaumont/Port Arthur Southeast Texas Regional Airport', - state: 'TX', - lat: 29.9521, - lon: -94.0261, - }, - KGLS: { - id: 'KGLS', - city: 'Galveston, Scholes Field', - state: 'TX', - lat: 29.27028, - lon: -94.86417, - }, - KHRL: { - id: 'KHRL', - city: 'Harlingen, Rio Grande Valley International Airport', - state: 'TX', - lat: 26.22972, - lon: -97.65528, - }, - KMFE: { - id: 'KMFE', - city: 'McAllen, Miller International Airport', - state: 'TX', - lat: 26.17972, - lon: -98.24444, - }, - KDYS: { - id: 'KDYS', - city: 'Abilene, Dyess Air Force Base', - state: 'TX', - lat: 32.42, - lon: -99.85694, - }, - KLFK: { - id: 'KLFK', - city: 'Lufkin, Angelina County Airport', - state: 'TX', - lat: 31.23389, - lon: -94.75, - }, - KJCT: { - id: 'KJCT', - city: 'Junction, Kimble County Airport', - state: 'TX', - lat: 30.51083, - lon: -99.76639, - }, - KALI: { - id: 'KALI', - city: 'Alice, Alice International Airport', - state: 'TX', - lat: 27.74111, - lon: -98.02694, - }, - KNFW: { - id: 'KNFW', - city: 'Fort Worth, Naval Air Station', - state: 'TX', - lat: 32.76583, - lon: -97.43333, - }, - KVCT: { - id: 'KVCT', - city: 'Victoria, Victoria Regional Airport', - state: 'TX', - lat: 28.8625, - lon: -96.92972, - }, - KNGP: { - id: 'KNGP', - city: 'Corpus Christi, Corpus Christi Naval Air Station/Truax Field', - state: 'TX', - lat: 27.6925, - lon: -97.29111, - }, - KRND: { - id: 'KRND', - city: 'Randolph Air Force Base', - state: 'TX', - lat: 29.53333, - lon: -98.28333, - }, - KSKF: { - id: 'KSKF', - city: 'Kelly Air Force Base', - state: 'TX', - lat: 29.38333, - lon: -98.58333, - }, - KPSX: { - id: 'KPSX', - city: 'Palacios Municipal Airport', - state: 'TX', - lat: 28.72485, - lon: -96.2534699, - }, - KNQI: { - id: 'KNQI', - city: 'Kingsville, Naval Air Station', - state: 'TX', - lat: 27.50306, - lon: -97.81167, - }, - KPPA: { - id: 'KPPA', - city: 'Pampa, Perry Lefors Field Airport', - state: 'TX', - lat: 35.61278, - lon: -100.99611, - }, - KODO: { - id: 'KODO', - city: 'Odessa, Odessa-Schlemeyer Field', - state: 'TX', - lat: 31.92139, - lon: -102.39167, - }, - KGDP: { - id: 'KGDP', - city: 'Pine Springs, Guadalupe Mountains National Park', - state: 'TX', - lat: 31.83111, - lon: -104.80889, - }, - KBGD: { - id: 'KBGD', - city: 'Borger, Hutchinson County Airport', - state: 'TX', - lat: 35.695, - lon: -101.395, - }, - KAFW: { - id: 'KAFW', - city: 'Fort Worth, Fort Worth Alliance Airport', - state: 'TX', - lat: 32.97333, - lon: -97.31806, - }, - KILE: { - id: 'KILE', - city: 'Killeen, Skylark Field Airport', - state: 'TX', - lat: 31.08333, - lon: -97.68333, - }, - KLBX: { - id: 'KLBX', - city: 'Angleton / Lake Jackson, Brazoria County Airport', - state: 'TX', - lat: 29.11536, - lon: -95.46323, - }, - KLVJ: { - id: 'KLVJ', - city: 'Houston, Pearland Regional Airport', - state: 'TX', - lat: 29.52111, - lon: -95.24194, - }, - KCRS: { - id: 'KCRS', - city: 'Corsicana, Campbell Field-Corsicana Municipal Airport', - state: 'TX', - lat: 32.03111, - lon: -96.39889, - }, - KEFD: { - id: 'KEFD', - city: 'Houston / Ellington', - state: 'TX', - lat: 29.6, - lon: -95.16667, - }, - KADS: { - id: 'KADS', - city: 'Dallas / Addison Airport', - state: 'TX', - lat: 32.96667, - lon: -96.83333, - }, - KATT: { - id: 'KATT', - city: 'Austin City, Austin Camp Mabry', - state: 'TX', - lat: 30.31667, - lon: -97.76667, - }, - KHDO: { - id: 'KHDO', - city: 'Hondo, Hondo Municipal Airport', - state: 'TX', - lat: 29.35944, - lon: -99.17417, - }, - KHHF: { - id: 'KHHF', - city: 'Canadian, Hemphill County Airport', - state: 'TX', - lat: 35.9, - lon: -100.4, - }, - KBMQ: { - id: 'KBMQ', - city: 'Burnet, Burnet Municipal Craddock Field', - state: 'TX', - lat: 30.74056, - lon: -98.23528, - }, - KCOT: { - id: 'KCOT', - city: 'Cotulla, Cotulla-La Salle County Airport', - state: 'TX', - lat: 28.45833, - lon: -99.22028, - }, - KGKY: { - id: 'KGKY', - city: 'Arlington Municipal Airport', - state: 'TX', - lat: 32.65829, - lon: -97.09509, - }, - KHYI: { - id: 'KHYI', - city: 'San Marcos, San Marcos Municipal Airport', - state: 'TX', - lat: 29.89361, - lon: -97.86472, - }, - KPVW: { - id: 'KPVW', - city: 'Plainview, Hale County Airport', - state: 'TX', - lat: 34.1680599, - lon: -101.71722, - }, - KDTO: { - id: 'KDTO', - city: 'Denton Municipal Airport', - state: 'TX', - lat: 33.20505, - lon: -97.20061, - }, - KGLE: { - id: 'KGLE', - city: 'Gainesville, Gainesville Municipal Airport', - state: 'TX', - lat: 33.65139, - lon: -97.19694, - }, - KGPM: { - id: 'KGPM', - city: 'Grand Prairie, Grand Prairie Municipal Airport', - state: 'TX', - lat: 32.69861, - lon: -97.04667, - }, - KBAZ: { - id: 'KBAZ', - city: 'New Braunfels, New Braunfels Municipal Airport', - state: 'TX', - lat: 29.70861, - lon: -98.04528, - }, - KBWD: { - id: 'KBWD', - city: 'Brownwood, Brownwood Regional Airport', - state: 'TX', - lat: 31.8, - lon: -98.95, - }, - KDWH: { - id: 'KDWH', - city: 'Houston, Hooks Memorial Airport', - state: 'TX', - lat: 30.0675, - lon: -95.55611, - }, - KGVT: { - id: 'KGVT', - city: 'Greenville / Majors', - state: 'TX', - lat: 33.06667, - lon: -96.06667, - }, - KHLR: { - id: 'KHLR', - city: 'Fort Hood, Hood AAF Ft Hood', - state: 'TX', - lat: 31.13333, - lon: -97.7, - }, - KGTU: { - id: 'KGTU', - city: 'Georgetown, Georgetown Municipal Airport', - state: 'TX', - lat: 30.68333, - lon: -97.68333, - }, - KUTS: { - id: 'KUTS', - city: 'Huntsville, Huntsville Municipal Airport', - state: 'TX', - lat: 30.74389, - lon: -95.58611, - }, - KPWG: { - id: 'KPWG', - city: 'Waco, Mc Gregor Executive Airport', - state: 'TX', - lat: 31.48333, - lon: -97.31667, - }, - KOCH: { - id: 'KOCH', - city: 'Nacogdoches, A L Mangham Jr. Regional Airport', - state: 'TX', - lat: 31.58333, - lon: -94.7166699, - }, - KRBD: { - id: 'KRBD', - city: 'Dallas, Redbird Airport', - state: 'TX', - lat: 32.67583, - lon: -96.86389, - }, - KTRL: { - id: 'KTRL', - city: 'Terrell, Terrell Municipal Airport', - state: 'TX', - lat: 32.71361, - lon: -96.26833, - }, - KTKI: { - id: 'KTKI', - city: 'McKinney - McKinney National Airport', - state: 'TX', - lat: 33.17778, - lon: -96.59028, - }, - KSSF: { - id: 'KSSF', - city: 'San Antonio, Stinson Municipal Airport', - state: 'TX', - lat: 29.33889, - lon: -98.47167, - }, - KPRX: { - id: 'KPRX', - city: 'Paris / Cox Field', - state: 'TX', - lat: 33.63333, - lon: -95.45, - }, - KTPL: { - id: 'KTPL', - city: 'Temple, Draughon-Miller Central Texas Regional Airport', - state: 'TX', - lat: 31.15, - lon: -97.4, - }, - KSGR: { - id: 'KSGR', - city: 'Houston, Sugar Land Municipal / Hull Field Airport', - state: 'TX', - lat: 29.62222, - lon: -95.65667, - }, - KSEP: { - id: 'KSEP', - city: 'Stephenville, Clark Field Municipal Airport', - state: 'TX', - lat: 32.21667, - lon: -98.18333, - }, - KPIL: { - id: 'KPIL', - city: 'Port Isabel, Port Isabel-Cameron County Airport', - state: 'TX', - lat: 26.15917, - lon: -97.3375, - }, - KRKP: { - id: 'KRKP', - city: 'Rockport Aransas County Airport', - state: 'TX', - lat: 28.08371, - lon: -97.04664, - }, - KCOM: { - id: 'KCOM', - city: 'COLEMAN', - state: 'TX', - lat: 31.84, - lon: -99.4, - }, - KAQO: { - id: 'KAQO', - city: 'Llano, Llano Municipal Airport', - state: 'TX', - lat: 30.78361, - lon: -98.66194, - }, - KDUX: { - id: 'KDUX', - city: 'Dumas, Moore County Airport', - state: 'TX', - lat: 35.85778, - lon: -102.01306, - }, - KGNC: { - id: 'KGNC', - city: 'Seminole, Gaines County Airport', - state: 'TX', - lat: 32.67528, - lon: -102.6525, - }, - KGYB: { - id: 'KGYB', - city: 'Giddings, Giddings-Lee County Airport', - state: 'TX', - lat: 30.16917, - lon: -96.98, - }, - KJXI: { - id: 'KJXI', - city: 'Gilmer, Fox Stephens Field - Gilmer Municipal Airport', - state: 'TX', - lat: 32.69889, - lon: -94.94861, - }, - KJWY: { - id: 'KJWY', - city: 'Midlothian/Waxahachie, Mid-Way Regional Airport', - state: 'TX', - lat: 32.45583, - lon: -96.91222, - }, - KSOA: { - id: 'KSOA', - city: 'Sonora, Sonora Municipal Airport', - state: 'TX', - lat: 30.58556, - lon: -100.64833, - }, - KUVA: { - id: 'KUVA', - city: 'Uvalde, Garner Field Airport', - state: 'TX', - lat: 29.21111, - lon: -99.74333, - }, - KEBG: { - id: 'KEBG', - city: 'Edinburg, Edinburg International Airport', - state: 'TX', - lat: 26.44194, - lon: -98.12944, - }, - KXBP: { - id: 'KXBP', - city: 'Bridgeport, Bridgeport Municipal Airport', - state: 'TX', - lat: 33.17528, - lon: -97.8283299, - }, - KLHB: { - id: 'KLHB', - city: 'Hearne, Hearne Municipal Airport', - state: 'TX', - lat: 30.87167, - lon: -96.62222, - }, - KSNK: { - id: 'KSNK', - city: 'Snyder, Winston Field Airport', - state: 'TX', - lat: 32.69333, - lon: -100.95028, - }, - KCPT: { - id: 'KCPT', - city: 'Cleburne, Cleburne Municipal Airport', - state: 'TX', - lat: 32.35361, - lon: -97.43361, - }, - KRBO: { - id: 'KRBO', - city: 'Robstown, Nueces County Airport', - state: 'TX', - lat: 27.77833, - lon: -97.69028, - }, - KHQZ: { - id: 'KHQZ', - city: 'Mesquite, Mesquite Metro Airport', - state: 'TX', - lat: 32.74694, - lon: -96.53028, - }, - KGYI: { - id: 'KGYI', - city: 'Sherman/Denison, Grayson County Airport', - state: 'TX', - lat: 33.71667, - lon: -96.66667, - }, - KHBV: { - id: 'KHBV', - city: 'Hebbronville, Jim Hogg County Airport', - state: 'TX', - lat: 27.33333, - lon: -98.73333, - }, - KJDD: { - id: 'KJDD', - city: 'Mineola/Quitman, Wood County Airport', - state: 'TX', - lat: 32.74194, - lon: -95.49639, - }, - KGDJ: { - id: 'KGDJ', - city: 'Granbury, Granbury Municipal Airport', - state: 'TX', - lat: 32.44417, - lon: -97.81667, - }, - KJSO: { - id: 'KJSO', - city: 'Jacksonville, Cherokee County Airport', - state: 'TX', - lat: 31.86917, - lon: -95.21722, - }, - KLNC: { - id: 'KLNC', - city: 'Lancaster Airport', - state: 'TX', - lat: 32.58323, - lon: -96.72091, - }, - KPSN: { - id: 'KPSN', - city: 'Palestine, Palestine Municipal Airport', - state: 'TX', - lat: 31.77944, - lon: -95.70611, - }, - KINJ: { - id: 'KINJ', - city: 'Hillsboro, Hillsboro Municipal Airport', - state: 'TX', - lat: 32.0833299, - lon: -97.0972199, - }, - KNOG: { - id: 'KNOG', - city: 'Orange Grove NALF', - state: 'TX', - lat: 27.8947, - lon: -98.0425099, - }, - KRPH: { - id: 'KRPH', - city: 'Graham, Graham Municipal Airport', - state: 'TX', - lat: 33.11, - lon: -98.55528, - }, - KBPC: { - id: 'KBPC', - city: 'Mesa Vista Ranch AP', - state: 'TX', - lat: 35.889, - lon: -101.03, - }, - KCZT: { - id: 'KCZT', - city: 'Carrizo Springs Dimmit County Airport', - state: 'TX', - lat: 28.5222, - lon: -99.8236, - }, - KJAS: { - id: 'KJAS', - city: 'Jasper, Jasper County-Bell Field Airport', - state: 'TX', - lat: 30.88556, - lon: -94.0347199, - }, - KCXO: { - id: 'KCXO', - city: 'Conroe, Montgomery County Airport', - state: 'TX', - lat: 30.35667, - lon: -95.41389, - }, - KERV: { - id: 'KERV', - city: 'Kerrville, Kerrville Municipal Airport/Louis Schreiner Field', - state: 'TX', - lat: 29.96667, - lon: -99.08333, - }, - KSWW: { - id: 'KSWW', - city: 'Sweetwater, Avenger Field Airport', - state: 'TX', - lat: 32.46722, - lon: -100.46639, - }, - KFWS: { - id: 'KFWS', - city: 'Fort Worth, Forth Worth Spinks Airport', - state: 'TX', - lat: 32.56667, - lon: -97.3, - }, - KARM: { - id: 'KARM', - city: 'Wharton, Wharton Regional Airport', - state: 'TX', - lat: 29.25417, - lon: -96.1541699, - }, - KLZZ: { - id: 'KLZZ', - city: 'Lampasas, Lampasas Airport', - state: 'TX', - lat: 31.10611, - lon: -98.19583, - }, - KRAS: { - id: 'KRAS', - city: 'Port Aransas, Mustang Beach Airport', - state: 'TX', - lat: 27.81167, - lon: -97.08861, - }, - KRWV: { - id: 'KRWV', - city: 'Caldwell, Caldwell Municipal Airport', - state: 'TX', - lat: 30.51528, - lon: -96.70389, - }, - KBPG: { - id: 'KBPG', - city: 'Big Spring, Big Spring McMahon-Wrinkle Airport', - state: 'TX', - lat: 32.2, - lon: -101.51667, - }, - KMKN: { - id: 'KMKN', - city: 'Comanche, Comanche County-City Airport', - state: 'TX', - lat: 31.91667, - lon: -98.60028, - }, - KBKS: { - id: 'KBKS', - city: 'Falfurrias, Brooks County Airport', - state: 'TX', - lat: 27.20667, - lon: -98.12111, - }, - KMDD: { - id: 'KMDD', - city: 'Midland, Midland Airpark', - state: 'TX', - lat: 32.03639, - lon: -102.10083, - }, - KOSA: { - id: 'KOSA', - city: 'Mount Pleasant, Mount Pleasant Regional Airport', - state: 'TX', - lat: 33.09528, - lon: -94.96139, - }, - KPYX: { - id: 'KPYX', - city: 'Perryton, Perryton Ochiltree County Airport', - state: 'TX', - lat: 36.4, - lon: -100.73333, - }, - KLUD: { - id: 'KLUD', - city: 'Decatur, Decatur Municipal Airport', - state: 'TX', - lat: 33.25444, - lon: -97.58056, - }, - KORG: { - id: 'KORG', - city: 'Orange, Orange County Airport', - state: 'TX', - lat: 30.06917, - lon: -93.80361, - }, - KBIF: { - id: 'KBIF', - city: 'Biggs Army Air Field - Fort Bliss', - state: 'TX', - lat: 31.86119, - lon: -106.3691599, - }, - KECU: { - id: 'KECU', - city: 'Rocksprings, Edwards County Airport', - state: 'TX', - lat: 29.94667, - lon: -100.17361, - }, - KBYY: { - id: 'KBYY', - city: 'Bay City, Bay City Municipal Airport', - state: 'TX', - lat: 28.97306, - lon: -95.86333, - }, - KPEQ: { - id: 'KPEQ', - city: 'Pecos, Pecos Municipal Airport', - state: 'TX', - lat: 31.38222, - lon: -103.51056, - }, - KGOP: { - id: 'KGOP', - city: 'Gatesville, City-County Airport', - state: 'TX', - lat: 31.42111, - lon: -97.79694, - }, - KPKV: { - id: 'KPKV', - city: 'Port Lavaca - Calhoun County Airport', - state: 'TX', - lat: 28.65159, - lon: -96.68196, - }, - KSLR: { - id: 'KSLR', - city: 'Sulphur Springs, Sulphur Springs Municipal Airport', - state: 'TX', - lat: 33.16111, - lon: -95.62111, - }, - KBBD: { - id: 'KBBD', - city: 'Brady, Curtis Field Airport', - state: 'TX', - lat: 31.17917, - lon: -99.32389, - }, - KDKR: { - id: 'KDKR', - city: 'Crockett, Houston County Airport', - state: 'TX', - lat: 31.30694, - lon: -95.40361, - }, - KTFP: { - id: 'KTFP', - city: 'Mc Campbell', - state: 'TX', - lat: 27.913, - lon: -97.2115, - }, - KBEA: { - id: 'KBEA', - city: 'Beeville Municipal Airport', - state: 'TX', - lat: 28.362, - lon: -97.791, - }, - KPEZ: { - id: 'KPEZ', - city: 'Pleasanton Municipal Airport', - state: 'TX', - lat: 28.9562, - lon: -98.5184, - }, - KCWC: { - id: 'KCWC', - city: 'Kickapoo Downtown Airport', - state: 'TX', - lat: 33.8578, - lon: -98.4903999, - }, - KHRX: { - id: 'KHRX', - city: 'Hereford Municipal Airport', - state: 'TX', - lat: 34.8578, - lon: -102.3264, - }, - KCNW: { - id: 'KCNW', - city: 'Waco-James Connally Airport', - state: 'TX', - lat: 31.6378, - lon: -97.0741, - }, - KMNZ: { - id: 'KMNZ', - city: 'Hamilton Municipal Airport', - state: 'TX', - lat: 31.6659, - lon: -98.1486, - }, - KTME: { - id: 'KTME', - city: 'Houston Executive Airport', - state: 'TX', - lat: 29.80717, - lon: -95.89791, - }, - KRFI: { - id: 'KRFI', - city: 'Rusk County Airport', - state: 'TX', - lat: 32.1417, - lon: -94.8516999, - }, - KBKD: { - id: 'KBKD', - city: 'Stephens County Airport', - state: 'TX', - lat: 32.719, - lon: -98.891, - }, - KAPY: { - id: 'KAPY', - city: 'Zapata, TX', - state: 'TX', - lat: 26.969, - lon: -99.249, - }, - KBQX: { - id: 'KBQX', - city: 'BRAZOS 451 OIL PLATFORM', - state: 'TX', - lat: 28.5, - lon: -95.72, - }, - KBBF: { - id: 'KBBF', - city: 'BRAZOS 133 OIL PLATFORM', - state: 'TX', - lat: 27.83, - lon: -96.02, - }, - KHQI: { - id: 'KHQI', - city: 'H ISLAND376 OIL PLATFORM', - state: 'TX', - lat: 27.97, - lon: -93.67, - }, - KRYW: { - id: 'KRYW', - city: 'Lago Vista TX, Rusty Allen Airport', - state: 'TX', - lat: 30.4967, - lon: -97.9659, - }, - KMZG: { - id: 'KMZG', - city: 'MUSTANG A85A OIL PLATFORM', - state: 'TX', - lat: 27.73, - lon: -96.18, - }, - KSPL: { - id: 'KSPL', - city: 'South Padre Island', - state: 'TX', - lat: 26.07, - lon: -97.16, - }, - KDZB: { - id: 'KDZB', - city: 'Horseshoe Bay Resort Airpark', - state: 'TX', - lat: 30.5271, - lon: -98.3588, - }, - KEDC: { - id: 'KEDC', - city: 'Austin Executive Airport', - state: 'TX', - lat: 30.3925, - lon: -97.5621, - }, - KOZA: { - id: 'KOZA', - city: 'Ozona Municipal Airport', - state: 'TX', - lat: 30.7353, - lon: -101.203, - }, - KFTN: { - id: 'KFTN', - city: 'Faith Ranch Airport', - state: 'TX', - lat: 28.2086, - lon: -100.0188, - }, - KASL: { - id: 'KASL', - city: 'Marshall', - state: 'TX', - lat: 32.5205, - lon: -94.3078, - }, - KVAF: { - id: 'KVAF', - city: 'East Breaks 643/Boomvang Spar', - state: 'TX', - lat: 27.354, - lon: -94.625, - }, - KHHV: { - id: 'KHHV', - city: 'Alaminos Canyon 25/H-D (ExxonMobil)', - state: 'TX', - lat: 26.939, - lon: -94.6889999, - }, - KMCJ: { - id: 'KMCJ', - city: 'John Dunn Helistop', - state: 'TX', - lat: 29.714, - lon: -95.395, - }, - KAXH: { - id: 'KAXH', - city: 'Houston Southwest Airport', - state: 'TX', - lat: 29.50613, - lon: -95.47692, - }, - KCVB: { - id: 'KCVB', - city: 'Castroville Municipal Airport', - state: 'TX', - lat: 29.34192, - lon: -98.8509, - }, - KBMT: { - id: 'KBMT', - city: 'Beaumont Municipal Airport', - state: 'TX', - lat: 30.0702, - lon: -94.2151, - }, - KPRS: { - id: 'KPRS', - city: 'Presidio Lely International Airport', - state: 'TX', - lat: 29.6341, - lon: -104.3616, - }, - KELA: { - id: 'KELA', - city: 'Eagle Lake', - state: 'TX', - lat: 29.6006, - lon: -96.3219, - }, - KGZN: { - id: 'KGZN', - city: 'Gregory M Simmons Memorial Airport', - state: 'TX', - lat: 32.3658, - lon: -99.0237, - }, - KGUL: { - id: 'KGUL', - city: 'GUNNISON OIL PLATFORM', - state: 'TX', - lat: 27.3, - lon: -93.53, - }, - KEMK: { - id: 'KEMK', - city: 'E BREAKS OIL PLATFORM', - state: 'TX', - lat: 27.82, - lon: -94.3199999, - }, - KCFD: { - id: 'KCFD', - city: 'Bryan Coulter Field', - state: 'TX', - lat: 30.7157, - lon: -96.3314, - }, - KLXY: { - id: 'KLXY', - city: 'Mexia Limestone County Airport', - state: 'TX', - lat: 31.6412, - lon: -96.5145, - }, - HDAX: { - id: 'HDAX', - city: 'HDA Harding Lake', - state: 'AK', - lat: 64.4091, - lon: -146.9478, - }, - MLYX: { - id: 'MLYX', - city: 'MLY Manley Hot Springs', - state: 'AK', - lat: 65.0304, - lon: -150.7442, - }, - HOMX: { - id: 'HOMX', - city: 'HOM Homer Trailer', - state: 'AK', - lat: 59.6572, - lon: -151.6515, - }, - CUTX: { - id: 'CUTX', - city: 'CUT Chulitna', - state: 'AK', - lat: 62.4058, - lon: -150.2625, - }, - SKNX: { - id: 'SKNX', - city: 'SKN Skwentna', - state: 'AK', - lat: 61.98, - lon: -151.5317, - }, - SSNX: { - id: 'SSNX', - city: 'SSN Susitna', - state: 'AK', - lat: 61.4636, - lon: -150.7467, - }, - PAJN: { - id: 'PAJN', - city: 'Juneau, Juneau International Airport', - state: 'AK', - lat: 58.35472, - lon: -134.57611, - }, - PACD: { - id: 'PACD', - city: 'Cold Bay, Cold Bay Airport', - state: 'AK', - lat: 55.22083, - lon: -162.72778, - }, - PAFA: { - id: 'PAFA', - city: 'Fairbanks, Fairbanks International Airport', - state: 'AK', - lat: 64.80389, - lon: -147.87611, - }, - PABR: { - id: 'PABR', - city: 'Barrow, Wiley Post-Will Rogers Memorial Airport', - state: 'AK', - lat: 71.28528, - lon: -156.76583, - }, - PAMC: { - id: 'PAMC', - city: 'McGrath, McGrath Airport', - state: 'AK', - lat: 62.96667, - lon: -155.61667, - }, - PANC: { - id: 'PANC', - city: 'Anchorage, Ted Stevens Anchorage International Airport', - state: 'AK', - lat: 61.17444, - lon: -149.9961099, - }, - PANT: { - id: 'PANT', - city: 'Annette Island Airport', - state: 'AK', - lat: 55.03835, - lon: -131.57664, - }, - PAKN: { - id: 'PAKN', - city: 'King Salmon, King Salmon Airport', - state: 'AK', - lat: 58.67667, - lon: -156.64917, - }, - PADQ: { - id: 'PADQ', - city: 'Kodiak, Kodiak Airport', - state: 'AK', - lat: 57.75, - lon: -152.5, - }, - PABE: { - id: 'PABE', - city: 'Bethel, Bethel Airport', - state: 'AK', - lat: 60.77972, - lon: -161.83778, - }, - PAYA: { - id: 'PAYA', - city: 'Yakutat', - state: 'AK', - lat: 59.51667, - lon: -139.66667, - }, - PAOM: { - id: 'PAOM', - city: 'Nome, Nome Airport', - state: 'AK', - lat: 64.51194, - lon: -165.445, - }, - PAOT: { - id: 'PAOT', - city: 'Ralph Wien Memorial Airport', - state: 'AK', - lat: 66.88576, - lon: -162.60624, - }, - PASN: { - id: 'PASN', - city: 'St. Paul Island, St. Paul Island Airport', - state: 'AK', - lat: 57.16667, - lon: -170.21667, - }, - PASY: { - id: 'PASY', - city: 'Shemya, Eareckson AFB', - state: 'AK', - lat: 52.71667, - lon: 174.11667, - }, - PAKT: { - id: 'PAKT', - city: 'Ketchikan, Ketchikan International Airport', - state: 'AK', - lat: 55.35556, - lon: -131.71361, - }, - PADL: { - id: 'PADL', - city: 'Dillingham, Dillingham Airport', - state: 'AK', - lat: 59.05, - lon: -158.51667, - }, - PAIL: { - id: 'PAIL', - city: 'Iliamna, Iliamna Airport', - state: 'AK', - lat: 59.75, - lon: -154.9, - }, - PADU: { - id: 'PADU', - city: 'Unalaska, Unalaska Airport', - state: 'AK', - lat: 53.9, - lon: -166.53333, - }, - PAGK: { - id: 'PAGK', - city: 'Gulkana, Gulkana Airport', - state: 'AK', - lat: 62.15, - lon: -145.45, - }, - PAHN: { - id: 'PAHN', - city: 'Haines, Haines Airport', - state: 'AK', - lat: 59.25, - lon: -135.51667, - }, - PACV: { - id: 'PACV', - city: 'Cordova, Merle K (Mudhole) Smith Airport', - state: 'AK', - lat: 60.49167, - lon: -145.47778, - }, - PAGS: { - id: 'PAGS', - city: 'Gustavus, Gustavus Airport', - state: 'AK', - lat: 58.41667, - lon: -135.7, - }, - PABT: { - id: 'PABT', - city: 'Bettles, Bettles Airport', - state: 'AK', - lat: 66.91667, - lon: -151.51667, - }, - PAEN: { - id: 'PAEN', - city: 'Kenai, Kenai Municipal Airport', - state: 'AK', - lat: 60.57306, - lon: -151.245, - }, - PAGA: { - id: 'PAGA', - city: 'Galena, Edward G. Pitka Sr. Airport', - state: 'AK', - lat: 64.73333, - lon: -156.93333, - }, - PABI: { - id: 'PABI', - city: 'Delta Junction/Ft Greely, Allen Army Airfield', - state: 'AK', - lat: 64, - lon: -145.73333, - }, - PAHO: { - id: 'PAHO', - city: 'Homer, Homer Airport', - state: 'AK', - lat: 59.65, - lon: -151.48333, - }, - PAAQ: { - id: 'PAAQ', - city: 'Palmer, Palmer Municipal Airport', - state: 'AK', - lat: 61.6, - lon: -149.08333, - }, - PASI: { - id: 'PASI', - city: 'Sitka, Sitka Airport', - state: 'AK', - lat: 57.04806, - lon: -135.36472, - }, - PAUN: { - id: 'PAUN', - city: 'Unalakleet', - state: 'AK', - lat: 63.88333, - lon: -160.8, - }, - PAPG: { - id: 'PAPG', - city: 'Petersburg', - state: 'AK', - lat: 56.81667, - lon: -132.96667, - }, - PAOR: { - id: 'PAOR', - city: 'Northway, Northway Airport', - state: 'AK', - lat: 62.96111, - lon: -141.92889, - }, - PAWG: { - id: 'PAWG', - city: 'Wrangell', - state: 'AK', - lat: 56.48333, - lon: -132.36667, - }, - PAVD: { - id: 'PAVD', - city: 'Valdez 2', - state: 'AK', - lat: 61.13333, - lon: -146.26667, - }, - PATK: { - id: 'PATK', - city: 'Talkeetna, Talkeetna Airport', - state: 'AK', - lat: 62.32056, - lon: -150.09361, - }, - PATA: { - id: 'PATA', - city: 'Tanana, Calhoun Memorial Airport', - state: 'AK', - lat: 65.16667, - lon: -152.1, - }, - PASC: { - id: 'PASC', - city: 'Deadhorse, Deadhorse Airport', - state: 'AK', - lat: 70.2, - lon: -148.46667, - }, - PAGY: { - id: 'PAGY', - city: 'Skagway', - state: 'AK', - lat: 59.46667, - lon: -135.3, - }, - PATC: { - id: 'PATC', - city: 'Tin City Airways Facilities Sector', - state: 'AK', - lat: 65.56667, - lon: -167.91667, - }, - PAED: { - id: 'PAED', - city: 'Anchorage, Elmendorf Air Force Base', - state: 'AK', - lat: 61.25306, - lon: -149.79389, - }, - PAFR: { - id: 'PAFR', - city: 'Ft. Richardson / Bryant U. S. Army Heliport, Ak', - state: 'AK', - lat: 61.26667, - lon: -149.65, - }, - PAQT: { - id: 'PAQT', - city: 'Nuiqsut, Nuiqsut Airport', - state: 'AK', - lat: 70.2099999, - lon: -151.00556, - }, - PAEH: { - id: 'PAEH', - city: 'Cape Newenham, Cape Newenham LRRS Airport', - state: 'AK', - lat: 58.65, - lon: -162.0666699, - }, - PACZ: { - id: 'PACZ', - city: 'Cape Romanzof, Cape Romanzof LRRS Airport', - state: 'AK', - lat: 61.78333, - lon: -166.03333, - }, - PAEI: { - id: 'PAEI', - city: 'Fairbanks, Eielson Air Force Base', - state: 'AK', - lat: 64.65, - lon: -147.1, - }, - PAIM: { - id: 'PAIM', - city: 'Utopia Creek, Indian Mountain LRRS Airport', - state: 'AK', - lat: 66, - lon: -153.7, - }, - PATL: { - id: 'PATL', - city: 'Takotna, Tatalina LRRS Airport', - state: 'AK', - lat: 62.9, - lon: -155.98333, - }, - PAFB: { - id: 'PAFB', - city: 'Fort Wainwright AAF', - state: 'AK', - lat: 64.83667, - lon: -147.59556, - }, - PALU: { - id: 'PALU', - city: 'Cape Lisburne, Cape Lisburne LRRS Airport', - state: 'AK', - lat: 68.88333, - lon: -166.1, - }, - PALH: { - id: 'PALH', - city: 'Anchorage, Lake Hood Seaplane Base', - state: 'AK', - lat: 61.18333, - lon: -149.96667, - }, - PFYU: { - id: 'PFYU', - city: 'Fort Yukon, Fort Yukon Airport', - state: 'AK', - lat: 66.56667, - lon: -145.26667, - }, - PAHY: { - id: 'PAHY', - city: 'Hydaburg - Hydaburg Seaplane Base', - state: 'AK', - lat: 55.2, - lon: -132.83333, - }, - PALK: { - id: 'PALK', - city: 'Snowshoe Lake', - state: 'AK', - lat: 62.0327, - lon: -146.6746, - }, - PAKP: { - id: 'PAKP', - city: 'Anaktuvuk Pass, Anaktuvuk Pass Airport', - state: 'AK', - lat: 68.13361, - lon: -151.7433299, - }, - PANV: { - id: 'PANV', - city: 'Anvik, Anvik Airport', - state: 'AK', - lat: 62.64833, - lon: -160.18972, - }, - PAHP: { - id: 'PAHP', - city: 'Hooper Bay, Hooper Bay Airport', - state: 'AK', - lat: 61.51667, - lon: -166.13333, - }, - PAFM: { - id: 'PAFM', - city: 'Ambler, Ambler Airport', - state: 'AK', - lat: 67.1, - lon: -157.85, - }, - PABV: { - id: 'PABV', - city: 'Birchwood, Birchwood Airport', - state: 'AK', - lat: 61.41667, - lon: -149.51667, - }, - PANI: { - id: 'PANI', - city: 'Aniak, Aniak Airport', - state: 'AK', - lat: 61.58139, - lon: -159.54278, - }, - PABL: { - id: 'PABL', - city: 'Buckland, Buckland Airport', - state: 'AK', - lat: 65.98222, - lon: -161.15194, - }, - PAEG: { - id: 'PAEG', - city: 'Eagle, Eagle Airport', - state: 'AK', - lat: 64.77639, - lon: -141.15083, - }, - PAEM: { - id: 'PAEM', - city: 'Emmonak, Emmonak Airport', - state: 'AK', - lat: 62.78333, - lon: -164.5, - }, - PAIN: { - id: 'PAIN', - city: 'McKinley Park, McKinley National Park Airport', - state: 'AK', - lat: 63.73333, - lon: -148.91667, - }, - PAFE: { - id: 'PAFE', - city: 'Kake, Kake Airport', - state: 'AK', - lat: 56.95, - lon: -133.9, - }, - PAMH: { - id: 'PAMH', - city: 'Minchumina, Minchumina Airport', - state: 'AK', - lat: 63.88056, - lon: -152.30056, - }, - PAMR: { - id: 'PAMR', - city: 'Anchorage, Merrill Field Airport', - state: 'AK', - lat: 61.21667, - lon: -149.85, - }, - PANN: { - id: 'PANN', - city: 'Nenana Municipal Airport', - state: 'AK', - lat: 64.54796, - lon: -149.08398, - }, - PAGB: { - id: 'PAGB', - city: 'Galbraith Lake, Galbraith Lake Airport', - state: 'AK', - lat: 68.48333, - lon: -149.48333, - }, - PADK: { - id: 'PADK', - city: 'Adak Island, Adak Airport', - state: 'AK', - lat: 51.87778, - lon: -176.64583, - }, - PAWI: { - id: 'PAWI', - city: 'Wainwright, Wainwright Airport', - state: 'AK', - lat: 70.63333, - lon: -159.85, - }, - PARC: { - id: 'PARC', - city: 'Arctic Village, Arctic Village Airport', - state: 'AK', - lat: 68.11444, - lon: -145.57917, - }, - PAKW: { - id: 'PAKW', - city: 'Klawock, Klawock Airport', - state: 'AK', - lat: 55.58333, - lon: -133.08333, - }, - PAGM: { - id: 'PAGM', - city: 'Gambell, Gambell Airport', - state: 'AK', - lat: 63.76667, - lon: -171.73333, - }, - PASM: { - id: 'PASM', - city: 'St. Mary\'s, St. Mary\'s Airport', - state: 'AK', - lat: 62.05, - lon: -163.3, - }, - PAMD: { - id: 'PAMD', - city: 'Middleton Island, Middleton Island Airport', - state: 'AK', - lat: 59.43333, - lon: -146.3, - }, - PAMO: { - id: 'PAMO', - city: 'Mountain Village', - state: 'AK', - lat: 62.0953, - lon: -163.6819, - }, - PAPB: { - id: 'PAPB', - city: 'St. George, St. George Airport', - state: 'AK', - lat: 56.57861, - lon: -169.66139, - }, - PAZK: { - id: 'PAZK', - city: 'Eureka, Skelton Airport', - state: 'AK', - lat: 61.93333, - lon: -147.16667, - }, - PAEC: { - id: 'PAEC', - city: 'Chulitna, Chulitna Airport', - state: 'AK', - lat: 62.88333, - lon: -149.83333, - }, - PABA: { - id: 'PABA', - city: 'Barter Island, Barter Island LRRS Airport', - state: 'AK', - lat: 70.1338899, - lon: -143.57694, - }, - PAEL: { - id: 'PAEL', - city: 'Elfin Cove - Elfin Cove Seaplane Base', - state: 'AK', - lat: 58.2, - lon: -136.35, - }, - PAOH: { - id: 'PAOH', - city: 'Hoonah - Hoonah Seaplane Base', - state: 'AK', - lat: 58.11667, - lon: -135.45, - }, - PAPH: { - id: 'PAPH', - city: 'Port Heiden, Port Heiden Airport', - state: 'AK', - lat: 56.95, - lon: -158.63333, - }, - PAWD: { - id: 'PAWD', - city: 'Seward', - state: 'AK', - lat: 60.11667, - lon: -149.45, - }, - PATG: { - id: 'PATG', - city: 'Togiac Village, Togiak Airport', - state: 'AK', - lat: 59.05, - lon: -160.4, - }, - PASA: { - id: 'PASA', - city: 'Savoonga Airport', - state: 'AK', - lat: 63.68333, - lon: -170.5, - }, - PASW: { - id: 'PASW', - city: 'Skwentna', - state: 'AK', - lat: 61.96667, - lon: -151.18333, - }, - PAPT: { - id: 'PAPT', - city: 'Puntilla', - state: 'AK', - lat: 62.1, - lon: -152.75, - }, - PAPR: { - id: 'PAPR', - city: 'Prospect Creek, Prospect Creek Airport', - state: 'AK', - lat: 66.81278, - lon: -150.64389, - }, - PAKU: { - id: 'PAKU', - city: 'Kuparuk, Ugnu-Kuparuk Airport', - state: 'AK', - lat: 70.31667, - lon: -149.58333, - }, - PAMY: { - id: 'PAMY', - city: 'Mekoryuk, Mekoryuk Airport', - state: 'AK', - lat: 60.36667, - lon: -166.26667, - }, - PASL: { - id: 'PASL', - city: 'Sleetmute', - state: 'AK', - lat: 61.69735, - lon: -157.16712, - }, - PASH: { - id: 'PASH', - city: 'Shishmaref, Shishmaref Airport', - state: 'AK', - lat: 66.26667, - lon: -166.08333, - }, - PPIZ: { - id: 'PPIZ', - city: 'Point Lay, Point Lay LRRS Airport', - state: 'AK', - lat: 69.7166699, - lon: -163, - }, - PASD: { - id: 'PASD', - city: 'Sand Point', - state: 'AK', - lat: 55.31667, - lon: -160.51667, - }, - PAWN: { - id: 'PAWN', - city: 'Noatak, Noatak Airport', - state: 'AK', - lat: 67.56667, - lon: -162.98333, - }, - PAPO: { - id: 'PAPO', - city: 'Point Hope, Point Hope Airport', - state: 'AK', - lat: 68.35, - lon: -166.8, - }, - PALJ: { - id: 'PALJ', - city: 'Port Alsworth, Port Alsworth Airport', - state: 'AK', - lat: 60.2, - lon: -154.3166699, - }, - PASX: { - id: 'PASX', - city: 'Soldotna', - state: 'AK', - lat: 60.48333, - lon: -151.03333, - }, - PAHL: { - id: 'PAHL', - city: 'Huslia, Huslia Airport', - state: 'AK', - lat: 65.6975, - lon: -156.35111, - }, - PARY: { - id: 'PARY', - city: 'Ruby', - state: 'AK', - lat: 64.7272, - lon: -155.4697, - }, - PAGL: { - id: 'PAGL', - city: 'Golovin, Golovin Airport', - state: 'AK', - lat: 64.54333, - lon: -163.03944, - }, - PAVL: { - id: 'PAVL', - city: 'Kivalina, Kivalina Airport', - state: 'AK', - lat: 67.73333, - lon: -164.55, - }, - PAKK: { - id: 'PAKK', - city: 'Koyuk, Koyuk Airport', - state: 'AK', - lat: 64.93389, - lon: -161.15806, - }, - PASO: { - id: 'PASO', - city: 'Seldovia, Seldovia Airport', - state: 'AK', - lat: 59.45, - lon: -151.7, - }, - PAMM: { - id: 'PAMM', - city: 'Metlakatla, Metlakatla Seaplane Base', - state: 'AK', - lat: 55.13111, - lon: -131.57806, - }, - PAAK: { - id: 'PAAK', - city: 'Atka, Atka Airport', - state: 'AK', - lat: 52.22028, - lon: -174.20639, - }, - PALP: { - id: 'PALP', - city: 'Deadhorse, Alpine Airstrip', - state: 'AK', - lat: 70.33333, - lon: -150.93333, - }, - PAWS: { - id: 'PAWS', - city: 'Wasilla, Wasilla Airport', - state: 'AK', - lat: 61.57194, - lon: -149.54056, - }, - PAII: { - id: 'PAII', - city: 'Egegik, Egegik Airport', - state: 'AK', - lat: 58.18528, - lon: -157.38556, - }, - PARD: { - id: 'PARD', - city: 'Red Dog, Red Dog Airport', - state: 'AK', - lat: 68.03139, - lon: -162.90306, - }, - PASV: { - id: 'PASV', - city: 'Sparrevohn Airways Facilities Sector', - state: 'AK', - lat: 61.1, - lon: -155.5666699, - }, - PAKV: { - id: 'PAKV', - city: 'Kaltag, Kaltag Airport', - state: 'AK', - lat: 64.31667, - lon: -158.73333, - }, - PAPM: { - id: 'PAPM', - city: 'Platinum', - state: 'AK', - lat: 59.01667, - lon: -161.8166699, - }, - PADE: { - id: 'PADE', - city: 'Deering, Deering/New Airport', - state: 'AK', - lat: 66.08333, - lon: -162.75, - }, - PAJC: { - id: 'PAJC', - city: 'Chignik, Chignik Airport', - state: 'AK', - lat: 56.31139, - lon: -158.37333, - }, - PASK: { - id: 'PASK', - city: 'Selawik', - state: 'AK', - lat: 66.61667, - lon: -160, - }, - PATO: { - id: 'PATO', - city: 'Portage, Portage Glacier', - state: 'AK', - lat: 60.78333, - lon: -148.83333, - }, - PAHC: { - id: 'PAHC', - city: 'Holy Cross', - state: 'AK', - lat: 62.1873, - lon: -159.77657, - }, - PAMB: { - id: 'PAMB', - city: 'Manokotak', - state: 'AK', - lat: 58.9902, - lon: -159.0499, - }, - PALG: { - id: 'PALG', - city: 'Kalskag', - state: 'AK', - lat: 61.5364, - lon: -160.3414, - }, - PAFS: { - id: 'PAFS', - city: 'Nikolai', - state: 'AK', - lat: 63.019, - lon: -154.358, - }, - PAIG: { - id: 'PAIG', - city: 'Igiugig', - state: 'AK', - lat: 59.32395, - lon: -155.90235, - }, - PACM: { - id: 'PACM', - city: 'Scammon Bay', - state: 'AK', - lat: 61.8453, - lon: -165.5713, - }, - PARS: { - id: 'PARS', - city: 'Russian Mission', - state: 'AK', - lat: 61.775, - lon: -161.3194, - }, - PATQ: { - id: 'PATQ', - city: 'Atqasuk', - state: 'AK', - lat: 70.4673, - lon: -157.4357, - }, - PAOO: { - id: 'PAOO', - city: 'Toksook Bay', - state: 'AK', - lat: 60.53352, - lon: -165.1142999, - }, - PADG: { - id: 'PADG', - city: 'Red Dog', - state: 'AK', - lat: 68.0321, - lon: -162.8992, - }, - PFNO: { - id: 'PFNO', - city: 'Noorvik', - state: 'AK', - lat: 66.8175, - lon: -161.0223, - }, - PAKF: { - id: 'PAKF', - city: 'False Pass Airport', - state: 'AK', - lat: 54.847, - lon: -163.41, - }, - PFEL: { - id: 'PFEL', - city: 'Elim Airport', - state: 'AK', - lat: 64.615, - lon: -162.2705, - }, - PAVA: { - id: 'PAVA', - city: 'Chevak Airport', - state: 'AK', - lat: 61.5408, - lon: -165.6009, - }, - PFKT: { - id: 'PFKT', - city: 'Brevig Mission Airport', - state: 'AK', - lat: 65.3313, - lon: -166.4657, - }, - PFCL: { - id: 'PFCL', - city: 'Clarks Point Airport', - state: 'AK', - lat: 58.8337, - lon: -158.5294, - }, - PFWS: { - id: 'PFWS', - city: 'South Naknek Nr 2 Airport', - state: 'AK', - lat: 58.7021, - lon: -157.0026, - }, - PAQH: { - id: 'PAQH', - city: 'Quinhagak Airport', - state: 'AK', - lat: 59.7551, - lon: -161.8454, - }, - PAHX: { - id: 'PAHX', - city: 'Shageluk Airport', - state: 'AK', - lat: 62.6923, - lon: -159.5692, - }, - PANA: { - id: 'PANA', - city: 'Napakiak Airport', - state: 'AK', - lat: 60.6903, - lon: -161.9785, - }, - PAUT: { - id: 'PAUT', - city: 'Akun Airport', - state: 'AK', - lat: 54.1446, - lon: -165.6041, - }, - PPIT: { - id: 'PPIT', - city: 'Nunapitchuk Airport', - state: 'AK', - lat: 60.906, - lon: -162.4406, - }, - PFKW: { - id: 'PFKW', - city: 'Kwethluk Airport', - state: 'AK', - lat: 60.7903, - lon: -161.4437, - }, - PAGN: { - id: 'PAGN', - city: 'Angoon', - state: 'AK', - lat: 57.5, - lon: -134.58333, - }, - PAIK: { - id: 'PAIK', - city: 'Kinana / Bob Baker Me', - state: 'AK', - lat: 66.98333, - lon: -160.43333, - }, - PAKI: { - id: 'PAKI', - city: 'Kipnuk, Kipnuk Airport', - state: 'AK', - lat: 59.93278, - lon: -164.03028, - }, - PAMK: { - id: 'PAMK', - city: 'St Michael', - state: 'AK', - lat: 63.48954, - lon: -162.11203, - }, - PAJZ: { - id: 'PAJZ', - city: 'Koliganek', - state: 'AK', - lat: 59.727, - lon: -157.2589999, - }, - PANW: { - id: 'PANW', - city: 'New Stuyahok', - state: 'AK', - lat: 59.45, - lon: -157.328, - }, - PAOU: { - id: 'PAOU', - city: 'Nelson Lagoon', - state: 'AK', - lat: 56.008, - lon: -161.16, - }, - PAPN: { - id: 'PAPN', - city: 'Pilot Point Airport', - state: 'AK', - lat: 57.58, - lon: -157.572, - }, - PADM: { - id: 'PADM', - city: 'Marshall', - state: 'AK', - lat: 61.8643, - lon: -162.0261, - }, - PAVC: { - id: 'PAVC', - city: 'King Cove', - state: 'AK', - lat: 55.116, - lon: -162.266, - }, - PAKH: { - id: 'PAKH', - city: 'Akhiok', - state: 'AK', - lat: 56.9387, - lon: -154.1826, - }, - PAJK: { - id: 'PAJK', - city: 'NWS Office: Juneau', - state: 'AK', - lat: 58.4, - lon: -134.57001, - }, - PFSH: { - id: 'PFSH', - city: 'Shaktoolik Airport', - state: 'AK', - lat: 64.3711, - lon: -161.224, - }, - PAGH: { - id: 'PAGH', - city: 'Shungnak Airport', - state: 'AK', - lat: 66.8881, - lon: -157.1624, - }, - PATE: { - id: 'PATE', - city: 'Teller', - state: 'AK', - lat: 65.2403999, - lon: -166.3393, - }, - PAIW: { - id: 'PAIW', - city: 'Wales', - state: 'AK', - lat: 65.6226, - lon: -168.0949, - }, - PAWM: { - id: 'PAWM', - city: 'White Mountain Airport', - state: 'AK', - lat: 64.6892, - lon: -163.4127, - }, - PAFC: { - id: 'PAFC', - city: 'PAFC Anchorage', - state: 'AK', - lat: 61.156, - lon: -149.98399, - }, - PAAD: { - id: 'PAAD', - city: 'Point Thomson Airstrip', - state: 'AK', - lat: 70.136, - lon: -146.2901, - }, - KIAD: { - id: 'KIAD', - city: 'Washington/Dulles International Airport, DC', - state: 'VA', - lat: 38.93472, - lon: -77.4475, - }, - KDCA: { - id: 'KDCA', - city: 'Washington/Reagan National Airport, DC', - state: 'VA', - lat: 38.84833, - lon: -77.03417, - }, - KORF: { - id: 'KORF', - city: 'Norfolk, Norfolk International Airport', - state: 'VA', - lat: 36.90361, - lon: -76.19194, - }, - KROA: { - id: 'KROA', - city: 'Roanoke, Roanoke Regional Airport', - state: 'VA', - lat: 37.31694, - lon: -79.97417, - }, - KRIC: { - id: 'KRIC', - city: 'Richmond, Richmond International Airport', - state: 'VA', - lat: 37.51111, - lon: -77.32333, - }, - KAKQ: { - id: 'KAKQ', - city: 'Wakefield Municipal Airport', - state: 'VA', - lat: 36.98274, - lon: -77.00137, - }, - KWAL: { - id: 'KWAL', - city: 'Wallops Flight Facility Airport', - state: 'VA', - lat: 37.9372, - lon: -75.46619, - }, - KFAF: { - id: 'KFAF', - city: 'Fort Eustis / Felker', - state: 'VA', - lat: 37.13333, - lon: -76.61667, - }, - KLYH: { - id: 'KLYH', - city: 'Lynchburg, Lynchburg Regional Airport', - state: 'VA', - lat: 37.32083, - lon: -79.20667, - }, - KLFI: { - id: 'KLFI', - city: 'Langley Air Force Base', - state: 'VA', - lat: 37.0833299, - lon: -76.35, - }, - KDAA: { - id: 'KDAA', - city: 'Fort Belvoir', - state: 'VA', - lat: 38.71667, - lon: -77.18333, - }, - KDAN: { - id: 'KDAN', - city: 'Danville, Danville Regional Airport', - state: 'VA', - lat: 36.57278, - lon: -79.33611, - }, - KCHO: { - id: 'KCHO', - city: 'Charlottesville-Albemarle Airport', - state: 'VA', - lat: 38.13738, - lon: -78.45516, - }, - KNGU: { - id: 'KNGU', - city: 'Norfolk, Naval Air Station', - state: 'VA', - lat: 36.93361, - lon: -76.29583, - }, - KNTU: { - id: 'KNTU', - city: 'Virginia Beach, Oceana, Naval Air Station', - state: 'VA', - lat: 36.82111, - lon: -76.02833, - }, - KNYG: { - id: 'KNYG', - city: 'Quantico Marine Corps Airfield - Turner Field', - state: 'VA', - lat: 38.50326, - lon: -77.30129, - }, - KPSK: { - id: 'KPSK', - city: 'Dublin / New River Valley', - state: 'VA', - lat: 37.13333, - lon: -80.68333, - }, - KPHF: { - id: 'KPHF', - city: 'Newport News, Newport News / Williamsburg International Airport', - state: 'VA', - lat: 37.13194, - lon: -76.49306, - }, - KLVL: { - id: 'KLVL', - city: 'Lawrenceville/Brunswick Municipal Airport', - state: 'VA', - lat: 36.7727999, - lon: -77.7943, - }, - KEZF: { - id: 'KEZF', - city: 'Fredericksburg, Shannon Airport', - state: 'VA', - lat: 38.26667, - lon: -77.45, - }, - KBCB: { - id: 'KBCB', - city: 'Virginia Tech Airport', - state: 'VA', - lat: 37.21667, - lon: -80.41667, - }, - KFKN: { - id: 'KFKN', - city: 'Franklin / J B Rose', - state: 'VA', - lat: 36.7, - lon: -76.9, - }, - KHSP: { - id: 'KHSP', - city: 'Hot Springs / Ingalls', - state: 'VA', - lat: 37.95, - lon: -79.83333, - }, - KAVC: { - id: 'KAVC', - city: 'South Hill, Mecklenburg-Brunswick Regional Airport', - state: 'VA', - lat: 36.68861, - lon: -78.05417, - }, - KCJR: { - id: 'KCJR', - city: 'Culpeper, Culpeper County Airport', - state: 'VA', - lat: 38.52667, - lon: -77.85889, - }, - KMFV: { - id: 'KMFV', - city: 'Melfa / Accomack Airport', - state: 'VA', - lat: 37.65, - lon: -75.76667, - }, - KLKU: { - id: 'KLKU', - city: 'Louisa, Louisa County Airport/Freeman Field', - state: 'VA', - lat: 38.00972, - lon: -77.97028, - }, - KLNP: { - id: 'KLNP', - city: 'Wise / Lonesome Pine', - state: 'VA', - lat: 36.98333, - lon: -82.53333, - }, - KHEF: { - id: 'KHEF', - city: 'Manassas, Manassas Regional Airport/Harry P. Davis Field', - state: 'VA', - lat: 38.71667, - lon: -77.51667, - }, - KJYO: { - id: 'KJYO', - city: 'Leesburg / Godfrey', - state: 'VA', - lat: 39.0833299, - lon: -77.56667, - }, - KMTV: { - id: 'KMTV', - city: 'Martinsville', - state: 'VA', - lat: 36.63333, - lon: -80.01667, - }, - KCPK: { - id: 'KCPK', - city: 'Chesapeake, Chesapeake Municipal Airport', - state: 'VA', - lat: 36.66556, - lon: -76.32056, - }, - KFVX: { - id: 'KFVX', - city: 'Farmville', - state: 'VA', - lat: 37.35, - lon: -78.43333, - }, - KBKT: { - id: 'KBKT', - city: 'Ft. Pickett / Blackstone', - state: 'VA', - lat: 37.0833299, - lon: -77.95, - }, - KHLX: { - id: 'KHLX', - city: 'Hillsville', - state: 'VA', - lat: 36.76667, - lon: -80.81667, - }, - KMKJ: { - id: 'KMKJ', - city: 'Marion / Wytheville', - state: 'VA', - lat: 36.9, - lon: -81.35, - }, - KOFP: { - id: 'KOFP', - city: 'Ashland, Hanover County Municipal Airport', - state: 'VA', - lat: 37.70806, - lon: -77.43444, - }, - KOMH: { - id: 'KOMH', - city: 'Orange, Orange County Airport', - state: 'VA', - lat: 38.24722, - lon: -78.04556, - }, - KSFQ: { - id: 'KSFQ', - city: 'Suffolk, Suffolk Municipal Airport', - state: 'VA', - lat: 36.68222, - lon: -76.60194, - }, - KSHD: { - id: 'KSHD', - city: 'Staunton / Shenandoah', - state: 'VA', - lat: 38.26667, - lon: -78.9, - }, - KOKV: { - id: 'KOKV', - city: 'Winchester Regional', - state: 'VA', - lat: 39.15, - lon: -78.15, - }, - KPTB: { - id: 'KPTB', - city: 'Petersburg, Dinwiddie County Airport', - state: 'VA', - lat: 37.18333, - lon: -77.51667, - }, - KVJI: { - id: 'KVJI', - city: 'Abingdon', - state: 'VA', - lat: 36.68333, - lon: -82.03333, - }, - KJGG: { - id: 'KJGG', - city: 'Williamsburg-Jamestown Airport', - state: 'VA', - lat: 37.24157, - lon: -76.71672, - }, - KFYJ: { - id: 'KFYJ', - city: 'West Point, Middle Peninsula Regional Airport', - state: 'VA', - lat: 37.52111, - lon: -76.7644399, - }, - KNFE: { - id: 'KNFE', - city: 'Fentress, Naval Auxiliary Landing Field', - state: 'VA', - lat: 36.70083, - lon: -76.12833, - }, - KRMN: { - id: 'KRMN', - city: 'Stafford, Stafford Regional Airport', - state: 'VA', - lat: 38.39806, - lon: -77.45528, - }, - KJFZ: { - id: 'KJFZ', - city: 'Tazewell County Airport', - state: 'VA', - lat: 37.064, - lon: -81.798, - }, - KLUA: { - id: 'KLUA', - city: 'Luray Caverns', - state: 'VA', - lat: 38.6671, - lon: -78.5006, - }, - KFRR: { - id: 'KFRR', - city: 'Front Royal-warren County Airport', - state: 'VA', - lat: 38.9174999, - lon: -78.2535, - }, - KEMV: { - id: 'KEMV', - city: 'Emporia, Emporia-Greensville Regional Airport', - state: 'VA', - lat: 36.68694, - lon: -77.48278, - }, - KHWY: { - id: 'KHWY', - city: 'Warrenton-Fauquier Airport', - state: 'VA', - lat: 38.5876499, - lon: -77.71501, - }, - KXSA: { - id: 'KXSA', - city: 'Tappahannock-Essex County Airport', - state: 'VA', - lat: 37.859611, - lon: -76.894111, - }, - KFCI: { - id: 'KFCI', - city: 'Chesterfield County Airport', - state: 'VA', - lat: 37.406444, - lon: -77.524833, - }, - KPVG: { - id: 'KPVG', - city: 'Norfolk Hampton Roads Executive Airport', - state: 'VA', - lat: 36.7801, - lon: -76.4488, - }, - KGVE: { - id: 'KGVE', - city: 'Gordonsville Municipal Airport', - state: 'VA', - lat: 38.156, - lon: -78.1658, - }, - KCXE: { - id: 'KCXE', - city: 'Chase City Municipal Airport', - state: 'VA', - lat: 36.7883, - lon: -78.5016, - }, - -}; diff --git a/dist/datagenerators/output/stations.json b/dist/datagenerators/output/stations.json deleted file mode 100644 index ac9607c..0000000 --- a/dist/datagenerators/output/stations.json +++ /dev/null @@ -1,15703 +0,0 @@ -{ - "KAIK": { - "id": "KAIK", - "city": "Aiken Municipal Airport", - "state": "SC", - "lat": 33.649, - "lon": -81.685 - }, - "KAND": { - "id": "KAND", - "city": "Anderson, Anderson County Airport", - "state": "SC", - "lat": 34.49778, - "lon": -82.70972 - }, - "KAQX": { - "id": "KAQX", - "city": "Allendale County Airport", - "state": "SC", - "lat": 32.9951, - "lon": -81.2703 - }, - "KARW": { - "id": "KARW", - "city": "Beaufort County Airport", - "state": "SC", - "lat": 32.412, - "lon": -80.634 - }, - "KBBP": { - "id": "KBBP", - "city": "Marlboro County Jetport", - "state": "SC", - "lat": 34.622, - "lon": -79.734 - }, - "KBNL": { - "id": "KBNL", - "city": "Barnwell Regional Airport", - "state": "SC", - "lat": 33.258, - "lon": -81.388 - }, - "KCAE": { - "id": "KCAE", - "city": "Columbia, Columbia Metropolitan Airport", - "state": "SC", - "lat": 33.94194, - "lon": -81.11806 - }, - "KCDN": { - "id": "KCDN", - "city": "Camden Woodward Field", - "state": "SC", - "lat": 34.284, - "lon": -80.565 - }, - "KCEU": { - "id": "KCEU", - "city": "Clemson, Clemson-Oconee County Airport", - "state": "SC", - "lat": 34.67222, - "lon": -82.88139 - }, - "KCHS": { - "id": "KCHS", - "city": "Charleston, Charleston Air Force Base", - "state": "SC", - "lat": 32.89889, - "lon": -80.04056 - }, - "KCKI": { - "id": "KCKI", - "city": "Kingstree Williamsburg Regional Airport", - "state": "SC", - "lat": 33.717, - "lon": -79.857 - }, - "KCQW": { - "id": "KCQW", - "city": "Cheraw Municipal Lynch Bellinger Field", - "state": "SC", - "lat": 34.713, - "lon": -79.9569999 - }, - "KCRE": { - "id": "KCRE", - "city": "North Myrtle Beach Grand Strand Airport", - "state": "SC", - "lat": 33.81619, - "lon": -78.7204299 - }, - "KCUB": { - "id": "KCUB", - "city": "Columbia - Jim Hamilton L.B. Owens Airport", - "state": "SC", - "lat": 33.97083, - "lon": -80.99444 - }, - "KDCM": { - "id": "KDCM", - "city": "Chester Catawba Regional Airport", - "state": "SC", - "lat": 34.789, - "lon": -81.196 - }, - "KDYB": { - "id": "KDYB", - "city": "Summerville Airport", - "state": "SC", - "lat": 33.063, - "lon": -80.279 - }, - "KEOE": { - "id": "KEOE", - "city": "Newberry County Airport", - "state": "SC", - "lat": 34.309, - "lon": -81.64 - }, - "KFDW": { - "id": "KFDW", - "city": "Winnsboro/Fairfield County Airport", - "state": "SC", - "lat": 34.315, - "lon": -81.109 - }, - "KFLO": { - "id": "KFLO", - "city": "Florence - Florence Regional Airport", - "state": "SC", - "lat": 34.1877799, - "lon": -79.73083 - }, - "KGGE": { - "id": "KGGE", - "city": "Georgetown County Airport ", - "state": "SC", - "lat": 33.3117, - "lon": -79.3196 - }, - "KGMU": { - "id": "KGMU", - "city": "Greenville Downtown Airport", - "state": "SC", - "lat": 34.84873, - "lon": -82.35004 - }, - "KGRD": { - "id": "KGRD", - "city": "Greenwood, Greenwood County Airport", - "state": "SC", - "lat": 34.24722, - "lon": -82.15472 - }, - "KGSP": { - "id": "KGSP", - "city": "Greer, Greenville-Spartanburg Airport", - "state": "SC", - "lat": 34.88389, - "lon": -82.22083 - }, - "KGYH": { - "id": "KGYH", - "city": "Greenville-Donaldson Center Airport", - "state": "SC", - "lat": 34.7583, - "lon": -82.3764 - }, - "KHVS": { - "id": "KHVS", - "city": "Hartsville Regional Airport", - "state": "SC", - "lat": 34.403, - "lon": -80.119 - }, - "KHXD": { - "id": "KHXD", - "city": "Hilton Head Island, Hilton Head Airport", - "state": "SC", - "lat": 32.21667, - "lon": -80.7 - }, - "KHYW": { - "id": "KHYW", - "city": "Conway Horry County Airport", - "state": "SC", - "lat": 33.829, - "lon": -79.122 - }, - "KJZI": { - "id": "KJZI", - "city": "Charleston Executive Airport", - "state": "SC", - "lat": 32.701, - "lon": -80.003 - }, - "KLKR": { - "id": "KLKR", - "city": "Lancaster County-mc Whirter Field", - "state": "SC", - "lat": 34.723, - "lon": -80.855 - }, - "KLQK": { - "id": "KLQK", - "city": "Pickens County Airport", - "state": "SC", - "lat": 34.80997, - "lon": -82.70289 - }, - "KLRO": { - "id": "KLRO", - "city": "Mount Pleasant Regional-Faison Field", - "state": "SC", - "lat": 32.898, - "lon": -79.783 - }, - "KLUX": { - "id": "KLUX", - "city": "Laurens County Airport", - "state": "SC", - "lat": 34.507, - "lon": -81.947 - }, - "KMAO": { - "id": "KMAO", - "city": "Marion County Airport", - "state": "SC", - "lat": 34.181, - "lon": -79.3349999 - }, - "KMKS": { - "id": "KMKS", - "city": "Moncks Corner Berkeley County", - "state": "SC", - "lat": 33.1855, - "lon": -80.0361999 - }, - "KMMT": { - "id": "KMMT", - "city": "McEntire Air National Guard Weather Facility Base", - "state": "SC", - "lat": 33.91667, - "lon": -80.8 - }, - "KMNI": { - "id": "KMNI", - "city": "Manning / Cooper Regional", - "state": "SC", - "lat": 33.5833299, - "lon": -80.2166699 - }, - "KMYR": { - "id": "KMYR", - "city": "Myrtle Beach International Airport", - "state": "SC", - "lat": 33.67975, - "lon": -78.92833 - }, - "KNBC": { - "id": "KNBC", - "city": "Beaufort, Marine Corps Air Station", - "state": "SC", - "lat": 32.4936099, - "lon": -80.7030599 - }, - "KOGB": { - "id": "KOGB", - "city": "Orangeburg, Orangeburg Municipal Airport", - "state": "SC", - "lat": 33.46389, - "lon": -80.85361 - }, - "KRBW": { - "id": "KRBW", - "city": "Walterboro Lowcountry Regional Airport", - "state": "SC", - "lat": 32.921, - "lon": -80.641 - }, - "KSMS": { - "id": "KSMS", - "city": "Sumter Airport", - "state": "SC", - "lat": 33.995, - "lon": -80.361 - }, - "KSPA": { - "id": "KSPA", - "city": "Spartanburg Memorial", - "state": "SC", - "lat": 34.91667, - "lon": -81.95 - }, - "KSSC": { - "id": "KSSC", - "city": "Shaw Air Force Base", - "state": "SC", - "lat": 33.96667, - "lon": -80.48333 - }, - "KUDG": { - "id": "KUDG", - "city": "Darlington, Darlington County Jetport Airport", - "state": "SC", - "lat": 34.44917, - "lon": -79.89028 - }, - "KUZA": { - "id": "KUZA", - "city": "Rock Hill, Rock Hill - York County Airport", - "state": "SC", - "lat": 34.98389, - "lon": -81.05583 - }, - "KXNO": { - "id": "KXNO", - "city": "North Air Force Auxiliary Field", - "state": "SC", - "lat": 33.60949, - "lon": -81.08118 - }, - "KBTV": { - "id": "KBTV", - "city": "Burlington, Burlington International Airport", - "state": "VT", - "lat": 44.46806, - "lon": -73.15028 - }, - "KCDA": { - "id": "KCDA", - "city": "Caledonia County Airport", - "state": "VT", - "lat": 44.5691142, - "lon": -72.0179789 - }, - "KDDH": { - "id": "KDDH", - "city": "Bennington Morse State Airport", - "state": "VT", - "lat": 42.89355, - "lon": -73.2486 - }, - "KEFK": { - "id": "KEFK", - "city": "Northeast Kingdom International Airport", - "state": "VT", - "lat": 44.88846, - "lon": -72.23593 - }, - "KFSO": { - "id": "KFSO", - "city": "Franklin County State Airport", - "state": "VT", - "lat": 44.9402807, - "lon": -73.09746 - }, - "KMPV": { - "id": "KMPV", - "city": "Barre / Montpelier, Knapp State Airport", - "state": "VT", - "lat": 44.20472, - "lon": -72.56611 - }, - "KMVL": { - "id": "KMVL", - "city": "Morrisville-Stowe State Airport", - "state": "VT", - "lat": 44.53589, - "lon": -72.6162499 - }, - "KRUT": { - "id": "KRUT", - "city": "Rutland-Southern Vermont Regional Airport", - "state": "VT", - "lat": 43.53333, - "lon": -72.95 - }, - "KVSF": { - "id": "KVSF", - "city": "Springfield, Hartness State Springfield Airport", - "state": "VT", - "lat": 43.3425, - "lon": -72.52167 - }, - "KABR": { - "id": "KABR", - "city": "Aberdeen, Aberdeen Regional Airport", - "state": "SD", - "lat": 45.44333, - "lon": -98.41306 - }, - "KAGZ": { - "id": "KAGZ", - "city": "WAGNERMUNC", - "state": "SD", - "lat": 43.06332, - "lon": -98.29618 - }, - "KATY": { - "id": "KATY", - "city": "Watertown, Watertown Municipal Airport", - "state": "SD", - "lat": 44.90472, - "lon": -97.14944 - }, - "KBKX": { - "id": "KBKX", - "city": "Brookings, Brookings Municipal Airport", - "state": "SD", - "lat": 44.3, - "lon": -96.81667 - }, - "KCUT": { - "id": "KCUT", - "city": "Custer, Custer County Airport", - "state": "SD", - "lat": 43.73306, - "lon": -103.6175 - }, - "KEFC": { - "id": "KEFC", - "city": "BELLEFCHE", - "state": "SD", - "lat": 44.7342, - "lon": -103.86199 - }, - "KFSD": { - "id": "KFSD", - "city": "Sioux Falls, Foss Field", - "state": "SD", - "lat": 43.57694, - "lon": -96.75361 - }, - "KHON": { - "id": "KHON", - "city": "Huron, Huron Regional Airport", - "state": "SD", - "lat": 44.38806, - "lon": -98.22833 - }, - "KICR": { - "id": "KICR", - "city": "Winner, Bob Wiley Field Airport", - "state": "SD", - "lat": 43.39056, - "lon": -99.8425 - }, - "KIEN": { - "id": "KIEN", - "city": "Pine Ridge, Pine Ridge Airport", - "state": "SD", - "lat": 43.02556, - "lon": -102.52306 - }, - "KLEM": { - "id": "KLEM", - "city": "LEMMON", - "state": "SD", - "lat": 45.91869, - "lon": -102.10617 - }, - "KMBG": { - "id": "KMBG", - "city": "Mobridge, Mobridge Municipal Airport", - "state": "SD", - "lat": 45.55, - "lon": -100.40861 - }, - "KMDS": { - "id": "KMDS", - "city": "Madison Municipal Airport", - "state": "SD", - "lat": 44.0164147, - "lon": -97.0855992 - }, - "KMHE": { - "id": "KMHE", - "city": "Mitchell, Mitchell Municipal Airport", - "state": "SD", - "lat": 43.76667, - "lon": -98.03333 - }, - "KMKA": { - "id": "KMKA", - "city": "MILLERMUNC", - "state": "SD", - "lat": 44.5252399, - "lon": -98.95811 - }, - "KPHP": { - "id": "KPHP", - "city": "Philip, Philip Airport", - "state": "SD", - "lat": 44.05111, - "lon": -101.60111 - }, - "KPIR": { - "id": "KPIR", - "city": "Pierre, Pierre Regional Airport", - "state": "SD", - "lat": 44.3827799, - "lon": -100.28583 - }, - "KRAP": { - "id": "KRAP", - "city": "Rapid City, Rapid City Regional Airport", - "state": "SD", - "lat": 44.04556, - "lon": -103.05389 - }, - "KRCA": { - "id": "KRCA", - "city": "Ellsworth Air Force Base", - "state": "SD", - "lat": 44.15, - "lon": -103.1 - }, - "KSPF": { - "id": "KSPF", - "city": "Spearfish / Clyde Ice", - "state": "SD", - "lat": 44.48333, - "lon": -103.78333 - }, - "KUNR": { - "id": "KUNR", - "city": "Rapid City/WFO", - "state": "SD", - "lat": 44.0727, - "lon": -103.2108 - }, - "KVMR": { - "id": "KVMR", - "city": "VERMILLION", - "state": "SD", - "lat": 42.76528, - "lon": -96.93425 - }, - "KYKN": { - "id": "KYKN", - "city": "Yankton, Chan Gurney Municipal Airport", - "state": "SD", - "lat": 42.91667, - "lon": -97.38333 - }, - "KAIG": { - "id": "KAIG", - "city": "Langlade County Airport", - "state": "WI", - "lat": 45.15659, - "lon": -89.11144 - }, - "KARV": { - "id": "KARV", - "city": "Minocqua/Woodruff, Lakeland Airport/Noble F. Lee Memorial Field", - "state": "WI", - "lat": 45.93333, - "lon": -89.73333 - }, - "KASX": { - "id": "KASX", - "city": "John F Kennedy Memorial Airport", - "state": "WI", - "lat": 46.54679, - "lon": -90.91841 - }, - "KATW": { - "id": "KATW", - "city": "Appleton-Outagamie", - "state": "WI", - "lat": 44.2595, - "lon": -88.51567 - }, - "KAUW": { - "id": "KAUW", - "city": "Wausau Downtown Airport", - "state": "WI", - "lat": 44.92759, - "lon": -89.62512 - }, - "KBCK": { - "id": "KBCK", - "city": "Black River Falls Area Airport", - "state": "WI", - "lat": 44.24996, - "lon": -90.84999 - }, - "KBUU": { - "id": "KBUU", - "city": "Burlington Municipal Airport", - "state": "WI", - "lat": 42.69088, - "lon": -88.308 - }, - "KCMY": { - "id": "KCMY", - "city": "Sparta, Sparta / Fort McCoy Airport", - "state": "WI", - "lat": 43.9583299, - "lon": -90.73778 - }, - "KCWA": { - "id": "KCWA", - "city": "Mosinee", - "state": "WI", - "lat": 44.77944, - "lon": -89.67098 - }, - "KDLL": { - "id": "KDLL", - "city": "Baraboo Wisconsin Dells Airport", - "state": "WI", - "lat": 43.52372, - "lon": -89.77345 - }, - "KEAU": { - "id": "KEAU", - "city": "Chippewa Valley Regional Airport", - "state": "WI", - "lat": 44.86668, - "lon": -91.488 - }, - "KEFT": { - "id": "KEFT", - "city": "Monroe Municipal Airport", - "state": "WI", - "lat": 42.61959, - "lon": -89.59309 - }, - "KEGV": { - "id": "KEGV", - "city": "Eagle River Union Airport", - "state": "WI", - "lat": 45.9309299, - "lon": -89.26702 - }, - "KENW": { - "id": "KENW", - "city": "Kenosha, Kenosha Regional Airport", - "state": "WI", - "lat": 42.595, - "lon": -87.9380599 - }, - "KETB": { - "id": "KETB", - "city": "West Bend Municipal Airport", - "state": "WI", - "lat": 43.42256, - "lon": -88.1326 - }, - "KEZS": { - "id": "KEZS", - "city": "Shawano Municipal Airport", - "state": "WI", - "lat": 44.787, - "lon": -88.56 - }, - "KFLD": { - "id": "KFLD", - "city": "Fond Du Lac County Airport", - "state": "WI", - "lat": 43.76955, - "lon": -88.49072 - }, - "KGRB": { - "id": "KGRB", - "city": "Green Bay, Austin Straubel International Airport", - "state": "WI", - "lat": 44.4794399, - "lon": -88.13667 - }, - "KHYR": { - "id": "KHYR", - "city": "Sawyer County Airport", - "state": "WI", - "lat": 46.03029, - "lon": -91.44259 - }, - "KISW": { - "id": "KISW", - "city": "Wisconsin Rapids, Alexander Field South Wood County Airport", - "state": "WI", - "lat": 44.35917, - "lon": -89.83694 - }, - "KJVL": { - "id": "KJVL", - "city": "Janesville-Rock County", - "state": "WI", - "lat": 42.62135, - "lon": -89.04186 - }, - "KLNL": { - "id": "KLNL", - "city": "Land O' Lakes, Kings Land O' Lakes Airport", - "state": "WI", - "lat": 46.1538899, - "lon": -89.21194 - }, - "KLNR": { - "id": "KLNR", - "city": "Lone Rock Tri-County Regional Airport", - "state": "WI", - "lat": 43.21108, - "lon": -90.18735 - }, - "KLSE": { - "id": "KLSE", - "city": "La Crosse - La Crosse Regional Airport", - "state": "WI", - "lat": 43.87944, - "lon": -91.25667 - }, - "KLUM": { - "id": "KLUM", - "city": "Menomonie Municipal Airport-Score Field", - "state": "WI", - "lat": 44.89363, - "lon": -91.86652 - }, - "KMDZ": { - "id": "KMDZ", - "city": "Taylor County Airport", - "state": "WI", - "lat": 45.10462, - "lon": -90.30253 - }, - "KMFI": { - "id": "KMFI", - "city": "Marshfield, Marshfield Municipal Airport", - "state": "WI", - "lat": 44.63806, - "lon": -90.1875 - }, - "KMKE": { - "id": "KMKE", - "city": "Milwaukee, General Mitchell International Airport", - "state": "WI", - "lat": 42.955, - "lon": -87.9044399 - }, - "KMRJ": { - "id": "KMRJ", - "city": "Iowa County Airport", - "state": "WI", - "lat": 42.88754, - "lon": -90.23147 - }, - "KMSN": { - "id": "KMSN", - "city": "Madison, Dane County Regional-Truax Field", - "state": "WI", - "lat": 43.14056, - "lon": -89.34528 - }, - "KMTW": { - "id": "KMTW", - "city": "Manitowoc, Manitowoc County Airport", - "state": "WI", - "lat": 44.13333, - "lon": -87.68333 - }, - "KMWC": { - "id": "KMWC", - "city": "Milwaukee-Timmerman", - "state": "WI", - "lat": 43.10961, - "lon": -88.03048 - }, - "KOCQ": { - "id": "KOCQ", - "city": "Oconto J. Douglas Bake Municipal Airport", - "state": "WI", - "lat": 44.8742, - "lon": -87.9096 - }, - "KOEO": { - "id": "KOEO", - "city": "L O Simenstad Municipal Airport", - "state": "WI", - "lat": 45.31084, - "lon": -92.6948 - }, - "KOLG": { - "id": "KOLG", - "city": "Solon Springs Municipal Airport", - "state": "WI", - "lat": 46.3148, - "lon": -91.8164 - }, - "KOSH": { - "id": "KOSH", - "city": "Wittman Regional Airport", - "state": "WI", - "lat": 43.96701, - "lon": -88.55814 - }, - "KOVS": { - "id": "KOVS", - "city": "Boscobel, Boscobel Airport", - "state": "WI", - "lat": 43.15611, - "lon": -90.6775 - }, - "KPBH": { - "id": "KPBH", - "city": "Phillips / Price County", - "state": "WI", - "lat": 45.7, - "lon": -90.4 - }, - "KPCZ": { - "id": "KPCZ", - "city": "Waupaca Municipal Airport", - "state": "WI", - "lat": 44.33425, - "lon": -89.02023 - }, - "KPDC": { - "id": "KPDC", - "city": "Prairie Du Chien Municipal Airport", - "state": "WI", - "lat": 43.01938, - "lon": -91.12112 - }, - "KPVB": { - "id": "KPVB", - "city": "Platteville Municipal Airport", - "state": "WI", - "lat": 42.69092, - "lon": -90.4412399 - }, - "KRAC": { - "id": "KRAC", - "city": "Racine, Batten International Airport", - "state": "WI", - "lat": 42.75861, - "lon": -87.81778 - }, - "KRCX": { - "id": "KRCX", - "city": "Ladysmith - Rusk County Airport", - "state": "WI", - "lat": 45.4935, - "lon": -90.9985 - }, - "KRGK": { - "id": "KRGK", - "city": "Red Wing - Red Wing Regional Airport", - "state": "WI", - "lat": 44.5926, - "lon": -92.48439 - }, - "KRHI": { - "id": "KRHI", - "city": "Rhinelander, Rhinelander-Oneida County Airport", - "state": "WI", - "lat": 45.63167, - "lon": -89.48222 - }, - "KRNH": { - "id": "KRNH", - "city": "New Richmond Municipal Airport", - "state": "WI", - "lat": 45.14762, - "lon": -92.53349 - }, - "KRPD": { - "id": "KRPD", - "city": "Rice Lake, Rice Lake Regional-Carl's Field Airport", - "state": "WI", - "lat": 45.4180599, - "lon": -91.77361 - }, - "KRRL": { - "id": "KRRL", - "city": "Merrill, Merrill Municipal Airport", - "state": "WI", - "lat": 45.19844, - "lon": -89.70996 - }, - "KRYV": { - "id": "KRYV", - "city": "Watertown", - "state": "WI", - "lat": 43.17016, - "lon": -88.72497 - }, - "KRZN": { - "id": "KRZN", - "city": "Siren, Burnett County Airport", - "state": "WI", - "lat": 45.82278, - "lon": -92.3725 - }, - "KSBM": { - "id": "KSBM", - "city": "Sheboygan County Memorial Airport", - "state": "WI", - "lat": 43.77483, - "lon": -87.84897 - }, - "KSTE": { - "id": "KSTE", - "city": "Stevens Point Municipal Airport", - "state": "WI", - "lat": 44.54371, - "lon": -89.53468 - }, - "KSUE": { - "id": "KSUE", - "city": "Door County Cherryland Airport", - "state": "WI", - "lat": 44.83941, - "lon": -87.42188 - }, - "KSUW": { - "id": "KSUW", - "city": "Richard I. Bong Airport", - "state": "WI", - "lat": 46.68335, - "lon": -92.09254 - }, - "KTKV": { - "id": "KTKV", - "city": "Tomahawk Regional Airport", - "state": "WI", - "lat": 45.46801, - "lon": -89.80962 - }, - "KUBE": { - "id": "KUBE", - "city": "Cumberland", - "state": "WI", - "lat": 45.506, - "lon": -91.9811 - }, - "KUES": { - "id": "KUES", - "city": "Waukesha County Airport", - "state": "WI", - "lat": 43.04245, - "lon": -88.24607 - }, - "KUNU": { - "id": "KUNU", - "city": "Juneau, Dodge County Airport", - "state": "WI", - "lat": 43.42667, - "lon": -88.7033299 - }, - "KVOK": { - "id": "KVOK", - "city": "Volk / Camp Douglas", - "state": "WI", - "lat": 43.93333, - "lon": -90.26667 - }, - "KADH": { - "id": "KADH", - "city": "Ada, Ada Municipal Airport", - "state": "OK", - "lat": 34.80444, - "lon": -96.67139 - }, - "KADM": { - "id": "KADM", - "city": "Ardmore, Ardmore Municipal Airport", - "state": "OK", - "lat": 34.30306, - "lon": -97.01944 - }, - "KAVK": { - "id": "KAVK", - "city": "Alva, Alva Regional Airport", - "state": "OK", - "lat": 36.77306, - "lon": -98.67 - }, - "KAXS": { - "id": "KAXS", - "city": "Altus, Altus/Quartz Mountain Regional Airport", - "state": "OK", - "lat": 34.69861, - "lon": -99.33806 - }, - "KBKN": { - "id": "KBKN", - "city": "Blackwell-Tonkawa Municipal Airport", - "state": "OK", - "lat": 36.7451099, - "lon": -97.34958 - }, - "KBVO": { - "id": "KBVO", - "city": "Bartlesville, Bartlesville Municipal Airport", - "state": "OK", - "lat": 36.76833, - "lon": -96.02611 - }, - "KCHK": { - "id": "KCHK", - "city": "Chickasha, Chickasha Municipal Airport", - "state": "OK", - "lat": 35.09611, - "lon": -97.96611 - }, - "KCLK": { - "id": "KCLK", - "city": "Clinton, Clinton Regional Airport", - "state": "OK", - "lat": 35.53806, - "lon": -98.92139 - }, - "KCQB": { - "id": "KCQB", - "city": "Chandler, Chandler Municipal Airport", - "state": "OK", - "lat": 35.72389, - "lon": -96.82028 - }, - "KCSM": { - "id": "KCSM", - "city": "Clinton, Clinton-Sherman Airport", - "state": "OK", - "lat": 35.35667, - "lon": -99.20361 - }, - "KCUH": { - "id": "KCUH", - "city": "Cushing, Cushing Municipal Airport", - "state": "OK", - "lat": 35.94972, - "lon": -96.77278 - }, - "KDUA": { - "id": "KDUA", - "city": "Durant, Eaker Field Airport", - "state": "OK", - "lat": 33.94222, - "lon": -96.39444 - }, - "KDUC": { - "id": "KDUC", - "city": "Duncan, Halliburton Field Airport", - "state": "OK", - "lat": 34.47083, - "lon": -97.9599999 - }, - "KELK": { - "id": "KELK", - "city": "Elk City Regional Business Airport", - "state": "OK", - "lat": 35.4308, - "lon": -99.3943 - }, - "KEND": { - "id": "KEND", - "city": "Vance Air Force Base / Enid", - "state": "OK", - "lat": 36.3333299, - "lon": -97.91667 - }, - "KFDR": { - "id": "KFDR", - "city": "Frederick, Frederick Municipal Airport", - "state": "OK", - "lat": 34.34444, - "lon": -98.98306 - }, - "KFSI": { - "id": "KFSI", - "city": "Fort Sill", - "state": "OK", - "lat": 34.6, - "lon": -98.4 - }, - "KGAG": { - "id": "KGAG", - "city": "Gage, Gage Airport", - "state": "OK", - "lat": 36.29667, - "lon": -99.76889 - }, - "KGCM": { - "id": "KGCM", - "city": "Claremore, Claremore Regional Airport", - "state": "OK", - "lat": 36.29444, - "lon": -95.47972 - }, - "KGMJ": { - "id": "KGMJ", - "city": "Grove, Grove Municipal Airport", - "state": "OK", - "lat": 36.60528, - "lon": -94.73861 - }, - "KGOK": { - "id": "KGOK", - "city": "Guthrie, Guthrie Municipal Airport", - "state": "OK", - "lat": 35.85194, - "lon": -97.4075 - }, - "KGUY": { - "id": "KGUY", - "city": "Guymon / Guymon Municipal Airport", - "state": "OK", - "lat": 36.6816699, - "lon": -101.50528 - }, - "KGZL": { - "id": "KGZL", - "city": "Stigler", - "state": "OK", - "lat": 35.2891, - "lon": -95.0939 - }, - "KHBR": { - "id": "KHBR", - "city": "Hobart, Hobart Municipal Airport", - "state": "OK", - "lat": 34.98944, - "lon": -99.0525 - }, - "KHHW": { - "id": "KHHW", - "city": "Hugo Stan Stamper Municipal Airport", - "state": "OK", - "lat": 34.0348, - "lon": -95.5419 - }, - "KHMY": { - "id": "KHMY", - "city": "MULDROWARMY", - "state": "OK", - "lat": 35.02638, - "lon": -97.23163 - }, - "KHSD": { - "id": "KHSD", - "city": "Sundance Airport", - "state": "OK", - "lat": 35.60183, - "lon": -97.70616 - }, - "KJSV": { - "id": "KJSV", - "city": "Sallisaw, Sallisaw Municipal Airport", - "state": "OK", - "lat": 35.43806, - "lon": -94.80278 - }, - "KJWG": { - "id": "KJWG", - "city": "Watonga, Watonga Airport", - "state": "OK", - "lat": 35.86472, - "lon": -98.42083 - }, - "KLAW": { - "id": "KLAW", - "city": "Lawton, Lawton Municipal Airport", - "state": "OK", - "lat": 34.5575, - "lon": -98.41667 - }, - "KLTS": { - "id": "KLTS", - "city": "Altus Air Force Base", - "state": "OK", - "lat": 34.65, - "lon": -99.26667 - }, - "KMIO": { - "id": "KMIO", - "city": "Miami Regional Airport", - "state": "OK", - "lat": 36.90922, - "lon": -94.8875 - }, - "KMKO": { - "id": "KMKO", - "city": "Muskogee-Davis Regional Airport", - "state": "OK", - "lat": 35.65694, - "lon": -95.35972 - }, - "KMLC": { - "id": "KMLC", - "city": "McAlester, McAlester Regional Airport", - "state": "OK", - "lat": 34.8822199, - "lon": -95.78306 - }, - "KOJA": { - "id": "KOJA", - "city": "Weatherford, Thomas P Stafford Airport", - "state": "OK", - "lat": 35.54472, - "lon": -98.66833 - }, - "KOKC": { - "id": "KOKC", - "city": "Oklahoma City, Will Rogers World Airport", - "state": "OK", - "lat": 35.38861, - "lon": -97.60028 - }, - "KOKM": { - "id": "KOKM", - "city": "Okmulgee, Okmulgee Municipal Airport", - "state": "OK", - "lat": 35.6680599, - "lon": -95.94861 - }, - "KOUN": { - "id": "KOUN", - "city": "Norman / Max Westheimer", - "state": "OK", - "lat": 35.2435, - "lon": -97.4708 - }, - "KOWP": { - "id": "KOWP", - "city": "William R Pogue Municipal Airport", - "state": "OK", - "lat": 36.1753, - "lon": -96.1518 - }, - "KPNC": { - "id": "KPNC", - "city": "Ponca City, Ponca City Municipal Airport", - "state": "OK", - "lat": 36.7305599, - "lon": -97.09972 - }, - "KPVJ": { - "id": "KPVJ", - "city": "Pauls Valley, Pauls Valley Municipal Airport", - "state": "OK", - "lat": 34.71111, - "lon": -97.22333 - }, - "KPWA": { - "id": "KPWA", - "city": "Oklahoma City, Wiley Post Airport", - "state": "OK", - "lat": 35.54111, - "lon": -97.64667 - }, - "KRCE": { - "id": "KRCE", - "city": "Clarence E Page Municipal Airport", - "state": "OK", - "lat": 35.4880799, - "lon": -97.82356 - }, - "KRKR": { - "id": "KRKR", - "city": "Poteau, Robert S Kerr Airport", - "state": "OK", - "lat": 35.02167, - "lon": -94.62139 - }, - "KRQO": { - "id": "KRQO", - "city": "El Reno, El Reno Regional Airport", - "state": "OK", - "lat": 35.4724999, - "lon": -98.00556 - }, - "KRVS": { - "id": "KRVS", - "city": "Tulsa - Jones Jr. Airport", - "state": "OK", - "lat": 36.04255, - "lon": -95.99005 - }, - "KSNL": { - "id": "KSNL", - "city": "Shawnee, Shawnee Municipal Airport", - "state": "OK", - "lat": 35.35722, - "lon": -96.94278 - }, - "KSRE": { - "id": "KSRE", - "city": "Seminole, Seminole Municipal Airport", - "state": "OK", - "lat": 35.27444, - "lon": -96.675 - }, - "KSWO": { - "id": "KSWO", - "city": "Stillwater, Stillwater Regional Airport", - "state": "OK", - "lat": 36.16222, - "lon": -97.08917 - }, - "KTIK": { - "id": "KTIK", - "city": "Tinker Air Force Base", - "state": "OK", - "lat": 35.41667, - "lon": -97.38333 - }, - "KTQH": { - "id": "KTQH", - "city": "Tahlequah, Tahlequah Municipal Airport", - "state": "OK", - "lat": 35.92889, - "lon": -95.00444 - }, - "KTUL": { - "id": "KTUL", - "city": "Tulsa, Tulsa International Airport", - "state": "OK", - "lat": 36.1975, - "lon": -95.88639 - }, - "KWDG": { - "id": "KWDG", - "city": "Enid, Enid Woodring Regional Airport", - "state": "OK", - "lat": 36.37917, - "lon": -97.79111 - }, - "KWWR": { - "id": "KWWR", - "city": "Woodward, West Woodward Airport", - "state": "OK", - "lat": 36.43667, - "lon": -99.5211099 - }, - "KAFO": { - "id": "KAFO", - "city": "Afton WY", - "state": "WY", - "lat": 42.7113299, - "lon": -110.94217 - }, - "KARL": { - "id": "KARL", - "city": "I80 - Arlington", - "state": "WY", - "lat": 41.5980599, - "lon": -106.21487 - }, - "KBFU": { - "id": "KBFU", - "city": "WY59 - Belle Fourche", - "state": "WY", - "lat": 43.93253, - "lon": -105.4467 - }, - "KBIT": { - "id": "KBIT", - "city": "I80/US30 - Bitter Creek", - "state": "WY", - "lat": 41.64599, - "lon": -108.5836 - }, - "KBPI": { - "id": "KBPI", - "city": "Big Piney - Marbleton Airport", - "state": "WY", - "lat": 42.57805, - "lon": -110.10972 - }, - "KBRX": { - "id": "KBRX", - "city": "I25/US87 - Bordeaux Interchange", - "state": "WY", - "lat": 41.93066, - "lon": -104.9436 - }, - "KBVR": { - "id": "KBVR", - "city": "US287/WY789 - Beaver Rim", - "state": "WY", - "lat": 42.58565, - "lon": -108.28199 - }, - "KBYG": { - "id": "KBYG", - "city": "Buffalo - Johnson County Airport", - "state": "WY", - "lat": 44.38122, - "lon": -106.71947 - }, - "KCHJ": { - "id": "KCHJ", - "city": "WY296 - Chief Joseph", - "state": "WY", - "lat": 44.73997, - "lon": -109.38088 - }, - "KCMS": { - "id": "KCMS", - "city": "I80/US30 - Peru Hill", - "state": "WY", - "lat": 41.54958, - "lon": -109.60197 - }, - "KCOD": { - "id": "KCOD", - "city": "Cody", - "state": "WY", - "lat": 44.51667, - "lon": -109.01667 - }, - "KCPR": { - "id": "KCPR", - "city": "Casper, Natrona County International Airport", - "state": "WY", - "lat": 42.8975, - "lon": -106.47306 - }, - "KCTD": { - "id": "KCTD", - "city": "I80/US30 - Continental Divide", - "state": "WY", - "lat": 41.71586, - "lon": -107.78256 - }, - "KCYS": { - "id": "KCYS", - "city": "Cheyenne, Cheyenne Airport", - "state": "WY", - "lat": 41.15789, - "lon": -104.80812 - }, - "KDGW": { - "id": "KDGW", - "city": "Douglas, Converse County Airport", - "state": "WY", - "lat": 42.79417, - "lon": -105.38194 - }, - "KDHS": { - "id": "KDHS", - "city": "I90 - Dead Horse", - "state": "WY", - "lat": 44.21906, - "lon": -106.10478 - }, - "KDRC": { - "id": "KDRC", - "city": "I25 - Deer Creek", - "state": "WY", - "lat": 42.83687, - "lon": -105.86063 - }, - "KDUB": { - "id": "KDUB", - "city": "Dubois Municipal Airport", - "state": "WY", - "lat": 43.5484, - "lon": -109.6903 - }, - "KDWX": { - "id": "KDWX", - "city": "Dixon Airport", - "state": "WY", - "lat": 41.03704, - "lon": -107.49976 - }, - "KEAN": { - "id": "KEAN", - "city": "Phifer Airfield - Wheatland", - "state": "WY", - "lat": 42.05472, - "lon": -104.93711 - }, - "KECS": { - "id": "KECS", - "city": "Mondell Field", - "state": "WY", - "lat": 43.8854, - "lon": -104.3179 - }, - "KEHY": { - "id": "KEHY", - "city": "Elk Mountain AWOS", - "state": "WY", - "lat": 41.7253, - "lon": -106.4594 - }, - "KEMM": { - "id": "KEMM", - "city": "KEMMERER", - "state": "WY", - "lat": 41.82, - "lon": -110.56 - }, - "KEVW": { - "id": "KEVW", - "city": "Evanston, Evanston-Uinta County Burns Field", - "state": "WY", - "lat": 41.27306, - "lon": -111.03056 - }, - "KFBR": { - "id": "KFBR", - "city": "Fort Bridger WY", - "state": "WY", - "lat": 41.392, - "lon": -110.40683 - }, - "KFEW": { - "id": "KFEW", - "city": "Francis E Warren Air Force Base Heliport", - "state": "WY", - "lat": 41.13332, - "lon": -104.8671899 - }, - "KFIR": { - "id": "KFIR", - "city": "I80/US189 - First Divide", - "state": "WY", - "lat": 41.27649, - "lon": -110.80066 - }, - "KGCC": { - "id": "KGCC", - "city": "Gillette, Gillette-Campbell County Airport", - "state": "WY", - "lat": 44.33944, - "lon": -105.54194 - }, - "KGEY": { - "id": "KGEY", - "city": "South Big Horn County Airport", - "state": "WY", - "lat": 44.5174, - "lon": -108.0752 - }, - "KGUN": { - "id": "KGUN", - "city": "US85 - Gun Barrel", - "state": "WY", - "lat": 41.44368, - "lon": -104.34428 - }, - "KGUR": { - "id": "KGUR", - "city": "Camp Guernsey", - "state": "WY", - "lat": 42.2597, - "lon": -104.7283 - }, - "KHLD": { - "id": "KHLD", - "city": "US20/US26 - Hiland", - "state": "WY", - "lat": 43.0923, - "lon": -107.32198 - }, - "KHSG": { - "id": "KHSG", - "city": "Hot Springs County Airport", - "state": "WY", - "lat": 43.7136, - "lon": -108.3897 - }, - "KIDV": { - "id": "KIDV", - "city": "I25/US87 - I-25 Divide", - "state": "WY", - "lat": 43.89864, - "lon": -106.63833 - }, - "KIKA": { - "id": "KIKA", - "city": "I90 - Inyan Kara", - "state": "WY", - "lat": 44.29414, - "lon": -104.62926 - }, - "KJAC": { - "id": "KJAC", - "city": "Jackson, Jackson Hole Airport", - "state": "WY", - "lat": 43.6, - "lon": -110.73333 - }, - "KLAR": { - "id": "KLAR", - "city": "Laramie Regional Airport", - "state": "WY", - "lat": 41.3165, - "lon": -105.67287 - }, - "KLND": { - "id": "KLND", - "city": "Lander", - "state": "WY", - "lat": 42.81472, - "lon": -108.72806 - }, - "KMTR": { - "id": "KMTR", - "city": "WY120 - Meeteetse Rim", - "state": "WY", - "lat": 44.27011, - "lon": -108.87343 - }, - "KPAT": { - "id": "KPAT", - "city": "WY220 - Pathfinder", - "state": "WY", - "lat": 42.5581, - "lon": -106.8453399 - }, - "KPER": { - "id": "KPER", - "city": "I80/US30 - Green River Tunnel East", - "state": "WY", - "lat": 41.53186, - "lon": -109.45995 - }, - "KPNA": { - "id": "KPNA", - "city": "Pinedale, Ralph Wenz Field Airport", - "state": "WY", - "lat": 42.79528, - "lon": -109.80694 - }, - "KPOY": { - "id": "KPOY", - "city": "Powell Municipal Airport", - "state": "WY", - "lat": 44.8671999, - "lon": -108.7934 - }, - "KPUM": { - "id": "KPUM", - "city": "US287 - Pumpkin Vine", - "state": "WY", - "lat": 41.05218, - "lon": -105.46906 - }, - "KREC": { - "id": "KREC", - "city": "WY28 - Lower Red Canyon", - "state": "WY", - "lat": 42.61795, - "lon": -108.61093 - }, - "KRIW": { - "id": "KRIW", - "city": "Riverton Regional Airport", - "state": "WY", - "lat": 43.06219, - "lon": -108.44701 - }, - "KRKS": { - "id": "KRKS", - "city": "Rock Springs, Rock Springs-Sweetwater County Airport", - "state": "WY", - "lat": 41.59417, - "lon": -109.06528 - }, - "KRWL": { - "id": "KRWL", - "city": "Rawlins Municipal Airport", - "state": "WY", - "lat": 41.80648, - "lon": -107.19516 - }, - "KSAA": { - "id": "KSAA", - "city": "Saratoga WY", - "state": "WY", - "lat": 41.44483, - "lon": -106.8235 - }, - "KSGE": { - "id": "KSGE", - "city": "US30 - Sage Junction", - "state": "WY", - "lat": 41.82447, - "lon": -110.90764 - }, - "KSHC": { - "id": "KSHC", - "city": "WY372 - Shute Creek", - "state": "WY", - "lat": 41.94409, - "lon": -110.00399 - }, - "KSHR": { - "id": "KSHR", - "city": "Sheridan County Airport", - "state": "WY", - "lat": 44.7603099, - "lon": -106.97411 - }, - "KSKL": { - "id": "KSKL", - "city": "WY230 - Skyline", - "state": "WY", - "lat": 41.13753, - "lon": -106.57687 - }, - "KSOU": { - "id": "KSOU", - "city": "WY28 - South Pass", - "state": "WY", - "lat": 42.47752, - "lon": -108.8444 - }, - "KTBX": { - "id": "KTBX", - "city": "Boysen", - "state": "WY", - "lat": 43.4667, - "lon": -108.2333 - }, - "KTET": { - "id": "KTET", - "city": "WY22 - Teton Pass", - "state": "WY", - "lat": 43.49873, - "lon": -110.9562 - }, - "KTMH": { - "id": "KTMH", - "city": "I25/US87 - Twenty Mile Hill", - "state": "WY", - "lat": 43.12271, - "lon": -106.33705 - }, - "KTOR": { - "id": "KTOR", - "city": "Torrington Municipal Airport", - "state": "WY", - "lat": 42.06134, - "lon": -104.15842 - }, - "KVDW": { - "id": "KVDW", - "city": "I80/US30 - Vedauwoo", - "state": "WY", - "lat": 41.15687, - "lon": -105.40237 - }, - "KWRL": { - "id": "KWRL", - "city": "Worland, Worland Municipal Airport", - "state": "WY", - "lat": 43.9658299, - "lon": -107.95083 - }, - "KWTR": { - "id": "KWTR", - "city": "I25/US87 - Whitaker", - "state": "WY", - "lat": 41.41772, - "lon": -104.87502 - }, - "KWYH": { - "id": "KWYH", - "city": "I25/US87 - Wyo Hill", - "state": "WY", - "lat": 41.04746, - "lon": -104.8901 - }, - "KDOV": { - "id": "KDOV", - "city": "Dover Air Force Base", - "state": "DE", - "lat": 39.13333, - "lon": -75.4666699 - }, - "KGED": { - "id": "KGED", - "city": "Georgetown - Delaware Coastal Airport", - "state": "DE", - "lat": 38.68974, - "lon": -75.36245 - }, - "KILG": { - "id": "KILG", - "city": "Wilmington, New Castle County Airport", - "state": "DE", - "lat": 39.67442, - "lon": -75.60567 - }, - "KBID": { - "id": "KBID", - "city": "Block Island State Airport", - "state": "RI", - "lat": 41.1694699, - "lon": -71.5787299 - }, - "KOQU": { - "id": "KOQU", - "city": "N. Kingston / Quonset", - "state": "RI", - "lat": 41.6, - "lon": -71.41667 - }, - "KPVD": { - "id": "KPVD", - "city": "Providence, Theodore Francis Green State Airport", - "state": "RI", - "lat": 41.72249, - "lon": -71.43247 - }, - "KSFZ": { - "id": "KSFZ", - "city": "Pawtucket, North Central State Airport", - "state": "RI", - "lat": 41.91667, - "lon": -71.5 - }, - "KUUU": { - "id": "KUUU", - "city": "Newport, Newport State Airport", - "state": "RI", - "lat": 41.53, - "lon": -71.28361 - }, - "KWST": { - "id": "KWST", - "city": "Westerly, Westerly State Airport", - "state": "RI", - "lat": 41.34972, - "lon": -71.79889 - }, - "KBAC": { - "id": "KBAC", - "city": "Valley City", - "state": "ND", - "lat": 46.9412, - "lon": -98.018 - }, - "KBIS": { - "id": "KBIS", - "city": "Bismarck, Bismarck Municipal Airport", - "state": "ND", - "lat": 46.7825, - "lon": -100.75722 - }, - "KBWP": { - "id": "KBWP", - "city": "Wahpeton, Harry Stern Airport", - "state": "ND", - "lat": 46.24389, - "lon": -96.60722 - }, - "KBWW": { - "id": "KBWW", - "city": "Bowman Regional Airport", - "state": "ND", - "lat": 46.16551, - "lon": -103.30074 - }, - "KDIK": { - "id": "KDIK", - "city": "Dickinson, Dickinson Municipal Airport", - "state": "ND", - "lat": 46.79722, - "lon": -102.80194 - }, - "KDVL": { - "id": "KDVL", - "city": "Devils Lake, Devils Lake Municipal Airport", - "state": "ND", - "lat": 48.11667, - "lon": -98.91667 - }, - "KFAR": { - "id": "KFAR", - "city": "Fargo, Hector International Airport", - "state": "ND", - "lat": 46.92528, - "lon": -96.81111 - }, - "KGAF": { - "id": "KGAF", - "city": "GRAFTON", - "state": "ND", - "lat": 48.4, - "lon": -97.37 - }, - "KGFK": { - "id": "KGFK", - "city": "Grand Forks, Grand Forks International Airport", - "state": "ND", - "lat": 47.94806, - "lon": -97.1825 - }, - "KGWR": { - "id": "KGWR", - "city": "Gwinner", - "state": "ND", - "lat": 46.2187, - "lon": -97.6435 - }, - "KHEI": { - "id": "KHEI", - "city": "Hettinger, Hettinger Municipal Airport", - "state": "ND", - "lat": 46.01056, - "lon": -102.64972 - }, - "KHZE": { - "id": "KHZE", - "city": "HAZEN", - "state": "ND", - "lat": 47.28, - "lon": -101.58 - }, - "KJMS": { - "id": "KJMS", - "city": "Jamestown, Jamestown Municipal Airport", - "state": "ND", - "lat": 46.92972, - "lon": -98.67833 - }, - "KMIB": { - "id": "KMIB", - "city": "Minot Air Force Base", - "state": "ND", - "lat": 48.41667, - "lon": -101.35 - }, - "KMOT": { - "id": "KMOT", - "city": "Minot International Airport", - "state": "ND", - "lat": 48.25203, - "lon": -101.2689 - }, - "KRDR": { - "id": "KRDR", - "city": "Grand Forks Air Force Base", - "state": "ND", - "lat": 47.96667, - "lon": -97.4 - }, - "KRUG": { - "id": "KRUG", - "city": "RUGBY", - "state": "ND", - "lat": 48.38, - "lon": -100.02 - }, - "KXWA": { - "id": "KXWA", - "city": "Williston Basin International Airport", - "state": "ND", - "lat": 48.26086, - "lon": -103.75114 - }, - "KBIX": { - "id": "KBIX", - "city": "Keesler Air Force Base / Biloxi", - "state": "MS", - "lat": 30.41667, - "lon": -88.91667 - }, - "KCBM": { - "id": "KCBM", - "city": "Columbus Air Force Base", - "state": "MS", - "lat": 33.65, - "lon": -88.45 - }, - "KCKM": { - "id": "KCKM", - "city": "Fletcher Field, Clarksdale", - "state": "MS", - "lat": 34.2997, - "lon": -90.5123 - }, - "KCRX": { - "id": "KCRX", - "city": "Corinth", - "state": "MS", - "lat": 34.915, - "lon": -88.6035 - }, - "KDLP": { - "id": "KDLP", - "city": "WEST DELTA OIL PLATFORM", - "state": "MS", - "lat": 29.12, - "lon": -89.55 - }, - "KGLH": { - "id": "KGLH", - "city": "Greenville, Mid Delta Regional Airport", - "state": "MS", - "lat": 33.48278, - "lon": -90.98556 - }, - "KGPT": { - "id": "KGPT", - "city": "Gulfport - Gulfport-Biloxi International Airport", - "state": "MS", - "lat": 30.41194, - "lon": -89.08083 - }, - "KGTR": { - "id": "KGTR", - "city": "Columbus/West Point/Starkville, Golden Triangle Regional Airport", - "state": "MS", - "lat": 33.45, - "lon": -88.58333 - }, - "KGWO": { - "id": "KGWO", - "city": "Greenwood, Greenwood-LeFlore Airport", - "state": "MS", - "lat": 33.4925, - "lon": -90.0836099 - }, - "KHBG": { - "id": "KHBG", - "city": "Hattiesburg, Bobby L Chain Municipal Airport", - "state": "MS", - "lat": 31.26945, - "lon": -89.25613 - }, - "KHEZ": { - "id": "KHEZ", - "city": "Natchez, Hardy-Anders Field Natchez-Adams County Airport", - "state": "MS", - "lat": 31.61593, - "lon": -91.29724 - }, - "KHKS": { - "id": "KHKS", - "city": "Jackson, Hawkins Field Airport", - "state": "MS", - "lat": 32.33472, - "lon": -90.2225 - }, - "KHSA": { - "id": "KHSA", - "city": "Bay St. Louis, Stennis International Airport", - "state": "MS", - "lat": 30.36778, - "lon": -89.45472 - }, - "KJAN": { - "id": "KJAN", - "city": "Jackson, Jackson International Airport", - "state": "MS", - "lat": 32.3197199, - "lon": -90.0775 - }, - "KJVW": { - "id": "KJVW", - "city": "JB Williams Airport", - "state": "MS", - "lat": 32.30447, - "lon": -90.41053 - }, - "KLUL": { - "id": "KLUL", - "city": "LAUREL/NOBLE FIELD", - "state": "MS", - "lat": 31.67, - "lon": -89.17 - }, - "KMBO": { - "id": "KMBO", - "city": "Madison Bruce Campbell Field Airport", - "state": "MS", - "lat": 32.4384, - "lon": -90.1014 - }, - "KMCB": { - "id": "KMCB", - "city": "McComb, McComb / Pike County / John E Lewis Field Airport", - "state": "MS", - "lat": 31.17833, - "lon": -90.47194 - }, - "KMEI": { - "id": "KMEI", - "city": "Meridian, Key Field", - "state": "MS", - "lat": 32.33806, - "lon": -88.74778 - }, - "KMJD": { - "id": "KMJD", - "city": "Picayune Municipal Airport", - "state": "MS", - "lat": 30.48747, - "lon": -89.65119 - }, - "KNMM": { - "id": "KNMM", - "city": "Meridian, Meridian Naval Air Station - McCain Field", - "state": "MS", - "lat": 32.55194, - "lon": -88.55528 - }, - "KOLV": { - "id": "KOLV", - "city": "Olive Branch, Olive Branch Airport", - "state": "MS", - "lat": 34.97889, - "lon": -89.78694 - }, - "KPIB": { - "id": "KPIB", - "city": "Hattiesburg/Laurel, Hattiesburg-Laurel Regional Airport", - "state": "MS", - "lat": 31.46667, - "lon": -89.33333 - }, - "KPMU": { - "id": "KPMU", - "city": "Batesville Panola County", - "state": "MS", - "lat": 34.3635, - "lon": -89.8929 - }, - "KPQL": { - "id": "KPQL", - "city": "Moss Point - Trent Lott International Airport", - "state": "MS", - "lat": 30.46305, - "lon": -88.53155 - }, - "KSTF": { - "id": "KSTF", - "city": "George M Bryan Airport, Starkville", - "state": "MS", - "lat": 33.4331, - "lon": -88.8486 - }, - "KTUP": { - "id": "KTUP", - "city": "Tupelo, Tupelo Regional Airport", - "state": "MS", - "lat": 34.26806, - "lon": -88.77 - }, - "KUOX": { - "id": "KUOX", - "city": "Oxford, University-Oxford Airport", - "state": "MS", - "lat": 34.38444, - "lon": -89.53556 - }, - "KUTA": { - "id": "KUTA", - "city": "Tunica, Tunica Municipal Airport", - "state": "MS", - "lat": 34.68083, - "lon": -90.34639 - }, - "KVKS": { - "id": "KVKS", - "city": "Vicksburg Municipal", - "state": "MS", - "lat": 32.23333, - "lon": -90.93333 - }, - "KBDL": { - "id": "KBDL", - "city": "Windsor Locks, Bradley International Airport", - "state": "CT", - "lat": 41.93806, - "lon": -72.6825 - }, - "KBDR": { - "id": "KBDR", - "city": "Bridgeport, Sikorsky Memorial Airport", - "state": "CT", - "lat": 41.16421, - "lon": -73.12663 - }, - "KDXR": { - "id": "KDXR", - "city": "Danbury, Danbury Municipal Airport", - "state": "CT", - "lat": 41.37167, - "lon": -73.48444 - }, - "KGON": { - "id": "KGON", - "city": "Groton / New London, Groton / New London Airport", - "state": "CT", - "lat": 41.3275, - "lon": -72.04944 - }, - "KHFD": { - "id": "KHFD", - "city": "Hartford, Hartford-Brainard Airport", - "state": "CT", - "lat": 41.735, - "lon": -72.65167 - }, - "KHVN": { - "id": "KHVN", - "city": "New Haven, Tweed-New Haven Airport", - "state": "CT", - "lat": 41.26389, - "lon": -72.88722 - }, - "KIJD": { - "id": "KIJD", - "city": "Willimantic, Windham Airport", - "state": "CT", - "lat": 41.74194, - "lon": -72.18361 - }, - "KMMK": { - "id": "KMMK", - "city": "Meriden, Meriden Markham Municipal Airport", - "state": "CT", - "lat": 41.50972, - "lon": -72.82778 - }, - "KOXC": { - "id": "KOXC", - "city": "Oxford, Waterbury-Oxford Airport", - "state": "CT", - "lat": 41.48333, - "lon": -73.13333 - }, - "KSNC": { - "id": "KSNC", - "city": "Chester, Chester Airport", - "state": "CT", - "lat": 41.38389, - "lon": -72.50583 - }, - "KAFN": { - "id": "KAFN", - "city": "Jaffrey Airport-Silver Ranch", - "state": "NH", - "lat": 42.8066699, - "lon": -72.00127 - }, - "KASH": { - "id": "KASH", - "city": "Nashua - Boire Field Airport", - "state": "NH", - "lat": 42.77981, - "lon": -71.51409 - }, - "KBML": { - "id": "KBML", - "city": "Berlin, Berlin Municipal Airport", - "state": "NH", - "lat": 44.57611, - "lon": -71.17861 - }, - "KCON": { - "id": "KCON", - "city": "Concord Municipal Airport", - "state": "NH", - "lat": 43.20489, - "lon": -71.50257 - }, - "KDAW": { - "id": "KDAW", - "city": "Rochester - Skyhaven Airport", - "state": "NH", - "lat": 43.27939, - "lon": -70.92426 - }, - "KEEN": { - "id": "KEEN", - "city": "Keene, Dillant-Hopkins Airport", - "state": "NH", - "lat": 42.9, - "lon": -72.26667 - }, - "KHIE": { - "id": "KHIE", - "city": "Whitefield - Mount Washington Regional Airport", - "state": "NH", - "lat": 44.36595, - "lon": -71.55218 - }, - "KLCI": { - "id": "KLCI", - "city": "Laconia, Laconia Municipal Airport", - "state": "NH", - "lat": 43.56667, - "lon": -71.41667 - }, - "KLEB": { - "id": "KLEB", - "city": "Lebanon Municipal Airport", - "state": "NH", - "lat": 43.6271, - "lon": -72.30537 - }, - "KMHT": { - "id": "KMHT", - "city": "Manchester Airport", - "state": "NH", - "lat": 42.92964, - "lon": -71.43559 - }, - "KMWN": { - "id": "KMWN", - "city": "Mount Washington", - "state": "NH", - "lat": 44.27086, - "lon": -71.30337 - }, - "KPSM": { - "id": "KPSM", - "city": "Pease Air Force Base / Portsmouth", - "state": "NH", - "lat": 43.0833299, - "lon": -70.81667 - }, - "KAID": { - "id": "KAID", - "city": "Anderson Municipal Airport", - "state": "IN", - "lat": 40.10612, - "lon": -85.60977 - }, - "KANQ": { - "id": "KANQ", - "city": "Angola Tri-State Steuben County Airport", - "state": "IN", - "lat": 41.6404, - "lon": -85.0851 - }, - "KASW": { - "id": "KASW", - "city": "Warsaw, Warsaw Municipal Airport", - "state": "IN", - "lat": 41.27444, - "lon": -85.84 - }, - "KBAK": { - "id": "KBAK", - "city": "Columbus / Bakalar", - "state": "IN", - "lat": 39.26667, - "lon": -85.9 - }, - "KBMG": { - "id": "KBMG", - "city": "Bloomington, Monroe County Airport", - "state": "IN", - "lat": 39.14306, - "lon": -86.61667 - }, - "KCFJ": { - "id": "KCFJ", - "city": "Crawfordsville Municipal Airport", - "state": "IN", - "lat": 39.9756, - "lon": -86.9199 - }, - "KDCY": { - "id": "KDCY", - "city": "Daviess County Airport", - "state": "IN", - "lat": 38.7004, - "lon": -87.1297 - }, - "KEKM": { - "id": "KEKM", - "city": "Elkhart Municipal", - "state": "IN", - "lat": 41.71667, - "lon": -86 - }, - "KEVV": { - "id": "KEVV", - "city": "Evansville, Evansville Regional Airport", - "state": "IN", - "lat": 38.0430599, - "lon": -87.52028 - }, - "KEYE": { - "id": "KEYE", - "city": "Indianapolis, Eagle Creek Airpark", - "state": "IN", - "lat": 39.825, - "lon": -86.29583 - }, - "KFKR": { - "id": "KFKR", - "city": "Frankfort Municipal Airport", - "state": "IN", - "lat": 40.2734, - "lon": -86.5622 - }, - "KFRH": { - "id": "KFRH", - "city": "French Lick Municipal Airport", - "state": "IN", - "lat": 38.50622, - "lon": -86.63694 - }, - "KFWA": { - "id": "KFWA", - "city": "Fort Wayne International Airport", - "state": "IN", - "lat": 40.97251, - "lon": -85.20637 - }, - "KGEZ": { - "id": "KGEZ", - "city": "Shelbyville Municipal Airport", - "state": "IN", - "lat": 39.58546, - "lon": -85.79982 - }, - "KGGP": { - "id": "KGGP", - "city": "Logansport/Cass County Airport", - "state": "IN", - "lat": 40.711, - "lon": -86.373 - }, - "KGPC": { - "id": "KGPC", - "city": "Putnam County Regional Airport", - "state": "IN", - "lat": 39.6354, - "lon": -86.8155 - }, - "KGSH": { - "id": "KGSH", - "city": "Goshen, Goshen Municipal Airport", - "state": "IN", - "lat": 41.52611, - "lon": -85.78667 - }, - "KGUS": { - "id": "KGUS", - "city": "Grissom Air Force Base / Peru", - "state": "IN", - "lat": 40.65, - "lon": -86.15 - }, - "KGWB": { - "id": "KGWB", - "city": "Auburn De Kalb County Airport", - "state": "IN", - "lat": 41.307, - "lon": -85.0639999 - }, - "KGYY": { - "id": "KGYY", - "city": "Gary Regional Airport", - "state": "IN", - "lat": 41.61212, - "lon": -87.40908 - }, - "KHHG": { - "id": "KHHG", - "city": "Huntington Municipal Airport", - "state": "IN", - "lat": 40.8529, - "lon": -85.4571 - }, - "KHLB": { - "id": "KHLB", - "city": "Batesville Airport", - "state": "IN", - "lat": 39.34313, - "lon": -85.25843 - }, - "KHNB": { - "id": "KHNB", - "city": "Huntingburg", - "state": "IN", - "lat": 38.25, - "lon": -86.95 - }, - "KHUF": { - "id": "KHUF", - "city": "Terre Haute Regional Airport", - "state": "IN", - "lat": 39.4429, - "lon": -87.32207 - }, - "KIMS": { - "id": "KIMS", - "city": "Madison Municipal Airport", - "state": "IN", - "lat": 38.7589, - "lon": -85.4655 - }, - "KIND": { - "id": "KIND", - "city": "Indianapolis International Airport", - "state": "IN", - "lat": 39.72518, - "lon": -86.2816 - }, - "KJVY": { - "id": "KJVY", - "city": "Clark Regional Airport", - "state": "IN", - "lat": 38.36661, - "lon": -85.73814 - }, - "KLAF": { - "id": "KLAF", - "city": "Lafayette, Purdue University Airport", - "state": "IN", - "lat": 40.4125, - "lon": -86.9475 - }, - "KMCX": { - "id": "KMCX", - "city": "Monticello White County Airport", - "state": "IN", - "lat": 40.7087999, - "lon": -86.7668 - }, - "KMGC": { - "id": "KMGC", - "city": "Michigan City Municipal Airport", - "state": "IN", - "lat": 41.7033, - "lon": -86.8212 - }, - "KMIE": { - "id": "KMIE", - "city": "Muncie, Delaware County-Johnson Field", - "state": "IN", - "lat": 40.23417, - "lon": -85.39361 - }, - "KMQJ": { - "id": "KMQJ", - "city": "Indianapolis Mount Comfort Airport", - "state": "IN", - "lat": 39.8435, - "lon": -85.8971 - }, - "KMZZ": { - "id": "KMZZ", - "city": "Marion Municipal Airport", - "state": "IN", - "lat": 40.49, - "lon": -85.68 - }, - "KOKK": { - "id": "KOKK", - "city": "Kokomo, Kokomo Municipal Airport", - "state": "IN", - "lat": 40.53333, - "lon": -86.06667 - }, - "KOXI": { - "id": "KOXI", - "city": "Starke County Airport", - "state": "IN", - "lat": 41.33, - "lon": -86.665 - }, - "KPLD": { - "id": "KPLD", - "city": "Portland Municipal Airport", - "state": "IN", - "lat": 40.45158, - "lon": -84.98903 - }, - "KPPO": { - "id": "KPPO", - "city": "La Porte Municipal Airport", - "state": "IN", - "lat": 41.5725, - "lon": -86.7345 - }, - "KRCR": { - "id": "KRCR", - "city": "Rochester Fulton County Airport", - "state": "IN", - "lat": 41.06553, - "lon": -86.18169 - }, - "KRID": { - "id": "KRID", - "city": "Richmond Municipal Airport", - "state": "IN", - "lat": 39.7572, - "lon": -84.8428 - }, - "KRZL": { - "id": "KRZL", - "city": "Rensselaer Jasper County Airport", - "state": "IN", - "lat": 40.94789, - "lon": -87.18258 - }, - "KSBN": { - "id": "KSBN", - "city": "South Bend International Airport", - "state": "IN", - "lat": 41.7088899, - "lon": -86.31861 - }, - "KTYQ": { - "id": "KTYQ", - "city": "INDIANAPOLIS", - "state": "IN", - "lat": 40.03066, - "lon": -86.2514999 - }, - "KVPZ": { - "id": "KVPZ", - "city": "Valparaiso Porter County Municipal Airport", - "state": "IN", - "lat": 41.45349, - "lon": -86.99805 - }, - "KACB": { - "id": "KACB", - "city": "Bellaire, Antrim County Airport", - "state": "MI", - "lat": 44.98833, - "lon": -85.19833 - }, - "KADG": { - "id": "KADG", - "city": "Adrian, Lenawee County Airport", - "state": "MI", - "lat": 41.86778, - "lon": -84.07944 - }, - "KAMN": { - "id": "KAMN", - "city": "Alma, Gratiot Community Airport", - "state": "MI", - "lat": 43.32194, - "lon": -84.68778 - }, - "KANJ": { - "id": "KANJ", - "city": "Sault Ste. Marie", - "state": "MI", - "lat": 46.4794399, - "lon": -84.35722 - }, - "KAPN": { - "id": "KAPN", - "city": "Alpena, Alpena County Regional Airport", - "state": "MI", - "lat": 45.07167, - "lon": -83.56444 - }, - "KARB": { - "id": "KARB", - "city": "Ann Arbor, Ann Arbor Municipal Airport", - "state": "MI", - "lat": 42.22389, - "lon": -83.74 - }, - "KAZO": { - "id": "KAZO", - "city": "Kalamazoo/Battle Creek International Airport", - "state": "MI", - "lat": 42.2283, - "lon": -85.54595 - }, - "KBAX": { - "id": "KBAX", - "city": "Huron County Memorial Airport", - "state": "MI", - "lat": 43.77741, - "lon": -82.98271 - }, - "KBEH": { - "id": "KBEH", - "city": "Southwest Michigan Regional Airport", - "state": "MI", - "lat": 42.12896, - "lon": -86.41515 - }, - "KBIV": { - "id": "KBIV", - "city": "Holland - West Michigan Regional Airport", - "state": "MI", - "lat": 42.74611, - "lon": -86.09667 - }, - "KBTL": { - "id": "KBTL", - "city": "Battle Creek Executive Airport", - "state": "MI", - "lat": 42.31197, - "lon": -85.24144 - }, - "KCAD": { - "id": "KCAD", - "city": "Wexford County Airport", - "state": "MI", - "lat": 44.27847, - "lon": -85.4206899 - }, - "KCFS": { - "id": "KCFS", - "city": "Caro, Tuscola Area Airport", - "state": "MI", - "lat": 43.45861, - "lon": -83.44528 - }, - "KCIU": { - "id": "KCIU", - "city": "Sault Ste Marie, Chippewa County International Airport", - "state": "MI", - "lat": 46.25, - "lon": -84.4666699 - }, - "KCMX": { - "id": "KCMX", - "city": "Houghton County Memorial Airport", - "state": "MI", - "lat": 47.16597, - "lon": -88.48072 - }, - "KCVX": { - "id": "KCVX", - "city": "Charlevoix, Charlevoix Municipal Airport", - "state": "MI", - "lat": 45.30472, - "lon": -85.27472 - }, - "KDET": { - "id": "KDET", - "city": "Coleman A Young Municipal Airport", - "state": "MI", - "lat": 42.40729, - "lon": -83.00894 - }, - "KDRM": { - "id": "KDRM", - "city": "Drummond Island Airport", - "state": "MI", - "lat": 46.0072, - "lon": -83.7427 - }, - "KDTW": { - "id": "KDTW", - "city": "Detroit, Detroit Metropolitan Wayne County Airport", - "state": "MI", - "lat": 42.23139, - "lon": -83.33083 - }, - "KDUH": { - "id": "KDUH", - "city": "Lambertville, Toledo Suburban Airport", - "state": "MI", - "lat": 41.73583, - "lon": -83.65528 - }, - "KERY": { - "id": "KERY", - "city": "Newberry, Luce County Airport", - "state": "MI", - "lat": 46.31111, - "lon": -85.45722 - }, - "KESC": { - "id": "KESC", - "city": "Delta County Airport", - "state": "MI", - "lat": 45.7226799, - "lon": -87.09372 - }, - "KFFX": { - "id": "KFFX", - "city": "Fremont Municipal Airport", - "state": "MI", - "lat": 43.43933, - "lon": -85.9948299 - }, - "KFKS": { - "id": "KFKS", - "city": "Frankfort, Frankfort Dow Memorial Field Airport", - "state": "MI", - "lat": 44.625, - "lon": -86.20056 - }, - "KFNT": { - "id": "KFNT", - "city": "Flint, Bishop International Airport", - "state": "MI", - "lat": 42.96667, - "lon": -83.74944 - }, - "KFPK": { - "id": "KFPK", - "city": "Charlotte, Fitch H Beach Airport", - "state": "MI", - "lat": 42.57444, - "lon": -84.81139 - }, - "KGLR": { - "id": "KGLR", - "city": "Gaylord Regional Airport", - "state": "MI", - "lat": 45.01658, - "lon": -84.68937 - }, - "KGOV": { - "id": "KGOV", - "city": "Grayling, Grayling Army Airfield", - "state": "MI", - "lat": 44.68028, - "lon": -84.72889 - }, - "KGRR": { - "id": "KGRR", - "city": "Grand Rapids, Gerald R. Ford International Airport", - "state": "MI", - "lat": 42.88083, - "lon": -85.52278 - }, - "KHAI": { - "id": "KHAI", - "city": "Haines Memorial Airport", - "state": "MI", - "lat": 41.9598, - "lon": -85.5934 - }, - "KHTL": { - "id": "KHTL", - "city": "Houghton Lake, Roscommon County Airport", - "state": "MI", - "lat": 44.35111, - "lon": -84.67417 - }, - "KHYX": { - "id": "KHYX", - "city": "Saginaw County H W Browne Airport", - "state": "MI", - "lat": 43.43191, - "lon": -83.86476 - }, - "KIKW": { - "id": "KIKW", - "city": "Jack Barstow Airport", - "state": "MI", - "lat": 43.6624, - "lon": -84.26213 - }, - "KIMT": { - "id": "KIMT", - "city": "Iron Mountain / Kingsford, Ford Airport", - "state": "MI", - "lat": 45.81417, - "lon": -88.10889 - }, - "KIRS": { - "id": "KIRS", - "city": "Sturgis, Kirsch Municipal Airport", - "state": "MI", - "lat": 41.8127799, - "lon": -85.43917 - }, - "KISQ": { - "id": "KISQ", - "city": "Manistique, Schoolcraft County Airport", - "state": "MI", - "lat": 45.97472, - "lon": -86.17194 - }, - "KIWD": { - "id": "KIWD", - "city": "Ironwood, Gogebic-Iron County Airport", - "state": "MI", - "lat": 46.53333, - "lon": -90.13333 - }, - "KJXN": { - "id": "KJXN", - "city": "Jackson County Airport - Reynolds Field", - "state": "MI", - "lat": 42.26171, - "lon": -84.46147 - }, - "KJYM": { - "id": "KJYM", - "city": "Hillsdale Municipal Airport", - "state": "MI", - "lat": 41.91972, - "lon": -84.58528 - }, - "KLAN": { - "id": "KLAN", - "city": "Capital Region International Airport", - "state": "MI", - "lat": 42.77616, - "lon": -84.5997 - }, - "KLDM": { - "id": "KLDM", - "city": "Ludington, Mason County Airport", - "state": "MI", - "lat": 43.96667, - "lon": -86.4 - }, - "KLWA": { - "id": "KLWA", - "city": "South Haven, South Haven Area Regional Airport", - "state": "MI", - "lat": 42.35083, - "lon": -86.25611 - }, - "KMBL": { - "id": "KMBL", - "city": "Manistee County - Blacker Airport", - "state": "MI", - "lat": 44.27142, - "lon": -86.23773 - }, - "KMBS": { - "id": "KMBS", - "city": "MBS International Airport", - "state": "MI", - "lat": 43.5281, - "lon": -84.08129 - }, - "KMCD": { - "id": "KMCD", - "city": "Mackinac Island Airport", - "state": "MI", - "lat": 45.86628, - "lon": -84.63437 - }, - "KMGN": { - "id": "KMGN", - "city": "Harbor Springs, Harbor Springs Airport", - "state": "MI", - "lat": 45.42556, - "lon": -84.91333 - }, - "KMKG": { - "id": "KMKG", - "city": "Muskegon, Muskegon County Airport", - "state": "MI", - "lat": 43.17111, - "lon": -86.23667 - }, - "KMNM": { - "id": "KMNM", - "city": "Menominee - Marinette Twin County Airport", - "state": "MI", - "lat": 45.12628, - "lon": -87.64438 - }, - "KMOP": { - "id": "KMOP", - "city": "Mount Pleasant, Mount Pleasant Municipal Airport", - "state": "MI", - "lat": 43.61667, - "lon": -84.73333 - }, - "KMTC": { - "id": "KMTC", - "city": "Selfridge Air National Guard Base", - "state": "MI", - "lat": 42.60458, - "lon": -82.83528 - }, - "KOEB": { - "id": "KOEB", - "city": "Branch County Memorial Airport", - "state": "MI", - "lat": 41.93085, - "lon": -85.05429 - }, - "KONZ": { - "id": "KONZ", - "city": "Detroit/Grosse Ile, Grosse Ile Airport", - "state": "MI", - "lat": 42.09861, - "lon": -83.1611099 - }, - "KOSC": { - "id": "KOSC", - "city": "Oscoda, Oscoda-Wurtsmith Airport", - "state": "MI", - "lat": 44.45, - "lon": -83.36667 - }, - "KOZW": { - "id": "KOZW", - "city": "Howell, Livingston County Airport", - "state": "MI", - "lat": 42.62944, - "lon": -83.98417 - }, - "KPHN": { - "id": "KPHN", - "city": "St Clair County International Airport", - "state": "MI", - "lat": 42.91031, - "lon": -82.53315 - }, - "KPLN": { - "id": "KPLN", - "city": "Pellston Regional Airport of Emmet County", - "state": "MI", - "lat": 45.56443, - "lon": -84.7928699 - }, - "KPTK": { - "id": "KPTK", - "city": "Pontiac, Oakland County International Airport", - "state": "MI", - "lat": 42.66306, - "lon": -83.41 - }, - "KPZQ": { - "id": "KPZQ", - "city": "Rogers City, Presque Isle County Airport", - "state": "MI", - "lat": 45.40694, - "lon": -83.81278 - }, - "KRMY": { - "id": "KRMY", - "city": "Brooks Field Airport", - "state": "MI", - "lat": 42.25238, - "lon": -84.95253 - }, - "KRNP": { - "id": "KRNP", - "city": "Owosso, Owosso Community Airport", - "state": "MI", - "lat": 42.99278, - "lon": -84.13889 - }, - "KRQB": { - "id": "KRQB", - "city": "Big Rapids, Roben-Hood Airport", - "state": "MI", - "lat": 43.7224999, - "lon": -85.50417 - }, - "KSAW": { - "id": "KSAW", - "city": "Marquette, Sawyer International Airport", - "state": "MI", - "lat": 46.35361, - "lon": -87.39528 - }, - "KSJX": { - "id": "KSJX", - "city": "Beaver Island, Beaver Island Airport", - "state": "MI", - "lat": 45.69222, - "lon": -85.56639 - }, - "KSLH": { - "id": "KSLH", - "city": "Cheboygan, Cheboygan County Airport", - "state": "MI", - "lat": 45.65361, - "lon": -84.51917 - }, - "KTEW": { - "id": "KTEW", - "city": "Mason, Mason Jewett Field Airport", - "state": "MI", - "lat": 42.56583, - "lon": -84.42333 - }, - "KTTF": { - "id": "KTTF", - "city": "Monroe, Custer Airport", - "state": "MI", - "lat": 41.94, - "lon": -83.43472 - }, - "KTVC": { - "id": "KTVC", - "city": "Cherry Capital Airport", - "state": "MI", - "lat": 44.73898, - "lon": -85.56788 - }, - "KVLL": { - "id": "KVLL", - "city": "Troy, Oakland/Troy Airport", - "state": "MI", - "lat": 42.54278, - "lon": -83.17778 - }, - "KYIP": { - "id": "KYIP", - "city": "Detroit, Willow Run Airport", - "state": "MI", - "lat": 42.2366699, - "lon": -83.52611 - }, - "KAFK": { - "id": "KAFK", - "city": "Nebraska City, Nebraska City Municipal Airport", - "state": "NE", - "lat": 40.6, - "lon": -95.85 - }, - "KAHQ": { - "id": "KAHQ", - "city": "Wahoo", - "state": "NE", - "lat": 41.2406, - "lon": -96.5946 - }, - "KAIA": { - "id": "KAIA", - "city": "Alliance, Alliance Municipal Airport", - "state": "NE", - "lat": 42.05722, - "lon": -102.8 - }, - "KANW": { - "id": "KANW", - "city": "Ainsworth Regional Airport", - "state": "NE", - "lat": 42.57484, - "lon": -99.99832 - }, - "KAUH": { - "id": "KAUH", - "city": "Aurora, Aurora Municipal Airport", - "state": "NE", - "lat": 40.89389, - "lon": -97.99444 - }, - "KBBW": { - "id": "KBBW", - "city": "Broken Bow, Broken Bow Municipal Airport", - "state": "NE", - "lat": 41.43333, - "lon": -99.65 - }, - "KBFF": { - "id": "KBFF", - "city": "Scottsbluff, Heilig Field", - "state": "NE", - "lat": 41.86694, - "lon": -103.58583 - }, - "KBIE": { - "id": "KBIE", - "city": "Beatrice Municipal", - "state": "NE", - "lat": 40.3, - "lon": -96.75 - }, - "KBTA": { - "id": "KBTA", - "city": "Blair Municipal Airport", - "state": "NE", - "lat": 41.4148, - "lon": -96.109 - }, - "KBVN": { - "id": "KBVN", - "city": "Albion Municipal Airport", - "state": "NE", - "lat": 41.73016, - "lon": -98.05453 - }, - "KCDR": { - "id": "KCDR", - "city": "Chadron, Chadron Municipal Airport", - "state": "NE", - "lat": 42.8375, - "lon": -103.09528 - }, - "KEAR": { - "id": "KEAR", - "city": "Kearney, Kearney Municipal Airport", - "state": "NE", - "lat": 40.73333, - "lon": -99 - }, - "KFET": { - "id": "KFET", - "city": "Fremont Municipal Airport", - "state": "NE", - "lat": 41.45, - "lon": -96.51667 - }, - "KFNB": { - "id": "KFNB", - "city": "Falls City, Brenner Field Airport", - "state": "NE", - "lat": 40.07889, - "lon": -95.5919399 - }, - "KGRI": { - "id": "KGRI", - "city": "Grand Island, Central Nebraska Regional Airport", - "state": "NE", - "lat": 40.9583299, - "lon": -98.3125 - }, - "KGRN": { - "id": "KGRN", - "city": "Gordon Municipal", - "state": "NE", - "lat": 42.8, - "lon": -102.16667 - }, - "KHDE": { - "id": "KHDE", - "city": "Brewster Field Airport", - "state": "NE", - "lat": 40.45, - "lon": -99.33333 - }, - "KHJH": { - "id": "KHJH", - "city": "Hebron, Hebron Municipal Airport", - "state": "NE", - "lat": 40.15222, - "lon": -97.58694 - }, - "KHSI": { - "id": "KHSI", - "city": "Hastings, Hastings Municipal Airport", - "state": "NE", - "lat": 40.60056, - "lon": -98.42583 - }, - "KIBM": { - "id": "KIBM", - "city": "Kimball, Kimball Municipal Airport/Robert E Arraj Field", - "state": "NE", - "lat": 41.18333, - "lon": -103.66667 - }, - "KIML": { - "id": "KIML", - "city": "Imperial, Imperial Municipal Airport", - "state": "NE", - "lat": 40.51667, - "lon": -101.61667 - }, - "KJYR": { - "id": "KJYR", - "city": "York, York Municipal Airport", - "state": "NE", - "lat": 40.89667, - "lon": -97.62278 - }, - "KLBF": { - "id": "KLBF", - "city": "North Platte, North Platte Regional Airport", - "state": "NE", - "lat": 41.12194, - "lon": -100.66833 - }, - "KLCG": { - "id": "KLCG", - "city": "Wayne, Wayne Municipal Airport", - "state": "NE", - "lat": 42.24167, - "lon": -96.98139 - }, - "KLNK": { - "id": "KLNK", - "city": "Lincoln, Lincoln Municipal Airport", - "state": "NE", - "lat": 40.83111, - "lon": -96.7644399 - }, - "KLXN": { - "id": "KLXN", - "city": "Lexington, Jim Kelly Field Airport", - "state": "NE", - "lat": 40.79111, - "lon": -99.77722 - }, - "KMCK": { - "id": "KMCK", - "city": "McCook, McCook Municipal Airport", - "state": "NE", - "lat": 40.20306, - "lon": -100.58833 - }, - "KMLE": { - "id": "KMLE", - "city": "Omaha, Millard Airport", - "state": "NE", - "lat": 41.19583, - "lon": -96.1122199 - }, - "KODX": { - "id": "KODX", - "city": "Ord, Evelyn Sharp Field Airport", - "state": "NE", - "lat": 41.62417, - "lon": -98.9525 - }, - "KOFF": { - "id": "KOFF", - "city": "Omaha / Offutt Air Force Base", - "state": "NE", - "lat": 41.11667, - "lon": -95.9 - }, - "KOFK": { - "id": "KOFK", - "city": "Norfolk, Stefan Memorial Airport", - "state": "NE", - "lat": 41.9805599, - "lon": -97.43694 - }, - "KOGA": { - "id": "KOGA", - "city": "Ogallala, Searle Field Airport", - "state": "NE", - "lat": 41.11972, - "lon": -101.76889 - }, - "KOLU": { - "id": "KOLU", - "city": "Columbus, Columbus Municipal Airport", - "state": "NE", - "lat": 41.45, - "lon": -97.33333 - }, - "KOMA": { - "id": "KOMA", - "city": "Omaha - Eppley Airfield", - "state": "NE", - "lat": 41.3119, - "lon": -95.90185 - }, - "KONL": { - "id": "KONL", - "city": "O'Neill / Baker Field", - "state": "NE", - "lat": 42.46667, - "lon": -98.68333 - }, - "KPMV": { - "id": "KPMV", - "city": "Plattsmouth, Plattsmouth Municipal Airport", - "state": "NE", - "lat": 40.95, - "lon": -95.9177799 - }, - "KSNY": { - "id": "KSNY", - "city": "Sidney, Sidney Municipal Airport", - "state": "NE", - "lat": 41.09944, - "lon": -102.98556 - }, - "KTIF": { - "id": "KTIF", - "city": "Thedford, Thomas County Airport", - "state": "NE", - "lat": 41.96194, - "lon": -100.56889 - }, - "KTQE": { - "id": "KTQE", - "city": "Tekamah, Tekamah Municipal Airport", - "state": "NE", - "lat": 41.76694, - "lon": -96.17778 - }, - "KVTN": { - "id": "KVTN", - "city": "Valentine, Miller Field", - "state": "NE", - "lat": 42.85861, - "lon": -100.55139 - }, - "KAUG": { - "id": "KAUG", - "city": "Augusta, Augusta State Airport", - "state": "ME", - "lat": 44.32056, - "lon": -69.79722 - }, - "KBGR": { - "id": "KBGR", - "city": "Bangor, Bangor International Airport", - "state": "ME", - "lat": 44.79722, - "lon": -68.81861 - }, - "KBHB": { - "id": "KBHB", - "city": "Bar Harbor, Hancock County-Bar Harbor Airport", - "state": "ME", - "lat": 44.45, - "lon": -68.36667 - }, - "KBXM": { - "id": "KBXM", - "city": "BRUNSWICK", - "state": "ME", - "lat": 43.8923599, - "lon": -69.93883 - }, - "KCAR": { - "id": "KCAR", - "city": "Caribou, Caribou Municipal Airport", - "state": "ME", - "lat": 46.86722, - "lon": -68.01333 - }, - "KFVE": { - "id": "KFVE", - "city": "Frenchville, Northern Aroostook Regional Airport", - "state": "ME", - "lat": 47.2849999, - "lon": -68.30722 - }, - "KGNR": { - "id": "KGNR", - "city": "Greenville", - "state": "ME", - "lat": 45.4646199, - "lon": -69.5538 - }, - "KHUL": { - "id": "KHUL", - "city": "Houlton, Houlton International Airport", - "state": "ME", - "lat": 46.12306, - "lon": -67.79194 - }, - "KIWI": { - "id": "KIWI", - "city": "Wiscasset Airport", - "state": "ME", - "lat": 43.96401, - "lon": -69.7107599 - }, - "KIZG": { - "id": "KIZG", - "city": "Fryeburg, Eastern Slopes Regional Airport", - "state": "ME", - "lat": 43.98917, - "lon": -70.95028 - }, - "KLEW": { - "id": "KLEW", - "city": "Auburn-Lewiston", - "state": "ME", - "lat": 44.05, - "lon": -70.28333 - }, - "KMLT": { - "id": "KMLT", - "city": "Millinocket, Millinocket Municipal Airport", - "state": "ME", - "lat": 45.64778, - "lon": -68.69194 - }, - "KPQI": { - "id": "KPQI", - "city": "Presque Isle", - "state": "ME", - "lat": 46.68333, - "lon": -68.05 - }, - "KPWM": { - "id": "KPWM", - "city": "Portland, Portland International Jetport", - "state": "ME", - "lat": 43.64222, - "lon": -70.30444 - }, - "KRKD": { - "id": "KRKD", - "city": "Rockland, Knox County Regional Airport", - "state": "ME", - "lat": 44.06667, - "lon": -69.1 - }, - "KSFM": { - "id": "KSFM", - "city": "Sanford, Sanford Regional Airport", - "state": "ME", - "lat": 43.4, - "lon": -70.7166699 - }, - "KWVL": { - "id": "KWVL", - "city": "Waterville, Waterville Robert LaFleur Airport", - "state": "ME", - "lat": 44.53333, - "lon": -69.68333 - }, - "KADW": { - "id": "KADW", - "city": "Camp Springs / Andrews Air Force Base", - "state": "MD", - "lat": 38.81667, - "lon": -76.85 - }, - "KANP": { - "id": "KANP", - "city": "LEEAIRPORT", - "state": "MD", - "lat": 38.94287, - "lon": -76.5683899 - }, - "KAPG": { - "id": "KAPG", - "city": "Phillips Army Air Field / Aberdeen", - "state": "MD", - "lat": 39.46667, - "lon": -76.16667 - }, - "KBWI": { - "id": "KBWI", - "city": "Baltimore, Baltimore-Washington International Airport", - "state": "MD", - "lat": 39.17329, - "lon": -76.68404 - }, - "KCGE": { - "id": "KCGE", - "city": "Cambridge-Dorchester Airport", - "state": "MD", - "lat": 38.5393, - "lon": -76.0304 - }, - "KCGS": { - "id": "KCGS", - "city": "College Park Airport", - "state": "MD", - "lat": 38.9806, - "lon": -76.9223 - }, - "KDMW": { - "id": "KDMW", - "city": "Carroll County Regional Jack B Poage Field", - "state": "MD", - "lat": 39.6083, - "lon": -77.0077 - }, - "KEDG": { - "id": "KEDG", - "city": "WEIDE", - "state": "MD", - "lat": 39.39205, - "lon": -76.29106 - }, - "KESN": { - "id": "KESN", - "city": "Easton / Newman Field", - "state": "MD", - "lat": 38.8, - "lon": -76.06667 - }, - "KFDK": { - "id": "KFDK", - "city": "Frederick Municipal Airport", - "state": "MD", - "lat": 39.41775, - "lon": -77.36982 - }, - "KFME": { - "id": "KFME", - "city": "Fort Meade / Tipton", - "state": "MD", - "lat": 39.0833299, - "lon": -76.76667 - }, - "KGAI": { - "id": "KGAI", - "city": "Gaithersburg - Montgomery County Airport", - "state": "MD", - "lat": 39.16957, - "lon": -77.16551 - }, - "KHGR": { - "id": "KHGR", - "city": "Hagerstown, Washington County Regional Airport", - "state": "MD", - "lat": 39.70583, - "lon": -77.73 - }, - "KMTN": { - "id": "KMTN", - "city": "Baltimore / Martin", - "state": "MD", - "lat": 39.3333299, - "lon": -76.41667 - }, - "KNAK": { - "id": "KNAK", - "city": "Annapolis, United States Naval Academy", - "state": "MD", - "lat": 38.99125, - "lon": -76.48907 - }, - "KNHK": { - "id": "KNHK", - "city": "Patuxent River, Naval Air Station", - "state": "MD", - "lat": 38.27861, - "lon": -76.41389 - }, - "KNUI": { - "id": "KNUI", - "city": "St. Inigoes, Webster Field, Naval Electronic Systems Engineering Activity", - "state": "MD", - "lat": 38.14889, - "lon": -76.42 - }, - "KOXB": { - "id": "KOXB", - "city": "Ocean City, Ocean City Municipal Airport", - "state": "MD", - "lat": 38.31056, - "lon": -75.12389 - }, - "KRSP": { - "id": "KRSP", - "city": "Camp David", - "state": "MD", - "lat": 39.645, - "lon": -77.468 - }, - "KSBY": { - "id": "KSBY", - "city": "Salisbury, Salisbury-Ocean City Wicomico County Regional Airport", - "state": "MD", - "lat": 38.34056, - "lon": -75.51028 - }, - "KVKX": { - "id": "KVKX", - "city": "POTOMAC", - "state": "MD", - "lat": 38.74761, - "lon": -76.95719 - }, - "KACY": { - "id": "KACY", - "city": "Atlantic City, Atlantic City International Airport", - "state": "NJ", - "lat": 39.45202, - "lon": -74.56699 - }, - "KBLM": { - "id": "KBLM", - "city": "Belmar-Farmingdale", - "state": "NJ", - "lat": 40.18333, - "lon": -74.13333 - }, - "KCDW": { - "id": "KCDW", - "city": "Caldwell, Essex County Airport", - "state": "NJ", - "lat": 40.87639, - "lon": -74.28306 - }, - "KEWR": { - "id": "KEWR", - "city": "Newark, Newark International Airport", - "state": "NJ", - "lat": 40.6825, - "lon": -74.16944 - }, - "KFWN": { - "id": "KFWN", - "city": "Sussex, Sussex Airport", - "state": "NJ", - "lat": 41.19925, - "lon": -74.62594 - }, - "KLDJ": { - "id": "KLDJ", - "city": "Linden Airport", - "state": "NJ", - "lat": 40.6174, - "lon": -74.2446 - }, - "KMIV": { - "id": "KMIV", - "city": "Millville, Millville Municipal Airport", - "state": "NJ", - "lat": 39.36623, - "lon": -75.0778 - }, - "KMJX": { - "id": "KMJX", - "city": "Miller Air Park", - "state": "NJ", - "lat": 39.927, - "lon": -74.292 - }, - "KMMU": { - "id": "KMMU", - "city": "Morristown Municipal", - "state": "NJ", - "lat": 40.8, - "lon": -74.41667 - }, - "KNEL": { - "id": "KNEL", - "city": "Lakehurst Naval Air Station", - "state": "NJ", - "lat": 40.03661, - "lon": -74.35251 - }, - "KSMQ": { - "id": "KSMQ", - "city": "Somerville, Somerset Airport", - "state": "NJ", - "lat": 40.6240499, - "lon": -74.66898 - }, - "KTEB": { - "id": "KTEB", - "city": "Teterboro, Teterboro Airport", - "state": "NJ", - "lat": 40.85889, - "lon": -74.05667 - }, - "KTTN": { - "id": "KTTN", - "city": "Trenton, Mercer County Airport", - "state": "NJ", - "lat": 40.27639, - "lon": -74.81639 - }, - "KVAY": { - "id": "KVAY", - "city": "Mount Holly, South Jersey Regional Airport", - "state": "NJ", - "lat": 39.94076, - "lon": -74.84071 - }, - "KWRI": { - "id": "KWRI", - "city": "Mcguire Air Force Base", - "state": "NJ", - "lat": 40.01667, - "lon": -74.6 - }, - "KWWD": { - "id": "KWWD", - "city": "Wildwood, Cape May County Airport", - "state": "NJ", - "lat": 39.01667, - "lon": -74.91667 - }, - "KBCE": { - "id": "KBCE", - "city": "Bryce Canyon Airport", - "state": "UT", - "lat": 37.7012799, - "lon": -112.14897 - }, - "KBDG": { - "id": "KBDG", - "city": "Blanding Municipal Airport", - "state": "UT", - "lat": 37.586, - "lon": -109.482 - }, - "KBMC": { - "id": "KBMC", - "city": "Brigham City Regional Airport", - "state": "UT", - "lat": 41.5464, - "lon": -112.0601 - }, - "KCDC": { - "id": "KCDC", - "city": "Cedar City Municipal Airport", - "state": "UT", - "lat": 37.70675, - "lon": -113.09695 - }, - "KCNY": { - "id": "KCNY", - "city": "Moab, Canyonlands Field", - "state": "UT", - "lat": 38.76, - "lon": -109.74472 - }, - "KDPG": { - "id": "KDPG", - "city": "Michael Army Airfield - Dugway Proving Ground", - "state": "UT", - "lat": 40.18376, - "lon": -112.9217 - }, - "KDTA": { - "id": "KDTA", - "city": "Delta, Delta Municipal Airport", - "state": "UT", - "lat": 39.38333, - "lon": -112.50967 - }, - "KENV": { - "id": "KENV", - "city": "Wendover / Air Force Auxillary Field", - "state": "UT", - "lat": 40.72056, - "lon": -114.03583 - }, - "KHCR": { - "id": "KHCR", - "city": "Heber City Municipal-Russ McDonald Field Airport", - "state": "UT", - "lat": 40.47742, - "lon": -111.43295 - }, - "KHIF": { - "id": "KHIF", - "city": "Hill Air Force Base", - "state": "UT", - "lat": 41.11112, - "lon": -111.96229 - }, - "KHVE": { - "id": "KHVE", - "city": "Hanksville", - "state": "UT", - "lat": 38.418037, - "lon": -110.704038 - }, - "KKNB": { - "id": "KKNB", - "city": "KANAB MUNICIPAL AIRPORT", - "state": "UT", - "lat": 37.01, - "lon": -112.53 - }, - "KLGU": { - "id": "KLGU", - "city": "Logan-Cache Airport", - "state": "UT", - "lat": 41.78652, - "lon": -111.85187 - }, - "KMLF": { - "id": "KMLF", - "city": "Milford Municipal Airport", - "state": "UT", - "lat": 38.42252, - "lon": -113.01089 - }, - "KOGD": { - "id": "KOGD", - "city": "Ogden-Hinckley Airport", - "state": "UT", - "lat": 41.19406, - "lon": -112.01681 - }, - "KPUC": { - "id": "KPUC", - "city": "Price - Carbon County Regional Airport", - "state": "UT", - "lat": 39.60886, - "lon": -110.75548 - }, - "KPVU": { - "id": "KPVU", - "city": "Provo, Provo Municipal Airport", - "state": "UT", - "lat": 40.21667, - "lon": -111.71667 - }, - "KRIF": { - "id": "KRIF", - "city": "Richfield Municipal Airport", - "state": "UT", - "lat": 38.73411, - "lon": -112.10158 - }, - "KSGU": { - "id": "KSGU", - "city": "St George Municipal Airport", - "state": "UT", - "lat": 37.0451, - "lon": -113.50561 - }, - "KSLC": { - "id": "KSLC", - "city": "Salt Lake City, Salt Lake City International Airport", - "state": "UT", - "lat": 40.77069, - "lon": -111.96503 - }, - "KSPK": { - "id": "KSPK", - "city": "Spanish Fork Municipal Airport", - "state": "UT", - "lat": 40.145, - "lon": -111.6677 - }, - "KTVY": { - "id": "KTVY", - "city": "Bolinder Field-Tooele Valley Airport", - "state": "UT", - "lat": 40.61269, - "lon": -112.35362 - }, - "KVEL": { - "id": "KVEL", - "city": "Vernal Airport", - "state": "UT", - "lat": 40.44295, - "lon": -109.51273 - }, - "KABQ": { - "id": "KABQ", - "city": "Albuquerque, Albuquerque International Airport", - "state": "NM", - "lat": 35.04167, - "lon": -106.61472 - }, - "KAEG": { - "id": "KAEG", - "city": "Albuquerque, Double Eagle II Airport", - "state": "NM", - "lat": 35.145, - "lon": -106.795 - }, - "KALM": { - "id": "KALM", - "city": "Alamogordo-White", - "state": "NM", - "lat": 32.83512, - "lon": -105.99408 - }, - "KATS": { - "id": "KATS", - "city": "Artesia Municipal Airport", - "state": "NM", - "lat": 32.85239, - "lon": -104.46444 - }, - "KAXX": { - "id": "KAXX", - "city": "Angel Fire Airport", - "state": "NM", - "lat": 36.42586, - "lon": -105.29028 - }, - "KBRG": { - "id": "KBRG", - "city": "Belen Regional Airport", - "state": "NM", - "lat": 34.64586, - "lon": -106.83634 - }, - "KCAO": { - "id": "KCAO", - "city": "Clayton Municipal Airpark", - "state": "NM", - "lat": 36.44834, - "lon": -103.15367 - }, - "KCNM": { - "id": "KCNM", - "city": "Carlsbad, Cavern City Air Terminal Airport", - "state": "NM", - "lat": 32.3375, - "lon": -104.26333 - }, - "KCQC": { - "id": "KCQC", - "city": "Clines Corners", - "state": "NM", - "lat": 35, - "lon": -105.66667 - }, - "KCVN": { - "id": "KCVN", - "city": "Clovis Municipal Airport", - "state": "NM", - "lat": 34.42274, - "lon": -103.0802 - }, - "KCVS": { - "id": "KCVS", - "city": "Cannon Air Force Base / Clovis", - "state": "NM", - "lat": 34.38333, - "lon": -103.31667 - }, - "KDMN": { - "id": "KDMN", - "city": "Deming Municipal Airport", - "state": "NM", - "lat": 32.25927, - "lon": -107.72051 - }, - "KDNA": { - "id": "KDNA", - "city": "Dona Ana County Jetport, Santa Teresa", - "state": "NM", - "lat": 31.87495, - "lon": -106.69385 - }, - "KFMN": { - "id": "KFMN", - "city": "Farmington, Four Corners Regional Airport", - "state": "NM", - "lat": 36.7436099, - "lon": -108.22917 - }, - "KGNT": { - "id": "KGNT", - "city": "Grants, Grants-Milan Municipal Airport", - "state": "NM", - "lat": 35.16528, - "lon": -107.90222 - }, - "KGUP": { - "id": "KGUP", - "city": "Gallup Municipal Airport", - "state": "NM", - "lat": 35.50859, - "lon": -108.79316 - }, - "KHMN": { - "id": "KHMN", - "city": "Holloman Air Force Base", - "state": "NM", - "lat": 32.85, - "lon": -106.1 - }, - "KHOB": { - "id": "KHOB", - "city": "Hobbs / Lea County", - "state": "NM", - "lat": 32.68333, - "lon": -103.2166699 - }, - "KLAM": { - "id": "KLAM", - "city": "Los Alamos Airport", - "state": "NM", - "lat": 35.8796899, - "lon": -106.26869 - }, - "KLRU": { - "id": "KLRU", - "city": "Las Cruces, Las Cruces International Airport", - "state": "NM", - "lat": 32.28944, - "lon": -106.92194 - }, - "KLVS": { - "id": "KLVS", - "city": "Las Vegas Municipal Airport", - "state": "NM", - "lat": 35.65584, - "lon": -105.13852 - }, - "KONM": { - "id": "KONM", - "city": "Socorro Municipal Airport", - "state": "NM", - "lat": 34.02633, - "lon": -106.90372 - }, - "KROW": { - "id": "KROW", - "city": "Roswell International Air Center Airport", - "state": "NM", - "lat": 33.30737, - "lon": -104.50816 - }, - "KRTN": { - "id": "KRTN", - "city": "Raton Municipal - Crews Field Airport", - "state": "NM", - "lat": 36.741528, - "lon": -104.502183 - }, - "KSAF": { - "id": "KSAF", - "city": "Santa Fe County Municipal Airport", - "state": "NM", - "lat": 35.61097, - "lon": -106.09573 - }, - "KSKX": { - "id": "KSKX", - "city": "Taos, Taos Regional Airport", - "state": "NM", - "lat": 36.45, - "lon": -105.66667 - }, - "KSRR": { - "id": "KSRR", - "city": "Sierra Blanca Regional Airport", - "state": "NM", - "lat": 33.4667699, - "lon": -105.52778 - }, - "KSVC": { - "id": "KSVC", - "city": "Grant County Airport", - "state": "NM", - "lat": 32.63099, - "lon": -108.14658 - }, - "KSXU": { - "id": "KSXU", - "city": "Santa Rosa Route 66 Airport", - "state": "NM", - "lat": 34.93567, - "lon": -104.64256 - }, - "KTCC": { - "id": "KTCC", - "city": "Tucumcari Municipal Airport", - "state": "NM", - "lat": 35.18053, - "lon": -103.60145 - }, - "KTCS": { - "id": "KTCS", - "city": "Truth Or Consequences, Truth Or Consequences Municipal Airport", - "state": "NM", - "lat": 33.2366699, - "lon": -107.26806 - }, - "KACK": { - "id": "KACK", - "city": "Nantucket, Nantucket Memorial Airport", - "state": "MA", - "lat": 41.25389, - "lon": -70.05972 - }, - "KAQW": { - "id": "KAQW", - "city": "North Adams Harriman-and-West Airport", - "state": "MA", - "lat": 42.69731, - "lon": -73.16955 - }, - "KBAF": { - "id": "KBAF", - "city": "Westfield, Barnes Municipal Airport", - "state": "MA", - "lat": 42.15972, - "lon": -72.71278 - }, - "KBED": { - "id": "KBED", - "city": "Laurence G Hanscom Field Airport", - "state": "MA", - "lat": 42.46811, - "lon": -71.29463 - }, - "KBOS": { - "id": "KBOS", - "city": "Boston, Logan International Airport", - "state": "MA", - "lat": 42.36056, - "lon": -71.01056 - }, - "KBVY": { - "id": "KBVY", - "city": "Beverly, Beverly Municipal Airport", - "state": "MA", - "lat": 42.58361, - "lon": -70.91639 - }, - "KCEF": { - "id": "KCEF", - "city": "Chicopee Falls / Westover Air Force Base", - "state": "MA", - "lat": 42.2, - "lon": -72.53333 - }, - "KCQX": { - "id": "KCQX", - "city": "Chatham, Chatham Municipal Airport", - "state": "MA", - "lat": 41.6875, - "lon": -69.99333 - }, - "KEWB": { - "id": "KEWB", - "city": "New Bedford, New Bedford Regional Airport", - "state": "MA", - "lat": 41.67528, - "lon": -70.95694 - }, - "KFIT": { - "id": "KFIT", - "city": "Fitchburg, Fitchburg Municipal Airport", - "state": "MA", - "lat": 42.55194, - "lon": -71.75583 - }, - "KFMH": { - "id": "KFMH", - "city": "Otis Air National Guard Base", - "state": "MA", - "lat": 41.65, - "lon": -70.51667 - }, - "KGHG": { - "id": "KGHG", - "city": "Marshfield Airport", - "state": "MA", - "lat": 42.0983, - "lon": -70.6722 - }, - "KHYA": { - "id": "KHYA", - "city": "Hyannis, Barnstable Municipal-Boardman Airport", - "state": "MA", - "lat": 41.67194, - "lon": -70.26972 - }, - "KLWM": { - "id": "KLWM", - "city": "Lawrence Municipal Airport", - "state": "MA", - "lat": 42.7126, - "lon": -71.12553 - }, - "KMVY": { - "id": "KMVY", - "city": "Marthas Vineyard Airport", - "state": "MA", - "lat": 41.39298, - "lon": -70.61588 - }, - "KORE": { - "id": "KORE", - "city": "Orange Municipal Airport", - "state": "MA", - "lat": 42.57, - "lon": -72.28693 - }, - "KORH": { - "id": "KORH", - "city": "Worcester, Worcester Regional Airport", - "state": "MA", - "lat": 42.27056, - "lon": -71.87306 - }, - "KOWD": { - "id": "KOWD", - "city": "Norwood, Norwood Memorial Airport", - "state": "MA", - "lat": 42.19083, - "lon": -71.17389 - }, - "KPSF": { - "id": "KPSF", - "city": "Pittsfield Municipal Airport", - "state": "MA", - "lat": 42.42691, - "lon": -73.28897 - }, - "KPVC": { - "id": "KPVC", - "city": "Provincetown Municipal Airport", - "state": "MA", - "lat": 42.07436, - "lon": -70.21816 - }, - "KPYM": { - "id": "KPYM", - "city": "Plymouth, Plymouth Municipal Airport", - "state": "MA", - "lat": 41.90861, - "lon": -70.72806 - }, - "KTAN": { - "id": "KTAN", - "city": "Taunton, Taunton Municipal Airport", - "state": "MA", - "lat": 41.87556, - "lon": -71.0211099 - }, - "KACQ": { - "id": "KACQ", - "city": "Waseca Municipal Airport", - "state": "MN", - "lat": 44.07024, - "lon": -93.55342 - }, - "KADC": { - "id": "KADC", - "city": "Wadena Municipal Airport", - "state": "MN", - "lat": 46.45022, - "lon": -95.21353 - }, - "KAEL": { - "id": "KAEL", - "city": "Albert Lea, Albert Lea Municipal Airport", - "state": "MN", - "lat": 43.68333, - "lon": -93.36667 - }, - "KAIT": { - "id": "KAIT", - "city": "Aitkin Municipal Airport - Steve Kurtz Field", - "state": "MN", - "lat": 46.54899, - "lon": -93.67573 - }, - "KANE": { - "id": "KANE", - "city": "Minneapolis / Blaine", - "state": "MN", - "lat": 45.14258, - "lon": -93.21272 - }, - "KAQP": { - "id": "KAQP", - "city": "Appleton Municipal Airport", - "state": "MN", - "lat": 45.22488, - "lon": -96.00412 - }, - "KBOI": { - "id": "KBOI", - "city": "Boise Air Terminal", - "state": "ID", - "lat": 43.56704, - "lon": -116.24053 - }, - "KBYI": { - "id": "KBYI", - "city": "Burley Municipal Airport", - "state": "ID", - "lat": 42.54525, - "lon": -113.7686 - }, - "KCOE": { - "id": "KCOE", - "city": "Coeur d'Alene Airport - Pappy Boyington Field", - "state": "ID", - "lat": 47.76667, - "lon": -116.81667 - }, - "KDIJ": { - "id": "KDIJ", - "city": "Driggs, Driggs-Reed Memorial Airport", - "state": "ID", - "lat": 43.74167, - "lon": -111.09778 - }, - "KEUL": { - "id": "KEUL", - "city": "Caldwell - Caldwell Industrial Airport", - "state": "ID", - "lat": 43.64055, - "lon": -116.63017 - }, - "KGIC": { - "id": "KGIC", - "city": "Grangeville - Idaho County Airport", - "state": "ID", - "lat": 45.94111, - "lon": -116.13257 - }, - "KGNG": { - "id": "KGNG", - "city": "Gooding Municipal Airport", - "state": "ID", - "lat": 42.91716, - "lon": -114.76516 - }, - "KIDA": { - "id": "KIDA", - "city": "Idaho Falls Regional Airport", - "state": "ID", - "lat": 43.5208299, - "lon": -112.06611 - }, - "KJER": { - "id": "KJER", - "city": "Jerome County Airport", - "state": "ID", - "lat": 42.72736, - "lon": -114.45469 - }, - "KLLJ": { - "id": "KLLJ", - "city": "Challis - Challis Airport", - "state": "ID", - "lat": 44.523, - "lon": -114.21611 - }, - "KLWS": { - "id": "KLWS", - "city": "Lewiston, Lewiston-Nez Perce County Airport", - "state": "ID", - "lat": 46.37472, - "lon": -117.01444 - }, - "KMAN": { - "id": "KMAN", - "city": "Nampa Municipal Airport", - "state": "ID", - "lat": 43.5813, - "lon": -116.5231 - }, - "KMUO": { - "id": "KMUO", - "city": "Mountain Home Air Force Base", - "state": "ID", - "lat": 43.05, - "lon": -115.86667 - }, - "KMYL": { - "id": "KMYL", - "city": "McCall Airport", - "state": "ID", - "lat": 44.89425, - "lon": -116.09978 - }, - "KPIH": { - "id": "KPIH", - "city": "Pocatello, Pocatello Regional Airport", - "state": "ID", - "lat": 42.92028, - "lon": -112.57111 - }, - "KRXE": { - "id": "KRXE", - "city": "Rexburg, Rexburg-Madison County Airport", - "state": "ID", - "lat": 43.83167, - "lon": -111.80611 - }, - "KSMN": { - "id": "KSMN", - "city": "Salmon, Lemhi County Airport", - "state": "ID", - "lat": 45.11667, - "lon": -113.88333 - }, - "KSNT": { - "id": "KSNT", - "city": "Stanley, Stanley Ranger Station", - "state": "ID", - "lat": 44.20861, - "lon": -114.93444 - }, - "KSUN": { - "id": "KSUN", - "city": "Hailey, Friedman Memorial Airport", - "state": "ID", - "lat": 43.5, - "lon": -114.3 - }, - "KBKW": { - "id": "KBKW", - "city": "Beckley, Raleigh County Memorial Airport", - "state": "WV", - "lat": 37.795, - "lon": -81.12472 - }, - "KBLF": { - "id": "KBLF", - "city": "Bluefield, Mercer County Airport", - "state": "WV", - "lat": 37.29583, - "lon": -81.20778 - }, - "KCBE": { - "id": "KCBE", - "city": "Cumberland, Greater Cumberland Regional Airport", - "state": "WV", - "lat": 39.61528, - "lon": -78.76083 - }, - "KCKB": { - "id": "KCKB", - "city": "Clarksburg, Clarksburg Benedum Airport", - "state": "WV", - "lat": 39.3, - "lon": -80.22472 - }, - "KCRW": { - "id": "KCRW", - "city": "Charleston, Yeager Airport", - "state": "WV", - "lat": 38.37944, - "lon": -81.59139 - }, - "KEKN": { - "id": "KEKN", - "city": "Elkins, Elkins-Randolph County-Jennings Randolph Field", - "state": "WV", - "lat": 38.88528, - "lon": -79.85278 - }, - "KHLG": { - "id": "KHLG", - "city": "Wheeling, Wheeling Ohio County Airport", - "state": "WV", - "lat": 40.17028, - "lon": -80.64444 - }, - "KHTS": { - "id": "KHTS", - "city": "Huntington, Tri-State Airport", - "state": "WV", - "lat": 38.365, - "lon": -82.555 - }, - "KLWB": { - "id": "KLWB", - "city": "Lewisburg / Greenbrier", - "state": "WV", - "lat": 37.86667, - "lon": -80.4 - }, - "KMGW": { - "id": "KMGW", - "city": "Morgantown Municipal-Hart Field", - "state": "WV", - "lat": 39.64985, - "lon": -79.92065 - }, - "KMRB": { - "id": "KMRB", - "city": "Eastern WV Regional Airport/Shepherd Field", - "state": "WV", - "lat": 39.40372, - "lon": -77.975 - }, - "KPKB": { - "id": "KPKB", - "city": "Parkersburg, Mid-Ohio Valley Regional Airport", - "state": "WV", - "lat": 39.345, - "lon": -81.43917 - }, - "PAAD": { - "id": "PAAD", - "city": "Point Thomson Airstrip", - "state": "AK", - "lat": 70.136, - "lon": -146.2901 - }, - "PAAQ": { - "id": "PAAQ", - "city": "Palmer, Palmer Municipal Airport", - "state": "AK", - "lat": 61.6, - "lon": -149.08333 - }, - "PABA": { - "id": "PABA", - "city": "Barter Island, Barter Island LRRS Airport", - "state": "AK", - "lat": 70.1338899, - "lon": -143.57694 - }, - "PABE": { - "id": "PABE", - "city": "Bethel, Bethel Airport", - "state": "AK", - "lat": 60.77972, - "lon": -161.83778 - }, - "PABI": { - "id": "PABI", - "city": "Delta Junction/Ft Greely, Allen Army Airfield", - "state": "AK", - "lat": 64, - "lon": -145.73333 - }, - "PABL": { - "id": "PABL", - "city": "Buckland, Buckland Airport", - "state": "AK", - "lat": 65.98222, - "lon": -161.15194 - }, - "PABR": { - "id": "PABR", - "city": "Wiley Post-Will Rogers Memorial Airport", - "state": "AK", - "lat": 71.28528, - "lon": -156.76583 - }, - "PABT": { - "id": "PABT", - "city": "Bettles, Bettles Airport", - "state": "AK", - "lat": 66.91667, - "lon": -151.51667 - }, - "PABV": { - "id": "PABV", - "city": "Birchwood, Birchwood Airport", - "state": "AK", - "lat": 61.41667, - "lon": -149.51667 - }, - "PACD": { - "id": "PACD", - "city": "Cold Bay, Cold Bay Airport", - "state": "AK", - "lat": 55.22083, - "lon": -162.72778 - }, - "PACM": { - "id": "PACM", - "city": "Scammon Bay", - "state": "AK", - "lat": 61.8453, - "lon": -165.5713 - }, - "PACV": { - "id": "PACV", - "city": "Cordova, Merle K (Mudhole) Smith Airport", - "state": "AK", - "lat": 60.49167, - "lon": -145.47778 - }, - "PACZ": { - "id": "PACZ", - "city": "Cape Romanzof, Cape Romanzof LRRS Airport", - "state": "AK", - "lat": 61.78333, - "lon": -166.03333 - }, - "PADG": { - "id": "PADG", - "city": "Red Dog", - "state": "AK", - "lat": 68.0321, - "lon": -162.8992 - }, - "PADK": { - "id": "PADK", - "city": "Adak Island, Adak Airport", - "state": "AK", - "lat": 51.87778, - "lon": -176.64583 - }, - "PADL": { - "id": "PADL", - "city": "Dillingham, Dillingham Airport", - "state": "AK", - "lat": 59.05, - "lon": -158.51667 - }, - "PADM": { - "id": "PADM", - "city": "Marshall", - "state": "AK", - "lat": 61.8643, - "lon": -162.0261 - }, - "PADQ": { - "id": "PADQ", - "city": "Kodiak, Kodiak Airport", - "state": "AK", - "lat": 57.75, - "lon": -152.5 - }, - "PADU": { - "id": "PADU", - "city": "Unalaska, Unalaska Airport", - "state": "AK", - "lat": 53.9, - "lon": -166.53333 - }, - "PAEC": { - "id": "PAEC", - "city": "Chulitna, Chulitna Airport", - "state": "AK", - "lat": 62.88333, - "lon": -149.83333 - }, - "PAED": { - "id": "PAED", - "city": "Anchorage, Elmendorf Air Force Base", - "state": "AK", - "lat": 61.25306, - "lon": -149.79389 - }, - "PAEG": { - "id": "PAEG", - "city": "Eagle, Eagle Airport", - "state": "AK", - "lat": 64.77639, - "lon": -141.15083 - }, - "PAEH": { - "id": "PAEH", - "city": "Cape Newenham, Cape Newenham LRRS Airport", - "state": "AK", - "lat": 58.65, - "lon": -162.0666699 - }, - "PAEI": { - "id": "PAEI", - "city": "Fairbanks, Eielson Air Force Base", - "state": "AK", - "lat": 64.65, - "lon": -147.1 - }, - "PAEL": { - "id": "PAEL", - "city": "Elfin Cove - Elfin Cove Seaplane Base", - "state": "AK", - "lat": 58.19467, - "lon": -136.34663 - }, - "PAEM": { - "id": "PAEM", - "city": "Emmonak, Emmonak Airport", - "state": "AK", - "lat": 62.78333, - "lon": -164.5 - }, - "PAEN": { - "id": "PAEN", - "city": "Kenai, Kenai Municipal Airport", - "state": "AK", - "lat": 60.57306, - "lon": -151.245 - }, - "PAFA": { - "id": "PAFA", - "city": "Fairbanks, Fairbanks International Airport", - "state": "AK", - "lat": 64.80389, - "lon": -147.87611 - }, - "PAFB": { - "id": "PAFB", - "city": "Fort Wainwright AAF", - "state": "AK", - "lat": 64.83667, - "lon": -147.59556 - }, - "PAFE": { - "id": "PAFE", - "city": "Kake - Kake Airport", - "state": "AK", - "lat": 56.964, - "lon": -133.913 - }, - "PAFM": { - "id": "PAFM", - "city": "Ambler, Ambler Airport", - "state": "AK", - "lat": 67.1, - "lon": -157.85 - }, - "PAFR": { - "id": "PAFR", - "city": "Ft. Richardson / Bryant U. S. Army Heliport, Ak", - "state": "AK", - "lat": 61.26667, - "lon": -149.65 - }, - "PAFS": { - "id": "PAFS", - "city": "Nikolai", - "state": "AK", - "lat": 63.019, - "lon": -154.358 - }, - "PAGA": { - "id": "PAGA", - "city": "Galena, Edward G. Pitka Sr. Airport", - "state": "AK", - "lat": 64.73333, - "lon": -156.93333 - }, - "PAGB": { - "id": "PAGB", - "city": "Galbraith Lake, Galbraith Lake Airport", - "state": "AK", - "lat": 68.48333, - "lon": -149.48333 - }, - "PAGH": { - "id": "PAGH", - "city": "Shungnak Airport", - "state": "AK", - "lat": 66.8881, - "lon": -157.1624 - }, - "PAGK": { - "id": "PAGK", - "city": "Gulkana, Gulkana Airport", - "state": "AK", - "lat": 62.15, - "lon": -145.45 - }, - "PAGL": { - "id": "PAGL", - "city": "Golovin, Golovin Airport", - "state": "AK", - "lat": 64.54333, - "lon": -163.03944 - }, - "PAGM": { - "id": "PAGM", - "city": "Gambell, Gambell Airport", - "state": "AK", - "lat": 63.76667, - "lon": -171.73333 - }, - "PAGN": { - "id": "PAGN", - "city": "Angoon", - "state": "AK", - "lat": 57.5, - "lon": -134.58333 - }, - "PAGS": { - "id": "PAGS", - "city": "Gustavus, Gustavus Airport", - "state": "AK", - "lat": 58.41667, - "lon": -135.7 - }, - "PAGY": { - "id": "PAGY", - "city": "Skagway", - "state": "AK", - "lat": 59.4544, - "lon": -135.3263 - }, - "PAHC": { - "id": "PAHC", - "city": "Holy Cross", - "state": "AK", - "lat": 62.1873, - "lon": -159.77657 - }, - "PAHL": { - "id": "PAHL", - "city": "Huslia, Huslia Airport", - "state": "AK", - "lat": 65.6975, - "lon": -156.35111 - }, - "PAHN": { - "id": "PAHN", - "city": "Haines - Haines Airport", - "state": "AK", - "lat": 59.2429, - "lon": -135.5114 - }, - "PAHO": { - "id": "PAHO", - "city": "Homer, Homer Airport", - "state": "AK", - "lat": 59.65, - "lon": -151.48333 - }, - "PAHP": { - "id": "PAHP", - "city": "Hooper Bay, Hooper Bay Airport", - "state": "AK", - "lat": 61.51667, - "lon": -166.13333 - }, - "PAHY": { - "id": "PAHY", - "city": "Hydaburg - Hydaburg Seaplane Base", - "state": "AK", - "lat": 55.2, - "lon": -132.83333 - }, - "PAIG": { - "id": "PAIG", - "city": "Igiugig", - "state": "AK", - "lat": 59.32395, - "lon": -155.90235 - }, - "PAII": { - "id": "PAII", - "city": "Egegik, Egegik Airport", - "state": "AK", - "lat": 58.18528, - "lon": -157.38556 - }, - "PAIK": { - "id": "PAIK", - "city": "Kinana / Bob Baker Me", - "state": "AK", - "lat": 66.98333, - "lon": -160.43333 - }, - "PAIL": { - "id": "PAIL", - "city": "Iliamna, Iliamna Airport", - "state": "AK", - "lat": 59.75, - "lon": -154.9 - }, - "PAIM": { - "id": "PAIM", - "city": "Utopia Creek, Indian Mountain LRRS Airport", - "state": "AK", - "lat": 66, - "lon": -153.7 - }, - "PAIN": { - "id": "PAIN", - "city": "McKinley Park, McKinley National Park Airport", - "state": "AK", - "lat": 63.73333, - "lon": -148.91667 - }, - "PAIW": { - "id": "PAIW", - "city": "Wales", - "state": "AK", - "lat": 65.6226, - "lon": -168.0949 - }, - "PAJC": { - "id": "PAJC", - "city": "Chignik, Chignik Airport", - "state": "AK", - "lat": 56.31139, - "lon": -158.37333 - }, - "PAJK": { - "id": "PAJK", - "city": "NWS Office: Juneau", - "state": "AK", - "lat": 58.4, - "lon": -134.57001 - }, - "PAJN": { - "id": "PAJN", - "city": "Juneau, Juneau International Airport", - "state": "AK", - "lat": 58.35472, - "lon": -134.57611 - }, - "PAJZ": { - "id": "PAJZ", - "city": "Koliganek", - "state": "AK", - "lat": 59.727, - "lon": -157.2589999 - }, - "PAKF": { - "id": "PAKF", - "city": "False Pass Airport", - "state": "AK", - "lat": 54.847, - "lon": -163.41 - }, - "PAKH": { - "id": "PAKH", - "city": "Akhiok", - "state": "AK", - "lat": 56.9387, - "lon": -154.1826 - }, - "PAKI": { - "id": "PAKI", - "city": "Kipnuk, Kipnuk Airport", - "state": "AK", - "lat": 59.93278, - "lon": -164.03028 - }, - "PAKK": { - "id": "PAKK", - "city": "Koyuk, Koyuk Airport", - "state": "AK", - "lat": 64.93389, - "lon": -161.15806 - }, - "PAKN": { - "id": "PAKN", - "city": "King Salmon, King Salmon Airport", - "state": "AK", - "lat": 58.67667, - "lon": -156.64917 - }, - "PAKP": { - "id": "PAKP", - "city": "Anaktuvuk Pass, Anaktuvuk Pass Airport", - "state": "AK", - "lat": 68.13361, - "lon": -151.7433299 - }, - "PAKT": { - "id": "PAKT", - "city": "Ketchikan, Ketchikan International Airport", - "state": "AK", - "lat": 55.35556, - "lon": -131.71361 - }, - "PAKU": { - "id": "PAKU", - "city": "Kuparuk, Ugnu-Kuparuk Airport", - "state": "AK", - "lat": 70.31667, - "lon": -149.58333 - }, - "PAKV": { - "id": "PAKV", - "city": "Kaltag, Kaltag Airport", - "state": "AK", - "lat": 64.31667, - "lon": -158.73333 - }, - "PAKW": { - "id": "PAKW", - "city": "Klawock - Klawock Airport", - "state": "AK", - "lat": 55.5839, - "lon": -133.067 - }, - "PALG": { - "id": "PALG", - "city": "Kalskag", - "state": "AK", - "lat": 61.5364, - "lon": -160.3414 - }, - "PALH": { - "id": "PALH", - "city": "Anchorage, Lake Hood Seaplane Base", - "state": "AK", - "lat": 61.18333, - "lon": -149.96667 - }, - "PALJ": { - "id": "PALJ", - "city": "Port Alsworth, Port Alsworth Airport", - "state": "AK", - "lat": 60.2, - "lon": -154.3166699 - }, - "PALP": { - "id": "PALP", - "city": "Deadhorse, Alpine Airstrip", - "state": "AK", - "lat": 70.33333, - "lon": -150.93333 - }, - "PALU": { - "id": "PALU", - "city": "Cape Lisburne, Cape Lisburne LRRS Airport", - "state": "AK", - "lat": 68.88333, - "lon": -166.1 - }, - "PAMB": { - "id": "PAMB", - "city": "Manokotak", - "state": "AK", - "lat": 58.9902, - "lon": -159.0499 - }, - "PAMC": { - "id": "PAMC", - "city": "McGrath, McGrath Airport", - "state": "AK", - "lat": 62.96667, - "lon": -155.61667 - }, - "PAMD": { - "id": "PAMD", - "city": "Middleton Island Airport", - "state": "AK", - "lat": 59.4423, - "lon": -146.3166 - }, - "PAMH": { - "id": "PAMH", - "city": "Minchumina, Minchumina Airport", - "state": "AK", - "lat": 63.88056, - "lon": -152.30056 - }, - "PAMK": { - "id": "PAMK", - "city": "St Michael Airport", - "state": "AK", - "lat": 63.49006, - "lon": -162.11039 - }, - "PAMM": { - "id": "PAMM", - "city": "Metlakatla, Metlakatla Seaplane Base", - "state": "AK", - "lat": 55.13111, - "lon": -131.57806 - }, - "PAMO": { - "id": "PAMO", - "city": "Mountain Village", - "state": "AK", - "lat": 62.0953, - "lon": -163.6819 - }, - "PAMR": { - "id": "PAMR", - "city": "Anchorage, Merrill Field Airport", - "state": "AK", - "lat": 61.21667, - "lon": -149.85 - }, - "PAMY": { - "id": "PAMY", - "city": "Mekoryuk, Mekoryuk Airport", - "state": "AK", - "lat": 60.36667, - "lon": -166.26667 - }, - "PANA": { - "id": "PANA", - "city": "Napakiak Airport", - "state": "AK", - "lat": 60.6903, - "lon": -161.9785 - }, - "PANC": { - "id": "PANC", - "city": "Anchorage, Ted Stevens Anchorage International Airport", - "state": "AK", - "lat": 61.17444, - "lon": -149.9961099 - }, - "PANI": { - "id": "PANI", - "city": "Aniak, Aniak Airport", - "state": "AK", - "lat": 61.58139, - "lon": -159.54278 - }, - "PANN": { - "id": "PANN", - "city": "Nenana Municipal Airport", - "state": "AK", - "lat": 64.54796, - "lon": -149.08398 - }, - "PANV": { - "id": "PANV", - "city": "Anvik, Anvik Airport", - "state": "AK", - "lat": 62.64833, - "lon": -160.18972 - }, - "PANW": { - "id": "PANW", - "city": "New Stuyahok", - "state": "AK", - "lat": 59.45, - "lon": -157.328 - }, - "PAOH": { - "id": "PAOH", - "city": "Hoonah - Hoonah Seaplane Base", - "state": "AK", - "lat": 58.097, - "lon": -135.4139999 - }, - "PAOM": { - "id": "PAOM", - "city": "Nome, Nome Airport", - "state": "AK", - "lat": 64.51194, - "lon": -165.445 - }, - "PAOO": { - "id": "PAOO", - "city": "Toksook Bay", - "state": "AK", - "lat": 60.53352, - "lon": -165.1142999 - }, - "PAOR": { - "id": "PAOR", - "city": "Northway, Northway Airport", - "state": "AK", - "lat": 62.96111, - "lon": -141.92889 - }, - "PAOT": { - "id": "PAOT", - "city": "Ralph Wien Memorial Airport", - "state": "AK", - "lat": 66.88576, - "lon": -162.60624 - }, - "PAOU": { - "id": "PAOU", - "city": "Nelson Lagoon", - "state": "AK", - "lat": 56.008, - "lon": -161.16 - }, - "PAPB": { - "id": "PAPB", - "city": "St. George, St. George Airport", - "state": "AK", - "lat": 56.57861, - "lon": -169.66139 - }, - "PAPG": { - "id": "PAPG", - "city": "Petersburg", - "state": "AK", - "lat": 56.8017, - "lon": -132.9453 - }, - "PAPH": { - "id": "PAPH", - "city": "Port Heiden, Port Heiden Airport", - "state": "AK", - "lat": 56.95, - "lon": -158.63333 - }, - "PAPM": { - "id": "PAPM", - "city": "Platinum", - "state": "AK", - "lat": 59.01667, - "lon": -161.8166699 - }, - "PAPN": { - "id": "PAPN", - "city": "Pilot Point Airport", - "state": "AK", - "lat": 57.58, - "lon": -157.572 - }, - "PAPO": { - "id": "PAPO", - "city": "Point Hope, Point Hope Airport", - "state": "AK", - "lat": 68.35, - "lon": -166.8 - }, - "PAPR": { - "id": "PAPR", - "city": "Prospect Creek, Prospect Creek Airport", - "state": "AK", - "lat": 66.81278, - "lon": -150.64389 - }, - "PAPT": { - "id": "PAPT", - "city": "Puntilla", - "state": "AK", - "lat": 62.1, - "lon": -152.75 - }, - "PAQH": { - "id": "PAQH", - "city": "Quinhagak Airport", - "state": "AK", - "lat": 59.7551, - "lon": -161.8454 - }, - "PAQT": { - "id": "PAQT", - "city": "Nuiqsut, Nuiqsut Airport", - "state": "AK", - "lat": 70.2099999, - "lon": -151.00556 - }, - "PARC": { - "id": "PARC", - "city": "Arctic Village, Arctic Village Airport", - "state": "AK", - "lat": 68.11444, - "lon": -145.57917 - }, - "PARS": { - "id": "PARS", - "city": "Russian Mission", - "state": "AK", - "lat": 61.775, - "lon": -161.3194 - }, - "PARY": { - "id": "PARY", - "city": "Ruby", - "state": "AK", - "lat": 64.7272, - "lon": -155.4697 - }, - "PASA": { - "id": "PASA", - "city": "Savoonga Airport", - "state": "AK", - "lat": 63.68333, - "lon": -170.5 - }, - "PASC": { - "id": "PASC", - "city": "Deadhorse, Deadhorse Airport", - "state": "AK", - "lat": 70.2, - "lon": -148.46667 - }, - "PASD": { - "id": "PASD", - "city": "Sand Point", - "state": "AK", - "lat": 55.31667, - "lon": -160.51667 - }, - "PASH": { - "id": "PASH", - "city": "Shishmaref, Shishmaref Airport", - "state": "AK", - "lat": 66.26667, - "lon": -166.08333 - }, - "PASI": { - "id": "PASI", - "city": "Sitka - Sitka Airport", - "state": "AK", - "lat": 57.048, - "lon": -135.3647 - }, - "PASK": { - "id": "PASK", - "city": "Selawik", - "state": "AK", - "lat": 66.61667, - "lon": -160 - }, - "PASL": { - "id": "PASL", - "city": "Sleetmute", - "state": "AK", - "lat": 61.69735, - "lon": -157.16712 - }, - "PASM": { - "id": "PASM", - "city": "St. Mary's, St. Mary's Airport", - "state": "AK", - "lat": 62.05, - "lon": -163.3 - }, - "PASN": { - "id": "PASN", - "city": "St. Paul Island, St. Paul Island Airport", - "state": "AK", - "lat": 57.16667, - "lon": -170.21667 - }, - "PASO": { - "id": "PASO", - "city": "Seldovia, Seldovia Airport", - "state": "AK", - "lat": 59.45, - "lon": -151.7 - }, - "PASV": { - "id": "PASV", - "city": "Sparrevohn Airways Facilities Sector", - "state": "AK", - "lat": 61.1, - "lon": -155.5666699 - }, - "PASX": { - "id": "PASX", - "city": "Soldotna", - "state": "AK", - "lat": 60.48333, - "lon": -151.03333 - }, - "PASY": { - "id": "PASY", - "city": "Shemya, Eareckson AFB", - "state": "AK", - "lat": 52.71667, - "lon": 174.11667 - }, - "PATA": { - "id": "PATA", - "city": "Tanana, Calhoun Memorial Airport", - "state": "AK", - "lat": 65.16667, - "lon": -152.1 - }, - "PATC": { - "id": "PATC", - "city": "Tin City Airways Facilities Sector", - "state": "AK", - "lat": 65.56667, - "lon": -167.91667 - }, - "PATE": { - "id": "PATE", - "city": "Teller", - "state": "AK", - "lat": 65.2403999, - "lon": -166.3393 - }, - "PATG": { - "id": "PATG", - "city": "Togiac Village, Togiak Airport", - "state": "AK", - "lat": 59.05, - "lon": -160.4 - }, - "PATK": { - "id": "PATK", - "city": "Talkeetna, Talkeetna Airport", - "state": "AK", - "lat": 62.32056, - "lon": -150.09361 - }, - "PATL": { - "id": "PATL", - "city": "Takotna, Tatalina LRRS Airport", - "state": "AK", - "lat": 62.9, - "lon": -155.98333 - }, - "PATO": { - "id": "PATO", - "city": "Portage, Portage Glacier", - "state": "AK", - "lat": 60.78333, - "lon": -148.83333 - }, - "PATQ": { - "id": "PATQ", - "city": "Atqasuk", - "state": "AK", - "lat": 70.4673, - "lon": -157.4357 - }, - "PAUN": { - "id": "PAUN", - "city": "Unalakleet", - "state": "AK", - "lat": 63.88333, - "lon": -160.8 - }, - "PAUT": { - "id": "PAUT", - "city": "Akun Airport", - "state": "AK", - "lat": 54.1446, - "lon": -165.6041 - }, - "PAVA": { - "id": "PAVA", - "city": "Chevak Airport", - "state": "AK", - "lat": 61.5408, - "lon": -165.6009 - }, - "PAVC": { - "id": "PAVC", - "city": "King Cove", - "state": "AK", - "lat": 55.116, - "lon": -162.266 - }, - "PAVD": { - "id": "PAVD", - "city": "Valdez 2", - "state": "AK", - "lat": 61.13333, - "lon": -146.26667 - }, - "PAVL": { - "id": "PAVL", - "city": "Kivalina, Kivalina Airport", - "state": "AK", - "lat": 67.73333, - "lon": -164.55 - }, - "PAWD": { - "id": "PAWD", - "city": "Seward", - "state": "AK", - "lat": 60.11667, - "lon": -149.45 - }, - "PAWG": { - "id": "PAWG", - "city": "Wrangell", - "state": "AK", - "lat": 56.48333, - "lon": -132.36667 - }, - "PAWI": { - "id": "PAWI", - "city": "Wainwright, Wainwright Airport", - "state": "AK", - "lat": 70.63333, - "lon": -159.85 - }, - "PAWM": { - "id": "PAWM", - "city": "White Mountain Airport", - "state": "AK", - "lat": 64.6892, - "lon": -163.4127 - }, - "PAWN": { - "id": "PAWN", - "city": "Noatak, Noatak Airport", - "state": "AK", - "lat": 67.56667, - "lon": -162.98333 - }, - "PAWS": { - "id": "PAWS", - "city": "Wasilla, Wasilla Airport", - "state": "AK", - "lat": 61.57194, - "lon": -149.54056 - }, - "PAYA": { - "id": "PAYA", - "city": "Yakutat", - "state": "AK", - "lat": 59.51667, - "lon": -139.66667 - }, - "PAZK": { - "id": "PAZK", - "city": "Eureka, Skelton Airport", - "state": "AK", - "lat": 61.93333, - "lon": -147.16667 - }, - "PFCL": { - "id": "PFCL", - "city": "Clarks Point Airport", - "state": "AK", - "lat": 58.8337, - "lon": -158.5294 - }, - "PFEL": { - "id": "PFEL", - "city": "Elim Airport", - "state": "AK", - "lat": 64.615, - "lon": -162.2705 - }, - "PFKT": { - "id": "PFKT", - "city": "Brevig Mission Airport", - "state": "AK", - "lat": 65.3313, - "lon": -166.4657 - }, - "PFKW": { - "id": "PFKW", - "city": "Kwethluk Airport", - "state": "AK", - "lat": 60.7903, - "lon": -161.4437 - }, - "PFNO": { - "id": "PFNO", - "city": "Noorvik", - "state": "AK", - "lat": 66.8175, - "lon": -161.0223 - }, - "PFSH": { - "id": "PFSH", - "city": "Shaktoolik Airport", - "state": "AK", - "lat": 64.3711, - "lon": -161.224 - }, - "PFWS": { - "id": "PFWS", - "city": "South Naknek Nr 2 Airport", - "state": "AK", - "lat": 58.7021, - "lon": -157.0026 - }, - "PFYU": { - "id": "PFYU", - "city": "Fort Yukon, Fort Yukon Airport", - "state": "AK", - "lat": 66.56667, - "lon": -145.26667 - }, - "PPIT": { - "id": "PPIT", - "city": "Nunapitchuk Airport", - "state": "AK", - "lat": 60.906, - "lon": -162.4406 - }, - "PPIZ": { - "id": "PPIZ", - "city": "Point Lay, Point Lay LRRS Airport", - "state": "AK", - "lat": 69.7166699, - "lon": -163 - }, - "KBAM": { - "id": "KBAM", - "city": "Battle Mountain - Lander County Airport", - "state": "NV", - "lat": 40.5989999, - "lon": -116.8743 - }, - "KBVU": { - "id": "KBVU", - "city": "Boulder City Municipal Airport", - "state": "NV", - "lat": 35.9475, - "lon": -114.8611 - }, - "KCXP": { - "id": "KCXP", - "city": "Carson City Airport", - "state": "NV", - "lat": 39.19056, - "lon": -119.73191 - }, - "KDRA": { - "id": "KDRA", - "city": "Mercury, Desert Rock Airport", - "state": "NV", - "lat": 36.6207, - "lon": -116.02868 - }, - "KEKO": { - "id": "KEKO", - "city": "Elko, Elko Regional Airport", - "state": "NV", - "lat": 40.8240399, - "lon": -115.78635 - }, - "KELY": { - "id": "KELY", - "city": "Ely, Ely Airport", - "state": "NV", - "lat": 39.295, - "lon": -114.84528 - }, - "KHND": { - "id": "KHND", - "city": "Las Vegas - Henderson Executive Airport", - "state": "NV", - "lat": 35.97665, - "lon": -115.13221 - }, - "KHTH": { - "id": "KHTH", - "city": "Hawthorne Industrial Airport", - "state": "NV", - "lat": 38.54482, - "lon": -118.63137 - }, - "KINS": { - "id": "KINS", - "city": "Nellis AFB - Indian Springs Auxiliary Airfield", - "state": "NV", - "lat": 36.58573, - "lon": -115.69008 - }, - "KLAS": { - "id": "KLAS", - "city": "Las Vegas, McCarran International Airport", - "state": "NV", - "lat": 36.07188, - "lon": -115.1634 - }, - "KLOL": { - "id": "KLOL", - "city": "Lovelock, Derby Field Airport", - "state": "NV", - "lat": 40.0683999, - "lon": -118.57017 - }, - "KLSV": { - "id": "KLSV", - "city": "Nellis Air Force Base", - "state": "NV", - "lat": 36.23333, - "lon": -115.03333 - }, - "KMEV": { - "id": "KMEV", - "city": "Minden-Tahoe Airport", - "state": "NV", - "lat": 38.9963, - "lon": -119.75 - }, - "KNFL": { - "id": "KNFL", - "city": "Fallon, Naval Air Station", - "state": "NV", - "lat": 39.43222, - "lon": -118.68556 - }, - "KRNO": { - "id": "KRNO", - "city": "Reno, Reno Tahoe International Airport", - "state": "NV", - "lat": 39.50776, - "lon": -119.76819 - }, - "KRTS": { - "id": "KRTS", - "city": "Reno/Stead", - "state": "NV", - "lat": 39.6682, - "lon": -119.8764 - }, - "KTMT": { - "id": "KTMT", - "city": "Austin Airport", - "state": "NV", - "lat": 39.46794, - "lon": -117.19745 - }, - "KTPH": { - "id": "KTPH", - "city": "Tonopah, Tonopah Airport", - "state": "NV", - "lat": 38.06028, - "lon": -117.08722 - }, - "KVGT": { - "id": "KVGT", - "city": "Las Vegas, North Las Vegas Airport", - "state": "NV", - "lat": 36.21205, - "lon": -115.19395 - }, - "KWMC": { - "id": "KWMC", - "city": "Winnemucca, Winnemucca Municipal Airport", - "state": "NV", - "lat": 40.90194, - "lon": -117.80722 - }, - "KADU": { - "id": "KADU", - "city": "Audubon, Audubon County Airport", - "state": "IA", - "lat": 41.70111, - "lon": -94.92028 - }, - "KAIO": { - "id": "KAIO", - "city": "Atlantic", - "state": "IA", - "lat": 41.4, - "lon": -95.05 - }, - "KALO": { - "id": "KALO", - "city": "Waterloo, Waterloo Municipal Airport", - "state": "IA", - "lat": 42.55444, - "lon": -92.40111 - }, - "KAMW": { - "id": "KAMW", - "city": "Ames, Ames Municipal Airport", - "state": "IA", - "lat": 41.99056, - "lon": -93.6188899 - }, - "KAWG": { - "id": "KAWG", - "city": "Washington", - "state": "IA", - "lat": 41.28333, - "lon": -91.66667 - }, - "KAXA": { - "id": "KAXA", - "city": "Algona", - "state": "IA", - "lat": 43.0833299, - "lon": -94.26667 - }, - "KBNW": { - "id": "KBNW", - "city": "Boone Municipal", - "state": "IA", - "lat": 42.05, - "lon": -93.85 - }, - "KBRL": { - "id": "KBRL", - "city": "Burlington Regional Airport", - "state": "IA", - "lat": 40.77293, - "lon": -91.12543 - }, - "KCAV": { - "id": "KCAV", - "city": "Clarion", - "state": "IA", - "lat": 42.75, - "lon": -93.76667 - }, - "KCBF": { - "id": "KCBF", - "city": "Council Bluffs", - "state": "IA", - "lat": 41.2612499, - "lon": -95.7604 - }, - "KCCY": { - "id": "KCCY", - "city": "Charles City", - "state": "IA", - "lat": 43.06667, - "lon": -92.61667 - }, - "KCID": { - "id": "KCID", - "city": "Cedar Rapids Airport", - "state": "IA", - "lat": 41.88295, - "lon": -91.72456 - }, - "KCIN": { - "id": "KCIN", - "city": "Carroll", - "state": "IA", - "lat": 42.05, - "lon": -94.78333 - }, - "KCKP": { - "id": "KCKP", - "city": "Cherokee, Cherokee Municipal Airport", - "state": "IA", - "lat": 42.73167, - "lon": -95.55583 - }, - "KCNC": { - "id": "KCNC", - "city": "Chariton", - "state": "IA", - "lat": 41.03333, - "lon": -93.36667 - }, - "KCSQ": { - "id": "KCSQ", - "city": "Creston Municipal Airport", - "state": "IA", - "lat": 41.0188599, - "lon": -94.361 - }, - "KCWI": { - "id": "KCWI", - "city": "Clinton Municipal Airport", - "state": "IA", - "lat": 41.82954, - "lon": -90.33279 - }, - "KDBQ": { - "id": "KDBQ", - "city": "Dubuque Regional Airport", - "state": "IA", - "lat": 42.39837, - "lon": -90.7091 - }, - "KDEH": { - "id": "KDEH", - "city": "Decorah", - "state": "IA", - "lat": 43.28333, - "lon": -91.73333 - }, - "KDNS": { - "id": "KDNS", - "city": "Denison", - "state": "IA", - "lat": 41.98333, - "lon": -95.38333 - }, - "KDSM": { - "id": "KDSM", - "city": "Des Moines International Airport", - "state": "IA", - "lat": 41.53399, - "lon": -93.65307 - }, - "KDVN": { - "id": "KDVN", - "city": "Davenport Municipal Airport", - "state": "IA", - "lat": 41.61338, - "lon": -90.59479 - }, - "KEBS": { - "id": "KEBS", - "city": "Webster City Municipal Airport", - "state": "IA", - "lat": 42.43724, - "lon": -93.87237 - }, - "KEOK": { - "id": "KEOK", - "city": "Keokuk Municipal Airport", - "state": "IA", - "lat": 40.46149, - "lon": -91.42739 - }, - "KEST": { - "id": "KEST", - "city": "Estherville, Estherville Municipal Airport", - "state": "IA", - "lat": 43.40111, - "lon": -94.74722 - }, - "KFFL": { - "id": "KFFL", - "city": "Fairfield Municipal Airport", - "state": "IA", - "lat": 41.0521, - "lon": -91.98339 - }, - "KFOD": { - "id": "KFOD", - "city": "Fort Dodge", - "state": "IA", - "lat": 42.55, - "lon": -94.18333 - }, - "KFSW": { - "id": "KFSW", - "city": "Fort Madison Municipal Airport", - "state": "IA", - "lat": 40.66154, - "lon": -91.32672 - }, - "KFXY": { - "id": "KFXY", - "city": "Forest City Municipal Airport", - "state": "IA", - "lat": 43.235, - "lon": -93.624 - }, - "KGGI": { - "id": "KGGI", - "city": "Grinnell Municipal Airfield", - "state": "IA", - "lat": 41.7092, - "lon": -92.7349 - }, - "KHNR": { - "id": "KHNR", - "city": "Harlan, Harlan Municipal Airport", - "state": "IA", - "lat": 41.58444, - "lon": -95.33972 - }, - "KHPT": { - "id": "KHPT", - "city": "Hampton Municipal Airport", - "state": "IA", - "lat": 42.72369, - "lon": -93.22633 - }, - "KICL": { - "id": "KICL", - "city": "Schenck Field Airport", - "state": "IA", - "lat": 40.72421, - "lon": -95.02224 - }, - "KIFA": { - "id": "KIFA", - "city": "Iowa Falls Municipal Airport", - "state": "IA", - "lat": 42.4709999, - "lon": -93.27 - }, - "KIIB": { - "id": "KIIB", - "city": "Independence, Independence Municipal Airport", - "state": "IA", - "lat": 42.45, - "lon": -91.93333 - }, - "KIKV": { - "id": "KIKV", - "city": "Ankeny Regional Airport", - "state": "IA", - "lat": 41.68782, - "lon": -93.56944 - }, - "KIOW": { - "id": "KIOW", - "city": "Iowa City Municipal Airport", - "state": "IA", - "lat": 41.6394499, - "lon": -91.5445 - }, - "KLRJ": { - "id": "KLRJ", - "city": "Le Mars Municipal Airport", - "state": "IA", - "lat": 42.77478, - "lon": -96.19239 - }, - "KLWD": { - "id": "KLWD", - "city": "Lamoni, Lamoni Municipal Airport", - "state": "IA", - "lat": 40.63056, - "lon": -93.90083 - }, - "KMCW": { - "id": "KMCW", - "city": "Mason City Municipal Airport", - "state": "IA", - "lat": 43.15442, - "lon": -93.32607 - }, - "KMIW": { - "id": "KMIW", - "city": "Marshalltown, Marshalltown Municipal Airport", - "state": "IA", - "lat": 42.11056, - "lon": -92.91611 - }, - "KMPZ": { - "id": "KMPZ", - "city": "Mount Pleasant, Mount Pleasant Municipal Airport", - "state": "IA", - "lat": 40.94667, - "lon": -91.51111 - }, - "KMUT": { - "id": "KMUT", - "city": "Muscatine", - "state": "IA", - "lat": 41.36667, - "lon": -91.15 - }, - "KMXO": { - "id": "KMXO", - "city": "Monticello Regional Airport", - "state": "IA", - "lat": 42.22035, - "lon": -91.16041 - }, - "KOLZ": { - "id": "KOLZ", - "city": "Oelwein Municipal Airport", - "state": "IA", - "lat": 42.68316, - "lon": -91.97595 - }, - "KOOA": { - "id": "KOOA", - "city": "Oskaloosa, Oskaloosa Municipal Airport", - "state": "IA", - "lat": 41.22611, - "lon": -92.49361 - }, - "KOTM": { - "id": "KOTM", - "city": "Ottumwa Regional Airport", - "state": "IA", - "lat": 41.10082, - "lon": -92.4445099 - }, - "KOXV": { - "id": "KOXV", - "city": "Knoxville", - "state": "IA", - "lat": 41.3, - "lon": -93.11667 - }, - "KPEA": { - "id": "KPEA", - "city": "Pella, Pella Municipal Airport", - "state": "IA", - "lat": 41.4, - "lon": -92.93333 - }, - "KPRO": { - "id": "KPRO", - "city": "Perry Municipal Airport", - "state": "IA", - "lat": 41.828, - "lon": -94.1598999 - }, - "KRDK": { - "id": "KRDK", - "city": "Red Oak", - "state": "IA", - "lat": 41.01667, - "lon": -95.26667 - }, - "KSDA": { - "id": "KSDA", - "city": "Shenandoah Municipal", - "state": "IA", - "lat": 40.75, - "lon": -95.41667 - }, - "KSHL": { - "id": "KSHL", - "city": "Sheldon", - "state": "IA", - "lat": 43.21667, - "lon": -95.83333 - }, - "KSLB": { - "id": "KSLB", - "city": "Storm Lake", - "state": "IA", - "lat": 42.6, - "lon": -95.23333 - }, - "KSPW": { - "id": "KSPW", - "city": "Spencer Municipal Airport", - "state": "IA", - "lat": 43.16825, - "lon": -95.21008 - }, - "KSUX": { - "id": "KSUX", - "city": "Sioux City, Sioux Gateway Airport", - "state": "IA", - "lat": 42.4025, - "lon": -96.38444 - }, - "KSXK": { - "id": "KSXK", - "city": "Sioux County Regional Airport", - "state": "IA", - "lat": 42.98583, - "lon": -96.1614 - }, - "KTNU": { - "id": "KTNU", - "city": "Newton Municipal Airport - Earl Johnson Field", - "state": "IA", - "lat": 41.67014, - "lon": -93.01902 - }, - "KTVK": { - "id": "KTVK", - "city": "Centerville Municipal Airport", - "state": "IA", - "lat": 40.6839, - "lon": -92.901 - }, - "KVTI": { - "id": "KVTI", - "city": "Vinton, Vinton Veterans Memorial Airpark Airport", - "state": "IA", - "lat": 42.21861, - "lon": -92.02583 - }, - "KBGF": { - "id": "KBGF", - "city": "Winchester Municipal Airport", - "state": "TN", - "lat": 35.1775, - "lon": -86.0662 - }, - "KBNA": { - "id": "KBNA", - "city": "Nashville, Nashville International Airport", - "state": "TN", - "lat": 36.11889, - "lon": -86.68917 - }, - "KCHA": { - "id": "KCHA", - "city": "Chattanooga, Lovell Field", - "state": "TN", - "lat": 35.03333, - "lon": -85.2 - }, - "KCKV": { - "id": "KCKV", - "city": "Clarksville Outlaw Field", - "state": "TN", - "lat": 36.61689, - "lon": -87.41174 - }, - "KCSV": { - "id": "KCSV", - "city": "Crossville, Crossville Memorial-Whitson Field Airport", - "state": "TN", - "lat": 35.95139, - "lon": -85.0849999 - }, - "KDKX": { - "id": "KDKX", - "city": "Knoxville Downtown Airport", - "state": "TN", - "lat": 35.96581, - "lon": -83.87169 - }, - "KDYR": { - "id": "KDYR", - "city": "Dyersburg, Dyersburg Municipal Airport", - "state": "TN", - "lat": 36, - "lon": -89.4 - }, - "KFYE": { - "id": "KFYE", - "city": "Somerville - Fayette County Airport", - "state": "TN", - "lat": 35.2061, - "lon": -89.3929 - }, - "KFYM": { - "id": "KFYM", - "city": "Fayetteville Municipal Airport", - "state": "TN", - "lat": 35.0597, - "lon": -86.5639999 - }, - "KGCY": { - "id": "KGCY", - "city": "Greeneville-Greene County Municipal Airport", - "state": "TN", - "lat": 36.19601, - "lon": -82.81099 - }, - "KGKT": { - "id": "KGKT", - "city": "Sevierville Gatlinburg - Pigeon Forge Airport", - "state": "TN", - "lat": 35.85681, - "lon": -83.53334 - }, - "KGZS": { - "id": "KGZS", - "city": "Pulaski Abernathy Field Airport", - "state": "TN", - "lat": 35.1537, - "lon": -87.0568 - }, - "KHZD": { - "id": "KHZD", - "city": "Huntingdon Carroll County Airport", - "state": "TN", - "lat": 36.08896, - "lon": -88.46538 - }, - "KJAU": { - "id": "KJAU", - "city": "Jacksboro Campbell County Airport", - "state": "TN", - "lat": 36.3341, - "lon": -84.163 - }, - "KJWN": { - "id": "KJWN", - "city": "John C Tune Airport", - "state": "TN", - "lat": 36.18521, - "lon": -86.88331 - }, - "KLUG": { - "id": "KLUG", - "city": "Ellington Airport", - "state": "TN", - "lat": 35.50697, - "lon": -86.80389 - }, - "KMBT": { - "id": "KMBT", - "city": "Murfreesboro Municipal Airport", - "state": "TN", - "lat": 35.87866, - "lon": -86.37749 - }, - "KMEG": { - "id": "KMEG", - "city": "Memphis WFO", - "state": "TN", - "lat": 35.0563999, - "lon": -89.9863 - }, - "KMEM": { - "id": "KMEM", - "city": "Memphis International Airport", - "state": "TN", - "lat": 35.05644, - "lon": -89.98634 - }, - "KMKL": { - "id": "KMKL", - "city": "Jackson, McKellar-Sipes Regional Airport", - "state": "TN", - "lat": 35.59306, - "lon": -88.91667 - }, - "KMMI": { - "id": "KMMI", - "city": "Athens McMinn County Airport", - "state": "TN", - "lat": 35.3973, - "lon": -84.5626 - }, - "KMNV": { - "id": "KMNV", - "city": "Monroe County Airport", - "state": "TN", - "lat": 35.54522, - "lon": -84.38039 - }, - "KMOR": { - "id": "KMOR", - "city": "Morristown Moore-Murrell Airport", - "state": "TN", - "lat": 36.1794, - "lon": -83.3754 - }, - "KMQY": { - "id": "KMQY", - "city": "Smyrna, Smyrna Airport", - "state": "TN", - "lat": 36.00889, - "lon": -86.52 - }, - "KMRC": { - "id": "KMRC", - "city": "Columbia / Maury County", - "state": "TN", - "lat": 35.55, - "lon": -87.18333 - }, - "KNQA": { - "id": "KNQA", - "city": "Millington, Millington Municipal Airport", - "state": "TN", - "lat": 35.35667, - "lon": -89.8702799 - }, - "KOQT": { - "id": "KOQT", - "city": "Oak Ridge", - "state": "TN", - "lat": 36.02278, - "lon": -84.23333 - }, - "KPHT": { - "id": "KPHT", - "city": "Paris - Henry County Airport", - "state": "TN", - "lat": 36.34, - "lon": -88.38 - }, - "KPVE": { - "id": "KPVE", - "city": "Lexington-Parsons Beech River Regional Airport", - "state": "TN", - "lat": 35.6564, - "lon": -88.1954 - }, - "KRKW": { - "id": "KRKW", - "city": "Rockwood Municipal Airport", - "state": "TN", - "lat": 35.92501, - "lon": -84.691 - }, - "KRNC": { - "id": "KRNC", - "city": "McMinnville Warren County Memorial Airport", - "state": "TN", - "lat": 35.6991, - "lon": -85.8402 - }, - "KSCX": { - "id": "KSCX", - "city": "Scott Municipal Airport", - "state": "TN", - "lat": 36.45569, - "lon": -84.58575 - }, - "KSNH": { - "id": "KSNH", - "city": "SAVANNAH/HARDIN CO", - "state": "TN", - "lat": 35.17, - "lon": -88.22 - }, - "KSRB": { - "id": "KSRB", - "city": "Sparta Upper Cumberland Regional Airport", - "state": "TN", - "lat": 36.0559, - "lon": -85.5307 - }, - "KSYI": { - "id": "KSYI", - "city": "Shelbyville Bomar Field & Shelbyville Municipal Airport", - "state": "TN", - "lat": 35.5593999, - "lon": -86.4425 - }, - "KTHA": { - "id": "KTHA", - "city": "Tullahoma Regional Airport/William Northern Field", - "state": "TN", - "lat": 35.38, - "lon": -86.2467 - }, - "KTRI": { - "id": "KTRI", - "city": "Bristol / Johnson / Kingsport, Tri-City Regional Airport", - "state": "TN", - "lat": 36.47972, - "lon": -82.39889 - }, - "KTYS": { - "id": "KTYS", - "city": "Knoxville, McGhee Tyson Airport", - "state": "TN", - "lat": 35.81806, - "lon": -83.98583 - }, - "KUCY": { - "id": "KUCY", - "city": "Union City - Everett-Stewart Regional Airport", - "state": "TN", - "lat": 36.38, - "lon": -88.98 - }, - "KXNX": { - "id": "KXNX", - "city": "Sumner County Regional Airport", - "state": "TN", - "lat": 36.3750799, - "lon": -86.40842 - }, - "KACP": { - "id": "KACP", - "city": "Oakdale, Allen Parish Airport", - "state": "LA", - "lat": 30.75056, - "lon": -92.68861 - }, - "KAEX": { - "id": "KAEX", - "city": "Alexandria, Alexandria International Airport", - "state": "LA", - "lat": 31.33472, - "lon": -92.55861 - }, - "KAPS": { - "id": "KAPS", - "city": "Port of South Louisiana Executive Regional Airport", - "state": "LA", - "lat": 30.08747, - "lon": -90.58283 - }, - "KAQV": { - "id": "KAQV", - "city": "Ft. Polk - Peason Ridge", - "state": "LA", - "lat": 31.4, - "lon": -93.2833 - }, - "KARA": { - "id": "KARA", - "city": "Acadiana Regional Airport", - "state": "LA", - "lat": 30.02918, - "lon": -91.88451 - }, - "KASD": { - "id": "KASD", - "city": "Slidell, Slidell Airport", - "state": "LA", - "lat": 30.34306, - "lon": -89.82194 - }, - "KATP": { - "id": "KATP", - "city": "Green Canyon 787 Atlantis", - "state": "LA", - "lat": 27.195, - "lon": -90.027 - }, - "KBAD": { - "id": "KBAD", - "city": "Barksdale Air Force Base", - "state": "LA", - "lat": 32.5, - "lon": -93.66667 - }, - "KBKB": { - "id": "KBKB", - "city": "Ft. Polk - Fullerton Landing Strip", - "state": "LA", - "lat": 31.0217, - "lon": -92.9107 - }, - "KBTR": { - "id": "KBTR", - "city": "Baton Rouge, Baton Rouge Metropolitan, Ryan Field", - "state": "LA", - "lat": 30.53722, - "lon": -91.14694 - }, - "KBXA": { - "id": "KBXA", - "city": "Bogalusa, George R Carr Memorial Air Field", - "state": "LA", - "lat": 30.81361, - "lon": -89.86472 - }, - "KCWF": { - "id": "KCWF", - "city": "Chenault Airpark", - "state": "LA", - "lat": 30.21667, - "lon": -93.15 - }, - "KDRI": { - "id": "KDRI", - "city": "De Ridder, Beauregard Parish Airport", - "state": "LA", - "lat": 30.83167, - "lon": -93.33972 - }, - "KDSF": { - "id": "KDSF", - "city": "Mississippi Canyon", - "state": "LA", - "lat": 28.35, - "lon": -88.26667 - }, - "KDTN": { - "id": "KDTN", - "city": "Shreveport, Shreveport Downtown Airport", - "state": "LA", - "lat": 32.5424999, - "lon": -93.74472 - }, - "KEIR": { - "id": "KEIR", - "city": "Eugene Island", - "state": "LA", - "lat": 28.634, - "lon": -91.489 - }, - "KESF": { - "id": "KESF", - "city": "Alexandria Esler Regional Airport", - "state": "LA", - "lat": 31.39634, - "lon": -92.28273 - }, - "KGAO": { - "id": "KGAO", - "city": "Galliano, South Lafourche Airport", - "state": "LA", - "lat": 29.44472, - "lon": -90.26111 - }, - "KGHB": { - "id": "KGHB", - "city": "GB172/Salsa (Shell E-P)", - "state": "LA", - "lat": 27.84, - "lon": -91.988 - }, - "KGRY": { - "id": "KGRY", - "city": "Green Canyon 338 Front Runner", - "state": "LA", - "lat": 27.625, - "lon": -90.441 - }, - "KHDC": { - "id": "KHDC", - "city": "Hammond, Hammond Municipal Airport", - "state": "LA", - "lat": 30.52083, - "lon": -90.4175 - }, - "KHUM": { - "id": "KHUM", - "city": "Houma-Terrebonne Airport", - "state": "LA", - "lat": 29.56341, - "lon": -90.66283 - }, - "KHZR": { - "id": "KHZR", - "city": "New Roads False River Regional Airport", - "state": "LA", - "lat": 30.7183, - "lon": -91.4787 - }, - "KIER": { - "id": "KIER", - "city": "Natchitoches, Natchitoches Regional Airport", - "state": "LA", - "lat": 31.73583, - "lon": -93.09917 - }, - "KIYA": { - "id": "KIYA", - "city": "Abbeville Chris Crusta Memorial Airport", - "state": "LA", - "lat": 29.97578, - "lon": -92.08422 - }, - "KLCH": { - "id": "KLCH", - "city": "Lake Charles Regional Airport", - "state": "LA", - "lat": 30.12556, - "lon": -93.22767 - }, - "KLFT": { - "id": "KLFT", - "city": "Lafayette, Lafayette Regional Airport", - "state": "LA", - "lat": 30.20222, - "lon": -91.99306 - }, - "KLNQ": { - "id": "KLNQ", - "city": "Boothville Heliport", - "state": "LA", - "lat": 29.35414, - "lon": -89.43591 - }, - "KMDJ": { - "id": "KMDJ", - "city": "MISS CANYON OIL PLATFORM", - "state": "LA", - "lat": 28.65, - "lon": -89.8 - }, - "KMIS": { - "id": "KMIS", - "city": "Main Pass 140B (Apache Corp)", - "state": "LA", - "lat": 29.296, - "lon": -88.842 - }, - "KMLU": { - "id": "KMLU", - "city": "Monroe Regional Airport", - "state": "LA", - "lat": 32.5155699, - "lon": -92.02995 - }, - "KMNE": { - "id": "KMNE", - "city": "Minden Airport", - "state": "LA", - "lat": 32.64603, - "lon": -93.29808 - }, - "KMSY": { - "id": "KMSY", - "city": "New Orleans, New Orleans International Airport", - "state": "LA", - "lat": 29.99278, - "lon": -90.2508299 - }, - "KNBG": { - "id": "KNBG", - "city": "New Orleans Naval Air Station - Alvin Callender Field", - "state": "LA", - "lat": 29.83736, - "lon": -90.02445 - }, - "KNEW": { - "id": "KNEW", - "city": "New Orleans, New Orleans Lakefront Airport", - "state": "LA", - "lat": 30.04944, - "lon": -90.02889 - }, - "KOPL": { - "id": "KOPL", - "city": "Opelousas St Landry Parish Airport", - "state": "LA", - "lat": 30.5584, - "lon": -92.0994 - }, - "KPOE": { - "id": "KPOE", - "city": "Fort Polk, Polk AAF Ft Polk", - "state": "LA", - "lat": 31.05, - "lon": -93.19389 - }, - "KPTN": { - "id": "KPTN", - "city": "Patterson Memorial", - "state": "LA", - "lat": 29.71667, - "lon": -91.33333 - }, - "KREG": { - "id": "KREG", - "city": "Louisiana Regional Airport", - "state": "LA", - "lat": 30.1714, - "lon": -90.9404 - }, - "KRSN": { - "id": "KRSN", - "city": "Ruston, Ruston Regional Airport", - "state": "LA", - "lat": 32.51444, - "lon": -92.58833 - }, - "KSHV": { - "id": "KSHV", - "city": "Shreveport, Shreveport Regional Airport", - "state": "LA", - "lat": 32.44694, - "lon": -93.82417 - }, - "KTVR": { - "id": "KTVR", - "city": "Vicksburg, Vicksburg / Tallulah Regional Airport", - "state": "LA", - "lat": 32.3480599, - "lon": -91.03 - }, - "KUXL": { - "id": "KUXL", - "city": "Southland Field", - "state": "LA", - "lat": 30.1314, - "lon": -93.3760999 - }, - "KVKY": { - "id": "KVKY", - "city": "Main Pass 289C (Apache Corp)", - "state": "LA", - "lat": 29.248, - "lon": -88.441 - }, - "KVOA": { - "id": "KVOA", - "city": "VK 786/Petronius (Chevron)", - "state": "LA", - "lat": 29.229, - "lon": -87.781 - }, - "KALB": { - "id": "KALB", - "city": "Albany International Airport", - "state": "NY", - "lat": 42.74722, - "lon": -73.79912 - }, - "KART": { - "id": "KART", - "city": "Watertown, Watertown International Airport", - "state": "NY", - "lat": 43.99194, - "lon": -76.02167 - }, - "KBGM": { - "id": "KBGM", - "city": "Binghamton, Binghamton Regional Airport", - "state": "NY", - "lat": 42.20778, - "lon": -75.98139 - }, - "KBUF": { - "id": "KBUF", - "city": "Buffalo, Greater Buffalo International Airport", - "state": "NY", - "lat": 42.93998, - "lon": -78.73604 - }, - "KDKK": { - "id": "KDKK", - "city": "Dunkirk, Chautauqua County / Dunkirk Airport", - "state": "NY", - "lat": 42.49306, - "lon": -79.27583 - }, - "KDSV": { - "id": "KDSV", - "city": "Dansville, Dansville Municipal Airport", - "state": "NY", - "lat": 42.56944, - "lon": -77.71444 - }, - "KELM": { - "id": "KELM", - "city": "Elmira, Elmira / Corning Regional Airport", - "state": "NY", - "lat": 42.15639, - "lon": -76.90278 - }, - "KELZ": { - "id": "KELZ", - "city": "Wellsville, Wellsville Municipal Airport", - "state": "NY", - "lat": 42.1075, - "lon": -77.98444 - }, - "KFOK": { - "id": "KFOK", - "city": "The Gabreski Airport", - "state": "NY", - "lat": 40.85053, - "lon": -72.61927 - }, - "KFRG": { - "id": "KFRG", - "city": "Farmingdale - Republic Airport", - "state": "NY", - "lat": 40.73443, - "lon": -73.41639 - }, - "KFZY": { - "id": "KFZY", - "city": "Fulton, Oswego County Airport", - "state": "NY", - "lat": 43.35083, - "lon": -76.38806 - }, - "KGFL": { - "id": "KGFL", - "city": "Glens Falls, Floyd Bennett Memorial Airport", - "state": "NY", - "lat": 43.34111, - "lon": -73.61056 - }, - "KGTB": { - "id": "KGTB", - "city": "Fort Drum / Wheeler-Sack U. S. Army Airfield", - "state": "NY", - "lat": 44.05, - "lon": -75.73333 - }, - "KGVQ": { - "id": "KGVQ", - "city": "Genesee County Airport", - "state": "NY", - "lat": 43.03175, - "lon": -78.16967 - }, - "KHPN": { - "id": "KHPN", - "city": "White Plains - Westchester County Airport", - "state": "NY", - "lat": 41.06237, - "lon": -73.70456 - }, - "KHTO": { - "id": "KHTO", - "city": "East Hampton, East Hampton Airport", - "state": "NY", - "lat": 40.95944, - "lon": -72.25194 - }, - "KHWV": { - "id": "KHWV", - "city": "Shirley, Brookhaven Airport", - "state": "NY", - "lat": 40.82167, - "lon": -72.8688899 - }, - "KIAG": { - "id": "KIAG", - "city": "Niagara Falls, Niagara Falls International Airport", - "state": "NY", - "lat": 43.1082899, - "lon": -78.93818 - }, - "KISP": { - "id": "KISP", - "city": "Islip, Long Island Mac Arthur Airport", - "state": "NY", - "lat": 40.79389, - "lon": -73.10167 - }, - "KITH": { - "id": "KITH", - "city": "Ithaca, Ithaca Tompkins Regional Airport", - "state": "NY", - "lat": 42.49083, - "lon": -76.45833 - }, - "KJFK": { - "id": "KJFK", - "city": "New York, Kennedy International Airport", - "state": "NY", - "lat": 40.63915, - "lon": -73.76393 - }, - "KJHW": { - "id": "KJHW", - "city": "Jamestown, Chautauqua County/Jamestown Airport", - "state": "NY", - "lat": 42.15, - "lon": -79.26667 - }, - "KJRB": { - "id": "KJRB", - "city": "New York Downtown Manhattan", - "state": "NY", - "lat": 40.7012, - "lon": -74.009 - }, - "KLGA": { - "id": "KLGA", - "city": "New York, La Guardia Airport", - "state": "NY", - "lat": 40.77917, - "lon": -73.88 - }, - "KMGJ": { - "id": "KMGJ", - "city": "Montgomery, Orange County Airport", - "state": "NY", - "lat": 41.50917, - "lon": -74.265 - }, - "KMSS": { - "id": "KMSS", - "city": "Massena, Massena International-Richards Field", - "state": "NY", - "lat": 44.93583, - "lon": -74.84556 - }, - "KMSV": { - "id": "KMSV", - "city": "Monticello, Sullivan County International Airport", - "state": "NY", - "lat": 41.7, - "lon": -74.8 - }, - "KMTP": { - "id": "KMTP", - "city": "Montauk, Montauk Airport", - "state": "NY", - "lat": 41.07306, - "lon": -71.92333 - }, - "KNYC": { - "id": "KNYC", - "city": "New York City, Central Park", - "state": "NY", - "lat": 40.78333, - "lon": -73.9666699 - }, - "KOGS": { - "id": "KOGS", - "city": "Ogdensburg International Airport", - "state": "NY", - "lat": 44.68186, - "lon": -75.4655 - }, - "KOLE": { - "id": "KOLE", - "city": "Cattaraugus County-Olean Airport", - "state": "NY", - "lat": 42.24119, - "lon": -78.37136 - }, - "KPBG": { - "id": "KPBG", - "city": "Plattsburgh International Airport ", - "state": "NY", - "lat": 44.65, - "lon": -73.4666699 - }, - "KPEO": { - "id": "KPEO", - "city": "Penn Yan, Penn Yan Airport", - "state": "NY", - "lat": 42.64306, - "lon": -77.04944 - }, - "KPOU": { - "id": "KPOU", - "city": "Poughkeepsie, Dutchess County Airport", - "state": "NY", - "lat": 41.62667, - "lon": -73.88417 - }, - "KPTD": { - "id": "KPTD", - "city": "Potsdam Municipal Airport/Damon Field", - "state": "NY", - "lat": 44.67667, - "lon": -74.94844 - }, - "KRME": { - "id": "KRME", - "city": "Griffiss Air Force Base / Rome", - "state": "NY", - "lat": 43.23333, - "lon": -75.4 - }, - "KROC": { - "id": "KROC", - "city": "Rochester, Greater Rochester International Airport", - "state": "NY", - "lat": 43.11667, - "lon": -77.67667 - }, - "KSCH": { - "id": "KSCH", - "city": "Schenectady Airport", - "state": "NY", - "lat": 42.85, - "lon": -73.93333 - }, - "KSDC": { - "id": "KSDC", - "city": "Williamson-Sodus Airport", - "state": "NY", - "lat": 43.23459, - "lon": -77.11946 - }, - "KSLK": { - "id": "KSLK", - "city": "Saranac Lake, Adirondack Regional Airport", - "state": "NY", - "lat": 44.39306, - "lon": -74.20278 - }, - "KSWF": { - "id": "KSWF", - "city": "Newburgh / Stewart", - "state": "NY", - "lat": 41.5, - "lon": -74.1 - }, - "KSYR": { - "id": "KSYR", - "city": "Syracuse, Syracuse Hancock International Airport", - "state": "NY", - "lat": 43.10917, - "lon": -76.10333 - }, - "KVGC": { - "id": "KVGC", - "city": "Hamilton Municipal Airport", - "state": "NY", - "lat": 42.84344, - "lon": -75.56119 - }, - "KSZT": { - "id": "KSZT", - "city": "Sandpoint, Sandpoint Airport", - "state": "ID", - "lat": 48.29944, - "lon": -116.56 - }, - "KTBI": { - "id": "KTBI", - "city": "Kettle Butte", - "state": "ID", - "lat": 43.5486099, - "lon": -112.32583 - }, - "KTWF": { - "id": "KTWF", - "city": "Joslin Field - Magic Valley Regional Airport", - "state": "ID", - "lat": 42.4784999, - "lon": -114.47739 - }, - "PICI": { - "id": "PICI", - "city": "PICABO", - "state": "ID", - "lat": 43.31167, - "lon": -114.16583 - }, - "PMAI": { - "id": "PMAI", - "city": "PARMA", - "state": "ID", - "lat": 43.8, - "lon": -116.93333 - }, - "KABE": { - "id": "KABE", - "city": "Allentown, Lehigh Valley International Airport", - "state": "PA", - "lat": 40.64985, - "lon": -75.44771 - }, - "KAFJ": { - "id": "KAFJ", - "city": "Washington - Washington County Airport", - "state": "PA", - "lat": 40.13333, - "lon": -80.28333 - }, - "KAGC": { - "id": "KAGC", - "city": "Pittsburgh - Allegheny County Airport", - "state": "PA", - "lat": 40.35521, - "lon": -79.92144 - }, - "KAOO": { - "id": "KAOO", - "city": "Altoona - Blair County Airport", - "state": "PA", - "lat": 40.29994, - "lon": -78.3168 - }, - "KAVP": { - "id": "KAVP", - "city": "Wilkes-Barre - Scranton, Wilkes-Barre / Scranton International Airport", - "state": "PA", - "lat": 41.33889, - "lon": -75.72667 - }, - "KBFD": { - "id": "KBFD", - "city": "Bradford Regional Airport", - "state": "PA", - "lat": 41.79838, - "lon": -78.63539 - }, - "KBTP": { - "id": "KBTP", - "city": "Butler, Butler County Airport/K W Scholter Field", - "state": "PA", - "lat": 40.78333, - "lon": -79.95 - }, - "KBVI": { - "id": "KBVI", - "city": "Beaver County Airport", - "state": "PA", - "lat": 40.77351, - "lon": -80.38248 - }, - "KCKZ": { - "id": "KCKZ", - "city": "Pennridge Airport", - "state": "PA", - "lat": 40.38919, - "lon": -75.29047 - }, - "KCXY": { - "id": "KCXY", - "city": "Harrisburg, Capital City Airport", - "state": "PA", - "lat": 40.21843, - "lon": -76.8552 - }, - "KDUJ": { - "id": "KDUJ", - "city": "Du Bois - Jefferson County Airport", - "state": "PA", - "lat": 41.17948, - "lon": -78.89326 - }, - "KDYL": { - "id": "KDYL", - "city": "Doylestown, Doylestown Airport", - "state": "PA", - "lat": 40.33016, - "lon": -75.12286 - }, - "KERI": { - "id": "KERI", - "city": "Erie, Erie International Airport", - "state": "PA", - "lat": 42.08, - "lon": -80.1825 - }, - "KFIG": { - "id": "KFIG", - "city": "Clearfield, Clearfield-Lawrence Airport", - "state": "PA", - "lat": 41.04667, - "lon": -78.41167 - }, - "KFKL": { - "id": "KFKL", - "city": "Franklin, Venango Regional Airport", - "state": "PA", - "lat": 41.38333, - "lon": -79.86667 - }, - "KGKJ": { - "id": "KGKJ", - "city": "Port Meadville Airport", - "state": "PA", - "lat": 41.6258399, - "lon": -80.21231 - }, - "KHMZ": { - "id": "KHMZ", - "city": "Bedford, Bedford County Airport", - "state": "PA", - "lat": 40.08528, - "lon": -78.51222 - }, - "KHZL": { - "id": "KHZL", - "city": "Hazleton Municipal Airport", - "state": "PA", - "lat": 40.98447, - "lon": -75.99005 - }, - "KIDI": { - "id": "KIDI", - "city": "Indiana / Stewart Field", - "state": "PA", - "lat": 40.63333, - "lon": -79.1 - }, - "KIPT": { - "id": "KIPT", - "city": "Williamsport - Lycoming County Airport", - "state": "PA", - "lat": 41.24298, - "lon": -76.92173 - }, - "KJST": { - "id": "KJST", - "city": "Johnstown - Cambria County Airport", - "state": "PA", - "lat": 40.3149, - "lon": -78.83074 - }, - "KLBE": { - "id": "KLBE", - "city": "Latrobe / Westmoreland", - "state": "PA", - "lat": 40.2731, - "lon": -79.41033 - }, - "KLNS": { - "id": "KLNS", - "city": "Lancaster, Lancaster Airport", - "state": "PA", - "lat": 40.1205799, - "lon": -76.29446 - }, - "KLOM": { - "id": "KLOM", - "city": "Philadelphia - Wings Field Airport", - "state": "PA", - "lat": 40.13758, - "lon": -75.2684 - }, - "KMDT": { - "id": "KMDT", - "city": "Harrisburg, Harrisburg International Airport", - "state": "PA", - "lat": 40.19361, - "lon": -76.76333 - }, - "KMPO": { - "id": "KMPO", - "city": "Mount Pocono, Pocono Mountains Municipal Airport", - "state": "PA", - "lat": 41.13821, - "lon": -75.37971 - }, - "KMQS": { - "id": "KMQS", - "city": "Chester County Airport", - "state": "PA", - "lat": 39.98333, - "lon": -75.86667 - }, - "KMUI": { - "id": "KMUI", - "city": "Muir Army Air Field / Indiantown", - "state": "PA", - "lat": 40.43808, - "lon": -76.56434 - }, - "KOQN": { - "id": "KOQN", - "city": "Brandywine Regional Airport", - "state": "PA", - "lat": 39.99011, - "lon": -75.5819 - }, - "KOYM": { - "id": "KOYM", - "city": "St Marys Municipal Airport", - "state": "PA", - "lat": 41.41248, - "lon": -78.50263 - }, - "KPHL": { - "id": "KPHL", - "city": "Philadelphia, Philadelphia International Airport", - "state": "PA", - "lat": 39.87327, - "lon": -75.22678 - }, - "KPIT": { - "id": "KPIT", - "city": "Pittsburgh, Pittsburgh International Airport", - "state": "PA", - "lat": 40.50389, - "lon": -80.26639 - }, - "KPJC": { - "id": "KPJC", - "city": "Zelienople Municipal Airport", - "state": "PA", - "lat": 40.80197, - "lon": -80.16086 - }, - "KPNE": { - "id": "KPNE", - "city": "Philadelphia, Northeast Philadelphia Airport", - "state": "PA", - "lat": 40.07889, - "lon": -75.01361 - }, - "KPTW": { - "id": "KPTW", - "city": "Pottstown, Pottstown Limerick Airport", - "state": "PA", - "lat": 40.23802, - "lon": -75.5548699 - }, - "KRDG": { - "id": "KRDG", - "city": "Reading, Reading Regional Airport", - "state": "PA", - "lat": 40.37333, - "lon": -75.95944 - }, - "KRVL": { - "id": "KRVL", - "city": "Reedsville / Mifflin", - "state": "PA", - "lat": 40.68333, - "lon": -77.63333 - }, - "KSEG": { - "id": "KSEG", - "city": "Selinsgrove Penn Valley Airport", - "state": "PA", - "lat": 40.81929, - "lon": -76.86582 - }, - "KTHV": { - "id": "KTHV", - "city": "York, York Airport", - "state": "PA", - "lat": 39.91944, - "lon": -76.87694 - }, - "KUCP": { - "id": "KUCP", - "city": "New Castle, New Castle Municipal Airport", - "state": "PA", - "lat": 41.02528, - "lon": -80.41333 - }, - "KUKT": { - "id": "KUKT", - "city": "Quakertown Airport", - "state": "PA", - "lat": 40.4368, - "lon": -75.38016 - }, - "KUNV": { - "id": "KUNV", - "city": "State College - University Park Airport", - "state": "PA", - "lat": 40.85344, - "lon": -77.8401 - }, - "KVVS": { - "id": "KVVS", - "city": "Joseph A Hardy Connellsville Airport", - "state": "PA", - "lat": 39.95906, - "lon": -79.65742 - }, - "KXLL": { - "id": "KXLL", - "city": "Allentown Queen City Municipal Airport", - "state": "PA", - "lat": 40.57, - "lon": -75.488 - }, - "KAKR": { - "id": "KAKR", - "city": "Akron, Akron Fulton International Airport", - "state": "OH", - "lat": 41.0375, - "lon": -81.46417 - }, - "KAOH": { - "id": "KAOH", - "city": "Lima, Lima Allen County Airport", - "state": "OH", - "lat": 40.70806, - "lon": -84.02139 - }, - "KAXV": { - "id": "KAXV", - "city": "Neil Armstrong Airport", - "state": "OH", - "lat": 40.49356, - "lon": -84.29808 - }, - "KBJJ": { - "id": "KBJJ", - "city": "Wooster, Wayne County Airport", - "state": "OH", - "lat": 40.87306, - "lon": -81.88667 - }, - "KBKL": { - "id": "KBKL", - "city": "Cleveland, Burke Lakefront Airport", - "state": "OH", - "lat": 41.52556, - "lon": -81.66889 - }, - "KCAK": { - "id": "KCAK", - "city": "Akron Canton Regional Airport", - "state": "OH", - "lat": 40.91811, - "lon": -81.44343 - }, - "KCDI": { - "id": "KCDI", - "city": "Cambridge Municipal Airport", - "state": "OH", - "lat": 39.975, - "lon": -81.5776 - }, - "KCGF": { - "id": "KCGF", - "city": "Cleveland / Cuyahoga", - "state": "OH", - "lat": 41.56667, - "lon": -81.48333 - }, - "KCLE": { - "id": "KCLE", - "city": "Cleveland Hopkins International Airport", - "state": "OH", - "lat": 41.40569, - "lon": -81.85193 - }, - "KCMH": { - "id": "KCMH", - "city": "John Glenn Columbus International Airport", - "state": "OH", - "lat": 39.9906999, - "lon": -82.87691 - }, - "KDAY": { - "id": "KDAY", - "city": "Dayton, Cox Dayton International Airport", - "state": "OH", - "lat": 39.90611, - "lon": -84.21861 - }, - "KDFI": { - "id": "KDFI", - "city": "Defiance, Defiance Memorial Airport", - "state": "OH", - "lat": 41.33639, - "lon": -84.42944 - }, - "KDLZ": { - "id": "KDLZ", - "city": "Delaware Municipal Airport", - "state": "OH", - "lat": 40.2797, - "lon": -83.1148 - }, - "KEDJ": { - "id": "KEDJ", - "city": "Bellefontaine Regional Airport", - "state": "OH", - "lat": 40.3723, - "lon": -83.8192 - }, - "KFDY": { - "id": "KFDY", - "city": "Findlay, Findlay Airport", - "state": "OH", - "lat": 41.01361, - "lon": -83.66861 - }, - "KFFO": { - "id": "KFFO", - "city": "Dayton / Wright-Patterson Air Force Base", - "state": "OH", - "lat": 39.8333299, - "lon": -84.05 - }, - "KHAO": { - "id": "KHAO", - "city": "Butler County Regional Airport", - "state": "OH", - "lat": 39.36121, - "lon": -84.52061 - }, - "KHZY": { - "id": "KHZY", - "city": "Ashtabula - Northeast Ohio Regional Airport", - "state": "OH", - "lat": 41.77944, - "lon": -80.69667 - }, - "KILN": { - "id": "KILN", - "city": "Wilmington, Airborne Airpark Airport", - "state": "OH", - "lat": 39.42833, - "lon": -83.7791699 - }, - "KLCK": { - "id": "KLCK", - "city": "Rickenbacker Air National Guard Base", - "state": "OH", - "lat": 39.81667, - "lon": -82.93333 - }, - "KLHQ": { - "id": "KLHQ", - "city": "Lancaster, Fairfield County Airport", - "state": "OH", - "lat": 39.7572199, - "lon": -82.66333 - }, - "KLNN": { - "id": "KLNN", - "city": "Willoughby", - "state": "OH", - "lat": 41.68333, - "lon": -81.38333 - }, - "KLPR": { - "id": "KLPR", - "city": "Lorain / Elyria, Lorain County Regional Airport", - "state": "OH", - "lat": 41.34611, - "lon": -82.17944 - }, - "KLUK": { - "id": "KLUK", - "city": "Cincinnati, Cincinnati Municipal Airport Lunken Field", - "state": "OH", - "lat": 39.10583, - "lon": -84.41583 - }, - "KMFD": { - "id": "KMFD", - "city": "Mansfield - Mansfield Lahm Regional Airport", - "state": "OH", - "lat": 40.8202799, - "lon": -82.51778 - }, - "KMGY": { - "id": "KMGY", - "city": "Dayton, Dayton-Wright Brothers Airport", - "state": "OH", - "lat": 39.58889, - "lon": -84.22472 - }, - "KMNN": { - "id": "KMNN", - "city": "Marion, Marion Municipal Airport", - "state": "OH", - "lat": 40.61667, - "lon": -83.06833 - }, - "KMRT": { - "id": "KMRT", - "city": "Marysville Union County Airport", - "state": "OH", - "lat": 40.2247, - "lon": -83.3516 - }, - "KMWO": { - "id": "KMWO", - "city": "Hook Field Municipal Airport", - "state": "OH", - "lat": 39.531, - "lon": -84.3953 - }, - "KOSU": { - "id": "KOSU", - "city": "Columbus, Ohio State University Airport", - "state": "OH", - "lat": 40.07806, - "lon": -83.0780599 - }, - "KOWX": { - "id": "KOWX", - "city": "Ottawa Putnam County Airport", - "state": "OH", - "lat": 41.0356, - "lon": -83.982 - }, - "KPCW": { - "id": "KPCW", - "city": "Port Clinton Carl R Keller Field Airport", - "state": "OH", - "lat": 41.5163, - "lon": -82.8687 - }, - "KPHD": { - "id": "KPHD", - "city": "New Philadelphia, Harry Clever Field", - "state": "OH", - "lat": 40.4719399, - "lon": -81.42361 - }, - "KPMH": { - "id": "KPMH", - "city": "Greater Portsmouth Regional Airport", - "state": "OH", - "lat": 38.84047, - "lon": -82.8473099 - }, - "KPOV": { - "id": "KPOV", - "city": "Portage County Airport", - "state": "OH", - "lat": 41.21, - "lon": -81.252 - }, - "KRZT": { - "id": "KRZT", - "city": "Chillicothe Ross County Airport", - "state": "OH", - "lat": 39.4403999, - "lon": -83.0231 - }, - "KSGH": { - "id": "KSGH", - "city": "Springfield, Springfield-Beckley Municipal Airport", - "state": "OH", - "lat": 39.84028, - "lon": -83.84 - }, - "KTDZ": { - "id": "KTDZ", - "city": "Toledo - Toledo Executive Airport", - "state": "OH", - "lat": 41.56306, - "lon": -83.47639 - }, - "KTOL": { - "id": "KTOL", - "city": "Toledo - Toledo Express Airport", - "state": "OH", - "lat": 41.58704, - "lon": -83.80539 - }, - "KTZR": { - "id": "KTZR", - "city": "Columbus, Bolton Field Airport", - "state": "OH", - "lat": 39.90083, - "lon": -83.13722 - }, - "KUNI": { - "id": "KUNI", - "city": "OHIO U/ATHEN-ALBANY", - "state": "OH", - "lat": 39.22, - "lon": -82.23 - }, - "KUSE": { - "id": "KUSE", - "city": "Wauseon Fulton County Airport", - "state": "OH", - "lat": 41.6101, - "lon": -84.1272 - }, - "KUYF": { - "id": "KUYF", - "city": "London Madison County Airport", - "state": "OH", - "lat": 39.9326999, - "lon": -83.462 - }, - "KVES": { - "id": "KVES", - "city": "Versailles Darke County Airport", - "state": "OH", - "lat": 40.2044, - "lon": -84.5318999 - }, - "KVNW": { - "id": "KVNW", - "city": "Van Wert County Airport", - "state": "OH", - "lat": 40.86383, - "lon": -84.60636 - }, - "KVTA": { - "id": "KVTA", - "city": "Newark, Newark Heath Airport", - "state": "OH", - "lat": 40.02278, - "lon": -82.4625 - }, - "KYNG": { - "id": "KYNG", - "city": "Youngstown, Youngstown-Warren Regional Airport", - "state": "OH", - "lat": 41.25444, - "lon": -80.67389 - }, - "KZZV": { - "id": "KZZV", - "city": "Zanesville, Zanesville Municipal Airport", - "state": "OH", - "lat": 39.94444, - "lon": -81.89222 - }, - "KAUM": { - "id": "KAUM", - "city": "Austin Municipal", - "state": "MN", - "lat": 43.66667, - "lon": -92.93333 - }, - "KAXN": { - "id": "KAXN", - "city": "Alexandria, Chandler Field", - "state": "MN", - "lat": 45.8686099, - "lon": -95.39417 - }, - "KBBB": { - "id": "KBBB", - "city": "Benson Municipal Airport", - "state": "MN", - "lat": 45.3309799, - "lon": -95.64692 - }, - "KBDE": { - "id": "KBDE", - "city": "Baudette International Airport", - "state": "MN", - "lat": 48.72605, - "lon": -94.61215 - }, - "KBDH": { - "id": "KBDH", - "city": "Willmar Municipal Airport - John L. Rice Field", - "state": "MN", - "lat": 45.11113, - "lon": -95.1258299 - }, - "KBJI": { - "id": "KBJI", - "city": "Bemidji", - "state": "MN", - "lat": 47.50762, - "lon": -94.92783 - }, - "KBRD": { - "id": "KBRD", - "city": "Brainerd - Crow Wing County Airport", - "state": "MN", - "lat": 46.40205, - "lon": -94.12734 - }, - "KCDD": { - "id": "KCDD", - "city": "Crane Lake - Scotts Seaplane Base", - "state": "MN", - "lat": 48.26014, - "lon": -92.47485 - }, - "KCFE": { - "id": "KCFE", - "city": "Buffalo, Buffalo Municipal Airport", - "state": "MN", - "lat": 45.15889, - "lon": -93.84306 - }, - "KCKC": { - "id": "KCKC", - "city": "Grand Marais/Cook County Airport", - "state": "MN", - "lat": 47.83665, - "lon": -90.3864399 - }, - "KCKN": { - "id": "KCKN", - "city": "Crookston Municipal Field", - "state": "MN", - "lat": 47.84042, - "lon": -96.6200999 - }, - "KCNB": { - "id": "KCNB", - "city": "Canby Airfield", - "state": "MN", - "lat": 44.7295, - "lon": -96.266 - }, - "KCOQ": { - "id": "KCOQ", - "city": "Cloquet Carlton County Airport", - "state": "MN", - "lat": 46.69869, - "lon": -92.5034 - }, - "KCQM": { - "id": "KCQM", - "city": "Cook Municipal Airport", - "state": "MN", - "lat": 47.81997, - "lon": -92.68169 - }, - "KDLH": { - "id": "KDLH", - "city": "Duluth International Airport", - "state": "MN", - "lat": 46.84347, - "lon": -92.1866 - }, - "KDTL": { - "id": "KDTL", - "city": "Detroit Lakes Airport-Wething Field", - "state": "MN", - "lat": 46.8285399, - "lon": -95.88567 - }, - "KDVP": { - "id": "KDVP", - "city": "Slayton Municipal Airport", - "state": "MN", - "lat": 43.99055, - "lon": -95.78102 - }, - "KDXX": { - "id": "KDXX", - "city": "Madison, Madison-Lac Qui Parle County Airport", - "state": "MN", - "lat": 44.9839399, - "lon": -96.1788399 - }, - "KDYT": { - "id": "KDYT", - "city": "Duluth - Sky Harbor Airport", - "state": "MN", - "lat": 46.72452, - "lon": -92.0444799 - }, - "KELO": { - "id": "KELO", - "city": "Ely, Ely Municipal Airport", - "state": "MN", - "lat": 47.81667, - "lon": -91.83333 - }, - "KETH": { - "id": "KETH", - "city": "Wheaton Municipal Airport", - "state": "MN", - "lat": 45.78284, - "lon": -96.54607 - }, - "KEVM": { - "id": "KEVM", - "city": "Eveleth-Virginia Municipal Airport", - "state": "MN", - "lat": 47.4274, - "lon": -92.49717 - }, - "KFBL": { - "id": "KFBL", - "city": "Faribault, Faribault Municipal Airport", - "state": "MN", - "lat": 44.32983, - "lon": -93.31186 - }, - "KFCM": { - "id": "KFCM", - "city": "Minneapolis - Flying Cloud Airport", - "state": "MN", - "lat": 44.83217, - "lon": -93.47051 - }, - "KFFM": { - "id": "KFFM", - "city": "Fergus Falls Municipal Airport-Einar Mickel", - "state": "MN", - "lat": 46.28655, - "lon": -96.15338 - }, - "KFGN": { - "id": "KFGN", - "city": "Flag Island", - "state": "MN", - "lat": 49.31667, - "lon": -94.9 - }, - "KFKA": { - "id": "KFKA", - "city": "Preston, Fillmore County Airport", - "state": "MN", - "lat": 43.67701, - "lon": -92.17422 - }, - "KFOZ": { - "id": "KFOZ", - "city": "Bigfork Municipal Airport", - "state": "MN", - "lat": 47.78317, - "lon": -93.65326 - }, - "KFRM": { - "id": "KFRM", - "city": "Fairmont, Fairmont Municipal Airport", - "state": "MN", - "lat": 43.65, - "lon": -94.41667 - }, - "KFSE": { - "id": "KFSE", - "city": "Fosston, Fosston Municipal Airport", - "state": "MN", - "lat": 47.59278, - "lon": -95.77333 - }, - "KGDB": { - "id": "KGDB", - "city": "Granite Falls, Granite Falls Municipal Airport/Lenzen-Roe Memorial Field", - "state": "MN", - "lat": 44.75306, - "lon": -95.55583 - }, - "KGHW": { - "id": "KGHW", - "city": "Glenwood Municipal Airport", - "state": "MN", - "lat": 45.64564, - "lon": -95.31876 - }, - "KGNA": { - "id": "KGNA", - "city": "Grand Marais, The Bay of Grand Marais", - "state": "MN", - "lat": 47.7472, - "lon": -90.3443999 - }, - "KGPZ": { - "id": "KGPZ", - "city": "Grand Rapids, Grand Rapids/Itasca County Airport-Gordon Newstrom Field", - "state": "MN", - "lat": 47.21667, - "lon": -93.51667 - }, - "KGYL": { - "id": "KGYL", - "city": "Glencoe Municipal Airport", - "state": "MN", - "lat": 44.7588, - "lon": -94.0905 - }, - "KHCD": { - "id": "KHCD", - "city": "Hutchinson, Hutchinson Municipal Airport-Butler Field", - "state": "MN", - "lat": 44.85961, - "lon": -94.38551 - }, - "KHCO": { - "id": "KHCO", - "city": "Hallock Municipal Airport", - "state": "MN", - "lat": 48.75245, - "lon": -96.93759 - }, - "KHIB": { - "id": "KHIB", - "city": "Chisholm-Hibbing Airport", - "state": "MN", - "lat": 47.38039, - "lon": -92.83245 - }, - "KHZX": { - "id": "KHZX", - "city": "Mc Gregor - Isedor Iverson Airport", - "state": "MN", - "lat": 46.61904, - "lon": -93.31267 - }, - "KINL": { - "id": "KINL", - "city": "Falls International Airport", - "state": "MN", - "lat": 48.55944, - "lon": -93.39556 - }, - "KJKJ": { - "id": "KJKJ", - "city": "Moorhead Municipal Airport", - "state": "MN", - "lat": 46.8404, - "lon": -96.65442 - }, - "KJMR": { - "id": "KJMR", - "city": "Mora Municipal Airport", - "state": "MN", - "lat": 45.88863, - "lon": -93.26901 - }, - "KJYG": { - "id": "KJYG", - "city": "St. James Municipal Airport", - "state": "MN", - "lat": 43.98558, - "lon": -94.55299 - }, - "KLJF": { - "id": "KLJF", - "city": "Litchfield Municipal Airport", - "state": "MN", - "lat": 45.09485, - "lon": -94.50837 - }, - "KLVN": { - "id": "KLVN", - "city": "Minneapolis, Airlake Airport", - "state": "MN", - "lat": 44.62778, - "lon": -93.22806 - }, - "KLXL": { - "id": "KLXL", - "city": "Little Falls, Little Falls/Morrison County Airport-Lindbergh Field", - "state": "MN", - "lat": 45.95, - "lon": -94.35 - }, - "KLYV": { - "id": "KLYV", - "city": "Quentin Aanenson Field Airport", - "state": "MN", - "lat": 43.62166, - "lon": -96.2139399 - }, - "KMGG": { - "id": "KMGG", - "city": "Maple Lake, Maple Lake Municipal Airport", - "state": "MN", - "lat": 45.2353499, - "lon": -93.98959 - }, - "KMIC": { - "id": "KMIC", - "city": "Minneapolis, Crystal Airport", - "state": "MN", - "lat": 45.0625, - "lon": -93.35083 - }, - "KMJQ": { - "id": "KMJQ", - "city": "Jackson, Jackson Municipal Airport", - "state": "MN", - "lat": 43.65, - "lon": -94.98333 - }, - "KMKT": { - "id": "KMKT", - "city": "Mankato, Mankato Regional Airport", - "state": "MN", - "lat": 44.21667, - "lon": -93.91667 - }, - "KMML": { - "id": "KMML", - "city": "Marshall, Southwest Minnesota Regional Airport - Marshall/Ryan Field", - "state": "MN", - "lat": 44.45, - "lon": -95.81667 - }, - "KMOX": { - "id": "KMOX", - "city": "Morris, Morris Municipal Airport", - "state": "MN", - "lat": 45.56667, - "lon": -95.9666699 - }, - "KMSP": { - "id": "KMSP", - "city": "Minneapolis, Minneapolis-St. Paul International Airport", - "state": "MN", - "lat": 44.88306, - "lon": -93.22889 - }, - "KMVE": { - "id": "KMVE", - "city": "Montevideo-Chippewa County Airport", - "state": "MN", - "lat": 44.96749, - "lon": -95.71159 - }, - "KMWM": { - "id": "KMWM", - "city": "Windom Municipal Airport", - "state": "MN", - "lat": 43.90999, - "lon": -95.10723 - }, - "KMZH": { - "id": "KMZH", - "city": "Moose Lake Carlton County Airport", - "state": "MN", - "lat": 46.41632, - "lon": -92.80491 - }, - "KONA": { - "id": "KONA", - "city": "Winona, Winona Municipal Airport-Max Conrad Field", - "state": "MN", - "lat": 44.0833299, - "lon": -91.7 - }, - "KORB": { - "id": "KORB", - "city": "Orr Regional Airport", - "state": "MN", - "lat": 48.0170699, - "lon": -92.85376 - }, - "KOTG": { - "id": "KOTG", - "city": "Worthington, Worthington Municipal Airport", - "state": "MN", - "lat": 43.65, - "lon": -95.58333 - }, - "KOVL": { - "id": "KOVL", - "city": "Olivia Regional Airport", - "state": "MN", - "lat": 44.77923, - "lon": -95.03033 - }, - "KOWA": { - "id": "KOWA", - "city": "Owatonna Degner Regional Airport", - "state": "MN", - "lat": 44.11907, - "lon": -93.25687 - }, - "KPEX": { - "id": "KPEX", - "city": "Paynesville, Paynesville Municipal Airport", - "state": "MN", - "lat": 45.37247, - "lon": -94.73878 - }, - "KPKD": { - "id": "KPKD", - "city": "Park Rapids Municipal Airport", - "state": "MN", - "lat": 46.8996799, - "lon": -95.06681 - }, - "KPNM": { - "id": "KPNM", - "city": "Princeton", - "state": "MN", - "lat": 45.56425, - "lon": -93.6080099 - }, - "KPQN": { - "id": "KPQN", - "city": "Pipestone Municipal Airport", - "state": "MN", - "lat": 43.98542, - "lon": -96.29764 - }, - "KPWC": { - "id": "KPWC", - "city": "Pine River Regional Airport", - "state": "MN", - "lat": 46.72654, - "lon": -94.38485 - }, - "KROS": { - "id": "KROS", - "city": "Rush City Regional Airport", - "state": "MN", - "lat": 45.69628, - "lon": -92.95424 - }, - "KROX": { - "id": "KROX", - "city": "Roseau, Roseau Municipal Airport/Rudy Billberg Field", - "state": "MN", - "lat": 48.85, - "lon": -95.7 - }, - "KRRT": { - "id": "KRRT", - "city": "Warroad International Memorial Airport", - "state": "MN", - "lat": 48.93183, - "lon": -95.3404599 - }, - "KRST": { - "id": "KRST", - "city": "Rochester, Rochester International Airport", - "state": "MN", - "lat": 43.90417, - "lon": -92.49167 - }, - "KRWF": { - "id": "KRWF", - "city": "Redwood Falls Municipal Airport", - "state": "MN", - "lat": 44.54828, - "lon": -95.08042 - }, - "KRYM": { - "id": "KRYM", - "city": "Ray S Miller Army Airfield", - "state": "MN", - "lat": 46.08997, - "lon": -94.35986 - }, - "KSAZ": { - "id": "KSAZ", - "city": "Staples, Staples Municipal Airport", - "state": "MN", - "lat": 46.38083, - "lon": -94.80667 - }, - "KSGS": { - "id": "KSGS", - "city": "South St. Paul Municipal-Richard E. Flemi", - "state": "MN", - "lat": 44.86006, - "lon": -93.03203 - }, - "KSTC": { - "id": "KSTC", - "city": "St. Cloud Regional Airport", - "state": "MN", - "lat": 45.54415, - "lon": -94.05165 - }, - "KSTP": { - "id": "KSTP", - "city": "Downtown Holman Field", - "state": "MN", - "lat": 44.93237, - "lon": -93.05588 - }, - "KSYN": { - "id": "KSYN", - "city": "Stanton Airfield", - "state": "MN", - "lat": 44.4736199, - "lon": -93.01448 - }, - "KTKC": { - "id": "KTKC", - "city": "Tracy, Tracy Municipal Airport", - "state": "MN", - "lat": 44.24951, - "lon": -95.61189 - }, - "KTOB": { - "id": "KTOB", - "city": "Dodge Center Airport", - "state": "MN", - "lat": 44.02026, - "lon": -92.8295 - }, - "KTVF": { - "id": "KTVF", - "city": "Thief River Falls, Thief River Falls Regional Airport", - "state": "MN", - "lat": 48.06667, - "lon": -96.18333 - }, - "KTWM": { - "id": "KTWM", - "city": "Two Harbors", - "state": "MN", - "lat": 47.05, - "lon": -91.75 - }, - "KULM": { - "id": "KULM", - "city": "New Ulm Municipal Airport", - "state": "MN", - "lat": 44.32274, - "lon": -94.50244 - }, - "KVVV": { - "id": "KVVV", - "city": "Ortonville, Ortonville Muncipal-Martinson Field Airport", - "state": "MN", - "lat": 45.30556, - "lon": -96.42444 - }, - "KVWU": { - "id": "KVWU", - "city": "Waskish Municipal Airport", - "state": "MN", - "lat": 48.15014, - "lon": -94.512 - }, - "KXVG": { - "id": "KXVG", - "city": "Longville, Longville Municipal Airport", - "state": "MN", - "lat": 46.99028, - "lon": -94.20389 - }, - "KAAA": { - "id": "KAAA", - "city": "Logan County Airport", - "state": "IL", - "lat": 40.15885, - "lon": -89.33891 - }, - "KAJG": { - "id": "KAJG", - "city": "Mount Carmel, Mount Carmel Municipal Airport", - "state": "IL", - "lat": 38.60928, - "lon": -87.72508 - }, - "KALN": { - "id": "KALN", - "city": "St. Louis Regional Airport", - "state": "IL", - "lat": 38.88968, - "lon": -90.03163 - }, - "KARR": { - "id": "KARR", - "city": "Aurora Municipal Airport", - "state": "IL", - "lat": 41.77132, - "lon": -88.48147 - }, - "KBLV": { - "id": "KBLV", - "city": "Belleville, Scott AFB/MidAmerica Airport", - "state": "IL", - "lat": 38.55, - "lon": -89.85 - }, - "KBMI": { - "id": "KBMI", - "city": "Bloomington/Normal, Central Illinois Regional Airport at Bloomington-Normal", - "state": "IL", - "lat": 40.47694, - "lon": -88.91583 - }, - "KCIR": { - "id": "KCIR", - "city": "Cairo Regional Airport", - "state": "IL", - "lat": 37.06388, - "lon": -89.2232 - }, - "KCMI": { - "id": "KCMI", - "city": "University of Illinois - Willard", - "state": "IL", - "lat": 40.03245, - "lon": -88.27547 - }, - "KCPS": { - "id": "KCPS", - "city": "St. Louis Downtown Airport", - "state": "IL", - "lat": 38.56403, - "lon": -90.14871 - }, - "KCUL": { - "id": "KCUL", - "city": "Carmi Municipal Airport", - "state": "IL", - "lat": 38.08875, - "lon": -88.12125 - }, - "KDEC": { - "id": "KDEC", - "city": "Decatur Airport", - "state": "IL", - "lat": 39.8308, - "lon": -88.87192 - }, - "KDKB": { - "id": "KDKB", - "city": "De Kalb Taylor Municipal Airport", - "state": "IL", - "lat": 41.93381, - "lon": -88.70657 - }, - "KDNV": { - "id": "KDNV", - "city": "Danville, Vermilion County Airport", - "state": "IL", - "lat": 40.19944, - "lon": -87.59556 - }, - "KDPA": { - "id": "KDPA", - "city": "Chicago / West Chicago, Dupage Airport", - "state": "IL", - "lat": 41.8963899, - "lon": -88.25111 - }, - "KENL": { - "id": "KENL", - "city": "Centralia Municipal Airport", - "state": "IL", - "lat": 38.50951, - "lon": -89.08996 - }, - "KFEP": { - "id": "KFEP", - "city": "Albertus Airport", - "state": "IL", - "lat": 42.24751, - "lon": -89.58104 - }, - "KFOA": { - "id": "KFOA", - "city": "Flora Municipal Airport", - "state": "IL", - "lat": 38.66726, - "lon": -88.4526999 - }, - "KFWC": { - "id": "KFWC", - "city": "Fairfield, Fairfield Municipal Airport", - "state": "IL", - "lat": 38.37861, - "lon": -88.41278 - }, - "KGBG": { - "id": "KGBG", - "city": "Galesburg Municipal Airport", - "state": "IL", - "lat": 40.9328999, - "lon": -90.43339 - }, - "KHSB": { - "id": "KHSB", - "city": "Harrisburg-Raleigh Airport", - "state": "IL", - "lat": 37.81281, - "lon": -88.54486 - }, - "KIGQ": { - "id": "KIGQ", - "city": "Lansing Municipal Airport", - "state": "IL", - "lat": 41.54125, - "lon": -87.52822 - }, - "KIJX": { - "id": "KIJX", - "city": "Jacksonville Municipal Airport", - "state": "IL", - "lat": 39.7740099, - "lon": -90.24187 - }, - "KIKK": { - "id": "KIKK", - "city": "Greater Kankakee Airport", - "state": "IL", - "lat": 41.06871, - "lon": -87.85372 - }, - "KJOT": { - "id": "KJOT", - "city": "Joliet Regional Airport", - "state": "IL", - "lat": 41.51755, - "lon": -88.17903 - }, - "KLOT": { - "id": "KLOT", - "city": "Lewis University Airport", - "state": "IL", - "lat": 41.60307, - "lon": -88.10164 - }, - "KLWV": { - "id": "KLWV", - "city": "Lawrenceville-Vincennes International Airport", - "state": "IL", - "lat": 38.76046, - "lon": -87.59903 - }, - "KMDH": { - "id": "KMDH", - "city": "Southern Illinois Airport", - "state": "IL", - "lat": 37.78328, - "lon": -89.24532 - }, - "KMDW": { - "id": "KMDW", - "city": "Chicago, Chicago Midway Airport", - "state": "IL", - "lat": 41.78417, - "lon": -87.75528 - }, - "KMLI": { - "id": "KMLI", - "city": "Moline Quad-City Airport", - "state": "IL", - "lat": 41.4482, - "lon": -90.52359 - }, - "KMQB": { - "id": "KMQB", - "city": "Macomb Municipal Airport", - "state": "IL", - "lat": 40.5176299, - "lon": -90.64807 - }, - "KMTO": { - "id": "KMTO", - "city": "Mattoon / Charleston, Coles County Memorial Airport", - "state": "IL", - "lat": 39.47806, - "lon": -88.2791699 - }, - "KMVN": { - "id": "KMVN", - "city": "Mount Vernon Airport", - "state": "IL", - "lat": 38.32842, - "lon": -88.85292 - }, - "KMWA": { - "id": "KMWA", - "city": "Marion - Williamson County Regional Airport", - "state": "IL", - "lat": 37.76671, - "lon": -89.00993 - }, - "KOLY": { - "id": "KOLY", - "city": "Olney-Noble Airport", - "state": "IL", - "lat": 38.72133, - "lon": -88.1799 - }, - "KORD": { - "id": "KORD", - "city": "Chicago, Chicago-O'Hare International Airport", - "state": "IL", - "lat": 41.97972, - "lon": -87.9044399 - }, - "KPIA": { - "id": "KPIA", - "city": "Peoria - General Downing-Peoria International Airport", - "state": "IL", - "lat": 40.6674999, - "lon": -89.68389 - }, - "KPNT": { - "id": "KPNT", - "city": "Pontiac Municipal Airport", - "state": "IL", - "lat": 40.92327, - "lon": -88.6213 - }, - "KPPQ": { - "id": "KPPQ", - "city": "Pittsfield, Pittsfield Penstone Municipal Airport", - "state": "IL", - "lat": 39.63889, - "lon": -90.77833 - }, - "KPRG": { - "id": "KPRG", - "city": "Edgar County Airport", - "state": "IL", - "lat": 39.69817, - "lon": -87.6669 - }, - "KPWK": { - "id": "KPWK", - "city": "Chicago / Wheeling, Pal-Waukee Airport", - "state": "IL", - "lat": 42.12083, - "lon": -87.90472 - }, - "KRFD": { - "id": "KRFD", - "city": "Rockford, Greater Rockford Airport", - "state": "IL", - "lat": 42.19278, - "lon": -89.09333 - }, - "KRPJ": { - "id": "KRPJ", - "city": "Rochelle, Rochelle Municipal-Koritz Field Airport", - "state": "IL", - "lat": 41.8905699, - "lon": -89.08175 - }, - "KRSV": { - "id": "KRSV", - "city": "Robinson Municipal Airport", - "state": "IL", - "lat": 39.01361, - "lon": -87.64846 - }, - "KSAR": { - "id": "KSAR", - "city": "Sparta Community-Hunter Field Airport", - "state": "IL", - "lat": 38.14624, - "lon": -89.70243 - }, - "KSFY": { - "id": "KSFY", - "city": "Tri-Township Airport", - "state": "IL", - "lat": 42.04544, - "lon": -90.11009 - }, - "KSLO": { - "id": "KSLO", - "city": "Salem, Salem-Leckrone Airport", - "state": "IL", - "lat": 38.64278, - "lon": -88.96417 - }, - "KSPI": { - "id": "KSPI", - "city": "Springfield - Abraham Lincoln Capital Airport", - "state": "IL", - "lat": 39.84527, - "lon": -89.68405 - }, - "KSQI": { - "id": "KSQI", - "city": "Sterling Rockfalls", - "state": "IL", - "lat": 41.7432, - "lon": -89.66547 - }, - "KTAZ": { - "id": "KTAZ", - "city": "Taylorville, Taylorville Municipal Airport", - "state": "IL", - "lat": 39.53417, - "lon": -89.32778 - }, - "KTIP": { - "id": "KTIP", - "city": "Rantoul National Aviation Center Airport", - "state": "IL", - "lat": 40.28952, - "lon": -88.1473 - }, - "KUGN": { - "id": "KUGN", - "city": "Chicago/Waukegan Regional Airport", - "state": "IL", - "lat": 42.42546, - "lon": -87.86339 - }, - "KUIN": { - "id": "KUIN", - "city": "Quincy Regional Airport-Baldwin Field", - "state": "IL", - "lat": 39.9371, - "lon": -91.19659 - }, - "KVYS": { - "id": "KVYS", - "city": "Illinois Valley Regional Airport", - "state": "IL", - "lat": 41.35175, - "lon": -89.14963 - }, - "PHBK": { - "id": "PHBK", - "city": "Kekaha, Pacific Missile Test Facility Barking Sands", - "state": "HI", - "lat": 22.03639, - "lon": -159.78639 - }, - "PHHI": { - "id": "PHHI", - "city": "Wheeler Air Force Base / Oahu", - "state": "HI", - "lat": 21.48333, - "lon": -158.03333 - }, - "PHJH": { - "id": "PHJH", - "city": "Lahaina - West Maui", - "state": "HI", - "lat": 20.9630699, - "lon": -156.67466 - }, - "PHJR": { - "id": "PHJR", - "city": "Oahu, Kalaeloa Airport", - "state": "HI", - "lat": 21.30833, - "lon": -158.06806 - }, - "PHKO": { - "id": "PHKO", - "city": "Kailua / Kona, Keahole Airport", - "state": "HI", - "lat": 19.74083, - "lon": -156.05056 - }, - "PHLI": { - "id": "PHLI", - "city": "Lihue, Lihue Airport", - "state": "HI", - "lat": 21.98389, - "lon": -159.3411099 - }, - "PHMK": { - "id": "PHMK", - "city": "Kaunakakai, Molokai Airport", - "state": "HI", - "lat": 21.15, - "lon": -157.1 - }, - "PHNG": { - "id": "PHNG", - "city": "Kaneohe, Marine Corps Air Station", - "state": "HI", - "lat": 21.45389, - "lon": -157.76556 - }, - "PHNL": { - "id": "PHNL", - "city": "Daniel K Inouye International Airport", - "state": "HI", - "lat": 21.3275, - "lon": -157.94306 - }, - "PHNY": { - "id": "PHNY", - "city": "Lanai City, Lanai Airport", - "state": "HI", - "lat": 20.78556, - "lon": -156.95139 - }, - "PHOG": { - "id": "PHOG", - "city": "Kahului, Kahului Airport", - "state": "HI", - "lat": 20.8924999, - "lon": -156.43694 - }, - "PHSF": { - "id": "PHSF", - "city": "Bradshaw Army Air Field / Hawaii", - "state": "HI", - "lat": 19.78333, - "lon": -155.55 - }, - "PHTO": { - "id": "PHTO", - "city": "Hilo, Hilo International Airport", - "state": "HI", - "lat": 19.72222, - "lon": -155.0558299 - }, - "KAAO": { - "id": "KAAO", - "city": "Wichita Jabara Airport", - "state": "KS", - "lat": 37.74969, - "lon": -97.21908 - }, - "KADT": { - "id": "KADT", - "city": "Atwood-Rawlins County City-County Airport", - "state": "KS", - "lat": 39.84034, - "lon": -101.04248 - }, - "KBEC": { - "id": "KBEC", - "city": "Beech Factory Airport", - "state": "KS", - "lat": 37.69392, - "lon": -97.21492 - }, - "KCBK": { - "id": "KCBK", - "city": "Colby Shaltz Field Airport", - "state": "KS", - "lat": 39.43, - "lon": -101.0511 - }, - "KCFV": { - "id": "KCFV", - "city": "Coffeyville, Coffeyville Municipal Airport", - "state": "KS", - "lat": 37.09111, - "lon": -95.56639 - }, - "KCNK": { - "id": "KCNK", - "city": "Concordia, Blosser Municipal Airport", - "state": "KS", - "lat": 39.55139, - "lon": -97.65056 - }, - "KCNU": { - "id": "KCNU", - "city": "Chanute, Chanute Martin Johnson Airport", - "state": "KS", - "lat": 37.67028, - "lon": -95.48417 - }, - "KDDC": { - "id": "KDDC", - "city": "Dodge City, Dodge City Regional Airport", - "state": "KS", - "lat": 37.77278, - "lon": -99.96972 - }, - "KEHA": { - "id": "KEHA", - "city": "Elkhart, Elkhart-Morton County Airport", - "state": "KS", - "lat": 37, - "lon": -101.88333 - }, - "KEMP": { - "id": "KEMP", - "city": "Emporia, Emporia Municipal Airport", - "state": "KS", - "lat": 38.32889, - "lon": -96.19389 - }, - "KEQA": { - "id": "KEQA", - "city": "El Dorado Captain Jack Thomas Airport", - "state": "KS", - "lat": 37.77534, - "lon": -96.81449 - }, - "KEWK": { - "id": "KEWK", - "city": "Newton, Newton City/County Airport", - "state": "KS", - "lat": 38.05, - "lon": -97.28333 - }, - "KFOE": { - "id": "KFOE", - "city": "Topeka, Forbes Field", - "state": "KS", - "lat": 38.94139, - "lon": -95.65056 - }, - "KFRI": { - "id": "KFRI", - "city": "Fort Riley - Marshall AAF", - "state": "KS", - "lat": 39.05586, - "lon": -96.76166 - }, - "KGBD": { - "id": "KGBD", - "city": "Great Bend, Great Bend Municipal Airport", - "state": "KS", - "lat": 38.35, - "lon": -98.86667 - }, - "KGCK": { - "id": "KGCK", - "city": "Garden City Regional Airport", - "state": "KS", - "lat": 37.9275, - "lon": -100.72444 - }, - "KGLD": { - "id": "KGLD", - "city": "Goodland, Renner Field", - "state": "KS", - "lat": 39.3675, - "lon": -101.69306 - }, - "KHLC": { - "id": "KHLC", - "city": "Hill City, Hill City Municipal Airport", - "state": "KS", - "lat": 39.37472, - "lon": -99.82972 - }, - "KHQG": { - "id": "KHQG", - "city": "Hugoton Municipal Airport", - "state": "KS", - "lat": 37.16308, - "lon": -101.37052 - }, - "KHUT": { - "id": "KHUT", - "city": "Hutchinson, Hutchinson Municipal Airport", - "state": "KS", - "lat": 38.06806, - "lon": -97.86056 - }, - "KHYS": { - "id": "KHYS", - "city": "Hays, Hays Regional Airport", - "state": "KS", - "lat": 38.85, - "lon": -99.26667 - }, - "KIAB": { - "id": "KIAB", - "city": "McConnell Air Force Base", - "state": "KS", - "lat": 37.61667, - "lon": -97.26667 - }, - "KICT": { - "id": "KICT", - "city": "Wichita - Wichita Dwight D. Eisenhower National Airport", - "state": "KS", - "lat": 37.64722, - "lon": -97.42944 - }, - "KIDP": { - "id": "KIDP", - "city": "INDEPENDENCE", - "state": "KS", - "lat": 37.1584, - "lon": -95.7784 - }, - "KIXD": { - "id": "KIXD", - "city": "Olathe, New Century Aircenter", - "state": "KS", - "lat": 38.82444, - "lon": -94.88694 - }, - "KJHN": { - "id": "KJHN", - "city": "Stanton County Municipal Airport", - "state": "KS", - "lat": 37.5782, - "lon": -101.7304 - }, - "KLBL": { - "id": "KLBL", - "city": "Liberal, Liberal Municipal Airport", - "state": "KS", - "lat": 37.05, - "lon": -100.9666699 - }, - "KLWC": { - "id": "KLWC", - "city": "Lawrence, Lawrence Municipal Airport", - "state": "KS", - "lat": 39.00833, - "lon": -95.21167 - }, - "KLYO": { - "id": "KLYO", - "city": "Lyons-Rice County Municipal Airport", - "state": "KS", - "lat": 38.34025, - "lon": -98.22856 - }, - "KMHK": { - "id": "KMHK", - "city": "Manhattan, Manhattan Municipal Airport", - "state": "KS", - "lat": 39.13528, - "lon": -96.67778 - }, - "KMYZ": { - "id": "KMYZ", - "city": "Marysville Municipal Airport", - "state": "KS", - "lat": 39.8553, - "lon": -96.6306 - }, - "KNRN": { - "id": "KNRN", - "city": "Norton Municipal Airport", - "state": "KS", - "lat": 39.85047, - "lon": -99.89469 - }, - "KOEL": { - "id": "KOEL", - "city": "Oakley Municipal Airport", - "state": "KS", - "lat": 39.11178, - "lon": -100.81667 - }, - "KOIN": { - "id": "KOIN", - "city": "Oberlin Municipal Airport", - "state": "KS", - "lat": 39.83489, - "lon": -100.5397799 - }, - "KOJC": { - "id": "KOJC", - "city": "Olathe, Johnson County Executive Airport", - "state": "KS", - "lat": 38.85, - "lon": -94.73917 - }, - "KOWI": { - "id": "KOWI", - "city": "Ottawa Municipal Airport", - "state": "KS", - "lat": 38.5409, - "lon": -95.2542 - }, - "KPPF": { - "id": "KPPF", - "city": "Parsons, Tri-City Airport", - "state": "KS", - "lat": 37.32778, - "lon": -95.50417 - }, - "KPTS": { - "id": "KPTS", - "city": "Atkinson Municipal Airport", - "state": "KS", - "lat": 37.4494, - "lon": -94.7311 - }, - "KPTT": { - "id": "KPTT", - "city": "Pratt Municipal", - "state": "KS", - "lat": 37.7, - "lon": -98.75 - }, - "KRSL": { - "id": "KRSL", - "city": "Russell, Russell Municipal Airport", - "state": "KS", - "lat": 38.87278, - "lon": -98.8130599 - }, - "KSLN": { - "id": "KSLN", - "city": "Salina, Salina Municipal Airport", - "state": "KS", - "lat": 38.78, - "lon": -97.64417 - }, - "KSYF": { - "id": "KSYF", - "city": "ST FRANCIS", - "state": "KS", - "lat": 39.763884, - "lon": -101.797861 - }, - "KTOP": { - "id": "KTOP", - "city": "Topeka, Philip Billard Municipal Airport", - "state": "KS", - "lat": 39.0725, - "lon": -95.6258299 - }, - "KTQK": { - "id": "KTQK", - "city": "Scott City Municipal Airport", - "state": "KS", - "lat": 38.47502, - "lon": -100.88444 - }, - "KUKL": { - "id": "KUKL", - "city": "Coffey County Airport", - "state": "KS", - "lat": 38.30247, - "lon": -95.72497 - }, - "KULS": { - "id": "KULS", - "city": "Ulysses Airport", - "state": "KS", - "lat": 37.604, - "lon": -101.37356 - }, - "KWLD": { - "id": "KWLD", - "city": "Winfield / Arkansas City, Strother Field", - "state": "KS", - "lat": 37.1680599, - "lon": -97.03694 - }, - "KAKQ": { - "id": "KAKQ", - "city": "Wakefield Municipal Airport", - "state": "VA", - "lat": 36.98274, - "lon": -77.00137 - }, - "KAVC": { - "id": "KAVC", - "city": "South Hill, Mecklenburg-Brunswick Regional Airport", - "state": "VA", - "lat": 36.68861, - "lon": -78.05417 - }, - "KBCB": { - "id": "KBCB", - "city": "Virginia Tech Airport", - "state": "VA", - "lat": 37.21667, - "lon": -80.41667 - }, - "KBKT": { - "id": "KBKT", - "city": "Ft. Pickett / Blackstone", - "state": "VA", - "lat": 37.0833299, - "lon": -77.95 - }, - "KCHO": { - "id": "KCHO", - "city": "Charlottesville-Albemarle Airport", - "state": "VA", - "lat": 38.13738, - "lon": -78.45516 - }, - "KCJR": { - "id": "KCJR", - "city": "Culpeper Regional Airport", - "state": "VA", - "lat": 38.52607, - "lon": -77.85738 - }, - "KCPK": { - "id": "KCPK", - "city": "Chesapeake, Chesapeake Municipal Airport", - "state": "VA", - "lat": 36.66556, - "lon": -76.32056 - }, - "KCXE": { - "id": "KCXE", - "city": "Chase City Municipal Airport", - "state": "VA", - "lat": 36.7883, - "lon": -78.5016 - }, - "KDAA": { - "id": "KDAA", - "city": "Fort Belvoir", - "state": "VA", - "lat": 38.71667, - "lon": -77.18333 - }, - "KDAN": { - "id": "KDAN", - "city": "Danville, Danville Regional Airport", - "state": "VA", - "lat": 36.57278, - "lon": -79.33611 - }, - "KDCA": { - "id": "KDCA", - "city": "Washington/Reagan National Airport, DC", - "state": "VA", - "lat": 38.84833, - "lon": -77.03417 - }, - "KEMV": { - "id": "KEMV", - "city": "Emporia, Emporia-Greensville Regional Airport", - "state": "VA", - "lat": 36.68694, - "lon": -77.48278 - }, - "KEZF": { - "id": "KEZF", - "city": "Fredericksburg, Shannon Airport", - "state": "VA", - "lat": 38.26667, - "lon": -77.45 - }, - "KFAF": { - "id": "KFAF", - "city": "Fort Eustis / Felker", - "state": "VA", - "lat": 37.13333, - "lon": -76.61667 - }, - "KFCI": { - "id": "KFCI", - "city": "Chesterfield County Airport", - "state": "VA", - "lat": 37.406444, - "lon": -77.524833 - }, - "KFKN": { - "id": "KFKN", - "city": "Franklin / J B Rose", - "state": "VA", - "lat": 36.7, - "lon": -76.9 - }, - "KFRR": { - "id": "KFRR", - "city": "Front Royal-warren County Airport", - "state": "VA", - "lat": 38.9174999, - "lon": -78.2535 - }, - "KFVX": { - "id": "KFVX", - "city": "Farmville", - "state": "VA", - "lat": 37.35, - "lon": -78.43333 - }, - "KFYJ": { - "id": "KFYJ", - "city": "West Point, Middle Peninsula Regional Airport", - "state": "VA", - "lat": 37.52111, - "lon": -76.7644399 - }, - "KGVE": { - "id": "KGVE", - "city": "Gordonsville Municipal Airport", - "state": "VA", - "lat": 38.156, - "lon": -78.1658 - }, - "KHEF": { - "id": "KHEF", - "city": "Manassas, Manassas Regional Airport/Harry P. Davis Field", - "state": "VA", - "lat": 38.71667, - "lon": -77.51667 - }, - "KHLX": { - "id": "KHLX", - "city": "Hillsville", - "state": "VA", - "lat": 36.76667, - "lon": -80.81667 - }, - "KHSP": { - "id": "KHSP", - "city": "Hot Springs / Ingalls", - "state": "VA", - "lat": 37.95, - "lon": -79.83333 - }, - "KHWY": { - "id": "KHWY", - "city": "Warrenton-Fauquier Airport", - "state": "VA", - "lat": 38.5876499, - "lon": -77.71501 - }, - "KIAD": { - "id": "KIAD", - "city": "Washington/Dulles International Airport, DC", - "state": "VA", - "lat": 38.93472, - "lon": -77.4475 - }, - "KJFZ": { - "id": "KJFZ", - "city": "Tazewell County Airport", - "state": "VA", - "lat": 37.064, - "lon": -81.798 - }, - "KJGG": { - "id": "KJGG", - "city": "Williamsburg-Jamestown Airport", - "state": "VA", - "lat": 37.24157, - "lon": -76.71672 - }, - "KJYO": { - "id": "KJYO", - "city": "Leesburg / Godfrey", - "state": "VA", - "lat": 39.0833299, - "lon": -77.56667 - }, - "KLFI": { - "id": "KLFI", - "city": "Langley Air Force Base", - "state": "VA", - "lat": 37.0833299, - "lon": -76.35 - }, - "KLKU": { - "id": "KLKU", - "city": "Louisa, Louisa County Airport/Freeman Field", - "state": "VA", - "lat": 38.00972, - "lon": -77.97028 - }, - "KLNP": { - "id": "KLNP", - "city": "Wise / Lonesome Pine", - "state": "VA", - "lat": 36.98333, - "lon": -82.53333 - }, - "KLUA": { - "id": "KLUA", - "city": "Luray Caverns", - "state": "VA", - "lat": 38.6671, - "lon": -78.5006 - }, - "KLVL": { - "id": "KLVL", - "city": "Lawrenceville/Brunswick Municipal Airport", - "state": "VA", - "lat": 36.7727999, - "lon": -77.7943 - }, - "KLYH": { - "id": "KLYH", - "city": "Lynchburg, Lynchburg Regional Airport", - "state": "VA", - "lat": 37.32083, - "lon": -79.20667 - }, - "KMFV": { - "id": "KMFV", - "city": "Melfa / Accomack Airport", - "state": "VA", - "lat": 37.65, - "lon": -75.76667 - }, - "KMKJ": { - "id": "KMKJ", - "city": "Marion / Wytheville", - "state": "VA", - "lat": 36.9, - "lon": -81.35 - }, - "KMTV": { - "id": "KMTV", - "city": "Martinsville", - "state": "VA", - "lat": 36.63333, - "lon": -80.01667 - }, - "KNFE": { - "id": "KNFE", - "city": "Fentress, Naval Auxiliary Landing Field", - "state": "VA", - "lat": 36.70083, - "lon": -76.12833 - }, - "KNGU": { - "id": "KNGU", - "city": "Norfolk, Naval Air Station", - "state": "VA", - "lat": 36.93361, - "lon": -76.29583 - }, - "KNTU": { - "id": "KNTU", - "city": "Virginia Beach, Oceana, Naval Air Station", - "state": "VA", - "lat": 36.82111, - "lon": -76.02833 - }, - "KNYG": { - "id": "KNYG", - "city": "Quantico Marine Corps Airfield - Turner Field", - "state": "VA", - "lat": 38.50326, - "lon": -77.30129 - }, - "KOFP": { - "id": "KOFP", - "city": "Ashland, Hanover County Municipal Airport", - "state": "VA", - "lat": 37.70806, - "lon": -77.43444 - }, - "KOKV": { - "id": "KOKV", - "city": "Winchester Regional", - "state": "VA", - "lat": 39.15, - "lon": -78.15 - }, - "KOMH": { - "id": "KOMH", - "city": "Orange, Orange County Airport", - "state": "VA", - "lat": 38.24722, - "lon": -78.04556 - }, - "KORF": { - "id": "KORF", - "city": "Norfolk, Norfolk International Airport", - "state": "VA", - "lat": 36.90361, - "lon": -76.19194 - }, - "KPHF": { - "id": "KPHF", - "city": "Newport News, Newport News / Williamsburg International Airport", - "state": "VA", - "lat": 37.13194, - "lon": -76.49306 - }, - "KPSK": { - "id": "KPSK", - "city": "Dublin / New River Valley", - "state": "VA", - "lat": 37.13333, - "lon": -80.68333 - }, - "KPTB": { - "id": "KPTB", - "city": "Petersburg, Dinwiddie County Airport", - "state": "VA", - "lat": 37.18333, - "lon": -77.51667 - }, - "KPVG": { - "id": "KPVG", - "city": "Norfolk Hampton Roads Executive Airport", - "state": "VA", - "lat": 36.7801, - "lon": -76.4488 - }, - "KRIC": { - "id": "KRIC", - "city": "Richmond, Richmond International Airport", - "state": "VA", - "lat": 37.51111, - "lon": -77.32333 - }, - "KRMN": { - "id": "KRMN", - "city": "Stafford, Stafford Regional Airport", - "state": "VA", - "lat": 38.39806, - "lon": -77.45528 - }, - "KROA": { - "id": "KROA", - "city": "Roanoke, Roanoke Regional Airport", - "state": "VA", - "lat": 37.31694, - "lon": -79.97417 - }, - "KSFQ": { - "id": "KSFQ", - "city": "Suffolk, Suffolk Municipal Airport", - "state": "VA", - "lat": 36.68222, - "lon": -76.60194 - }, - "KSHD": { - "id": "KSHD", - "city": "Staunton / Shenandoah", - "state": "VA", - "lat": 38.26667, - "lon": -78.9 - }, - "KTGI": { - "id": "KTGI", - "city": "Tangier Island Airport", - "state": "VA", - "lat": 37.82587, - "lon": -75.99766 - }, - "KVBW": { - "id": "KVBW", - "city": "Bridgewater Air Park", - "state": "VA", - "lat": 38.36674, - "lon": -78.96033 - }, - "KVJI": { - "id": "KVJI", - "city": "Abingdon", - "state": "VA", - "lat": 36.68333, - "lon": -82.03333 - }, - "KWAL": { - "id": "KWAL", - "city": "Wallops Flight Facility Airport", - "state": "VA", - "lat": 37.9372, - "lon": -75.46619 - }, - "KXSA": { - "id": "KXSA", - "city": "Tappahannock-Essex County Airport", - "state": "VA", - "lat": 37.859611, - "lon": -76.894111 - }, - "KALX": { - "id": "KALX", - "city": "Alexander City, Thomas C Russell Field Airport", - "state": "AL", - "lat": 32.91472, - "lon": -85.96278 - }, - "KANB": { - "id": "KANB", - "city": "Anniston Metro Airport", - "state": "AL", - "lat": 33.59045, - "lon": -85.84789 - }, - "KASN": { - "id": "KASN", - "city": "Talladega Municipal Airport", - "state": "AL", - "lat": 33.5695, - "lon": -86.0512 - }, - "KAUO": { - "id": "KAUO", - "city": "Auburn-Opelika Airport", - "state": "AL", - "lat": 32.61667, - "lon": -85.43333 - }, - "KBFM": { - "id": "KBFM", - "city": "Mobile, Mobile Downtown Airport", - "state": "AL", - "lat": 30.61389, - "lon": -88.0633299 - }, - "KBHM": { - "id": "KBHM", - "city": "Birmingham, Birmingham International Airport", - "state": "AL", - "lat": 33.56556, - "lon": -86.745 - }, - "KCMD": { - "id": "KCMD", - "city": "Cullman Regional Folsom Field", - "state": "AL", - "lat": 34.2687, - "lon": -86.858 - }, - "KCQF": { - "id": "KCQF", - "city": "Sonny Callahan Airport", - "state": "AL", - "lat": 30.461, - "lon": -87.877 - }, - "KDCU": { - "id": "KDCU", - "city": "Decatur, Pryor Field", - "state": "AL", - "lat": 34.65806, - "lon": -86.94333 - }, - "KDHN": { - "id": "KDHN", - "city": "Dothan, Dothan Regional Airport", - "state": "AL", - "lat": 31.32139, - "lon": -85.44972 - }, - "KDYA": { - "id": "KDYA", - "city": "Demopolis Municipal Airport", - "state": "AL", - "lat": 32.4638, - "lon": -87.9541 - }, - "KEDN": { - "id": "KEDN", - "city": "Enterprise Municipal Airport", - "state": "AL", - "lat": 31.2982, - "lon": -85.9048 - }, - "KEET": { - "id": "KEET", - "city": "Alabaster, Shelby County Airport", - "state": "AL", - "lat": 33.17833, - "lon": -86.78167 - }, - "KEKY": { - "id": "KEKY", - "city": "Bessemer Airport", - "state": "AL", - "lat": 33.3126, - "lon": -86.9263 - }, - "KEUF": { - "id": "KEUF", - "city": "Eufaula Municipal Airport", - "state": "AL", - "lat": 31.951, - "lon": -85.129 - }, - "KGAD": { - "id": "KGAD", - "city": "Gadsden, Gadsden Municipal Airport", - "state": "AL", - "lat": 33.96667, - "lon": -86.08333 - }, - "KGZH": { - "id": "KGZH", - "city": "Evergreen, Middleton Field", - "state": "AL", - "lat": 31.41889, - "lon": -87.04806 - }, - "KHEY": { - "id": "KHEY", - "city": "Hanchey AHP / Ozark", - "state": "AL", - "lat": 31.35, - "lon": -85.66667 - }, - "KHSV": { - "id": "KHSV", - "city": "Huntsville, Huntsville International / Jones Field", - "state": "AL", - "lat": 34.64361, - "lon": -86.78556 - }, - "KHUA": { - "id": "KHUA", - "city": "Redstone Airfield", - "state": "AL", - "lat": 34.6786, - "lon": -86.6847 - }, - "KJFX": { - "id": "KJFX", - "city": "Jasper Walker County Airport & Bevill Field", - "state": "AL", - "lat": 33.902, - "lon": -87.31417 - }, - "KJKA": { - "id": "KJKA", - "city": "Jack Edwards Airport", - "state": "AL", - "lat": 30.2896, - "lon": -87.6718 - }, - "KLOR": { - "id": "KLOR", - "city": "Fort Rucker, Lowe Army Heliport", - "state": "AL", - "lat": 31.35889, - "lon": -85.74833 - }, - "KMDQ": { - "id": "KMDQ", - "city": "Huntsville, Madison County Executive Airport", - "state": "AL", - "lat": 34.86139, - "lon": -86.55722 - }, - "KMGM": { - "id": "KMGM", - "city": "Montgomery, Dannelly Field", - "state": "AL", - "lat": 32.30028, - "lon": -86.40611 - }, - "KMOB": { - "id": "KMOB", - "city": "Mobile, Mobile Regional Airport", - "state": "AL", - "lat": 30.68833, - "lon": -88.24556 - }, - "KMSL": { - "id": "KMSL", - "city": "Muscle Shoals, North West Alabama Regional Airport", - "state": "AL", - "lat": 34.74389, - "lon": -87.59944 - }, - "KMXF": { - "id": "KMXF", - "city": "Maxwell Air Force Base / Montgomery", - "state": "AL", - "lat": 32.38333, - "lon": -86.36667 - }, - "KOZR": { - "id": "KOZR", - "city": "Cairns Army Air Field / Ozark", - "state": "AL", - "lat": 31.27672, - "lon": -85.71099 - }, - "KPLR": { - "id": "KPLR", - "city": "St Clair County Airport", - "state": "AL", - "lat": 33.5588, - "lon": -86.2491 - }, - "KPRN": { - "id": "KPRN", - "city": "Mac Crenshaw Memorial Airport", - "state": "AL", - "lat": 31.8457, - "lon": -86.6107 - }, - "KSCD": { - "id": "KSCD", - "city": "Merkel Field Sylacauga Municipal Airport", - "state": "AL", - "lat": 33.1718, - "lon": -86.3055 - }, - "KSEM": { - "id": "KSEM", - "city": "Craig Field / Selma", - "state": "AL", - "lat": 32.35, - "lon": -86.98333 - }, - "KSXS": { - "id": "KSXS", - "city": "SCHELL AHP", - "state": "AL", - "lat": 31.35, - "lon": -85.85 - }, - "KTCL": { - "id": "KTCL", - "city": "Tuscaloosa Regional Airport", - "state": "AL", - "lat": 33.21215, - "lon": -87.61554 - }, - "KTOI": { - "id": "KTOI", - "city": "Troy, Troy Municipal Airport", - "state": "AL", - "lat": 31.86056, - "lon": -86.01222 - }, - "KAAS": { - "id": "KAAS", - "city": "Taylor County Airport", - "state": "KY", - "lat": 37.35828, - "lon": -85.30942 - }, - "KBRY": { - "id": "KBRY", - "city": "Samuels Field Airport", - "state": "KY", - "lat": 37.81433, - "lon": -85.49964 - }, - "KBWG": { - "id": "KBWG", - "city": "Bowling Green, Bowling Green-Warren County Regional Airport", - "state": "KY", - "lat": 36.96444, - "lon": -86.41944 - }, - "KBYL": { - "id": "KBYL", - "city": "Williamsburg-Whitley County Airport", - "state": "KY", - "lat": 36.7954099, - "lon": -84.2012699 - }, - "KCEY": { - "id": "KCEY", - "city": "Murray Kyle Oakley Field, KY", - "state": "KY", - "lat": 36.6646, - "lon": -88.3728 - }, - "KCPF": { - "id": "KCPF", - "city": "Wendell H Ford Airport", - "state": "KY", - "lat": 37.38736, - "lon": -83.26161 - }, - "KCVG": { - "id": "KCVG", - "city": "Cincinnati/Northern Kentucky International Airport", - "state": "KY", - "lat": 39.04456, - "lon": -84.67229 - }, - "KDVK": { - "id": "KDVK", - "city": "Stuart Powell Field Airport", - "state": "KY", - "lat": 37.5775751, - "lon": -84.7694978 - }, - "KDWU": { - "id": "KDWU", - "city": "Ashland Regional Airport", - "state": "KY", - "lat": 38.5545, - "lon": -82.738 - }, - "KEHR": { - "id": "KEHR", - "city": "Henderson City", - "state": "KY", - "lat": 37.81667, - "lon": -87.68333 - }, - "KEKQ": { - "id": "KEKQ", - "city": "Monticello, Wayne County Airport", - "state": "KY", - "lat": 36.85528, - "lon": -84.85611 - }, - "KEKX": { - "id": "KEKX", - "city": "Elizabethtown Addington Field Airport", - "state": "KY", - "lat": 37.686, - "lon": -85.925 - }, - "KFFT": { - "id": "KFFT", - "city": "Frankfort, Capital City Airport", - "state": "KY", - "lat": 38.18472, - "lon": -84.90333 - }, - "KFGX": { - "id": "KFGX", - "city": "Flemingsburg Fleming-Mason Airport", - "state": "KY", - "lat": 38.5418, - "lon": -83.7434 - }, - "KFTK": { - "id": "KFTK", - "city": "Fort Knox", - "state": "KY", - "lat": 37.9, - "lon": -85.9666699 - }, - "KGLW": { - "id": "KGLW", - "city": "Glasgow, Glasgow Municipal Airport", - "state": "KY", - "lat": 37.03167, - "lon": -85.95361 - }, - "KHOP": { - "id": "KHOP", - "city": "Fort Campbell U. S. Army Airfield", - "state": "KY", - "lat": 36.66667, - "lon": -87.5 - }, - "KIOB": { - "id": "KIOB", - "city": "Mount Sterling-Montgomery County Airport", - "state": "KY", - "lat": 38.0575, - "lon": -83.9829 - }, - "KJKL": { - "id": "KJKL", - "city": "Jackson, Carroll Airport", - "state": "KY", - "lat": 37.5913899, - "lon": -83.31444 - }, - "KLEX": { - "id": "KLEX", - "city": "Lexington Blue Grass Airport", - "state": "KY", - "lat": 38.0339, - "lon": -84.6114599 - }, - "KLOU": { - "id": "KLOU", - "city": "Louisville, Bowman Field Airport", - "state": "KY", - "lat": 38.22778, - "lon": -85.66361 - }, - "KLOZ": { - "id": "KLOZ", - "city": "London, London-Corbin Airport-Magee Field", - "state": "KY", - "lat": 37.08944, - "lon": -84.06861 - }, - "KOWB": { - "id": "KOWB", - "city": "Owensboro, Owensboro-Daviess County Airport", - "state": "KY", - "lat": 37.74, - "lon": -87.16667 - }, - "KPAH": { - "id": "KPAH", - "city": "Paducah, Barkley Regional Airport", - "state": "KY", - "lat": 37.05639, - "lon": -88.77389 - }, - "KPBX": { - "id": "KPBX", - "city": "Pikeville Pike County Airport and Hatcher Field", - "state": "KY", - "lat": 37.5587, - "lon": -82.5674 - }, - "KRGA": { - "id": "KRGA", - "city": "Central Kentucky Regional Airport", - "state": "KY", - "lat": 37.6308475, - "lon": -84.3323372 - }, - "KSDF": { - "id": "KSDF", - "city": "Louisville Muhammad Ali International Airport", - "state": "KY", - "lat": 38.17406, - "lon": -85.7365 - }, - "KSJS": { - "id": "KSJS", - "city": "Big Sandy Regional Airport", - "state": "KY", - "lat": 37.751, - "lon": -82.6367 - }, - "KSME": { - "id": "KSME", - "city": "Somerset, Somerset-Pulaski County - J.T. Wilson Field Airport", - "state": "KY", - "lat": 37.05417, - "lon": -84.615 - }, - "KSYM": { - "id": "KSYM", - "city": "Clyde A. Thomas Regional Airport", - "state": "KY", - "lat": 38.215, - "lon": -83.5874 - }, - "KTWT": { - "id": "KTWT", - "city": "Sturgis, Sturgis Municipal Airport", - "state": "KY", - "lat": 37.54083, - "lon": -87.9516699 - }, - "KAST": { - "id": "KAST", - "city": "Astoria, Astoria Regional Airport", - "state": "OR", - "lat": 46.15694, - "lon": -123.8825 - }, - "KBDN": { - "id": "KBDN", - "city": "Bend Airport AWOS", - "state": "OR", - "lat": 44.0948, - "lon": -121.2006 - }, - "KBKE": { - "id": "KBKE", - "city": "Baker Municipal Airport", - "state": "OR", - "lat": 44.84302, - "lon": -117.80987 - }, - "KBNO": { - "id": "KBNO", - "city": "Burns Municipal Airport", - "state": "OR", - "lat": 43.59488, - "lon": -118.95791 - }, - "KBOK": { - "id": "KBOK", - "city": "Brookings, Brookings Airport", - "state": "OR", - "lat": 42.07444, - "lon": -124.29 - }, - "KCVO": { - "id": "KCVO", - "city": "Corvallis, Corvallis Municipal Airport", - "state": "OR", - "lat": 44.5, - "lon": -123.28333 - }, - "KEUG": { - "id": "KEUG", - "city": "Eugene, Mahlon Sweet Field", - "state": "OR", - "lat": 44.13333, - "lon": -123.21444 - }, - "KGCD": { - "id": "KGCD", - "city": "Grant County Regional Airport", - "state": "OR", - "lat": 44.40287, - "lon": -118.96715 - }, - "KHIO": { - "id": "KHIO", - "city": "Portland-Hillsboro Airport", - "state": "OR", - "lat": 45.54765, - "lon": -122.95568 - }, - "KHRI": { - "id": "KHRI", - "city": "Hermiston, Hermiston Municipal Airport", - "state": "OR", - "lat": 45.82583, - "lon": -119.26111 - }, - "KAIZ": { - "id": "KAIZ", - "city": "Kaiser Lake Ozark, Lee C Fine Memorial Airport", - "state": "MO", - "lat": 38.1, - "lon": -92.55 - }, - "KBBG": { - "id": "KBBG", - "city": "Branson", - "state": "MO", - "lat": 36.5321, - "lon": -93.2005 - }, - "KCDJ": { - "id": "KCDJ", - "city": "Chillicothe, Chillicothe Agri-Science Center", - "state": "MO", - "lat": 39.81667, - "lon": -93.58333 - }, - "KCGI": { - "id": "KCGI", - "city": "Cape Girardeau, Cape Girardeau Regional Airport", - "state": "MO", - "lat": 37.22556, - "lon": -89.5783299 - }, - "KCOU": { - "id": "KCOU", - "city": "Columbia, Columbia Regional Airport", - "state": "MO", - "lat": 38.81694, - "lon": -92.21833 - }, - "KDMO": { - "id": "KDMO", - "city": "Sedalia, Sedalia Memorial Airport", - "state": "MO", - "lat": 38.71222, - "lon": -93.17444 - }, - "KEOS": { - "id": "KEOS", - "city": "NEOSHOAIRPORT", - "state": "MO", - "lat": 36.8108, - "lon": -94.39169 - }, - "KEVU": { - "id": "KEVU", - "city": "Maryville Northwest Missouri Regional Airport", - "state": "MO", - "lat": 40.3525, - "lon": -94.915 - }, - "KEZZ": { - "id": "KEZZ", - "city": "Cameron Memorial Airport", - "state": "MO", - "lat": 39.7275599, - "lon": -94.27639 - }, - "KFAM": { - "id": "KFAM", - "city": "Farmington Airport", - "state": "MO", - "lat": 37.76667, - "lon": -90.43333 - }, - "KFWB": { - "id": "KFWB", - "city": "Branson West Muni - Emerson Field", - "state": "MO", - "lat": 36.6985, - "lon": -93.4021999 - }, - "KFYG": { - "id": "KFYG", - "city": "Washington Regional Airport", - "state": "MO", - "lat": 38.5876, - "lon": -90.9937999 - }, - "KADF": { - "id": "KADF", - "city": "Dexter B Florence Memorial Field", - "state": "AR", - "lat": 34.0998, - "lon": -93.0661 - }, - "KARG": { - "id": "KARG", - "city": "Walnut Ridge Regional Airport", - "state": "AR", - "lat": 36.12562, - "lon": -90.92148 - }, - "KASG": { - "id": "KASG", - "city": "Springdale Municipal", - "state": "AR", - "lat": 36.18333, - "lon": -94.11667 - }, - "KAWM": { - "id": "KAWM", - "city": "West Memphis, West Memphis Municipal Airport", - "state": "AR", - "lat": 35.13333, - "lon": -90.23333 - }, - "KBPK": { - "id": "KBPK", - "city": "Baxter County Airport", - "state": "AR", - "lat": 36.37056, - "lon": -92.47194 - }, - "KBVX": { - "id": "KBVX", - "city": "Batesville, Batesville Regional Airport", - "state": "AR", - "lat": 35.73333, - "lon": -91.65 - }, - "KBYH": { - "id": "KBYH", - "city": "Eaker Air Force Base", - "state": "AR", - "lat": 35.96667, - "lon": -89.95 - }, - "KCCA": { - "id": "KCCA", - "city": "Clinton Memorial Airfield", - "state": "AR", - "lat": 35.598, - "lon": -92.4516 - }, - "KCDH": { - "id": "KCDH", - "city": "Camden / Harrell Field", - "state": "AR", - "lat": 33.61667, - "lon": -92.76667 - }, - "KCXW": { - "id": "KCXW", - "city": "Conway - Cantrell Field", - "state": "AR", - "lat": 35.0199, - "lon": -92.5551 - }, - "KDEQ": { - "id": "KDEQ", - "city": "De Queen, J Lynn Helms Sevier County Airport", - "state": "AR", - "lat": 34.04694, - "lon": -94.39944 - }, - "KELD": { - "id": "KELD", - "city": "South Arkansas Regional Airport", - "state": "AR", - "lat": 33.22075, - "lon": -92.8139999 - }, - "KFLP": { - "id": "KFLP", - "city": "Flippin, Marion County Regional Airport", - "state": "AR", - "lat": 36.3, - "lon": -92.58333 - }, - "KFSM": { - "id": "KFSM", - "city": "Fort Smith Regional Airport", - "state": "AR", - "lat": 35.3335, - "lon": -94.36524 - }, - "KFYV": { - "id": "KFYV", - "city": "Fayetteville, Drake Field", - "state": "AR", - "lat": 36.01028, - "lon": -94.1677799 - }, - "KHKA": { - "id": "KHKA", - "city": "Blytheville, Blytheville Municipal Airport", - "state": "AR", - "lat": 35.93889, - "lon": -89.8325 - }, - "KHOT": { - "id": "KHOT", - "city": "Hot Springs, Memorial Field Airport", - "state": "AR", - "lat": 34.47806, - "lon": -93.09611 - }, - "KHRO": { - "id": "KHRO", - "city": "Harrison, Boone County Airport", - "state": "AR", - "lat": 36.26167, - "lon": -93.15472 - }, - "KJBR": { - "id": "KJBR", - "city": "Jonesboro, Jonesboro Municipal Airport", - "state": "AR", - "lat": 35.83722, - "lon": -90.64306 - }, - "KLIT": { - "id": "KLIT", - "city": "Little Rock, Adams Field", - "state": "AR", - "lat": 34.72667, - "lon": -92.23611 - }, - "KLLQ": { - "id": "KLLQ", - "city": "Monticello, Monticello Municipal Airport/Ellis Field", - "state": "AR", - "lat": 33.63833, - "lon": -91.75111 - }, - "KLRF": { - "id": "KLRF", - "city": "Little Rock Air Force Base", - "state": "AR", - "lat": 34.91667, - "lon": -92.15 - }, - "KMEZ": { - "id": "KMEZ", - "city": "Mena, Mena Intermountain Municipal Airport", - "state": "AR", - "lat": 34.54528, - "lon": -94.2025 - }, - "KMWT": { - "id": "KMWT", - "city": "Mount Ida", - "state": "AR", - "lat": 34.55, - "lon": -93.58333 - }, - "KORK": { - "id": "KORK", - "city": "North Little Rock Municipal Airport", - "state": "AR", - "lat": 34.83314, - "lon": -92.25414 - }, - "KPBF": { - "id": "KPBF", - "city": "Pine Bluff, Grider Field Airport", - "state": "AR", - "lat": 34.175, - "lon": -91.93472 - }, - "KROG": { - "id": "KROG", - "city": "Rogers - Rogers Executive Airport - Carter Field", - "state": "AR", - "lat": 36.36667, - "lon": -94.1 - }, - "KRUE": { - "id": "KRUE", - "city": "Russelville Municipal Airport", - "state": "AR", - "lat": 35.25737, - "lon": -93.0949399 - }, - "KSGT": { - "id": "KSGT", - "city": "Stuttgart, Stuttgart Municipal Airport", - "state": "AR", - "lat": 34.6, - "lon": -91.56667 - }, - "KSLG": { - "id": "KSLG", - "city": "Siloam Springs, Smith Field Airport", - "state": "AR", - "lat": 36.2, - "lon": -94.48333 - }, - "KSRC": { - "id": "KSRC", - "city": "Searcy Municipal Airport", - "state": "AR", - "lat": 35.21349, - "lon": -91.7392799 - }, - "KSUZ": { - "id": "KSUZ", - "city": "Saline County Regional Airport", - "state": "AR", - "lat": 34.59039, - "lon": -92.47944 - }, - "KTXK": { - "id": "KTXK", - "city": "Texarkana, Texarkana Regional-Webb Field", - "state": "AR", - "lat": 33.45611, - "lon": -93.9875 - }, - "KVBT": { - "id": "KVBT", - "city": "Bentonville, Bentonville Municipal Airport/Louise M Thaden Field", - "state": "AR", - "lat": 36.35, - "lon": -94.2166699 - }, - "KXNA": { - "id": "KXNA", - "city": "Northwest Arkansas Regional Airport", - "state": "AR", - "lat": 36.28977, - "lon": -94.3114499 - }, - "KABY": { - "id": "KABY", - "city": "Southwest Georgia Regional Airport", - "state": "GA", - "lat": 31.53652, - "lon": -84.19571 - }, - "KACJ": { - "id": "KACJ", - "city": "Americus Souther Field Airport", - "state": "GA", - "lat": 32.11081, - "lon": -84.18886 - }, - "KAGS": { - "id": "KAGS", - "city": "Augusta, Bush Field", - "state": "GA", - "lat": 33.36444, - "lon": -81.96333 - }, - "KAHN": { - "id": "KAHN", - "city": "Athens, Athens Airport", - "state": "GA", - "lat": 33.95083, - "lon": -83.3280599 - }, - "KAJR": { - "id": "KAJR", - "city": "Cornelia Habersham County Airport", - "state": "GA", - "lat": 34.4998, - "lon": -83.5567 - }, - "KAMG": { - "id": "KAMG", - "city": "Alma, Bacon County Airport", - "state": "GA", - "lat": 31.53611, - "lon": -82.50667 - }, - "KATL": { - "id": "KATL", - "city": "Atlanta, Hartsfield - Jackson Atlanta International Airport", - "state": "GA", - "lat": 33.64028, - "lon": -84.42694 - }, - "KAYS": { - "id": "KAYS", - "city": "Waycross / Ware County, Ga", - "state": "GA", - "lat": 31.25, - "lon": -82.4 - }, - "KAZE": { - "id": "KAZE", - "city": "Hazlehurst Airport", - "state": "GA", - "lat": 31.8847, - "lon": -82.6474 - }, - "KBGE": { - "id": "KBGE", - "city": "Bainbridge, Decatur County Industrial Air Park Airport", - "state": "GA", - "lat": 30.96667, - "lon": -84.63333 - }, - "KBHC": { - "id": "KBHC", - "city": "Baxley Municipal Airport", - "state": "GA", - "lat": 31.7138, - "lon": -82.3938 - }, - "KBIJ": { - "id": "KBIJ", - "city": "Blakely, Early County Airport", - "state": "GA", - "lat": 31.39694, - "lon": -84.895 - }, - "KBQK": { - "id": "KBQK", - "city": "Brunswick / Glynco", - "state": "GA", - "lat": 31.25, - "lon": -81.4666699 - }, - "KCCO": { - "id": "KCCO", - "city": "Newnan, Newnan Coweta County Airport", - "state": "GA", - "lat": 33.31222, - "lon": -84.77028 - }, - "KCKF": { - "id": "KCKF", - "city": "Cordele Crisp County Airport", - "state": "GA", - "lat": 31.9888, - "lon": -83.7739 - }, - "KCNI": { - "id": "KCNI", - "city": "Canton, Cherokee County Airport", - "state": "GA", - "lat": 34.31056, - "lon": -84.42389 - }, - "KCSG": { - "id": "KCSG", - "city": "Columbus, Columbus Metropolitan Airport", - "state": "GA", - "lat": 32.51611, - "lon": -84.94222 - }, - "KCTJ": { - "id": "KCTJ", - "city": "Carrollton West Georgia Regional Airport", - "state": "GA", - "lat": 33.63, - "lon": -85.15 - }, - "KCVC": { - "id": "KCVC", - "city": "Covington Municipal Airport", - "state": "GA", - "lat": 33.632, - "lon": -83.85 - }, - "KCWV": { - "id": "KCWV", - "city": "Claxton Evans County Airport", - "state": "GA", - "lat": 32.1950999, - "lon": -81.8696 - }, - "KCXU": { - "id": "KCXU", - "city": "Camilla-Mitchell County Airport", - "state": "GA", - "lat": 31.2132, - "lon": -84.2352 - }, - "KCZL": { - "id": "KCZL", - "city": "Calhoun Tom B. David Field Airport", - "state": "GA", - "lat": 34.4554, - "lon": -84.9392 - }, - "KDBN": { - "id": "KDBN", - "city": "Dublin, W H 'Bud' Barron Airport", - "state": "GA", - "lat": 32.56444, - "lon": -82.985 - }, - "KDNL": { - "id": "KDNL", - "city": "Augusta Daniel Field", - "state": "GA", - "lat": 33.4669, - "lon": -82.03836 - }, - "KDNN": { - "id": "KDNN", - "city": "Dalton, Dalton Municipal Airport", - "state": "GA", - "lat": 34.72167, - "lon": -84.86917 - }, - "KDQH": { - "id": "KDQH", - "city": "Douglas, Douglas Municipal Airport", - "state": "GA", - "lat": 31.47667, - "lon": -82.86028 - }, - "KDZJ": { - "id": "KDZJ", - "city": "Blairsville Airport", - "state": "GA", - "lat": 34.8544, - "lon": -83.9973 - }, - "KEZM": { - "id": "KEZM", - "city": "Eastman, Heart of Georgia Regional Airport", - "state": "GA", - "lat": 32.21417, - "lon": -83.12778 - }, - "KFFC": { - "id": "KFFC", - "city": "Atlanta Regional Airport-Falcon Field", - "state": "GA", - "lat": 33.35436, - "lon": -84.56893 - }, - "KFTY": { - "id": "KFTY", - "city": "Fulton County Airport-Brown Field", - "state": "GA", - "lat": 33.77764, - "lon": -84.52461 - }, - "KFZG": { - "id": "KFZG", - "city": "Fitzgerald Municipal Airport", - "state": "GA", - "lat": 31.6839, - "lon": -83.2709 - }, - "KGVL": { - "id": "KGVL", - "city": "Gainesville, Gilmer Memorial Airport", - "state": "GA", - "lat": 34.27194, - "lon": -83.83028 - }, - "KHMP": { - "id": "KHMP", - "city": "Henry County Airport", - "state": "GA", - "lat": 33.3899, - "lon": -84.331 - }, - "KHOE": { - "id": "KHOE", - "city": "Homerville Airport", - "state": "GA", - "lat": 31.0559, - "lon": -82.7741 - }, - "KHQU": { - "id": "KHQU", - "city": "Thomson, Thomson-McDuffie County Airport", - "state": "GA", - "lat": 33.52944, - "lon": -82.51639 - }, - "KIIY": { - "id": "KIIY", - "city": "Washington, Washington-Wilkes County Airport", - "state": "GA", - "lat": 33.77972, - "lon": -82.81639 - }, - "KJCA": { - "id": "KJCA", - "city": "Jackson County Airport", - "state": "GA", - "lat": 34.17586, - "lon": -83.5616 - }, - "KJES": { - "id": "KJES", - "city": "Jesup-Wayne County Airport", - "state": "GA", - "lat": 31.554, - "lon": -81.8824999 - }, - "KJYL": { - "id": "KJYL", - "city": "Sylvania, Plantation Airpark", - "state": "GA", - "lat": 32.64528, - "lon": -81.59639 - }, - "KJZP": { - "id": "KJZP", - "city": "Jasper Pickens County Airport", - "state": "GA", - "lat": 34.45417, - "lon": -84.45971 - }, - "KLGC": { - "id": "KLGC", - "city": "LaGrange-Callaway Airport", - "state": "GA", - "lat": 33.00617, - "lon": -85.06609 - }, - "KLHW": { - "id": "KLHW", - "city": "Wright Army Airfield (Fort Stewart)/Midcoast Regional Airport", - "state": "GA", - "lat": 31.88724, - "lon": -81.56244 - }, - "KLSF": { - "id": "KLSF", - "city": "Fort Benning", - "state": "GA", - "lat": 32.3333299, - "lon": -84.83333 - }, - "KLZU": { - "id": "KLZU", - "city": "Gwinnett County Airport-Briscoe Field", - "state": "GA", - "lat": 33.98288, - "lon": -83.95842 - }, - "KMCN": { - "id": "KMCN", - "city": "Middle Georgia Regional Airport", - "state": "GA", - "lat": 32.68892, - "lon": -83.65293 - }, - "KMGE": { - "id": "KMGE", - "city": "Marietta / Dobbins Air Force Base", - "state": "GA", - "lat": 33.91667, - "lon": -84.51667 - }, - "KMGR": { - "id": "KMGR", - "city": "Moultrie, Moultrie Municipal Airport", - "state": "GA", - "lat": 31.08472, - "lon": -83.80306 - }, - "KMHP": { - "id": "KMHP", - "city": "Metter Municipal Airport", - "state": "GA", - "lat": 32.37397, - "lon": -82.08144 - }, - "KMLJ": { - "id": "KMLJ", - "city": "Milledgeville, Baldwin County Airport", - "state": "GA", - "lat": 33.15417, - "lon": -83.24056 - }, - "KOKZ": { - "id": "KOKZ", - "city": "Sandersville Kaolin Field Airport", - "state": "GA", - "lat": 32.9667, - "lon": -82.8382 - }, - "KOPN": { - "id": "KOPN", - "city": "Thomaston, Thomaston-Upson County Airport", - "state": "GA", - "lat": 32.955, - "lon": -84.2644399 - }, - "KPDK": { - "id": "KPDK", - "city": "Atlanta, De Kalb-Peachtree Airport", - "state": "GA", - "lat": 33.87833, - "lon": -84.29806 - }, - "KPIM": { - "id": "KPIM", - "city": "Pine Mountain Harris County Airport", - "state": "GA", - "lat": 32.8407, - "lon": -84.8824 - }, - "KPUJ": { - "id": "KPUJ", - "city": "Dallas Paulding County Regional Airport", - "state": "GA", - "lat": 33.9189999, - "lon": -84.952 - }, - "KPXE": { - "id": "KPXE", - "city": "Perry-Houston County Airport", - "state": "GA", - "lat": 32.5105999, - "lon": -83.7673 - }, - "KRMG": { - "id": "KRMG", - "city": "Rome, R. B. Russell Airport", - "state": "GA", - "lat": 34.34778, - "lon": -85.1611099 - }, - "KRVJ": { - "id": "KRVJ", - "city": "Swinton Smith Field at Reidsville Municipal Airport", - "state": "GA", - "lat": 32.0594899, - "lon": -82.15358 - }, - "KRYY": { - "id": "KRYY", - "city": "Cobb County International Airport - McCollum Field", - "state": "GA", - "lat": 34.01467, - "lon": -84.59635 - }, - "KSAV": { - "id": "KSAV", - "city": "Savannah-Hilton Head International Airport", - "state": "GA", - "lat": 32.1313699, - "lon": -81.20226 - }, - "KSBO": { - "id": "KSBO", - "city": "Swainsboro Emanuel County Airport", - "state": "GA", - "lat": 32.6091, - "lon": -82.3699 - }, - "KSSI": { - "id": "KSSI", - "city": "Brunswick, Malcolm McKinnon Airport", - "state": "GA", - "lat": 31.15167, - "lon": -81.39139 - }, - "KSVN": { - "id": "KSVN", - "city": "Hunter U. S. Army Airfield", - "state": "GA", - "lat": 32.01667, - "lon": -81.15 - }, - "KTBR": { - "id": "KTBR", - "city": "Statesboro, Statesboro-Bulloch County Airport", - "state": "GA", - "lat": 32.48306, - "lon": -81.7372199 - }, - "KTMA": { - "id": "KTMA", - "city": "Tifton Henry Tift Myers", - "state": "GA", - "lat": 31.429, - "lon": -83.4885 - }, - "KTOC": { - "id": "KTOC", - "city": "Toccoa Le Tourneau Airport", - "state": "GA", - "lat": 34.5927999, - "lon": -83.2964 - }, - "KTVI": { - "id": "KTVI", - "city": "Thomasville Regional Airport", - "state": "GA", - "lat": 30.90179, - "lon": -83.88113 - }, - "KVAD": { - "id": "KVAD", - "city": "Moody Air Force Base", - "state": "GA", - "lat": 30.97913, - "lon": -83.19247 - }, - "KVDI": { - "id": "KVDI", - "city": "Vidalia, Vidalia Municipal Airport", - "state": "GA", - "lat": 32.1925, - "lon": -82.37194 - }, - "KVLD": { - "id": "KVLD", - "city": "Valdosta Regional Airport", - "state": "GA", - "lat": 30.77632, - "lon": -83.27389 - }, - "KVPC": { - "id": "KVPC", - "city": "Cartersville Airport", - "state": "GA", - "lat": 34.11589, - "lon": -84.85064 - }, - "KWDR": { - "id": "KWDR", - "city": "Winder, Winder-Barrow Airport", - "state": "GA", - "lat": 33.98222, - "lon": -83.66806 - }, - "KWRB": { - "id": "KWRB", - "city": "Warner Robins Air Force Base", - "state": "GA", - "lat": 32.63333, - "lon": -83.6 - }, - "KGLY": { - "id": "KGLY", - "city": "Clinton, MO", - "state": "MO", - "lat": 38.3566, - "lon": -93.6842 - }, - "KGPH": { - "id": "KGPH", - "city": "Mosby Midwest National Air Center Airport", - "state": "MO", - "lat": 39.3325, - "lon": -94.3096 - }, - "KHAE": { - "id": "KHAE", - "city": "Hannibal Regional Airport", - "state": "MO", - "lat": 39.7252, - "lon": -91.4439 - }, - "KHFJ": { - "id": "KHFJ", - "city": "Monett", - "state": "MO", - "lat": 36.9062, - "lon": -94.0128 - }, - "KIRK": { - "id": "KIRK", - "city": "Kirksville, Kirksville Regional Airport", - "state": "MO", - "lat": 40.09722, - "lon": -92.54333 - }, - "KJEF": { - "id": "KJEF", - "city": "Jefferson City, Jefferson City Memorial Airport", - "state": "MO", - "lat": 38.59444, - "lon": -92.15583 - }, - "KJLN": { - "id": "KJLN", - "city": "Joplin, Joplin Regional Airport", - "state": "MO", - "lat": 37.15611, - "lon": -94.5005599 - }, - "KLBO": { - "id": "KLBO", - "city": "LEBANON", - "state": "MO", - "lat": 37.64833, - "lon": -92.6525 - }, - "KLRY": { - "id": "KLRY", - "city": "Harrisonville Lawrence Smith Memorial Airport", - "state": "MO", - "lat": 38.611, - "lon": -94.3421 - }, - "KLXT": { - "id": "KLXT", - "city": "Lee's Summit, Lee's Summit Municipal Airport", - "state": "MO", - "lat": 38.95972, - "lon": -94.37167 - }, - "KMAW": { - "id": "KMAW", - "city": "Malden Municipal Airport", - "state": "MO", - "lat": 36.6004999, - "lon": -89.9922 - }, - "KMBY": { - "id": "KMBY", - "city": "Omar N Bradley Airport", - "state": "MO", - "lat": 39.46341, - "lon": -92.42638 - }, - "KMCI": { - "id": "KMCI", - "city": "Kansas City, Kansas City International Airport", - "state": "MO", - "lat": 39.29722, - "lon": -94.73056 - }, - "KMHL": { - "id": "KMHL", - "city": "Marshall Memorial Municipal Airport", - "state": "MO", - "lat": 39.0955, - "lon": -93.2028 - }, - "KMKC": { - "id": "KMKC", - "city": "Kansas City, Kansas City Downtown Airport", - "state": "MO", - "lat": 39.12083, - "lon": -94.59694 - }, - "KMYJ": { - "id": "KMYJ", - "city": "Mexico Memorial Airport", - "state": "MO", - "lat": 39.1575, - "lon": -91.8182999 - }, - "KOZS": { - "id": "KOZS", - "city": "Camdenton Memorial Airport", - "state": "MO", - "lat": 37.9739999, - "lon": -92.6912 - }, - "KPCD": { - "id": "KPCD", - "city": "Perryville Regional Airport", - "state": "MO", - "lat": 37.86867, - "lon": -89.86214 - }, - "KPOF": { - "id": "KPOF", - "city": "Poplar Bluff, Poplar Bluff Municipal Airport", - "state": "MO", - "lat": 36.77056, - "lon": -90.32222 - }, - "KRAW": { - "id": "KRAW", - "city": "Warsaw Municipal Airport", - "state": "MO", - "lat": 38.3469, - "lon": -93.3454 - }, - "KRCM": { - "id": "KRCM", - "city": "Skyhaven Airport", - "state": "MO", - "lat": 38.7842, - "lon": -93.8028999 - }, - "KSET": { - "id": "KSET", - "city": "St. Charles, St. Charles County Smartt Airport", - "state": "MO", - "lat": 38.93056, - "lon": -90.4325 - }, - "KSGF": { - "id": "KSGF", - "city": "Springfield, Springfield Regional Airport", - "state": "MO", - "lat": 37.23972, - "lon": -93.38972 - }, - "KSIK": { - "id": "KSIK", - "city": "Sikeston Memorial Municipal Airport", - "state": "MO", - "lat": 36.8989, - "lon": -89.5618 - }, - "KSTJ": { - "id": "KSTJ", - "city": "St. Joseph, Rosecrans Memorial Airport", - "state": "MO", - "lat": 39.76806, - "lon": -94.90917 - }, - "KSTL": { - "id": "KSTL", - "city": "St. Louis Lambert International Airport", - "state": "MO", - "lat": 38.7525, - "lon": -90.37361 - }, - "KSUS": { - "id": "KSUS", - "city": "St. Louis, Spirit Of St. Louis Airport", - "state": "MO", - "lat": 38.65722, - "lon": -90.65583 - }, - "KSZL": { - "id": "KSZL", - "city": "Whiteman Air Force Base", - "state": "MO", - "lat": 38.73333, - "lon": -93.55 - }, - "KTBN": { - "id": "KTBN", - "city": "Fort Leonard Wood", - "state": "MO", - "lat": 37.73333, - "lon": -92.13333 - }, - "KTKX": { - "id": "KTKX", - "city": "Kennett - Kennett Memorial Airport", - "state": "MO", - "lat": 36.22256, - "lon": -90.03671 - }, - "KUNO": { - "id": "KUNO", - "city": "West Plains, West Plains Municipal Airport", - "state": "MO", - "lat": 36.87917, - "lon": -91.905 - }, - "KVER": { - "id": "KVER", - "city": "Jesse Viertel Memorial Airport", - "state": "MO", - "lat": 38.94672, - "lon": -92.68267 - }, - "KVIH": { - "id": "KVIH", - "city": "Rolla / Vichy, Rolla National Airport", - "state": "MO", - "lat": 38.13194, - "lon": -91.76528 - }, - "KAFP": { - "id": "KAFP", - "city": "Anson County Airport", - "state": "NC", - "lat": 35.01944, - "lon": -80.07836 - }, - "KAKH": { - "id": "KAKH", - "city": "Gastonia Municipal Airport", - "state": "NC", - "lat": 35.1968699, - "lon": -81.15545 - }, - "KASJ": { - "id": "KASJ", - "city": "Ahoskie, Tri-County Airport", - "state": "NC", - "lat": 36.2975, - "lon": -77.17083 - }, - "KAVL": { - "id": "KAVL", - "city": "Asheville, Asheville Regional Airport", - "state": "NC", - "lat": 35.43194, - "lon": -82.5375 - }, - "KBUY": { - "id": "KBUY", - "city": "Burlington Alamance Regional Airport", - "state": "NC", - "lat": 36.04753, - "lon": -79.47375 - }, - "KCLT": { - "id": "KCLT", - "city": "Charlotte, Charlotte / Douglas International Airport", - "state": "NC", - "lat": 35.21333, - "lon": -80.94861 - }, - "KCPC": { - "id": "KCPC", - "city": "Whiteville, Columbus County Municipal Airport", - "state": "NC", - "lat": 34.27278, - "lon": -78.715 - }, - "KCTZ": { - "id": "KCTZ", - "city": "Sampson County Airport", - "state": "NC", - "lat": 34.97522, - "lon": -78.36276 - }, - "KDPL": { - "id": "KDPL", - "city": "Duplin County Airport", - "state": "NC", - "lat": 34.99942, - "lon": -77.97995 - }, - "KECG": { - "id": "KECG", - "city": "Elizabeth City C/G Regional Airport", - "state": "NC", - "lat": 36.25771, - "lon": -76.1716 - }, - "KEDE": { - "id": "KEDE", - "city": "Edenton, Northeastern Regional Airport", - "state": "NC", - "lat": 36.02778, - "lon": -76.56722 - }, - "KEHO": { - "id": "KEHO", - "city": "Shelby Municipal Airport", - "state": "NC", - "lat": 35.2556299, - "lon": -81.59858 - }, - "KEQY": { - "id": "KEQY", - "city": "Monroe, Monroe Airport", - "state": "NC", - "lat": 35.01694, - "lon": -80.62056 - }, - "KETC": { - "id": "KETC", - "city": "Tarboro-Edgecombe Airport", - "state": "NC", - "lat": 35.9373, - "lon": -77.54648 - }, - "KEWN": { - "id": "KEWN", - "city": "New Bern, Craven County Regional Airport", - "state": "NC", - "lat": 35.0675, - "lon": -77.04722 - }, - "KEXX": { - "id": "KEXX", - "city": "Lexington, Davidson County Airport", - "state": "NC", - "lat": 35.78111, - "lon": -80.30389 - }, - "KEYF": { - "id": "KEYF", - "city": "Curtis L Brown Jr. Field Airport", - "state": "NC", - "lat": 34.60418, - "lon": -78.57902 - }, - "KFAY": { - "id": "KFAY", - "city": "Fayetteville, Fayetteville Regional Airport", - "state": "NC", - "lat": 34.98944, - "lon": -78.88 - }, - "KFBG": { - "id": "KFBG", - "city": "Fort Bragg / Simmons Army Airfield", - "state": "NC", - "lat": 35.1314, - "lon": -78.93158 - }, - "KFFA": { - "id": "KFFA", - "city": "Kill Devil Hills, First Flight Airport", - "state": "NC", - "lat": 36.01667, - "lon": -75.66667 - }, - "KFQD": { - "id": "KFQD", - "city": "Rutherfordton, Rutherford County-Marchman Field Airport", - "state": "NC", - "lat": 35.42833, - "lon": -81.935 - }, - "KGEV": { - "id": "KGEV", - "city": "Jefferson - Ashe County Airport", - "state": "NC", - "lat": 36.43333, - "lon": -81.41667 - }, - "KGSB": { - "id": "KGSB", - "city": "Seymour-Johnson Air Force Base", - "state": "NC", - "lat": 35.34457, - "lon": -77.94583 - }, - "KGSO": { - "id": "KGSO", - "city": "Greensboro, Piedmont Triad International Airport", - "state": "NC", - "lat": 36.0974999, - "lon": -79.94361 - }, - "KGWW": { - "id": "KGWW", - "city": "Goldsboro, Goldsboro-Wayne Municipal Airport", - "state": "NC", - "lat": 35.46056, - "lon": -77.965 - }, - "KHBI": { - "id": "KHBI", - "city": "Asheboro, Asheboro Municipal Airport", - "state": "NC", - "lat": 35.6538899, - "lon": -79.895 - }, - "KHFF": { - "id": "KHFF", - "city": "Mackall U. S. Army Airfield", - "state": "NC", - "lat": 35.03333, - "lon": -79.5 - }, - "KHKY": { - "id": "KHKY", - "city": "Hickory, Hickory Regional Airport", - "state": "NC", - "lat": 35.74222, - "lon": -81.38222 - }, - "KHNZ": { - "id": "KHNZ", - "city": "Henderson-Oxford Airport", - "state": "NC", - "lat": 36.36352, - "lon": -78.52889 - }, - "KHRJ": { - "id": "KHRJ", - "city": "Erwin, Harnett County Airport", - "state": "NC", - "lat": 35.37861, - "lon": -78.73361 - }, - "KHSE": { - "id": "KHSE", - "city": "Hatteras, Mitchell Field", - "state": "NC", - "lat": 35.23222, - "lon": -75.6225 - }, - "KILM": { - "id": "KILM", - "city": "Wilmington International Airport", - "state": "NC", - "lat": 34.26681, - "lon": -77.89987 - }, - "KINT": { - "id": "KINT", - "city": "Winston Salem, Smith Reynolds Airport", - "state": "NC", - "lat": 36.13333, - "lon": -80.22472 - }, - "KIPJ": { - "id": "KIPJ", - "city": "Lincolnton, Lincolnton-Lincoln County Regional Airport", - "state": "NC", - "lat": 35.48306, - "lon": -81.16139 - }, - "KISO": { - "id": "KISO", - "city": "Kinston, Kinston Regional Jetport at Stallings Field", - "state": "NC", - "lat": 35.3333299, - "lon": -77.61667 - }, - "KIXA": { - "id": "KIXA", - "city": "Halifax-Northampton Regional Airport", - "state": "NC", - "lat": 36.33, - "lon": -77.635 - }, - "KJNX": { - "id": "KJNX", - "city": "Smithfield, Johnston County Airport", - "state": "NC", - "lat": 35.54083, - "lon": -78.39028 - }, - "KJQF": { - "id": "KJQF", - "city": "Concord Regional Airport", - "state": "NC", - "lat": 35.3896299, - "lon": -80.70735 - }, - "KLHZ": { - "id": "KLHZ", - "city": "Franklin County Airport", - "state": "NC", - "lat": 36.02288, - "lon": -78.33405 - }, - "KMEB": { - "id": "KMEB", - "city": "Laurinburg Maxton Airport", - "state": "NC", - "lat": 34.79132, - "lon": -79.3683 - }, - "KMQI": { - "id": "KMQI", - "city": "Manteo / Dare County Regional", - "state": "NC", - "lat": 35.91667, - "lon": -75.7 - }, - "KMRH": { - "id": "KMRH", - "city": "Beaufort Smith Field", - "state": "NC", - "lat": 34.73259, - "lon": -76.6566 - }, - "KMRN": { - "id": "KMRN", - "city": "Morganton-Lenoir Airport", - "state": "NC", - "lat": 35.81922, - "lon": -81.60971 - }, - "KMWK": { - "id": "KMWK", - "city": "Mount Airy/Surry County Airport", - "state": "NC", - "lat": 36.45675, - "lon": -80.55483 - }, - "KNBT": { - "id": "KNBT", - "city": "Piney Island, Bt-11 Bombing Range", - "state": "NC", - "lat": 35.02222, - "lon": -76.4625 - }, - "KNCA": { - "id": "KNCA", - "city": "MCAS New River", - "state": "NC", - "lat": 34.70627, - "lon": -77.44066 - }, - "KNJM": { - "id": "KNJM", - "city": "Bogue Field Marine Corps Auxiliary Field", - "state": "NC", - "lat": 34.69403, - "lon": -77.02945 - }, - "KNKT": { - "id": "KNKT", - "city": "Cherry Point Marine Corps Air Station", - "state": "NC", - "lat": 34.89719, - "lon": -76.88135 - }, - "KOAJ": { - "id": "KOAJ", - "city": "Jacksonville, Albert J Ellis Airport", - "state": "NC", - "lat": 34.8333299, - "lon": -77.61667 - }, - "KOCW": { - "id": "KOCW", - "city": "Washington, Warren Field Airport", - "state": "NC", - "lat": 35.57056, - "lon": -77.0497199 - }, - "KONX": { - "id": "KONX", - "city": "Currituck, Currituck County Airport", - "state": "NC", - "lat": 36.39889, - "lon": -76.01611 - }, - "KPGV": { - "id": "KPGV", - "city": "Pitt-Greenville Airport", - "state": "NC", - "lat": 35.63742, - "lon": -77.38506 - }, - "KPOB": { - "id": "KPOB", - "city": "Pope Air Force Base", - "state": "NC", - "lat": 35.17531, - "lon": -79.00771 - }, - "KRCZ": { - "id": "KRCZ", - "city": "Rockingham-Hamlet Airport", - "state": "NC", - "lat": 34.8954499, - "lon": -79.75755 - }, - "KRDU": { - "id": "KRDU", - "city": "Raleigh / Durham, Raleigh-Durham International Airport", - "state": "NC", - "lat": 35.89223, - "lon": -78.78185 - }, - "KRHP": { - "id": "KRHP", - "city": "Andrews-Murphy Airport", - "state": "NC", - "lat": 35.19394, - "lon": -83.86182 - }, - "KRUQ": { - "id": "KRUQ", - "city": "Rowan County Airport", - "state": "NC", - "lat": 35.64417, - "lon": -80.52359 - }, - "KRWI": { - "id": "KRWI", - "city": "Rocky Mount, Rocky Mount-Wilson Regional Airport", - "state": "NC", - "lat": 35.8549999, - "lon": -77.89306 - }, - "KSCR": { - "id": "KSCR", - "city": "Siler City Municipal Airport", - "state": "NC", - "lat": 35.7043, - "lon": -79.5043 - }, - "KSIF": { - "id": "KSIF", - "city": "Reidsville, Rockingham County NC Shiloh Airport", - "state": "NC", - "lat": 36.43722, - "lon": -79.85083 - }, - "KSOP": { - "id": "KSOP", - "city": "Pinehurst/Southern Pines, Moore County Airport", - "state": "NC", - "lat": 35.23333, - "lon": -79.4 - }, - "KSUT": { - "id": "KSUT", - "city": "Brunswick County Airport", - "state": "NC", - "lat": 33.92921, - "lon": -78.07223 - }, - "KSVH": { - "id": "KSVH", - "city": "Statesville Municipal Airport", - "state": "NC", - "lat": 35.76362, - "lon": -80.9473 - }, - "KTDF": { - "id": "KTDF", - "city": "Roxboro, Person County Airport", - "state": "NC", - "lat": 36.2849999, - "lon": -78.98417 - }, - "KTNB": { - "id": "KTNB", - "city": "Watauga County Hospital Heliport", - "state": "NC", - "lat": 36.19856, - "lon": -81.65171 - }, - "KTTA": { - "id": "KTTA", - "city": "Sanford, Sanford-Lee County Regional Airport", - "state": "NC", - "lat": 35.5825, - "lon": -79.10139 - }, - "KUKF": { - "id": "KUKF", - "city": "North Wilkesboro, Wilkes County Airport", - "state": "NC", - "lat": 36.21667, - "lon": -81.08333 - }, - "KVUJ": { - "id": "KVUJ", - "city": "Albemarle, Stanly County Airport", - "state": "NC", - "lat": 35.41667, - "lon": -80.15083 - }, - "KABH": { - "id": "KABH", - "city": "ELLICOTT-B AFA", - "state": "CO", - "lat": 38.7578, - "lon": -104.3013 - }, - "KAEJ": { - "id": "KAEJ", - "city": "Central Colorado Regional Airport", - "state": "CO", - "lat": 38.81416, - "lon": -106.12069 - }, - "KAFF": { - "id": "KAFF", - "city": "Air Force Academy", - "state": "CO", - "lat": 38.96667, - "lon": -104.81667 - }, - "KAJZ": { - "id": "KAJZ", - "city": "Delta/Blake Field Airport", - "state": "CO", - "lat": 38.7868799, - "lon": -108.06584 - }, - "KAKO": { - "id": "KAKO", - "city": "Colorado Plains Regional Airport", - "state": "CO", - "lat": 40.17428, - "lon": -103.21459 - }, - "KALS": { - "id": "KALS", - "city": "San Luis Valley Regional Airport", - "state": "CO", - "lat": 37.43933, - "lon": -105.8618 - }, - "KANK": { - "id": "KANK", - "city": "Harriet Alexander Field Airport", - "state": "CO", - "lat": 38.53828, - "lon": -106.04864 - }, - "KAPA": { - "id": "KAPA", - "city": "Denver - Centennial Airport", - "state": "CO", - "lat": 39.55991, - "lon": -104.84841 - }, - "KASE": { - "id": "KASE", - "city": "Aspen-Pitkin County Airport", - "state": "CO", - "lat": 39.22992, - "lon": -106.87051 - }, - "KBDU": { - "id": "KBDU", - "city": "Boulder Municipal Airport", - "state": "CO", - "lat": 40.0394297, - "lon": -105.2258217 - }, - "KBJC": { - "id": "KBJC", - "city": "Broomfield / Jeffco", - "state": "CO", - "lat": 39.90085, - "lon": -105.10417 - }, - "KBKF": { - "id": "KBKF", - "city": "Buckley Air Force Base Airport", - "state": "CO", - "lat": 39.71331, - "lon": -104.75806 - }, - "KCAG": { - "id": "KCAG", - "city": "Craig-Moffat Airport", - "state": "CO", - "lat": 40.49297, - "lon": -107.52394 - }, - "KCCU": { - "id": "KCCU", - "city": "Copper Mountain - Red Cliff Pass", - "state": "CO", - "lat": 39.47523, - "lon": -106.15228 - }, - "KCEZ": { - "id": "KCEZ", - "city": "Cortez-Montezuma County Airport", - "state": "CO", - "lat": 37.30706, - "lon": -108.62644 - }, - "KCFO": { - "id": "KCFO", - "city": "Colorado Air and Space Port Airport", - "state": "CO", - "lat": 39.78419, - "lon": -104.53764 - }, - "KCOS": { - "id": "KCOS", - "city": "City of Colorado Springs Municipal Airport", - "state": "CO", - "lat": 38.8094899, - "lon": -104.68873 - }, - "KCPW": { - "id": "KCPW", - "city": "Pagosa Springs, Wolf Creek Pass", - "state": "CO", - "lat": 37.45139, - "lon": -106.80028 - }, - "KCWN": { - "id": "KCWN", - "city": "Cheyenne Mountain", - "state": "CO", - "lat": 38.7434299, - "lon": -104.84334 - }, - "KDEN": { - "id": "KDEN", - "city": "Denver, Denver International Airport", - "state": "CO", - "lat": 39.84658, - "lon": -104.65622 - }, - "KDRO": { - "id": "KDRO", - "city": "Durango-La Plata County Airport", - "state": "CO", - "lat": 37.14312, - "lon": -107.76023 - }, - "KEEO": { - "id": "KEEO", - "city": "Meeker Airport", - "state": "CO", - "lat": 40.0444, - "lon": -107.88832 - }, - "KEGE": { - "id": "KEGE", - "city": "Eagle County Regional", - "state": "CO", - "lat": 39.65, - "lon": -106.91667 - }, - "KEIK": { - "id": "KEIK", - "city": "Erie Municipal Airport", - "state": "CO", - "lat": 40.01169, - "lon": -105.05033 - }, - "KFCS": { - "id": "KFCS", - "city": "Butts Army Airfield (Fort Carson)", - "state": "CO", - "lat": 38.68312, - "lon": -104.75977 - }, - "KFLY": { - "id": "KFLY", - "city": "Meadow Lake Airport", - "state": "CO", - "lat": 38.94391, - "lon": -104.5684 - }, - "KFMM": { - "id": "KFMM", - "city": "Fort Morgan Municipal Airport", - "state": "CO", - "lat": 40.33148, - "lon": -103.80704 - }, - "KFNL": { - "id": "KFNL", - "city": "Fort Collins/Loveland - Northern Colorado Regional Airport", - "state": "CO", - "lat": 40.45, - "lon": -105.01667 - }, - "KGJT": { - "id": "KGJT", - "city": "Grand Junction Regional Airport", - "state": "CO", - "lat": 39.13389, - "lon": -108.53861 - }, - "KGNB": { - "id": "KGNB", - "city": "Granby-Grand County Airport", - "state": "CO", - "lat": 40.09006, - "lon": -105.91664 - }, - "KGUC": { - "id": "KGUC", - "city": "Gunnison, Gunnison-Crested Butte Regional Airport", - "state": "CO", - "lat": 38.53333, - "lon": -106.93333 - }, - "KGXY": { - "id": "KGXY", - "city": "Greeley, Greeley-Weld County Airport", - "state": "CO", - "lat": 40.43333, - "lon": -104.63333 - }, - "KHDN": { - "id": "KHDN", - "city": "Hayden, Yampa Valley Airport", - "state": "CO", - "lat": 40.48333, - "lon": -107.2166699 - }, - "KHEQ": { - "id": "KHEQ", - "city": "Holyoke Airport", - "state": "CO", - "lat": 40.57155, - "lon": -102.27676 - }, - "KITR": { - "id": "KITR", - "city": "Burlington - Carson County Airport", - "state": "CO", - "lat": 39.24149, - "lon": -102.2818999 - }, - "KLAA": { - "id": "KLAA", - "city": "Lamar Municipal Airport", - "state": "CO", - "lat": 38.0717799, - "lon": -102.68745 - }, - "KLHX": { - "id": "KLHX", - "city": "La Junta Municipal Airport", - "state": "CO", - "lat": 38.04949, - "lon": -103.51334 - }, - "KLIC": { - "id": "KLIC", - "city": "Limon Municipal Airport", - "state": "CO", - "lat": 39.27334, - "lon": -103.66738 - }, - "KLMO": { - "id": "KLMO", - "city": "Vance Brand Airport", - "state": "CO", - "lat": 40.16115, - "lon": -105.16042 - }, - "KLXV": { - "id": "KLXV", - "city": "Leadville, Lake County Airport", - "state": "CO", - "lat": 39.22806, - "lon": -106.31611 - }, - "KMNH": { - "id": "KMNH", - "city": "Elbert Mountain - Monument Pass", - "state": "CO", - "lat": 39.22317, - "lon": -104.6422599 - }, - "KMTJ": { - "id": "KMTJ", - "city": "Montrose, Montrose Regional Airport", - "state": "CO", - "lat": 38.505, - "lon": -107.8975 - }, - "KMYP": { - "id": "KMYP", - "city": "Salida - Monarch Pass", - "state": "CO", - "lat": 38.4972, - "lon": -106.3197 - }, - "KPSO": { - "id": "KPSO", - "city": "Stevens Field, Pagosa Springs", - "state": "CO", - "lat": 37.2862, - "lon": -107.056 - }, - "KPUB": { - "id": "KPUB", - "city": "Pueblo Memorial Airport", - "state": "CO", - "lat": 38.28869, - "lon": -104.5057 - }, - "KRCV": { - "id": "KRCV", - "city": "Astronaut Kent Rominger - Del Norte", - "state": "CO", - "lat": 37.7138, - "lon": -106.352 - }, - "KRIL": { - "id": "KRIL", - "city": "Garfield County Regional Airport", - "state": "CO", - "lat": 39.52793, - "lon": -107.71961 - }, - "KSBS": { - "id": "KSBS", - "city": "Steamboat Springs", - "state": "CO", - "lat": 40.5153, - "lon": -106.86767 - }, - "KSPD": { - "id": "KSPD", - "city": "Springfield, Comanche National Grassland", - "state": "CO", - "lat": 37.28333, - "lon": -102.61667 - }, - "KSTK": { - "id": "KSTK", - "city": "Sterling Municipal Airport", - "state": "CO", - "lat": 40.61331, - "lon": -103.26109 - }, - "KTAD": { - "id": "KTAD", - "city": "Perry Stokes Airport", - "state": "CO", - "lat": 37.26218, - "lon": -104.33184 - }, - "KTEX": { - "id": "KTEX", - "city": "Telluride, Telluride Regional Airport", - "state": "CO", - "lat": 37.95389, - "lon": -107.90861 - }, - "KVTP": { - "id": "KVTP", - "city": "La Veta Mountain, La Veta Pass", - "state": "CO", - "lat": 37.50111, - "lon": -105.16694 - }, - "KBHK": { - "id": "KBHK", - "city": "Baker, Baker Municipal Airport", - "state": "MT", - "lat": 46.34778, - "lon": -104.2574999 - }, - "KBIL": { - "id": "KBIL", - "city": "Billings, Billings Logan International Airport", - "state": "MT", - "lat": 45.80694, - "lon": -108.54222 - }, - "KBTM": { - "id": "KBTM", - "city": "Butte, Bert Mooney Airport", - "state": "MT", - "lat": 45.95472, - "lon": -112.4975 - }, - "KBZN": { - "id": "KBZN", - "city": "Bozeman, Gallatin Field", - "state": "MT", - "lat": 45.78806, - "lon": -111.16083 - }, - "KCII": { - "id": "KCII", - "city": "Choteau Airport", - "state": "MT", - "lat": 47.82835, - "lon": -112.16834 - }, - "KCTB": { - "id": "KCTB", - "city": "Cut Bank, Cut Bank Municipal Airport", - "state": "MT", - "lat": 48.60833, - "lon": -112.37611 - }, - "KDLN": { - "id": "KDLN", - "city": "Dillon, Dillon Airport", - "state": "MT", - "lat": 45.2575, - "lon": -112.55444 - }, - "KEKS": { - "id": "KEKS", - "city": "Ennis - Big Sky Airport", - "state": "MT", - "lat": 45.27436, - "lon": -111.64886 - }, - "KGDV": { - "id": "KGDV", - "city": "Glendive, Dawson Community Airport", - "state": "MT", - "lat": 47.13333, - "lon": -104.8 - }, - "KGFA": { - "id": "KGFA", - "city": "Malmstrom Air Force Base", - "state": "MT", - "lat": 47.5, - "lon": -111.18333 - }, - "KGGW": { - "id": "KGGW", - "city": "Glasgow, Glasgow International Airport", - "state": "MT", - "lat": 48.21389, - "lon": -106.62139 - }, - "KGPI": { - "id": "KGPI", - "city": "Kalispell, Glacier Park International Airport", - "state": "MT", - "lat": 48.30417, - "lon": -114.26361 - }, - "KGTF": { - "id": "KGTF", - "city": "Great Falls, Great Falls International Airport", - "state": "MT", - "lat": 47.47333, - "lon": -111.38222 - }, - "KHLN": { - "id": "KHLN", - "city": "Helena Regional Airport", - "state": "MT", - "lat": 46.60445, - "lon": -111.9892 - }, - "KHVR": { - "id": "KHVR", - "city": "Havre, Havre City-County Airport", - "state": "MT", - "lat": 48.54278, - "lon": -109.76333 - }, - "KJDN": { - "id": "KJDN", - "city": "Jordan, Jordan Airport", - "state": "MT", - "lat": 47.32583, - "lon": -106.9475 - }, - "KLVM": { - "id": "KLVM", - "city": "Livingston, Mission Field Airport", - "state": "MT", - "lat": 45.69944, - "lon": -110.44833 - }, - "KLWT": { - "id": "KLWT", - "city": "Lewistown, Lewistown Municipal Airport", - "state": "MT", - "lat": 47.0491699, - "lon": -109.46639 - }, - "KMLP": { - "id": "KMLP", - "city": "Mullan Pass, Mullan Pass Vor", - "state": "MT", - "lat": 47.45417, - "lon": -115.66972 - }, - "KMLS": { - "id": "KMLS", - "city": "Miles City, Frank Wiley Field Airport", - "state": "MT", - "lat": 46.42806, - "lon": -105.88639 - }, - "KMSO": { - "id": "KMSO", - "city": "Missoula, Missoula International Airport", - "state": "MT", - "lat": 46.92083, - "lon": -114.0925 - }, - "KMVH": { - "id": "KMVH", - "city": "N BAR Ranch Airport", - "state": "MT", - "lat": 46.8381, - "lon": -108.9368 - }, - "KOLF": { - "id": "KOLF", - "city": "Wolf Point, Clayton Airport", - "state": "MT", - "lat": 48.09444, - "lon": -105.57722 - }, - "KPWD": { - "id": "KPWD", - "city": "Sher-Wood Airport", - "state": "MT", - "lat": 48.789, - "lon": -104.52297 - }, - "KRPX": { - "id": "KRPX", - "city": "ROUNDUP", - "state": "MT", - "lat": 46.47499, - "lon": -108.54339 - }, - "KRVF": { - "id": "KRVF", - "city": "Ruby Valley Field Airport", - "state": "MT", - "lat": 45.53542, - "lon": -112.30228 - }, - "KSDY": { - "id": "KSDY", - "city": "Sidney-Richland", - "state": "MT", - "lat": 47.7, - "lon": -104.2 - }, - "KTHM": { - "id": "KTHM", - "city": "THOMPSON FALLS", - "state": "MT", - "lat": 47.5735, - "lon": -115.28066 - }, - "KWYS": { - "id": "KWYS", - "city": "West Yellowstone", - "state": "MT", - "lat": 44.68333, - "lon": -111.11667 - }, - "KJSY": { - "id": "KJSY", - "city": "Joseph State Airport AWOS", - "state": "OR", - "lat": 45.355889, - "lon": -117.254083 - }, - "KLGD": { - "id": "KLGD", - "city": "La Grande/Union County Airport", - "state": "OR", - "lat": 45.29066, - "lon": -118.00884 - }, - "KLKV": { - "id": "KLKV", - "city": "Lake County Airport", - "state": "OR", - "lat": 42.15664, - "lon": -120.39721 - }, - "KLMT": { - "id": "KLMT", - "city": "Klamath Falls International Airport", - "state": "OR", - "lat": 42.14703, - "lon": -121.72548 - }, - "KMEH": { - "id": "KMEH", - "city": "Meacham", - "state": "OR", - "lat": 45.51176, - "lon": -118.42466 - }, - "KMFR": { - "id": "KMFR", - "city": "Rogue Valley International Airport", - "state": "OR", - "lat": 42.37503, - "lon": -122.87696 - }, - "KMMV": { - "id": "KMMV", - "city": "McMinnville, McMinnville Municipal Airport", - "state": "OR", - "lat": 45.19611, - "lon": -123.13222 - }, - "KONO": { - "id": "KONO", - "city": "Ontario Municipal Airport", - "state": "OR", - "lat": 44.01424, - "lon": -117.00808 - }, - "KONP": { - "id": "KONP", - "city": "Newport, Newport Municipal Airport", - "state": "OR", - "lat": 44.58028, - "lon": -124.05806 - }, - "KOTH": { - "id": "KOTH", - "city": "Southwest Oregon Regional Airport", - "state": "OR", - "lat": 43.41948, - "lon": -124.2437 - }, - "KPDT": { - "id": "KPDT", - "city": "Eastern Oregon Regional Airport at Pendleton", - "state": "OR", - "lat": 45.69757, - "lon": -118.83444 - }, - "KPDX": { - "id": "KPDX", - "city": "Portland, Portland International Airport", - "state": "OR", - "lat": 45.59578, - "lon": -122.60917 - }, - "KRBG": { - "id": "KRBG", - "city": "Roseburg Regional Airport", - "state": "OR", - "lat": 43.23368, - "lon": -123.3577 - }, - "KRDM": { - "id": "KRDM", - "city": "Redmond Roberts Field", - "state": "OR", - "lat": 44.25588, - "lon": -121.14059 - }, - "KREO": { - "id": "KREO", - "city": "Rome", - "state": "OR", - "lat": 42.5901799, - "lon": -117.86458 - }, - "KSLE": { - "id": "KSLE", - "city": "Salem - McNary Field", - "state": "OR", - "lat": 44.90493, - "lon": -123.00096 - }, - "KSPB": { - "id": "KSPB", - "city": "Scappoose Industrial Airpark", - "state": "OR", - "lat": 45.7691, - "lon": -122.86365 - }, - "KSXT": { - "id": "KSXT", - "city": "Sexton Summit", - "state": "OR", - "lat": 42.6, - "lon": -123.3656 - }, - "KTMK": { - "id": "KTMK", - "city": "Tillamook, Tillamook Airport", - "state": "OR", - "lat": 45.4180599, - "lon": -123.81444 - }, - "KTTD": { - "id": "KTTD", - "city": "Portland, Portland-Troutdale Airport", - "state": "OR", - "lat": 45.55111, - "lon": -122.40889 - }, - "KUAO": { - "id": "KUAO", - "city": "Aurora State Airport", - "state": "OR", - "lat": 45.24658, - "lon": -122.77095 - }, - "PARO": { - "id": "PARO", - "city": "PARKDALE", - "state": "OR", - "lat": 45.54444, - "lon": -121.61667 - }, - "PCYO": { - "id": "PCYO", - "city": "PRARIE CITY", - "state": "OR", - "lat": 44.44083, - "lon": -118.62778 - }, - "PNGO": { - "id": "PNGO", - "city": "PINEGROVE", - "state": "OR", - "lat": 45.65222, - "lon": -121.50917 - }, - "POBO": { - "id": "POBO", - "city": "POWELL BUTTE", - "state": "OR", - "lat": 44.24833, - "lon": -120.94972 - }, - "KALK": { - "id": "KALK", - "city": "Pioneer Airfield", - "state": "AZ", - "lat": 31.60564, - "lon": -110.4281 - }, - "KAVQ": { - "id": "KAVQ", - "city": "Tucson Marana Regional Airport", - "state": "AZ", - "lat": 32.4096, - "lon": -111.2184 - }, - "KAZC": { - "id": "KAZC", - "city": "Colorado City, Colorado City Municipal Airport", - "state": "AZ", - "lat": 36.95, - "lon": -113 - }, - "KBXK": { - "id": "KBXK", - "city": "Buckeye Municipal Airport", - "state": "AZ", - "lat": 33.4204, - "lon": -112.6862 - }, - "KCGZ": { - "id": "KCGZ", - "city": "Casa Grande, Casa Grande Municipal Airport", - "state": "AZ", - "lat": 32.95, - "lon": -111.76667 - }, - "KCHD": { - "id": "KCHD", - "city": "Chandler, Chandler Municipal Airport", - "state": "AZ", - "lat": 33.26917, - "lon": -111.81111 - }, - "KCMR": { - "id": "KCMR", - "city": "Williams/Clark Memorial Airport", - "state": "AZ", - "lat": 35.3054721, - "lon": -112.1943889 - }, - "KDMA": { - "id": "KDMA", - "city": "Davis-Monthan Air Force Base", - "state": "AZ", - "lat": 32.16667, - "lon": -110.88333 - }, - "KDVT": { - "id": "KDVT", - "city": "Phoenix, Phoenix-Deer Valley Municipal Airport", - "state": "AZ", - "lat": 33.69026, - "lon": -112.06618 - }, - "KFFZ": { - "id": "KFFZ", - "city": "Mesa / Falcon Field", - "state": "AZ", - "lat": 33.46667, - "lon": -111.73333 - }, - "KFHU": { - "id": "KFHU", - "city": "Fort Huachuca, Libby AAF Ft Huachuca", - "state": "AZ", - "lat": 31.58333, - "lon": -110.33333 - }, - "KFLG": { - "id": "KFLG", - "city": "Flagstaff Pulliam Airport", - "state": "AZ", - "lat": 35.1443299, - "lon": -111.66637 - }, - "KGCN": { - "id": "KGCN", - "city": "Grand Canyon National Park Airport", - "state": "AZ", - "lat": 35.94582, - "lon": -112.15538 - }, - "KGEU": { - "id": "KGEU", - "city": "Glendale, Glendale Municipal Airport", - "state": "AZ", - "lat": 33.52722, - "lon": -112.29528 - }, - "KGXF": { - "id": "KGXF", - "city": "Gila Bend Air Force Auxiliary Field", - "state": "AZ", - "lat": 32.8875, - "lon": -112.72 - }, - "KGYR": { - "id": "KGYR", - "city": "Goodyear Municipal", - "state": "AZ", - "lat": 33.41667, - "lon": -112.38333 - }, - "KHII": { - "id": "KHII", - "city": "Havasu City Airport", - "state": "AZ", - "lat": 34.56595, - "lon": -114.35224 - }, - "KIFP": { - "id": "KIFP", - "city": "Bullhead City, Laughlin/Bullhead International Airport", - "state": "AZ", - "lat": 35.1575, - "lon": -114.55944 - }, - "KIGM": { - "id": "KIGM", - "city": "Kingman, Kingman Airport", - "state": "AZ", - "lat": 35.2577799, - "lon": -113.93306 - }, - "KINW": { - "id": "KINW", - "city": "Winslow, Winslow Municipal Airport", - "state": "AZ", - "lat": 35.02806, - "lon": -110.72083 - }, - "KIWA": { - "id": "KIWA", - "city": "Phoenix-Mesa Gateway Airport", - "state": "AZ", - "lat": 33.31667, - "lon": -111.65 - }, - "KJTC": { - "id": "KJTC", - "city": "Springerville Municipal Airport", - "state": "AZ", - "lat": 34.1293999, - "lon": -109.3109 - }, - "KLGF": { - "id": "KLGF", - "city": "Laguna Army Airfield", - "state": "AZ", - "lat": 32.86459, - "lon": -114.39298 - }, - "KLUF": { - "id": "KLUF", - "city": "Luke Air Force Base / Phoenix", - "state": "AZ", - "lat": 33.53333, - "lon": -112.38333 - }, - "KMZJ": { - "id": "KMZJ", - "city": "Pinal Airpark", - "state": "AZ", - "lat": 32.50983, - "lon": -111.32533 - }, - "KNOZ": { - "id": "KNOZ", - "city": "Yuma Auxiliary Airfield", - "state": "AZ", - "lat": 32.5, - "lon": -114.45 - }, - "KNYL": { - "id": "KNYL", - "city": "Yuma, Marine Corps Air Station", - "state": "AZ", - "lat": 32.6594399, - "lon": -114.59306 - }, - "KOLS": { - "id": "KOLS", - "city": "Nogales, Nogales International Airport", - "state": "AZ", - "lat": 31.42083, - "lon": -110.84583 - }, - "KPAN": { - "id": "KPAN", - "city": "Payson Airport", - "state": "AZ", - "lat": 34.2568364, - "lon": -111.3392558 - }, - "KPGA": { - "id": "KPGA", - "city": "Page, Page Municipal Airport", - "state": "AZ", - "lat": 36.92056, - "lon": -111.44806 - }, - "KPHX": { - "id": "KPHX", - "city": "Phoenix, Phoenix Sky Harbor International Airport", - "state": "AZ", - "lat": 33.427799, - "lon": -112.003465 - }, - "KPRC": { - "id": "KPRC", - "city": "Prescott, Love Field", - "state": "AZ", - "lat": 34.64917, - "lon": -112.42222 - }, - "KRQE": { - "id": "KRQE", - "city": "Window Rock, Window Rock Airport", - "state": "AZ", - "lat": 35.65, - "lon": -109.06667 - }, - "KRYN": { - "id": "KRYN", - "city": "Tucson Ryan Field Airport", - "state": "AZ", - "lat": 32.1422, - "lon": -111.1746 - }, - "KSAD": { - "id": "KSAD", - "city": "Safford, Safford Municipal Airport", - "state": "AZ", - "lat": 32.85722, - "lon": -109.63556 - }, - "KSDL": { - "id": "KSDL", - "city": "Scottsdale Airport", - "state": "AZ", - "lat": 33.61235, - "lon": -111.92316 - }, - "KSEZ": { - "id": "KSEZ", - "city": "Sedona Airport", - "state": "AZ", - "lat": 34.85, - "lon": -111.78333 - }, - "KSJN": { - "id": "KSJN", - "city": "St. Johns, St. Johns Industrial Airpark", - "state": "AZ", - "lat": 34.51833, - "lon": -109.37917 - }, - "KSOW": { - "id": "KSOW", - "city": "Show Low, Show Low Regional Airport", - "state": "AZ", - "lat": 34.26528, - "lon": -110.00556 - }, - "KTUS": { - "id": "KTUS", - "city": "Tucson, Tucson International Airport", - "state": "AZ", - "lat": 32.13153, - "lon": -110.95635 - }, - "KTYL": { - "id": "KTYL", - "city": "Taylor Airport", - "state": "AZ", - "lat": 34.45272, - "lon": -110.11503 - }, - "KALW": { - "id": "KALW", - "city": "Walla Walla Regional Airport", - "state": "WA", - "lat": 46.09462, - "lon": -118.2858 - }, - "KAWO": { - "id": "KAWO", - "city": "Arlington Municipal Airport", - "state": "WA", - "lat": 48.1584999, - "lon": -122.15909 - }, - "KBFI": { - "id": "KBFI", - "city": "Boeing Field - King County International Airport", - "state": "WA", - "lat": 47.54548, - "lon": -122.3147 - }, - "KBLI": { - "id": "KBLI", - "city": "Bellingham, Bellingham International Airport", - "state": "WA", - "lat": 48.79911, - "lon": -122.54064 - }, - "KBVS": { - "id": "KBVS", - "city": "Burlington/Mount Vernon, Skagit Regional Airport", - "state": "WA", - "lat": 48.47083, - "lon": -122.42083 - }, - "KCLM": { - "id": "KCLM", - "city": "Port Angeles Fairchild International Airport", - "state": "WA", - "lat": 48.12194, - "lon": -123.50661 - }, - "KCLS": { - "id": "KCLS", - "city": "Chehalis-Centralia Airport", - "state": "WA", - "lat": 46.677, - "lon": -122.9827 - }, - "KDEW": { - "id": "KDEW", - "city": "Deer Park, Deer Park Airport", - "state": "WA", - "lat": 47.97417, - "lon": -117.42833 - }, - "KDLS": { - "id": "KDLS", - "city": "The Dalles Municipal Airport", - "state": "WA", - "lat": 45.61901, - "lon": -121.16572 - }, - "KEAT": { - "id": "KEAT", - "city": "Wenatchee - Pangborn Memorial Airport", - "state": "WA", - "lat": 47.39749, - "lon": -120.20121 - }, - "KELN": { - "id": "KELN", - "city": "Ellensburg, Ellensburg Bowers Field", - "state": "WA", - "lat": 47.0337699, - "lon": -120.53132 - }, - "KEPH": { - "id": "KEPH", - "city": "Ephrata, Ephrata Municipal Airport", - "state": "WA", - "lat": 47.3075, - "lon": -119.51583 - }, - "KFHR": { - "id": "KFHR", - "city": "Friday Harbor Airport", - "state": "WA", - "lat": 48.52, - "lon": -123.02637 - }, - "KFLW": { - "id": "KFLW", - "city": "Kettle Falls", - "state": "WA", - "lat": 48.595, - "lon": -118.12417 - }, - "KGEG": { - "id": "KGEG", - "city": "Spokane, Spokane International Airport", - "state": "WA", - "lat": 47.62139, - "lon": -117.52778 - }, - "KGRF": { - "id": "KGRF", - "city": "Fort Lewis / Gray U. S. Army Airfield", - "state": "WA", - "lat": 47.11667, - "lon": -122.55 - }, - "KHQM": { - "id": "KHQM", - "city": "Hoquiam, Bowerman Airport", - "state": "WA", - "lat": 46.97111, - "lon": -123.92 - }, - "KKLS": { - "id": "KKLS", - "city": "Southwest Washington Regional Airport", - "state": "WA", - "lat": 46.11553, - "lon": -122.89273 - }, - "KMWH": { - "id": "KMWH", - "city": "Grant County Airport", - "state": "WA", - "lat": 47.19299, - "lon": -119.31451 - }, - "KNOW": { - "id": "KNOW", - "city": "Port Angeles Coast Guard Air Station", - "state": "WA", - "lat": 48.13333, - "lon": -123.4 - }, - "KNUW": { - "id": "KNUW", - "city": "Whidbey Island Naval Air Station - Ault Field", - "state": "WA", - "lat": 48.35525, - "lon": -122.66352 - }, - "KOLM": { - "id": "KOLM", - "city": "Olympia, Olympia Airport", - "state": "WA", - "lat": 46.97333, - "lon": -122.90333 - }, - "KOMK": { - "id": "KOMK", - "city": "Omak Airport", - "state": "WA", - "lat": 48.46116, - "lon": -119.52086 - }, - "KORS": { - "id": "KORS", - "city": "Eastsound, Orcas Island Airport", - "state": "WA", - "lat": 48.70806, - "lon": -122.91028 - }, - "KPAE": { - "id": "KPAE", - "city": "Everett Snohomish County", - "state": "WA", - "lat": 47.92331, - "lon": -122.28305 - }, - "KPLU": { - "id": "KPLU", - "city": "Pierce County-Thun Field", - "state": "WA", - "lat": 47.104, - "lon": -122.287 - }, - "KPSC": { - "id": "KPSC", - "city": "Tri-Cities Airport", - "state": "WA", - "lat": 46.26955, - "lon": -119.11813 - }, - "KPUW": { - "id": "KPUW", - "city": "Pullman / Moscow Regional Airport", - "state": "WA", - "lat": 46.74377, - "lon": -117.11579 - }, - "KPWT": { - "id": "KPWT", - "city": "Bremerton, Bremerton National Airport", - "state": "WA", - "lat": 47.5, - "lon": -122.75 - }, - "KRLD": { - "id": "KRLD", - "city": "Richland Airport", - "state": "WA", - "lat": 46.30859, - "lon": -119.3058 - }, - "KRNT": { - "id": "KRNT", - "city": "Renton Municipal Airport", - "state": "WA", - "lat": 47.49509, - "lon": -122.21437 - }, - "KSEA": { - "id": "KSEA", - "city": "Seattle, Seattle-Tacoma International Airport", - "state": "WA", - "lat": 47.4447199, - "lon": -122.31361 - }, - "KSFF": { - "id": "KSFF", - "city": "Spokane, Felts Field", - "state": "WA", - "lat": 47.68556, - "lon": -117.32028 - }, - "KSHN": { - "id": "KSHN", - "city": "Shelton, Shelton Sanderson Field", - "state": "WA", - "lat": 47.23806, - "lon": -123.14083 - }, - "KSKA": { - "id": "KSKA", - "city": "Fairchild Air Force Base", - "state": "WA", - "lat": 47.61667, - "lon": -117.65 - }, - "KSMP": { - "id": "KSMP", - "city": "Stampede Pass", - "state": "WA", - "lat": 47.27648, - "lon": -121.33817 - }, - "KTCM": { - "id": "KTCM", - "city": "Tacoma / McChord Air Force Base", - "state": "WA", - "lat": 47.15, - "lon": -122.48333 - }, - "KTIW": { - "id": "KTIW", - "city": "Tacoma, Tacoma Narrows Airport", - "state": "WA", - "lat": 47.2675, - "lon": -122.57611 - }, - "KUIL": { - "id": "KUIL", - "city": "Quillayute, Quillayute State Airport", - "state": "WA", - "lat": 47.9375, - "lon": -124.555 - }, - "KVUO": { - "id": "KVUO", - "city": "Pearson Airfield", - "state": "WA", - "lat": 45.62103, - "lon": -122.65419 - }, - "KYKM": { - "id": "KYKM", - "city": "Yakima Air Terminal - McAllister Field", - "state": "WA", - "lat": 46.56402, - "lon": -120.53484 - }, - "KAAF": { - "id": "KAAF", - "city": "Apalachicola, Apalachicola", - "state": "FL", - "lat": 29.72694, - "lon": -85.02472 - }, - "KAPF": { - "id": "KAPF", - "city": "Naples, Naples Municipal Airport", - "state": "FL", - "lat": 26.15, - "lon": -81.76667 - }, - "KBCT": { - "id": "KBCT", - "city": "Boca Raton, Boca Raton Airport", - "state": "FL", - "lat": 26.3786099, - "lon": -80.10778 - }, - "KBKV": { - "id": "KBKV", - "city": "Brooksville-Tampa Bay Regional Airport", - "state": "FL", - "lat": 28.47361, - "lon": -82.45444 - }, - "KBOW": { - "id": "KBOW", - "city": "Bartow Municipal", - "state": "FL", - "lat": 27.95, - "lon": -81.78333 - }, - "KCEW": { - "id": "KCEW", - "city": "Crestview, Sikes Airport", - "state": "FL", - "lat": 30.77222, - "lon": -86.52 - }, - "KCGC": { - "id": "KCGC", - "city": "Crystal River Airport", - "state": "FL", - "lat": 28.8673, - "lon": -82.5712999 - }, - "KCLW": { - "id": "KCLW", - "city": "Clearwater Air Park", - "state": "FL", - "lat": 27.9742, - "lon": -82.7563 - }, - "KCOF": { - "id": "KCOF", - "city": "Cocoa - Patrick Air Force Base", - "state": "FL", - "lat": 28.24219, - "lon": -80.60799 - }, - "KCRG": { - "id": "KCRG", - "city": "Jacksonville Craig Municipal Airport", - "state": "FL", - "lat": 30.33709, - "lon": -81.51275 - }, - "KCTY": { - "id": "KCTY", - "city": "Cross City Airport", - "state": "FL", - "lat": 29.633326, - "lon": -83.105458 - }, - "KDAB": { - "id": "KDAB", - "city": "Daytona Beach International Airport", - "state": "FL", - "lat": 29.17354, - "lon": -81.07186 - }, - "KDED": { - "id": "KDED", - "city": "DeLand Municipal Airport", - "state": "FL", - "lat": 29.067, - "lon": -81.2837 - }, - "KDTS": { - "id": "KDTS", - "city": "Destin, Destin-Ft. Walton Beach Airport", - "state": "FL", - "lat": 30.39333, - "lon": -86.4675 - }, - "KECP": { - "id": "KECP", - "city": "Panama City - Northwest Florida Beaches International Airport", - "state": "FL", - "lat": 30.3582, - "lon": -85.7955999 - }, - "KEGI": { - "id": "KEGI", - "city": "Duke Field / Eglin Auxiliary", - "state": "FL", - "lat": 30.65, - "lon": -86.51667 - }, - "KEVB": { - "id": "KEVB", - "city": "New Smyrna Beach Municipal Airport", - "state": "FL", - "lat": 29.05687, - "lon": -80.94909 - }, - "KEYW": { - "id": "KEYW", - "city": "Key West International Airport", - "state": "FL", - "lat": 24.55707, - "lon": -81.75539 - }, - "KFHB": { - "id": "KFHB", - "city": "Fernandina Beach Municipal Airport", - "state": "FL", - "lat": 30.61183, - "lon": -81.46119 - }, - "KFIN": { - "id": "KFIN", - "city": "Flagler County Airport", - "state": "FL", - "lat": 29.4657, - "lon": -81.20872 - }, - "KFLL": { - "id": "KFLL", - "city": "Fort Lauderdale/Hollywood International Airport", - "state": "FL", - "lat": 26.07874, - "lon": -80.1622 - }, - "KFMY": { - "id": "KFMY", - "city": "Fort Myers, Page Field", - "state": "FL", - "lat": 26.58417, - "lon": -81.8625 - }, - "KFPR": { - "id": "KFPR", - "city": "Fort Pierce, St. Lucie County International Airport", - "state": "FL", - "lat": 27.49806, - "lon": -80.37667 - }, - "KFPY": { - "id": "KFPY", - "city": "Perry-Foley Airport", - "state": "FL", - "lat": 30.07081, - "lon": -83.58154 - }, - "KFXE": { - "id": "KFXE", - "city": "Fort Lauderdale, Fort Lauderdale Executive Airport", - "state": "FL", - "lat": 26.2, - "lon": -80.18333 - }, - "KGIF": { - "id": "KGIF", - "city": "Winter Havens Gilbert Airport", - "state": "FL", - "lat": 28.06138, - "lon": -81.75684 - }, - "KGNV": { - "id": "KGNV", - "city": "Gainesville, Gainesville Regional Airport", - "state": "FL", - "lat": 29.69194, - "lon": -82.27556 - }, - "KHRT": { - "id": "KHRT", - "city": "Hurlburt Field", - "state": "FL", - "lat": 30.41667, - "lon": -86.68333 - }, - "KHST": { - "id": "KHST", - "city": "Homestead Air Reserve Base", - "state": "FL", - "lat": 25.4948799, - "lon": -80.37324 - }, - "KHWO": { - "id": "KHWO", - "city": "Hollywood, North Perry Airport", - "state": "FL", - "lat": 25.99889, - "lon": -80.24111 - }, - "KIMM": { - "id": "KIMM", - "city": "IMMOKALEE", - "state": "FL", - "lat": 26.43, - "lon": -81.4 - }, - "KINF": { - "id": "KINF", - "city": "Inverness Airport", - "state": "FL", - "lat": 28.8086, - "lon": -82.3165 - }, - "KISM": { - "id": "KISM", - "city": "Kissimmee Gateway Airport", - "state": "FL", - "lat": 28.29236, - "lon": -81.43716 - }, - "KJAX": { - "id": "KJAX", - "city": "Jacksonville International Airport", - "state": "FL", - "lat": 30.49534, - "lon": -81.6937 - }, - "KLAL": { - "id": "KLAL", - "city": "Lakeland Regional", - "state": "FL", - "lat": 27.98333, - "lon": -82.01667 - }, - "KLCQ": { - "id": "KLCQ", - "city": "Lake City Municipal Airport", - "state": "FL", - "lat": 30.1821, - "lon": -82.5769 - }, - "KLEE": { - "id": "KLEE", - "city": "Leesburg International Airport", - "state": "FL", - "lat": 28.82142, - "lon": -81.80964 - }, - "KLNA": { - "id": "KLNA", - "city": "Palm Beach County Park Airport", - "state": "FL", - "lat": 26.59305, - "lon": -80.08506 - }, - "KMAI": { - "id": "KMAI", - "city": "Marianna Municipal Airport", - "state": "FL", - "lat": 30.83698, - "lon": -85.18347 - }, - "KMCF": { - "id": "KMCF", - "city": "Macdill Air Force Base, Fl.", - "state": "FL", - "lat": 27.85, - "lon": -82.5 - }, - "KMCO": { - "id": "KMCO", - "city": "Orlando International Airport", - "state": "FL", - "lat": 28.41826, - "lon": -81.32413 - }, - "KMIA": { - "id": "KMIA", - "city": "Miami, Miami International Airport", - "state": "FL", - "lat": 25.79056, - "lon": -80.31639 - }, - "KMKY": { - "id": "KMKY", - "city": "Marco Island Airport", - "state": "FL", - "lat": 25.995, - "lon": -81.6725 - }, - "KMLB": { - "id": "KMLB", - "city": "Melbourne International Airport", - "state": "FL", - "lat": 28.09973, - "lon": -80.6356 - }, - "KMTH": { - "id": "KMTH", - "city": "The Florida Keys - Marathon International Airport", - "state": "FL", - "lat": 24.72626, - "lon": -81.04765 - }, - "KNDZ": { - "id": "KNDZ", - "city": "Milton, Whiting Field South", - "state": "FL", - "lat": 30.69722, - "lon": -87.02 - }, - "KNIP": { - "id": "KNIP", - "city": "Jacksonville Naval Air Station", - "state": "FL", - "lat": 30.23468, - "lon": -81.67462 - }, - "KNPA": { - "id": "KNPA", - "city": "Pensacola Naval Air Station", - "state": "FL", - "lat": 30.35641, - "lon": -87.32326 - }, - "KNQX": { - "id": "KNQX", - "city": "Key West Naval Air Station", - "state": "FL", - "lat": 24.5800899, - "lon": -81.68293 - }, - "KNRB": { - "id": "KNRB", - "city": "Mayport Naval Station - Adm David L. McDonald Field", - "state": "FL", - "lat": 30.39589, - "lon": -81.42286 - }, - "KNSE": { - "id": "KNSE", - "city": "Milton - Whiting Field Naval Air Station North", - "state": "FL", - "lat": 30.72848, - "lon": -87.02192 - }, - "KOBE": { - "id": "KOBE", - "city": "Okeechobee County Airport", - "state": "FL", - "lat": 27.2628, - "lon": -80.8498 - }, - "KOCF": { - "id": "KOCF", - "city": "Ocala International Airport - Jim Taylor Field", - "state": "FL", - "lat": 29.16372, - "lon": -82.22097 - }, - "KOMN": { - "id": "KOMN", - "city": "Ormond Beach, Ormond Beach Municipal Airport", - "state": "FL", - "lat": 29.30111, - "lon": -81.11361 - }, - "KOPF": { - "id": "KOPF", - "city": "Miami, Opa Locka Airport", - "state": "FL", - "lat": 25.91, - "lon": -80.28306 - }, - "KORL": { - "id": "KORL", - "city": "Orlando Executive Airport", - "state": "FL", - "lat": 28.54655, - "lon": -81.33543 - }, - "KPAM": { - "id": "KPAM", - "city": "Tyndall Air Force Base", - "state": "FL", - "lat": 30.06444, - "lon": -85.5637 - }, - "KPBI": { - "id": "KPBI", - "city": "West Palm Beach - Palm Beach International Airport", - "state": "FL", - "lat": 26.6850999, - "lon": -80.0991899 - }, - "KPCM": { - "id": "KPCM", - "city": "Plant City, Plant City Municipal Airport", - "state": "FL", - "lat": 28, - "lon": -82.15 - }, - "KPGD": { - "id": "KPGD", - "city": "Punta Gorda, Charlotte County Airport", - "state": "FL", - "lat": 26.91778, - "lon": -81.99361 - }, - "KPIE": { - "id": "KPIE", - "city": "St. Petersburg/Clearwater Airport", - "state": "FL", - "lat": 27.91259, - "lon": -82.68554 - }, - "KPMP": { - "id": "KPMP", - "city": "Pompano Beach, Pompano Beach Airpark", - "state": "FL", - "lat": 26.24556, - "lon": -80.11139 - }, - "KPNS": { - "id": "KPNS", - "city": "Pensacola - Pensacola International Airport", - "state": "FL", - "lat": 30.47806, - "lon": -87.18694 - }, - "KRSW": { - "id": "KRSW", - "city": "Fort Myers, Southwest Florida International Airport", - "state": "FL", - "lat": 26.52694, - "lon": -81.76639 - }, - "KSEF": { - "id": "KSEF", - "city": "Sebring Regional Airport", - "state": "FL", - "lat": 27.45639, - "lon": -81.34239 - }, - "KSFB": { - "id": "KSFB", - "city": "Orlando / Sanford Airport", - "state": "FL", - "lat": 28.78333, - "lon": -81.25 - }, - "KSGJ": { - "id": "KSGJ", - "city": "Northeast Florida Regional Airport", - "state": "FL", - "lat": 29.95924, - "lon": -81.34105 - }, - "KSPG": { - "id": "KSPG", - "city": "Albert Whitted Airport", - "state": "FL", - "lat": 27.76852, - "lon": -82.62564 - }, - "KSRQ": { - "id": "KSRQ", - "city": "Sarasota / Bradenton, Sarasota-Bradenton International Airport", - "state": "FL", - "lat": 27.40139, - "lon": -82.55861 - }, - "KSUA": { - "id": "KSUA", - "city": "Witham Field Airport", - "state": "FL", - "lat": 27.18157, - "lon": -80.22519 - }, - "KTDR": { - "id": "KTDR", - "city": "Tyndall Drone Runway", - "state": "FL", - "lat": 30.0333, - "lon": -85.5333 - }, - "KTIX": { - "id": "KTIX", - "city": "Titusville", - "state": "FL", - "lat": 28.51667, - "lon": -80.8 - }, - "KTLH": { - "id": "KTLH", - "city": "Tallahassee International Airport", - "state": "FL", - "lat": 30.39675, - "lon": -84.35087 - }, - "KTMB": { - "id": "KTMB", - "city": "Miami, Kendall-Tamiami Executive Airport", - "state": "FL", - "lat": 25.64194, - "lon": -80.43472 - }, - "KTPA": { - "id": "KTPA", - "city": "Tampa, Tampa International Airport", - "state": "FL", - "lat": 27.96139, - "lon": -82.54028 - }, - "KTPF": { - "id": "KTPF", - "city": "Tampa, Peter O Knight Airport", - "state": "FL", - "lat": 27.91556, - "lon": -82.44917 - }, - "KTTS": { - "id": "KTTS", - "city": "Titusville, NASA Shuttle Landing Facility", - "state": "FL", - "lat": 28.61667, - "lon": -80.7 - }, - "KVDF": { - "id": "KVDF", - "city": "Tampa, Vandenberg Airport", - "state": "FL", - "lat": 28.01983, - "lon": -82.3415 - }, - "KVNC": { - "id": "KVNC", - "city": "Venice Municipal Airport", - "state": "FL", - "lat": 27.0716, - "lon": -82.44033 - }, - "KVPS": { - "id": "KVPS", - "city": "Valparaiso / Eglin Air Force Base", - "state": "FL", - "lat": 30.48333, - "lon": -86.51667 - }, - "KVQQ": { - "id": "KVQQ", - "city": "Cecil Airport", - "state": "FL", - "lat": 30.21292, - "lon": -81.8707 - }, - "KVRB": { - "id": "KVRB", - "city": "Vero Beach, Vero Beach Municipal Airport", - "state": "FL", - "lat": 27.65556, - "lon": -80.41806 - }, - "KXMR": { - "id": "KXMR", - "city": "Cocoa Beach, Cape Canaveral Air Force Station Skid Strip", - "state": "FL", - "lat": 28.46667, - "lon": -80.56667 - }, - "KZPH": { - "id": "KZPH", - "city": "Zephyrhills Airport", - "state": "FL", - "lat": 28.2281, - "lon": -82.1559 - }, - "KABI": { - "id": "KABI", - "city": "Abilene, Abilene Regional Airport", - "state": "TX", - "lat": 32.41028, - "lon": -99.68167 - }, - "KACT": { - "id": "KACT", - "city": "Waco, Waco Regional Airport", - "state": "TX", - "lat": 31.61722, - "lon": -97.22778 - }, - "KADS": { - "id": "KADS", - "city": "Dallas / Addison Airport", - "state": "TX", - "lat": 32.96667, - "lon": -96.83333 - }, - "KAFW": { - "id": "KAFW", - "city": "Fort Worth, Fort Worth Alliance Airport", - "state": "TX", - "lat": 32.97333, - "lon": -97.31806 - }, - "KALI": { - "id": "KALI", - "city": "Alice, Alice International Airport", - "state": "TX", - "lat": 27.74111, - "lon": -98.02694 - }, - "KAMA": { - "id": "KAMA", - "city": "Amarillo, Amarillo International Airport", - "state": "TX", - "lat": 35.22, - "lon": -101.71722 - }, - "KAPY": { - "id": "KAPY", - "city": "Zapata, TX", - "state": "TX", - "lat": 26.969, - "lon": -99.249 - }, - "KAQO": { - "id": "KAQO", - "city": "Llano, Llano Municipal Airport", - "state": "TX", - "lat": 30.78361, - "lon": -98.66194 - }, - "KARM": { - "id": "KARM", - "city": "Wharton, Wharton Regional Airport", - "state": "TX", - "lat": 29.25417, - "lon": -96.1541699 - }, - "KASL": { - "id": "KASL", - "city": "Marshall", - "state": "TX", - "lat": 32.5205, - "lon": -94.3078 - }, - "KATT": { - "id": "KATT", - "city": "Austin City, Austin Camp Mabry", - "state": "TX", - "lat": 30.31667, - "lon": -97.76667 - }, - "KAUS": { - "id": "KAUS", - "city": "Austin-Bergstrom International Airport", - "state": "TX", - "lat": 30.18304, - "lon": -97.6798699 - }, - "KAXH": { - "id": "KAXH", - "city": "Houston Southwest Airport", - "state": "TX", - "lat": 29.50613, - "lon": -95.47692 - }, - "KBAZ": { - "id": "KBAZ", - "city": "New Braunfels Regional Airport", - "state": "TX", - "lat": 29.70861, - "lon": -98.04528 - }, - "KBBD": { - "id": "KBBD", - "city": "Brady, Curtis Field Airport", - "state": "TX", - "lat": 31.17917, - "lon": -99.32389 - }, - "KBEA": { - "id": "KBEA", - "city": "Beeville Municipal Airport", - "state": "TX", - "lat": 28.362, - "lon": -97.791 - }, - "KBGD": { - "id": "KBGD", - "city": "Borger, Hutchinson County Airport", - "state": "TX", - "lat": 35.695, - "lon": -101.395 - }, - "KBIF": { - "id": "KBIF", - "city": "Biggs Army Air Field - Fort Bliss", - "state": "TX", - "lat": 31.86119, - "lon": -106.3691599 - }, - "KBKD": { - "id": "KBKD", - "city": "Stephens County Airport", - "state": "TX", - "lat": 32.719, - "lon": -98.891 - }, - "KBKS": { - "id": "KBKS", - "city": "Falfurrias, Brooks County Airport", - "state": "TX", - "lat": 27.20667, - "lon": -98.12111 - }, - "KBMQ": { - "id": "KBMQ", - "city": "Burnet, Burnet Municipal Craddock Field", - "state": "TX", - "lat": 30.74056, - "lon": -98.23528 - }, - "KBMT": { - "id": "KBMT", - "city": "Beaumont Municipal Airport", - "state": "TX", - "lat": 30.0702, - "lon": -94.2151 - }, - "KBPC": { - "id": "KBPC", - "city": "Mesa Vista Ranch AP", - "state": "TX", - "lat": 35.889, - "lon": -101.03 - }, - "KBPG": { - "id": "KBPG", - "city": "Big Spring, Big Spring McMahon-Wrinkle Airport", - "state": "TX", - "lat": 32.2, - "lon": -101.51667 - }, - "KBPT": { - "id": "KBPT", - "city": "Beaumont/Port Arthur Southeast Texas Regional Airport", - "state": "TX", - "lat": 29.9521, - "lon": -94.0261 - }, - "KBQX": { - "id": "KBQX", - "city": "BRAZOS 451 OIL PLATFORM", - "state": "TX", - "lat": 28.5, - "lon": -95.72 - }, - "KBRO": { - "id": "KBRO", - "city": "Brownsville, Brownsville / South Padre Island International Airport", - "state": "TX", - "lat": 25.91417, - "lon": -97.42306 - }, - "KBWD": { - "id": "KBWD", - "city": "Brownwood, Brownwood Regional Airport", - "state": "TX", - "lat": 31.8, - "lon": -98.95 - }, - "KBYY": { - "id": "KBYY", - "city": "Bay City, Bay City Municipal Airport", - "state": "TX", - "lat": 28.97306, - "lon": -95.86333 - }, - "KCDS": { - "id": "KCDS", - "city": "Childress, Childress Municipal Airport", - "state": "TX", - "lat": 34.4275, - "lon": -100.28333 - }, - "KCFD": { - "id": "KCFD", - "city": "Bryan Coulter Field", - "state": "TX", - "lat": 30.7157, - "lon": -96.3314 - }, - "KCLL": { - "id": "KCLL", - "city": "College Station, Easterwood Field", - "state": "TX", - "lat": 30.58222, - "lon": -96.36167 - }, - "KCNW": { - "id": "KCNW", - "city": "Waco-James Connally Airport", - "state": "TX", - "lat": 31.6378, - "lon": -97.0741 - }, - "KCOM": { - "id": "KCOM", - "city": "COLEMAN", - "state": "TX", - "lat": 31.84, - "lon": -99.4 - }, - "KCOT": { - "id": "KCOT", - "city": "Cotulla, Cotulla-La Salle County Airport", - "state": "TX", - "lat": 28.45833, - "lon": -99.22028 - }, - "KCPT": { - "id": "KCPT", - "city": "Cleburne, Cleburne Municipal Airport", - "state": "TX", - "lat": 32.35361, - "lon": -97.43361 - }, - "KCRP": { - "id": "KCRP", - "city": "Corpus Christi, Corpus Christi International Airport", - "state": "TX", - "lat": 27.77306, - "lon": -97.51278 - }, - "KCRS": { - "id": "KCRS", - "city": "Corsicana, Campbell Field-Corsicana Municipal Airport", - "state": "TX", - "lat": 32.03111, - "lon": -96.39889 - }, - "KCVB": { - "id": "KCVB", - "city": "Castroville Municipal Airport", - "state": "TX", - "lat": 29.34192, - "lon": -98.8509 - }, - "KCWC": { - "id": "KCWC", - "city": "Kickapoo Downtown Airport", - "state": "TX", - "lat": 33.8606, - "lon": -98.4903999 - }, - "KCXO": { - "id": "KCXO", - "city": "Conroe, Montgomery County Airport", - "state": "TX", - "lat": 30.35667, - "lon": -95.41389 - }, - "KCZT": { - "id": "KCZT", - "city": "Carrizo Springs Dimmit County Airport", - "state": "TX", - "lat": 28.5222, - "lon": -99.8236 - }, - "KDAL": { - "id": "KDAL", - "city": "Dallas Love Field", - "state": "TX", - "lat": 32.85416, - "lon": -96.85506 - }, - "KDFW": { - "id": "KDFW", - "city": "Dallas/Fort Worth International Airport", - "state": "TX", - "lat": 32.89743, - "lon": -97.02196 - }, - "KDHT": { - "id": "KDHT", - "city": "Dalhart, Dalhart Municipal Airport", - "state": "TX", - "lat": 36.02333, - "lon": -102.54722 - }, - "KDKR": { - "id": "KDKR", - "city": "Crockett, Houston County Airport", - "state": "TX", - "lat": 31.30694, - "lon": -95.40361 - }, - "KDLF": { - "id": "KDLF", - "city": "Laughlin Air Force Base Auxiliary Airfield", - "state": "TX", - "lat": 29.36652, - "lon": -100.78469 - }, - "KDRT": { - "id": "KDRT", - "city": "Del Rio, Del Rio International Airport", - "state": "TX", - "lat": 29.37472, - "lon": -100.92361 - }, - "KDTO": { - "id": "KDTO", - "city": "Denton Enterprise Airport", - "state": "TX", - "lat": 33.20505, - "lon": -97.20061 - }, - "KDUX": { - "id": "KDUX", - "city": "Dumas, Moore County Airport", - "state": "TX", - "lat": 35.85778, - "lon": -102.01306 - }, - "KDWH": { - "id": "KDWH", - "city": "Houston, Hooks Memorial Airport", - "state": "TX", - "lat": 30.0675, - "lon": -95.55611 - }, - "KDYS": { - "id": "KDYS", - "city": "Abilene, Dyess Air Force Base", - "state": "TX", - "lat": 32.42, - "lon": -99.85694 - }, - "KDZB": { - "id": "KDZB", - "city": "Horseshoe Bay Resort Airpark", - "state": "TX", - "lat": 30.5271, - "lon": -98.3588 - }, - "KEBG": { - "id": "KEBG", - "city": "Edinburg, Edinburg International Airport", - "state": "TX", - "lat": 26.44194, - "lon": -98.12944 - }, - "KECU": { - "id": "KECU", - "city": "Rocksprings, Edwards County Airport", - "state": "TX", - "lat": 29.94667, - "lon": -100.17361 - }, - "KEDC": { - "id": "KEDC", - "city": "Austin Executive Airport", - "state": "TX", - "lat": 30.3925, - "lon": -97.5621 - }, - "KEFD": { - "id": "KEFD", - "city": "Houston / Ellington", - "state": "TX", - "lat": 29.6, - "lon": -95.16667 - }, - "KELA": { - "id": "KELA", - "city": "Eagle Lake", - "state": "TX", - "lat": 29.6006, - "lon": -96.3219 - }, - "KELP": { - "id": "KELP", - "city": "El Paso, El Paso International Airport", - "state": "TX", - "lat": 31.81111, - "lon": -106.3758299 - }, - "KEMK": { - "id": "KEMK", - "city": "E BREAKS OIL PLATFORM", - "state": "TX", - "lat": 27.82, - "lon": -94.3199999 - }, - "KERV": { - "id": "KERV", - "city": "Kerrville, Kerrville Municipal Airport/Louis Schreiner Field", - "state": "TX", - "lat": 29.96667, - "lon": -99.08333 - }, - "KETN": { - "id": "KETN", - "city": "Eastland Municipal Airport", - "state": "TX", - "lat": 32.41489, - "lon": -98.80969 - }, - "KFST": { - "id": "KFST", - "city": "Fort Stockton, Fort Stockton-Pecos County Airport", - "state": "TX", - "lat": 30.91194, - "lon": -102.91667 - }, - "KFTW": { - "id": "KFTW", - "city": "Fort Worth, Meacham International Airport", - "state": "TX", - "lat": 32.82528, - "lon": -97.36417 - }, - "KFWS": { - "id": "KFWS", - "city": "Fort Worth Spinks Airport", - "state": "TX", - "lat": 32.56537, - "lon": -97.30837 - }, - "KGDJ": { - "id": "KGDJ", - "city": "Granbury, Granbury Municipal Airport", - "state": "TX", - "lat": 32.44417, - "lon": -97.81667 - }, - "KGDP": { - "id": "KGDP", - "city": "Pine Springs, Guadalupe Mountains National Park", - "state": "TX", - "lat": 31.83111, - "lon": -104.80889 - }, - "KGGG": { - "id": "KGGG", - "city": "Longview - East Texas Regional Airport", - "state": "TX", - "lat": 32.39056, - "lon": -94.71389 - }, - "KGKY": { - "id": "KGKY", - "city": "Arlington Municipal Airport", - "state": "TX", - "lat": 32.65829, - "lon": -97.09509 - }, - "KGLE": { - "id": "KGLE", - "city": "Gainesville, Gainesville Municipal Airport", - "state": "TX", - "lat": 33.65139, - "lon": -97.19694 - }, - "KGLS": { - "id": "KGLS", - "city": "Galveston, Scholes Field", - "state": "TX", - "lat": 29.27028, - "lon": -94.86417 - }, - "KGNC": { - "id": "KGNC", - "city": "Seminole, Gaines County Airport", - "state": "TX", - "lat": 32.67528, - "lon": -102.6525 - }, - "KGOP": { - "id": "KGOP", - "city": "Gatesville, City-County Airport", - "state": "TX", - "lat": 31.42111, - "lon": -97.79694 - }, - "KGPM": { - "id": "KGPM", - "city": "Grand Prairie, Grand Prairie Municipal Airport", - "state": "TX", - "lat": 32.69861, - "lon": -97.04667 - }, - "KGRK": { - "id": "KGRK", - "city": "Fort Hood, Robert Gray AAF Ft Hood", - "state": "TX", - "lat": 31.06667, - "lon": -97.81667 - }, - "KGTU": { - "id": "KGTU", - "city": "Georgetown, Georgetown Municipal Airport", - "state": "TX", - "lat": 30.68333, - "lon": -97.68333 - }, - "KGVT": { - "id": "KGVT", - "city": "Greenville / Majors", - "state": "TX", - "lat": 33.06667, - "lon": -96.06667 - }, - "KGYB": { - "id": "KGYB", - "city": "Giddings, Giddings-Lee County Airport", - "state": "TX", - "lat": 30.16917, - "lon": -96.98 - }, - "KGYI": { - "id": "KGYI", - "city": "Sherman/Denison, Grayson County Airport", - "state": "TX", - "lat": 33.71667, - "lon": -96.66667 - }, - "KGZN": { - "id": "KGZN", - "city": "Gregory M Simmons Memorial Airport", - "state": "TX", - "lat": 32.3658, - "lon": -99.0237 - }, - "KHBV": { - "id": "KHBV", - "city": "Hebbronville, Jim Hogg County Airport", - "state": "TX", - "lat": 27.33333, - "lon": -98.73333 - }, - "KHDO": { - "id": "KHDO", - "city": "Hondo, Hondo Municipal Airport", - "state": "TX", - "lat": 29.35944, - "lon": -99.17417 - }, - "KHHF": { - "id": "KHHF", - "city": "Canadian, Hemphill County Airport", - "state": "TX", - "lat": 35.9, - "lon": -100.4 - }, - "KHHV": { - "id": "KHHV", - "city": "Alaminos Canyon 25/H-D (ExxonMobil)", - "state": "TX", - "lat": 26.939, - "lon": -94.6889999 - }, - "KHLR": { - "id": "KHLR", - "city": "Fort Hood, Hood AAF Ft Hood", - "state": "TX", - "lat": 31.13333, - "lon": -97.7 - }, - "KHOU": { - "id": "KHOU", - "city": "Houston, Houston Hobby Airport", - "state": "TX", - "lat": 29.6375, - "lon": -95.2825 - }, - "KHQZ": { - "id": "KHQZ", - "city": "Mesquite, Mesquite Metro Airport", - "state": "TX", - "lat": 32.74694, - "lon": -96.53028 - }, - "KHRL": { - "id": "KHRL", - "city": "Harlingen, Rio Grande Valley International Airport", - "state": "TX", - "lat": 26.22972, - "lon": -97.65528 - }, - "KHRX": { - "id": "KHRX", - "city": "Hereford Municipal Airport", - "state": "TX", - "lat": 34.8578, - "lon": -102.3264 - }, - "KHYI": { - "id": "KHYI", - "city": "San Marcos, San Marcos Municipal Airport", - "state": "TX", - "lat": 29.89361, - "lon": -97.86472 - }, - "KIAH": { - "id": "KIAH", - "city": "Houston Intercontinental Airport", - "state": "TX", - "lat": 29.9844, - "lon": -95.36074 - }, - "KIKG": { - "id": "KIKG", - "city": "Kleberg County Airport", - "state": "TX", - "lat": 27.5509, - "lon": -98.0309 - }, - "KILE": { - "id": "KILE", - "city": "Killeen, Skylark Field Airport", - "state": "TX", - "lat": 31.08333, - "lon": -97.68333 - }, - "KINJ": { - "id": "KINJ", - "city": "Hillsboro, Hillsboro Municipal Airport", - "state": "TX", - "lat": 32.0833299, - "lon": -97.0972199 - }, - "KINK": { - "id": "KINK", - "city": "Wink, Winkler County Airport", - "state": "TX", - "lat": 31.77972, - "lon": -103.20139 - }, - "KJAS": { - "id": "KJAS", - "city": "Jasper, Jasper County-Bell Field Airport", - "state": "TX", - "lat": 30.88556, - "lon": -94.0347199 - }, - "KJCT": { - "id": "KJCT", - "city": "Junction, Kimble County Airport", - "state": "TX", - "lat": 30.51083, - "lon": -99.76639 - }, - "KJDD": { - "id": "KJDD", - "city": "Mineola/Quitman, Wood County Airport", - "state": "TX", - "lat": 32.74194, - "lon": -95.49639 - }, - "KJSO": { - "id": "KJSO", - "city": "Jacksonville, Cherokee County Airport", - "state": "TX", - "lat": 31.86917, - "lon": -95.21722 - }, - "KJWY": { - "id": "KJWY", - "city": "Midlothian/Waxahachie, Mid-Way Regional Airport", - "state": "TX", - "lat": 32.45583, - "lon": -96.91222 - }, - "KJXI": { - "id": "KJXI", - "city": "Gilmer, Fox Stephens Field - Gilmer Municipal Airport", - "state": "TX", - "lat": 32.69889, - "lon": -94.94861 - }, - "KLBB": { - "id": "KLBB", - "city": "Lubbock, Lubbock International Airport", - "state": "TX", - "lat": 33.6674999, - "lon": -101.8213899 - }, - "KLBX": { - "id": "KLBX", - "city": "Angleton / Lake Jackson, Brazoria County Airport", - "state": "TX", - "lat": 29.11536, - "lon": -95.46323 - }, - "KLFK": { - "id": "KLFK", - "city": "Lufkin, Angelina County Airport", - "state": "TX", - "lat": 31.23389, - "lon": -94.75 - }, - "KLHB": { - "id": "KLHB", - "city": "Hearne, Hearne Municipal Airport", - "state": "TX", - "lat": 30.87167, - "lon": -96.62222 - }, - "KLLN": { - "id": "KLLN", - "city": "Levelland Municipal Airport", - "state": "TX", - "lat": 33.55253, - "lon": -102.37253 - }, - "KLNC": { - "id": "KLNC", - "city": "Lancaster Airport", - "state": "TX", - "lat": 32.58323, - "lon": -96.72091 - }, - "KLRD": { - "id": "KLRD", - "city": "Laredo, Laredo International Airport", - "state": "TX", - "lat": 27.54361, - "lon": -99.46139 - }, - "KLUD": { - "id": "KLUD", - "city": "Decatur, Decatur Municipal Airport", - "state": "TX", - "lat": 33.25444, - "lon": -97.58056 - }, - "KLUV": { - "id": "KLUV", - "city": "Lamesa Municipal Airport", - "state": "TX", - "lat": 32.75631, - "lon": -101.92022 - }, - "KLVJ": { - "id": "KLVJ", - "city": "Houston, Pearland Regional Airport", - "state": "TX", - "lat": 29.52111, - "lon": -95.24194 - }, - "KLXY": { - "id": "KLXY", - "city": "Mexia Limestone County Airport", - "state": "TX", - "lat": 31.6412, - "lon": -96.5145 - }, - "KLZZ": { - "id": "KLZZ", - "city": "Lampasas, Lampasas Airport", - "state": "TX", - "lat": 31.10611, - "lon": -98.19583 - }, - "KMAF": { - "id": "KMAF", - "city": "Midland, Midland International Airport", - "state": "TX", - "lat": 31.94778, - "lon": -102.2086099 - }, - "KMCJ": { - "id": "KMCJ", - "city": "John Dunn Helistop", - "state": "TX", - "lat": 29.714, - "lon": -95.395 - }, - "KMDD": { - "id": "KMDD", - "city": "Midland, Midland Airpark", - "state": "TX", - "lat": 32.03639, - "lon": -102.10083 - }, - "KMFE": { - "id": "KMFE", - "city": "McAllen, Miller International Airport", - "state": "TX", - "lat": 26.17972, - "lon": -98.24444 - }, - "KMKN": { - "id": "KMKN", - "city": "Comanche, Comanche County-City Airport", - "state": "TX", - "lat": 31.91667, - "lon": -98.60028 - }, - "KMNZ": { - "id": "KMNZ", - "city": "Hamilton Municipal Airport", - "state": "TX", - "lat": 31.6659, - "lon": -98.1486 - }, - "KMRF": { - "id": "KMRF", - "city": "Marfa", - "state": "TX", - "lat": 30.36667, - "lon": -104.01667 - }, - "KMWL": { - "id": "KMWL", - "city": "Mineral Wells, Mineral Wells Airport", - "state": "TX", - "lat": 32.78167, - "lon": -98.06028 - }, - "KNFW": { - "id": "KNFW", - "city": "Fort Worth, Naval Air Station", - "state": "TX", - "lat": 32.76583, - "lon": -97.43333 - }, - "KNGP": { - "id": "KNGP", - "city": "Corpus Christi, Corpus Christi Naval Air Station/Truax Field", - "state": "TX", - "lat": 27.6925, - "lon": -97.29111 - }, - "KNOG": { - "id": "KNOG", - "city": "Orange Grove NALF", - "state": "TX", - "lat": 27.8947, - "lon": -98.0425099 - }, - "KNQI": { - "id": "KNQI", - "city": "Kingsville, Naval Air Station", - "state": "TX", - "lat": 27.50306, - "lon": -97.81167 - }, - "KOCH": { - "id": "KOCH", - "city": "Nacogdoches, A L Mangham Jr. Regional Airport", - "state": "TX", - "lat": 31.58333, - "lon": -94.7166699 - }, - "KODO": { - "id": "KODO", - "city": "Odessa, Odessa-Schlemeyer Field", - "state": "TX", - "lat": 31.92139, - "lon": -102.39167 - }, - "KORG": { - "id": "KORG", - "city": "Orange, Orange County Airport", - "state": "TX", - "lat": 30.06917, - "lon": -93.80361 - }, - "KOSA": { - "id": "KOSA", - "city": "Mount Pleasant, Mount Pleasant Regional Airport", - "state": "TX", - "lat": 33.09528, - "lon": -94.96139 - }, - "KOZA": { - "id": "KOZA", - "city": "Ozona Municipal Airport", - "state": "TX", - "lat": 30.7353, - "lon": -101.203 - }, - "KPEQ": { - "id": "KPEQ", - "city": "Pecos, Pecos Municipal Airport", - "state": "TX", - "lat": 31.38222, - "lon": -103.51056 - }, - "KPEZ": { - "id": "KPEZ", - "city": "Pleasanton Municipal Airport", - "state": "TX", - "lat": 28.9562, - "lon": -98.5184 - }, - "KPIL": { - "id": "KPIL", - "city": "Port Isabel, Port Isabel-Cameron County Airport", - "state": "TX", - "lat": 26.15917, - "lon": -97.3375 - }, - "KPKV": { - "id": "KPKV", - "city": "Port Lavaca - Calhoun County Airport", - "state": "TX", - "lat": 28.65159, - "lon": -96.68196 - }, - "KPPA": { - "id": "KPPA", - "city": "Pampa, Perry Lefors Field Airport", - "state": "TX", - "lat": 35.61278, - "lon": -100.99611 - }, - "KPRS": { - "id": "KPRS", - "city": "Presidio Lely International Airport", - "state": "TX", - "lat": 29.6341, - "lon": -104.3616 - }, - "KPRX": { - "id": "KPRX", - "city": "Paris / Cox Field", - "state": "TX", - "lat": 33.63333, - "lon": -95.45 - }, - "KPSN": { - "id": "KPSN", - "city": "Palestine, Palestine Municipal Airport", - "state": "TX", - "lat": 31.77944, - "lon": -95.70611 - }, - "KPSX": { - "id": "KPSX", - "city": "Palacios Municipal Airport", - "state": "TX", - "lat": 28.72485, - "lon": -96.2534699 - }, - "KPVW": { - "id": "KPVW", - "city": "Plainview, Hale County Airport", - "state": "TX", - "lat": 34.1680599, - "lon": -101.71722 - }, - "KPWG": { - "id": "KPWG", - "city": "Waco, Mc Gregor Executive Airport", - "state": "TX", - "lat": 31.48333, - "lon": -97.31667 - }, - "KPYX": { - "id": "KPYX", - "city": "Perryton, Perryton Ochiltree County Airport", - "state": "TX", - "lat": 36.4, - "lon": -100.73333 - }, - "KRAS": { - "id": "KRAS", - "city": "Port Aransas, Mustang Beach Airport", - "state": "TX", - "lat": 27.81167, - "lon": -97.08861 - }, - "KRBD": { - "id": "KRBD", - "city": "Dallas, Redbird Airport", - "state": "TX", - "lat": 32.67583, - "lon": -96.86389 - }, - "KRBO": { - "id": "KRBO", - "city": "Robstown, Nueces County Airport", - "state": "TX", - "lat": 27.77833, - "lon": -97.69028 - }, - "KRFI": { - "id": "KRFI", - "city": "Rusk County Airport", - "state": "TX", - "lat": 32.1417, - "lon": -94.8516999 - }, - "KRKP": { - "id": "KRKP", - "city": "Rockport Aransas County Airport", - "state": "TX", - "lat": 28.08371, - "lon": -97.04664 - }, - "KRND": { - "id": "KRND", - "city": "Randolph Air Force Base", - "state": "TX", - "lat": 29.53333, - "lon": -98.28333 - }, - "KRWV": { - "id": "KRWV", - "city": "Caldwell, Caldwell Municipal Airport", - "state": "TX", - "lat": 30.51528, - "lon": -96.70389 - }, - "KRYW": { - "id": "KRYW", - "city": "Lago Vista TX, Rusty Allen Airport", - "state": "TX", - "lat": 30.4967, - "lon": -97.9659 - }, - "KSAT": { - "id": "KSAT", - "city": "San Antonio, San Antonio International Airport", - "state": "TX", - "lat": 29.53278, - "lon": -98.46361 - }, - "KSEP": { - "id": "KSEP", - "city": "Stephenville, Clark Field Municipal Airport", - "state": "TX", - "lat": 32.21667, - "lon": -98.18333 - }, - "KSEQ": { - "id": "KSEQ", - "city": "Seguin - Randolph AFB Auxiliary Field", - "state": "TX", - "lat": 29.56579, - "lon": -97.90834 - }, - "KSGR": { - "id": "KSGR", - "city": "Houston, Sugar Land Municipal / Hull Field Airport", - "state": "TX", - "lat": 29.62222, - "lon": -95.65667 - }, - "KSJT": { - "id": "KSJT", - "city": "San Angelo, Mathis Field", - "state": "TX", - "lat": 31.35139, - "lon": -100.4938899 - }, - "KSKF": { - "id": "KSKF", - "city": "San Antonio - Kelly Field", - "state": "TX", - "lat": 29.38333, - "lon": -98.58333 - }, - "KSLR": { - "id": "KSLR", - "city": "Sulphur Springs, Sulphur Springs Municipal Airport", - "state": "TX", - "lat": 33.16111, - "lon": -95.62111 - }, - "KSNK": { - "id": "KSNK", - "city": "Snyder, Winston Field Airport", - "state": "TX", - "lat": 32.69333, - "lon": -100.95028 - }, - "KSOA": { - "id": "KSOA", - "city": "Sonora, Sonora Municipal Airport", - "state": "TX", - "lat": 30.58556, - "lon": -100.64833 - }, - "KSPS": { - "id": "KSPS", - "city": "Wichita Falls, Sheppard Air Force Base", - "state": "TX", - "lat": 33.97861, - "lon": -98.49278 - }, - "KSSF": { - "id": "KSSF", - "city": "San Antonio, Stinson Municipal Airport", - "state": "TX", - "lat": 29.33889, - "lon": -98.47167 - }, - "KSWW": { - "id": "KSWW", - "city": "Sweetwater, Avenger Field Airport", - "state": "TX", - "lat": 32.46722, - "lon": -100.46639 - }, - "KTFP": { - "id": "KTFP", - "city": "Mc Campbell", - "state": "TX", - "lat": 27.913, - "lon": -97.2115 - }, - "KTKI": { - "id": "KTKI", - "city": "McKinney - McKinney National Airport", - "state": "TX", - "lat": 33.17778, - "lon": -96.59028 - }, - "KTME": { - "id": "KTME", - "city": "Houston Executive Airport", - "state": "TX", - "lat": 29.80717, - "lon": -95.89791 - }, - "KTPL": { - "id": "KTPL", - "city": "Temple, Draughon-Miller Central Texas Regional Airport", - "state": "TX", - "lat": 31.15, - "lon": -97.4 - }, - "KTRL": { - "id": "KTRL", - "city": "Terrell, Terrell Municipal Airport", - "state": "TX", - "lat": 32.71361, - "lon": -96.26833 - }, - "KTXW": { - "id": "KTXW", - "city": "Mid Valley Airport", - "state": "TX", - "lat": 26.17871, - "lon": -97.97401 - }, - "KTYR": { - "id": "KTYR", - "city": "Tyler, Tyler Pounds Field", - "state": "TX", - "lat": 32.35861, - "lon": -95.40389 - }, - "KUTS": { - "id": "KUTS", - "city": "Huntsville, Huntsville Municipal Airport", - "state": "TX", - "lat": 30.74389, - "lon": -95.58611 - }, - "KUVA": { - "id": "KUVA", - "city": "Uvalde, Garner Field Airport", - "state": "TX", - "lat": 29.21111, - "lon": -99.74333 - }, - "KVAF": { - "id": "KVAF", - "city": "East Breaks 643/Boomvang Spar", - "state": "TX", - "lat": 27.354, - "lon": -94.625 - }, - "KVCT": { - "id": "KVCT", - "city": "Victoria, Victoria Regional Airport", - "state": "TX", - "lat": 28.8625, - "lon": -96.92972 - }, - "KVHN": { - "id": "KVHN", - "city": "Culberson County Airport", - "state": "TX", - "lat": 31.05783, - "lon": -104.78381 - }, - "KXBP": { - "id": "KXBP", - "city": "Bridgeport, Bridgeport Municipal Airport", - "state": "TX", - "lat": 33.17528, - "lon": -97.8283299 - }, - "KAAT": { - "id": "KAAT", - "city": "Alturas", - "state": "CA", - "lat": 41.48362, - "lon": -120.5615 - }, - "KACV": { - "id": "KACV", - "city": "Arcata / Eureka, Arcata Airport", - "state": "CA", - "lat": 40.97806, - "lon": -124.10861 - }, - "KAJO": { - "id": "KAJO", - "city": "Corona Airport", - "state": "CA", - "lat": 33.8977, - "lon": -117.6024 - }, - "KAPC": { - "id": "KAPC", - "city": "Napa, Napa County Airport", - "state": "CA", - "lat": 38.2075, - "lon": -122.27944 - }, - "KAPV": { - "id": "KAPV", - "city": "APPLEVALLEY", - "state": "CA", - "lat": 34.57533, - "lon": -117.18619 - }, - "KAUN": { - "id": "KAUN", - "city": "Auburn Municipal Airport", - "state": "CA", - "lat": 38.95535, - "lon": -121.08636 - }, - "KAVX": { - "id": "KAVX", - "city": "Avalon Catalina Airport", - "state": "CA", - "lat": 33.40421, - "lon": -118.41456 - }, - "KBAB": { - "id": "KBAB", - "city": "Marysville, Beale Air Force Base", - "state": "CA", - "lat": 39.13333, - "lon": -121.43333 - }, - "KBAN": { - "id": "KBAN", - "city": "MCMWTC BRIDGEPORT", - "state": "CA", - "lat": 38.3557, - "lon": -119.5188 - }, - "KBFL": { - "id": "KBFL", - "city": "Bakersfield, Meadows Field Airport", - "state": "CA", - "lat": 35.43361, - "lon": -119.05667 - }, - "KBIH": { - "id": "KBIH", - "city": "Bishop, Bishop Airport", - "state": "CA", - "lat": 37.37111, - "lon": -118.35806 - }, - "KBLH": { - "id": "KBLH", - "city": "Blythe, Blythe Airport", - "state": "CA", - "lat": 33.6191699, - "lon": -114.71694 - }, - "KBLU": { - "id": "KBLU", - "city": "Emigrant Gap, Blue Canyon Nyack Airport", - "state": "CA", - "lat": 39.27611, - "lon": -120.70806 - }, - "KBUR": { - "id": "KBUR", - "city": "Burbank - Bob Hope Airport", - "state": "CA", - "lat": 34.19967, - "lon": -118.36538 - }, - "KBYS": { - "id": "KBYS", - "city": "Fort Irwin/Barstow, Bicycle Lake Army Airfield", - "state": "CA", - "lat": 35.28333, - "lon": -116.61667 - }, - "KCCB": { - "id": "KCCB", - "city": "Cable Airport", - "state": "CA", - "lat": 34.11161, - "lon": -117.68739 - }, - "KCCR": { - "id": "KCCR", - "city": "Concord, Buchanan Field", - "state": "CA", - "lat": 37.99167, - "lon": -122.05194 - }, - "KCEC": { - "id": "KCEC", - "city": "Crescent City, Jack McNamara Field Airport", - "state": "CA", - "lat": 41.78028, - "lon": -124.23667 - }, - "KCIC": { - "id": "KCIC", - "city": "Chico Municipal Airport", - "state": "CA", - "lat": 39.7987899, - "lon": -121.85795 - }, - "KCMA": { - "id": "KCMA", - "city": "Camarillo, Camarillo Airport", - "state": "CA", - "lat": 34.21667, - "lon": -119.08333 - }, - "KCNO": { - "id": "KCNO", - "city": "Chino, Chino Airport", - "state": "CA", - "lat": 33.97556, - "lon": -117.62361 - }, - "KCPU": { - "id": "KCPU", - "city": "San Andreas Calaveras County Airport", - "state": "CA", - "lat": 38.1460999, - "lon": -120.6482 - }, - "KCQT": { - "id": "KCQT", - "city": "Los Angeles / USC Campus Downtown", - "state": "CA", - "lat": 34.02355, - "lon": -118.29122 - }, - "KCRQ": { - "id": "KCRQ", - "city": "Carlsbad, McClellan-Palomar Airport", - "state": "CA", - "lat": 33.13, - "lon": -117.27583 - }, - "KCVH": { - "id": "KCVH", - "city": "Hollister, CA", - "state": "CA", - "lat": 36.8933, - "lon": -121.4103 - }, - "KDAG": { - "id": "KDAG", - "city": "Daggett, Barstow-Daggett Airport", - "state": "CA", - "lat": 34.85361, - "lon": -116.78667 - }, - "KDLO": { - "id": "KDLO", - "city": "Delano Municipal Airport", - "state": "CA", - "lat": 35.74556, - "lon": -119.2365 - }, - "KDVO": { - "id": "KDVO", - "city": "Novato / Gnoss Field", - "state": "CA", - "lat": 38.14178, - "lon": -122.55463 - }, - "KDWA": { - "id": "KDWA", - "city": "Yolo County Airport", - "state": "CA", - "lat": 38.5793899, - "lon": -121.85694 - }, - "KEDW": { - "id": "KEDW", - "city": "Edwards Air Force Base", - "state": "CA", - "lat": 34.918, - "lon": -117.879 - }, - "KEED": { - "id": "KEED", - "city": "Needles, Needles Airport", - "state": "CA", - "lat": 34.76611, - "lon": -114.62333 - }, - "KEMT": { - "id": "KEMT", - "city": "El Monte", - "state": "CA", - "lat": 34.0833299, - "lon": -118.03333 - }, - "KFAT": { - "id": "KFAT", - "city": "Fresno, Fresno Air Terminal", - "state": "CA", - "lat": 36.78, - "lon": -119.71944 - }, - "KFOT": { - "id": "KFOT", - "city": "Fortuna Rohnerville Airport", - "state": "CA", - "lat": 40.55296, - "lon": -124.13338 - }, - "KFUL": { - "id": "KFUL", - "city": "Fullerton, Fullerton Municipal Airport", - "state": "CA", - "lat": 33.87194, - "lon": -117.98472 - }, - "KGOO": { - "id": "KGOO", - "city": "Nevada County Air Park", - "state": "CA", - "lat": 39.2240279, - "lon": -121.003083 - }, - "KGXA": { - "id": "KGXA", - "city": "Gray Butte Field Airport", - "state": "CA", - "lat": 34.5666, - "lon": -117.6704 - }, - "KHAF": { - "id": "KHAF", - "city": "Half Moon Bay Airport", - "state": "CA", - "lat": 37.5135999, - "lon": -122.4996 - }, - "KHHR": { - "id": "KHHR", - "city": "Hawthorne, Hawthorne Municipal Airport", - "state": "CA", - "lat": 33.9236099, - "lon": -118.33194 - }, - "KHJO": { - "id": "KHJO", - "city": "Hanford Municipal Airport", - "state": "CA", - "lat": 36.31145, - "lon": -119.62315 - }, - "KHMT": { - "id": "KHMT", - "city": "Hemet-Ryan Airport", - "state": "CA", - "lat": 33.73403, - "lon": -117.02231 - }, - "KHWD": { - "id": "KHWD", - "city": "Hayward, Hayward Air Terminal", - "state": "CA", - "lat": 37.66083, - "lon": -122.11833 - }, - "KIPL": { - "id": "KIPL", - "city": "Imperial, Imperial County Airport", - "state": "CA", - "lat": 32.83417, - "lon": -115.57861 - }, - "KIZA": { - "id": "KIZA", - "city": "Santa Ynez, Santa Ynez Airport", - "state": "CA", - "lat": 34.60694, - "lon": -120.07556 - }, - "KJAQ": { - "id": "KJAQ", - "city": "Westover Field - Amador County Airport", - "state": "CA", - "lat": 38.3768, - "lon": -120.79391 - }, - "KLAX": { - "id": "KLAX", - "city": "Los Angeles, Los Angeles International Airport", - "state": "CA", - "lat": 33.93806, - "lon": -118.38889 - }, - "KLGB": { - "id": "KLGB", - "city": "Long Beach, Long Beach Airport", - "state": "CA", - "lat": 33.81167, - "lon": -118.14639 - }, - "KLHM": { - "id": "KLHM", - "city": "Lincoln Regional Karl Harder Field", - "state": "CA", - "lat": 38.9092, - "lon": -121.3513 - }, - "KLPC": { - "id": "KLPC", - "city": "Lompoc, Lompoc Airport", - "state": "CA", - "lat": 34.66667, - "lon": -120.46667 - }, - "KLVK": { - "id": "KLVK", - "city": "Livermore, Livermore Municipal Airport", - "state": "CA", - "lat": 37.69278, - "lon": -121.81444 - }, - "KMAE": { - "id": "KMAE", - "city": "Madera Municipal Airport", - "state": "CA", - "lat": 36.9851, - "lon": -120.11064 - }, - "KMCC": { - "id": "KMCC", - "city": "Sacramento, McClellan Airfield Airport", - "state": "CA", - "lat": 38.66667, - "lon": -121.4 - }, - "KMCE": { - "id": "KMCE", - "city": "Merced Regional Airport", - "state": "CA", - "lat": 37.28306, - "lon": -120.50778 - }, - "KMER": { - "id": "KMER", - "city": "Merced / Castle Air Force Base", - "state": "CA", - "lat": 37.36667, - "lon": -120.56667 - }, - "KMHR": { - "id": "KMHR", - "city": "Sacramento Mather Airport", - "state": "CA", - "lat": 38.5599599, - "lon": -121.28397 - }, - "KMHS": { - "id": "KMHS", - "city": "Mount Shasta", - "state": "CA", - "lat": 41.31494, - "lon": -122.31702 - }, - "KMHV": { - "id": "KMHV", - "city": "Mojave", - "state": "CA", - "lat": 35.06667, - "lon": -118.15 - }, - "KMMH": { - "id": "KMMH", - "city": "Mammoth Yosemite Airport", - "state": "CA", - "lat": 37.6241, - "lon": -118.8423 - }, - "KMOD": { - "id": "KMOD", - "city": "Modesto City-County Airport - Harry Sham Field", - "state": "CA", - "lat": 37.62549, - "lon": -120.9549 - }, - "KMRY": { - "id": "KMRY", - "city": "Monterey Regional Airport", - "state": "CA", - "lat": 36.59047, - "lon": -121.84875 - }, - "KMYF": { - "id": "KMYF", - "city": "San Diego, Montgomery Field", - "state": "CA", - "lat": 32.81444, - "lon": -117.13639 - }, - "KMYV": { - "id": "KMYV", - "city": "Marysville, Yuba County Airport", - "state": "CA", - "lat": 39.09778, - "lon": -121.56972 - }, - "KNFG": { - "id": "KNFG", - "city": "Oceanside, Camp Pendleton, Marine Corps Air Station", - "state": "CA", - "lat": 33.30472, - "lon": -117.35389 - }, - "KNID": { - "id": "KNID", - "city": "China Lake, Naval Air Facility", - "state": "CA", - "lat": 35.68639, - "lon": -117.69 - }, - "KNJK": { - "id": "KNJK", - "city": "El Centro, Naval Air Facility", - "state": "CA", - "lat": 32.825, - "lon": -115.66056 - }, - "KNKX": { - "id": "KNKX", - "city": "San Diego, Miramar MCAS/Mitscher Field Airport", - "state": "CA", - "lat": 32.86833, - "lon": -117.1425 - }, - "KNLC": { - "id": "KNLC", - "city": "Lemoore Naval Air Station - Reeves Field", - "state": "CA", - "lat": 36.30244, - "lon": -119.93968 - }, - "KNRS": { - "id": "KNRS", - "city": "Imperial Beach Naval Outlying Field - Ream Field", - "state": "CA", - "lat": 32.56302, - "lon": -117.11091 - }, - "KNSI": { - "id": "KNSI", - "city": "San Nicolas Island Naval Outlying Field", - "state": "CA", - "lat": 33.23379, - "lon": -119.45588 - }, - "KNTD": { - "id": "KNTD", - "city": "Point Mugu, Naval Air Warfare Center", - "state": "CA", - "lat": 34.12389, - "lon": -119.12167 - }, - "KNUC": { - "id": "KNUC", - "city": "San Clemente Island NALF", - "state": "CA", - "lat": 33.0218, - "lon": -118.58266 - }, - "KNXP": { - "id": "KNXP", - "city": "Twentynine Palms SELF Airport", - "state": "CA", - "lat": 34.29401, - "lon": -116.14717 - }, - "KNZY": { - "id": "KNZY", - "city": "San Diego, North Island, Naval Air Station", - "state": "CA", - "lat": 32.69083, - "lon": -117.20889 - }, - "KOAK": { - "id": "KOAK", - "city": "Oakland, Metro Oakland International Airport", - "state": "CA", - "lat": 37.7177999, - "lon": -122.23294 - }, - "KOAR": { - "id": "KOAR", - "city": "FORT ORD/FRITZSCHE", - "state": "CA", - "lat": 36.68, - "lon": -121.77 - }, - "KOKB": { - "id": "KOKB", - "city": "Oceanside, Oceanside Municipal Airport", - "state": "CA", - "lat": 33.21806, - "lon": -117.35139 - }, - "KONT": { - "id": "KONT", - "city": "Ontario International Airport", - "state": "CA", - "lat": 34.05316, - "lon": -117.57685 - }, - "KOVE": { - "id": "KOVE", - "city": "Oroville Municipal Airport", - "state": "CA", - "lat": 39.49436, - "lon": -121.62223 - }, - "KOXR": { - "id": "KOXR", - "city": "Oxnard, Oxnard Airport", - "state": "CA", - "lat": 34.20056, - "lon": -119.20306 - }, - "KPAO": { - "id": "KPAO", - "city": "Palo Alto Airport", - "state": "CA", - "lat": 37.46667, - "lon": -122.11667 - }, - "KPMD": { - "id": "KPMD", - "city": "Palmdale, Palmdale Production Flight Plant", - "state": "CA", - "lat": 34.62972, - "lon": -118.08139 - }, - "KPOC": { - "id": "KPOC", - "city": "Brackett Field Airport", - "state": "CA", - "lat": 34.09282, - "lon": -117.77937 - }, - "KPRB": { - "id": "KPRB", - "city": "Paso Robles Municipal Airport", - "state": "CA", - "lat": 35.66941, - "lon": -120.62912 - }, - "KPSP": { - "id": "KPSP", - "city": "Palm Springs Regional Airport", - "state": "CA", - "lat": 33.82219, - "lon": -116.50431 - }, - "KPTV": { - "id": "KPTV", - "city": "Porterville, Porterville Municipal Airport", - "state": "CA", - "lat": 36.03333, - "lon": -119.06667 - }, - "KPVF": { - "id": "KPVF", - "city": "Placerville Airport", - "state": "CA", - "lat": 38.7242, - "lon": -120.7533 - }, - "KRAL": { - "id": "KRAL", - "city": "Riverside Municipal Airport", - "state": "CA", - "lat": 33.95189, - "lon": -117.44511 - }, - "KRBL": { - "id": "KRBL", - "city": "Red Bluff, Red Bluff Municipal Airport", - "state": "CA", - "lat": 40.15056, - "lon": -122.25222 - }, - "KRDD": { - "id": "KRDD", - "city": "Redding Municipal Airport", - "state": "CA", - "lat": 40.51461, - "lon": -122.2977 - }, - "KREI": { - "id": "KREI", - "city": "REDLANDS", - "state": "CA", - "lat": 34.08526, - "lon": -117.14637 - }, - "KRHV": { - "id": "KRHV", - "city": "San Jose / Reid / Hillv", - "state": "CA", - "lat": 37.3333299, - "lon": -121.81667 - }, - "KRIV": { - "id": "KRIV", - "city": "March Air Reserve Base", - "state": "CA", - "lat": 33.88194, - "lon": -117.25902 - }, - "KRNM": { - "id": "KRNM", - "city": "Ramona, Ramona Airport", - "state": "CA", - "lat": 33.0375, - "lon": -116.91583 - }, - "KSAC": { - "id": "KSAC", - "city": "Sacramento Executive Airport", - "state": "CA", - "lat": 38.50674, - "lon": -121.49597 - }, - "KSAN": { - "id": "KSAN", - "city": "San Diego International Airport", - "state": "CA", - "lat": 32.73361, - "lon": -117.18306 - }, - "KSBA": { - "id": "KSBA", - "city": "Santa Barbara, Santa Barbara Municipal Airport", - "state": "CA", - "lat": 34.42611, - "lon": -119.84361 - }, - "KSBD": { - "id": "KSBD", - "city": "San Bernardino Intl. Airport", - "state": "CA", - "lat": 34.0902699, - "lon": -117.24705 - }, - "KSBP": { - "id": "KSBP", - "city": "San Luis Obispo, San Luis Obispo County-Mc Chesney Field", - "state": "CA", - "lat": 35.2361099, - "lon": -120.63611 - }, - "KSCK": { - "id": "KSCK", - "city": "Stockton, Stockton Metropolitan Airport", - "state": "CA", - "lat": 37.8897199, - "lon": -121.22361 - }, - "KSDB": { - "id": "KSDB", - "city": "Sandberg", - "state": "CA", - "lat": 34.7436099, - "lon": -118.72444 - }, - "KSDM": { - "id": "KSDM", - "city": "San Diego, Brown Field Municipal Airport", - "state": "CA", - "lat": 32.57528, - "lon": -116.99306 - }, - "KSEE": { - "id": "KSEE", - "city": "Gillespie Field Airport", - "state": "CA", - "lat": 32.82738, - "lon": -116.97369 - }, - "KSFO": { - "id": "KSFO", - "city": "San Francisco, San Francisco International Airport", - "state": "CA", - "lat": 37.61961, - "lon": -122.36558 - }, - "KSIY": { - "id": "KSIY", - "city": "Montague Siskiyou County Airport", - "state": "CA", - "lat": 41.77375, - "lon": -122.46817 - }, - "KSJC": { - "id": "KSJC", - "city": "San Jose, San Jose International Airport", - "state": "CA", - "lat": 37.35917, - "lon": -121.92417 - }, - "KSLI": { - "id": "KSLI", - "city": "Los Alamitos Army Airfield", - "state": "CA", - "lat": 33.79628, - "lon": -118.04179 - }, - "KSMF": { - "id": "KSMF", - "city": "Sacramento International Airport", - "state": "CA", - "lat": 38.70071, - "lon": -121.59479 - }, - "KSMO": { - "id": "KSMO", - "city": "Santa Monica, Santa Monica Municipal Airport", - "state": "CA", - "lat": 34.01583, - "lon": -118.45139 - }, - "KSMX": { - "id": "KSMX", - "city": "Santa Maria Public Airport/Capt G Allan Hancock Field", - "state": "CA", - "lat": 34.89408, - "lon": -120.45212 - }, - "KSNA": { - "id": "KSNA", - "city": "John Wayne-Orange County Airport", - "state": "CA", - "lat": 33.6798, - "lon": -117.8674 - }, - "KSNS": { - "id": "KSNS", - "city": "Salinas, Salinas Municipal Airport", - "state": "CA", - "lat": 36.66361, - "lon": -121.60806 - }, - "KSQL": { - "id": "KSQL", - "city": "San Carlos Airport", - "state": "CA", - "lat": 37.51667, - "lon": -122.25 - }, - "KSTS": { - "id": "KSTS", - "city": "Santa Rosa, Santa Rosa Sonoma County Airport", - "state": "CA", - "lat": 38.5, - "lon": -122.81667 - }, - "KSUU": { - "id": "KSUU", - "city": "Fairfield / Travis Air Force Base", - "state": "CA", - "lat": 38.26667, - "lon": -121.95 - }, - "KSVE": { - "id": "KSVE", - "city": "Susanville Municipal Airport", - "state": "CA", - "lat": 40.37569, - "lon": -120.57269 - }, - "KTCY": { - "id": "KTCY", - "city": "Tracy Municipal Airport", - "state": "CA", - "lat": 37.6888999, - "lon": -121.44158 - }, - "KTNP": { - "id": "KTNP", - "city": "29PALMS", - "state": "CA", - "lat": 34.13159, - "lon": -115.94582 - }, - "KTOA": { - "id": "KTOA", - "city": "Torrance, Zamperini Field Airport", - "state": "CA", - "lat": 33.8, - "lon": -118.33333 - }, - "KTRK": { - "id": "KTRK", - "city": "Truckee-Tahoe", - "state": "CA", - "lat": 39.31667, - "lon": -120.13333 - }, - "KTRM": { - "id": "KTRM", - "city": "Palm Springs, Jacqueline Cochran Regional Airport", - "state": "CA", - "lat": 33.62667, - "lon": -116.15944 - }, - "KTSP": { - "id": "KTSP", - "city": "Tehachapi Municipal Airport", - "state": "CA", - "lat": 35.135, - "lon": -118.4392 - }, - "KTVL": { - "id": "KTVL", - "city": "South Lake Tahoe, Lake Tahoe Airport", - "state": "CA", - "lat": 38.8983599, - "lon": -119.99615 - }, - "KUKI": { - "id": "KUKI", - "city": "Ukiah Municipal Airport", - "state": "CA", - "lat": 39.12783, - "lon": -123.20011 - }, - "KVBG": { - "id": "KVBG", - "city": "Lompoc, Vandenberg Air Force Base", - "state": "CA", - "lat": 34.7294399, - "lon": -120.57667 - }, - "KVCB": { - "id": "KVCB", - "city": "Vacaville Nut Tree Airport", - "state": "CA", - "lat": 38.37755, - "lon": -121.95853 - }, - "KVCV": { - "id": "KVCV", - "city": "Victorville, Southern California Logistics Airport", - "state": "CA", - "lat": 34.59722, - "lon": -117.38278 - }, - "KVIS": { - "id": "KVIS", - "city": "Visalia, Visalia Municipal Airport", - "state": "CA", - "lat": 36.31667, - "lon": -119.4 - }, - "KVNY": { - "id": "KVNY", - "city": "Van Nuys, Van Nuys Airport", - "state": "CA", - "lat": 34.2125, - "lon": -118.49083 - }, - "KWHP": { - "id": "KWHP", - "city": "Los Angeles, Whiteman Airport", - "state": "CA", - "lat": 34.25, - "lon": -118.4 - }, - "KWJF": { - "id": "KWJF", - "city": "General Wm J Fox Airfield", - "state": "CA", - "lat": 34.74123, - "lon": -118.21251 - }, - "KWVI": { - "id": "KWVI", - "city": "Watsonville, Watsonville Municipal Airport", - "state": "CA", - "lat": 36.93944, - "lon": -121.78889 - } -} \ No newline at end of file diff --git a/dist/datagenerators/output/travelcities.json b/dist/datagenerators/output/travelcities.json deleted file mode 100644 index ba6f654..0000000 --- a/dist/datagenerators/output/travelcities.json +++ /dev/null @@ -1,242 +0,0 @@ -[ - { - "Name": "Atlanta", - "Latitude": 33.749, - "Longitude": -84.388, - "point": { - "x": 50, - "y": 86, - "wfo": "FFC" - } - }, - { - "Name": "Boston", - "Latitude": 42.3584, - "Longitude": -71.0598, - "point": { - "x": 71, - "y": 90, - "wfo": "BOX" - } - }, - { - "Name": "Chicago", - "Latitude": 41.9796, - "Longitude": -87.9045, - "point": { - "x": 65, - "y": 76, - "wfo": "LOT" - } - }, - { - "Name": "Cleveland", - "Latitude": 41.4995, - "Longitude": -81.6954, - "point": { - "x": 82, - "y": 64, - "wfo": "CLE" - } - }, - { - "Name": "Dallas", - "Latitude": 32.8959, - "Longitude": -97.0372, - "point": { - "x": 79, - "y": 108, - "wfo": "FWD" - } - }, - { - "Name": "Denver", - "Latitude": 39.7391, - "Longitude": -104.9847, - "point": { - "x": 62, - "y": 60, - "wfo": "BOU" - } - }, - { - "Name": "Detroit", - "Latitude": 42.3314, - "Longitude": -83.0457, - "point": { - "x": 65, - "y": 33, - "wfo": "DTX" - } - }, - { - "Name": "Hartford", - "Latitude": 41.7637, - "Longitude": -72.6851, - "point": { - "x": 21, - "y": 54, - "wfo": "BOX" - } - }, - { - "Name": "Houston", - "Latitude": 29.7633, - "Longitude": -95.3633, - "point": { - "x": 65, - "y": 97, - "wfo": "HGX" - } - }, - { - "Name": "Indianapolis", - "Latitude": 39.7684, - "Longitude": -86.158, - "point": { - "x": 57, - "y": 68, - "wfo": "IND" - } - }, - { - "Name": "Los Angeles", - "Latitude": 34.0522, - "Longitude": -118.2437, - "point": { - "x": 154, - "y": 44, - "wfo": "LOX" - } - }, - { - "Name": "Miami", - "Latitude": 25.7743, - "Longitude": -80.1937, - "point": { - "x": 109, - "y": 50, - "wfo": "MFL" - } - }, - { - "Name": "Minneapolis", - "Latitude": 44.98, - "Longitude": -93.2638, - "point": { - "x": 107, - "y": 71, - "wfo": "MPX" - } - }, - { - "Name": "New York", - "Latitude": 40.7142, - "Longitude": -74.0059, - "point": { - "x": 32, - "y": 34, - "wfo": "OKX" - } - }, - { - "Name": "Norfolk", - "Latitude": 36.8468, - "Longitude": -76.2852, - "point": { - "x": 89, - "y": 51, - "wfo": "AKQ" - } - }, - { - "Name": "Orlando", - "Latitude": 28.5383, - "Longitude": -81.3792, - "point": { - "x": 26, - "y": 68, - "wfo": "MLB" - } - }, - { - "Name": "Philadelphia", - "Latitude": 39.9523, - "Longitude": -75.1638, - "point": { - "x": 49, - "y": 75, - "wfo": "PHI" - } - }, - { - "Name": "Pittsburgh", - "Latitude": 40.4406, - "Longitude": -79.9959, - "point": { - "x": 77, - "y": 65, - "wfo": "PBZ" - } - }, - { - "Name": "St. Louis", - "Latitude": 38.6273, - "Longitude": -90.1979, - "point": { - "x": 94, - "y": 73, - "wfo": "LSX" - } - }, - { - "Name": "San Francisco", - "Latitude": 37.7749, - "Longitude": -122.4194, - "point": { - "x": 85, - "y": 105, - "wfo": "MTR" - } - }, - { - "Name": "Seattle", - "Latitude": 47.6062, - "Longitude": -122.3321, - "point": { - "x": 124, - "y": 67, - "wfo": "SEW" - } - }, - { - "Name": "Syracuse", - "Latitude": 43.0481, - "Longitude": -76.1474, - "point": { - "x": 51, - "y": 98, - "wfo": "BGM" - } - }, - { - "Name": "Tampa", - "Latitude": 27.9475, - "Longitude": -82.4584, - "point": { - "x": 70, - "y": 96, - "wfo": "TBW" - } - }, - { - "Name": "Washington DC", - "Latitude": 38.8951, - "Longitude": -77.0364, - "point": { - "x": 97, - "y": 71, - "wfo": "LWX" - } - } -] \ No newline at end of file diff --git a/dist/datagenerators/regionalcities-raw.json b/dist/datagenerators/regionalcities-raw.json deleted file mode 100644 index 6963742..0000000 --- a/dist/datagenerators/regionalcities-raw.json +++ /dev/null @@ -1,582 +0,0 @@ -[ - { - "city": "Atlanta", - "lat": 33.749, - "lon": -84.388 - }, - { - "city": "Boston", - "lat": 42.3584, - "lon": -71.0598 - }, - { - "city": "Chicago", - "lat": 41.9796, - "lon": -87.9045 - }, - { - "city": "Cleveland", - "lat": 41.4995, - "lon": -81.6954 - }, - { - "city": "Dallas", - "lat": 32.8959, - "lon": -97.0372 - }, - { - "city": "Denver", - "lat": 39.7391, - "lon": -104.9847 - }, - { - "city": "Detroit", - "lat": 42.3314, - "lon": -83.0457 - }, - { - "city": "Hartford", - "lat": 41.7637, - "lon": -72.6851 - }, - { - "city": "Houston", - "lat": 29.7633, - "lon": -95.3633 - }, - { - "city": "Indianapolis", - "lat": 39.7684, - "lon": -86.158 - }, - { - "city": "Los Angeles", - "lat": 34.0522, - "lon": -118.2437 - }, - { - "city": "Miami", - "lat": 25.7743, - "lon": -80.1937 - }, - { - "city": "Minneapolis", - "lat": 44.98, - "lon": -93.2638 - }, - { - "city": "New York", - "lat": 40.78, - "lon": -73.88 - }, - { - "city": "Norfolk", - "lat": 36.8468, - "lon": -76.2852 - }, - { - "city": "Orlando", - "lat": 28.5383, - "lon": -81.3792 - }, - { - "city": "Philadelphia", - "lat": 39.9523, - "lon": -75.1638 - }, - { - "city": "Pittsburgh", - "lat": 40.4406, - "lon": -79.9959 - }, - { - "city": "St. Louis", - "lat": 38.6273, - "lon": -90.1979 - }, - { - "city": "San Francisco", - "lat": 37.6148, - "lon": -122.3918 - }, - { - "city": "Seattle", - "lat": 47.6062, - "lon": -122.3321 - }, - { - "city": "Syracuse", - "lat": 43.0481, - "lon": -76.1474 - }, - { - "city": "Tampa", - "lat": 27.9756, - "lon": -82.5329 - }, - { - "city": "Washington DC", - "lat": 38.8951, - "lon": -77.0364 - }, - { - "city": "Albany", - "lat": 42.6526, - "lon": -73.7562 - }, - { - "city": "Albuquerque", - "lat": 35.0845, - "lon": -106.6511 - }, - { - "city": "Amarillo", - "lat": 35.222, - "lon": -101.8313 - }, - { - "city": "Anchorage", - "lat": 61.2181, - "lon": -149.9003 - }, - { - "city": "Austin", - "lat": 30.2671, - "lon": -97.7431 - }, - { - "city": "Baker", - "lat": 44.7502, - "lon": -117.6677 - }, - { - "city": "Baltimore", - "lat": 39.2904, - "lon": -76.6122 - }, - { - "city": "Bangor", - "lat": 44.8012, - "lon": -68.7778 - }, - { - "city": "Birmingham", - "lat": 33.5207, - "lon": -86.8025 - }, - { - "city": "Bismarck", - "lat": 46.8083, - "lon": -100.7837 - }, - { - "city": "Boise", - "lat": 43.6135, - "lon": -116.2034 - }, - { - "city": "Buffalo", - "lat": 42.8864, - "lon": -78.8784 - }, - { - "city": "Carlsbad", - "lat": 32.4207, - "lon": -104.2288 - }, - { - "city": "Charleston", - "lat": 32.7766, - "lon": -79.9309 - }, - { - "city": "Charleston", - "lat": 38.3498, - "lon": -81.6326 - }, - { - "city": "Charlotte", - "lat": 35.2271, - "lon": -80.8431 - }, - { - "city": "Cheyenne", - "lat": 41.14, - "lon": -104.8202 - }, - { - "city": "Cincinnati", - "lat": 39.162, - "lon": -84.4569 - }, - { - "city": "Columbia", - "lat": 34.0007, - "lon": -81.0348 - }, - { - "city": "Columbus", - "lat": 39.9612, - "lon": -82.9988 - }, - { - "city": "Des Moines", - "lat": 41.6005, - "lon": -93.6091 - }, - { - "city": "Dubuque", - "lat": 42.5006, - "lon": -90.6646 - }, - { - "city": "Duluth", - "lat": 46.7833, - "lon": -92.1066 - }, - { - "city": "Eastport", - "lat": 44.9062, - "lon": -66.99 - }, - { - "city": "El Centro", - "lat": 32.792, - "lon": -115.563 - }, - { - "city": "El Paso", - "lat": 31.7587, - "lon": -106.4869 - }, - { - "city": "Eugene", - "lat": 44.0521, - "lon": -123.0867 - }, - { - "city": "Fargo", - "lat": 46.8772, - "lon": -96.7898 - }, - { - "city": "Flagstaff", - "lat": 35.1981, - "lon": -111.6513 - }, - { - "city": "Fresno", - "lat": 36.7477, - "lon": -119.7724 - }, - { - "city": "Grand Junction", - "lat": 39.0639, - "lon": -108.5506 - }, - { - "city": "Grand Rapids", - "lat": 42.9634, - "lon": -85.6681 - }, - { - "city": "Havre", - "lat": 48.55, - "lon": -109.6841 - }, - { - "city": "Helena", - "lat": 46.5927, - "lon": -112.0361 - }, - { - "city": "Honolulu", - "lat": 21.3069, - "lon": -157.8583 - }, - { - "city": "Hot Springs", - "lat": 34.5037, - "lon": -93.0552 - }, - { - "city": "Idaho Falls", - "lat": 43.4666, - "lon": -112.0341 - }, - { - "city": "Jackson", - "lat": 32.2988, - "lon": -90.1848 - }, - { - "city": "Jacksonville", - "lat": 30.3322, - "lon": -81.6556 - }, - { - "city": "Juneau", - "lat": 58.3019, - "lon": -134.4197 - }, - { - "city": "Kansas City", - "lat": 39.1142, - "lon": -94.6275 - }, - { - "city": "Key West", - "lat": 24.5557, - "lon": -81.7826 - }, - { - "city": "Klamath Falls", - "lat": 42.2249, - "lon": -121.7817 - }, - { - "city": "Knoxville", - "lat": 35.9606, - "lon": -83.9207 - }, - { - "city": "Las Vegas", - "lat": 36.175, - "lon": -115.1372 - }, - { - "city": "Lewiston", - "lat": 46.4165, - "lon": -117.0177 - }, - { - "city": "Lincoln", - "lat": 40.8, - "lon": -96.667 - }, - { - "city": "Long Beach", - "lat": 33.767, - "lon": -118.1892 - }, - { - "city": "Louisville", - "lat": 38.2542, - "lon": -85.7594 - }, - { - "city": "Manchester", - "lat": 42.9956, - "lon": -71.4548 - }, - { - "city": "Memphis", - "lat": 35.1495, - "lon": -90.049 - }, - { - "city": "Milwaukee", - "lat": 43.0389, - "lon": -87.9065 - }, - { - "city": "Mobile", - "lat": 30.6944, - "lon": -88.043 - }, - { - "city": "Montgomery", - "lat": 32.3668, - "lon": -86.3 - }, - { - "city": "Montpelier", - "lat": 44.2601, - "lon": -72.5754 - }, - { - "city": "Nashville", - "lat": 36.1659, - "lon": -86.7844 - }, - { - "city": "Newark", - "lat": 40.7357, - "lon": -74.1724 - }, - { - "city": "New Haven", - "lat": 41.3081, - "lon": -72.9282 - }, - { - "city": "New Orleans", - "lat": 29.9546, - "lon": -90.0751 - }, - { - "city": "Nome", - "lat": 64.5011, - "lon": -165.4064 - }, - { - "city": "Oklahoma City", - "lat": 35.4676, - "lon": -97.5164 - }, - { - "city": "Omaha", - "lat": 41.2586, - "lon": -95.9378 - }, - { - "city": "Phoenix", - "lat": 33.4484, - "lon": -112.074 - }, - { - "city": "Pierre", - "lat": 44.3683, - "lon": -100.351 - }, - { - "city": "Portland", - "lat": 43.6615, - "lon": -70.2553 - }, - { - "city": "Portland", - "lat": 45.5234, - "lon": -122.6762 - }, - { - "city": "Providence", - "lat": 41.824, - "lon": -71.4128 - }, - { - "city": "Raleigh", - "lat": 35.7721, - "lon": -78.6386 - }, - { - "city": "Reno", - "lat": 39.4986, - "lon": -119.7681 - }, - { - "city": "Richfield", - "lat": 38.7725, - "lon": -112.0841 - }, - { - "city": "Richmond", - "lat": 37.5538, - "lon": -77.4603 - }, - { - "city": "Roanoke", - "lat": 37.271, - "lon": -79.9414 - }, - { - "city": "Sacramento", - "lat": 38.5816, - "lon": -121.4944 - }, - { - "city": "Salt Lake City", - "lat": 40.7608, - "lon": -111.891 - }, - { - "city": "San Antonio", - "lat": 29.4241, - "lon": -98.4936 - }, - { - "city": "San Diego", - "lat": 32.7153, - "lon": -117.1573 - }, - { - "city": "San Jose", - "lat": 37.3394, - "lon": -121.895 - }, - { - "city": "Santa Fe", - "lat": 35.687, - "lon": -105.9378 - }, - { - "city": "Savannah", - "lat": 32.0835, - "lon": -81.0998 - }, - { - "city": "Shreveport", - "lat": 32.5251, - "lon": -93.7502 - }, - { - "city": "Sioux Falls", - "lat": 43.55, - "lon": -96.7003 - }, - { - "city": "Sitka", - "lat": 57.0531, - "lon": -135.33 - }, - { - "city": "Spokane", - "lat": 47.6597, - "lon": -117.4291 - }, - { - "city": "Springfield", - "lat": 39.8017, - "lon": -89.6437 - }, - { - "city": "Springfield", - "lat": 42.1015, - "lon": -72.5898 - }, - { - "city": "Springfield", - "lat": 37.2153, - "lon": -93.2982 - }, - { - "city": "Toledo", - "lat": 41.6639, - "lon": -83.5552 - }, - { - "city": "Tulsa", - "lat": 36.154, - "lon": -95.9928 - }, - { - "city": "Virginia Beach", - "lat": 36.8529, - "lon": -75.978 - }, - { - "city": "Wichita", - "lat": 37.6922, - "lon": -97.3375 - }, - { - "city": "Wilmington", - "lat": 34.2257, - "lon": -77.9447 - }, - { - "city": "Tuscan", - "lat": 32.2216, - "lon": -110.9698 - } -] \ No newline at end of file diff --git a/dist/datagenerators/regionalcities.js b/dist/datagenerators/regionalcities.js deleted file mode 100644 index b8d6a37..0000000 --- a/dist/datagenerators/regionalcities.js +++ /dev/null @@ -1,41 +0,0 @@ -// look up points for each regional city -const fs = require('fs/promises'); -const chunk = require('./chunk'); -const https = require('./https'); - -(async () => { - // source data - const regionalCities = JSON.parse(await fs.readFile('./datagenerators/regionalcities-raw.json')); - - const result = []; - const dataChunks = chunk(regionalCities, 5); - - // for loop intentional for use of await - // this keeps the api from getting overwhelmed - for (let i = 0; i < dataChunks.length; i += 1) { - const cityChunk = dataChunks[i]; - - // eslint-disable-next-line no-await-in-loop - const chunkResult = await Promise.all(cityChunk.map(async (city) => { - try { - const data = await https(`https://api.weather.gov/points/${city.lat},${city.lon}`); - const point = JSON.parse(data); - return { - ...city, - point: { - x: point.properties.gridX, - y: point.properties.gridY, - wfo: point.properties.gridId, - }, - }; - } catch (e) { - console.error(e); - return city; - } - })); - - result.push(...chunkResult); - } - - await fs.writeFile('./datagenerators/output/regionalcities.json', JSON.stringify(result, null, ' ')); -})(); diff --git a/dist/datagenerators/stations-states.js b/dist/datagenerators/stations-states.js deleted file mode 100644 index f16cd63..0000000 --- a/dist/datagenerators/stations-states.js +++ /dev/null @@ -1,53 +0,0 @@ -module.exports = [ - 'AZ', - 'AL', - 'AK', - 'AR', - 'CA', - 'CO', - 'CT', - 'DE', - 'FL', - 'GA', - 'HI', - 'ID', - 'IL', - 'IN', - 'IA', - 'KS', - 'KY', - 'LA', - 'ME', - 'MD', - 'MA', - 'MI', - 'MN', - 'MS', - 'MO', - 'MT', - 'NE', - 'NV', - 'NH', - 'NJ', - 'NM', - 'NY', - 'NC', - 'ND', - 'OH', - 'OK', - 'OR', - 'PA', - 'RI', - 'SC', - 'SD', - 'TN', - 'TX', - 'UT', - 'VT', - 'VA', - 'WA', - 'WV', - 'WI', - 'WY', - 'PR', -]; \ No newline at end of file diff --git a/dist/datagenerators/stations.js b/dist/datagenerators/stations.js deleted file mode 100644 index 5f789c7..0000000 --- a/dist/datagenerators/stations.js +++ /dev/null @@ -1,73 +0,0 @@ -// list all stations in a single file -// only find stations with 4 letter codes - -const fs = require('fs'); -const path = require('path'); -const https = require('./https'); -const states = require('./stations-states'); -const chunk = require('./chunk'); - -// skip stations starting with these letters -const skipStations = ['U', 'C', 'H', 'W', 'Y', 'T', 'S', 'M', 'O', 'L', 'A', 'F', 'B', 'N', 'V', 'R', 'D', 'E', 'I', 'G', 'J']; - -// immediately invoked function so we can access async/await -const start = async () => { - // chunk the list of states - const chunkStates = chunk(states, 5); - - // store output - const output = {}; - - // process all chunks - for (let i = 0; i < chunkStates.length; i += 1) { - const stateChunk = chunkStates[i]; - // loop through states - - stateChunk.forEach(async (state) => { - try { - let stations; - let next = `https://api.weather.gov/stations?state=${state}`; - do { - // get list and parse the JSON - // eslint-disable-next-line no-await-in-loop - const stationsRaw = await https(next); - stations = JSON.parse(stationsRaw); - // filter stations for 4 letter identifiers - const stationsFiltered4 = stations.features.filter((station) => station.properties.stationIdentifier.match(/^[A-Z]{4}$/)); - // filter against starting letter - const stationsFiltered = stationsFiltered4.filter((station) => !skipStations.includes(station.properties.stationIdentifier.slice(0, 1))); - // add each resulting station to the output - stationsFiltered.forEach((station) => { - const id = station.properties.stationIdentifier; - if (output[id]) { - console.log(`Duplicate station: ${state}-${id}`); - return; - } - output[id] = { - id, - city: station.properties.name, - state, - lat: station.geometry.coordinates[1], - lon: station.geometry.coordinates[0], - }; - }); - next = stations?.pagination?.next; - // write the output - // write the output - fs.writeFileSync(path.join(__dirname, 'output/stations.json'), JSON.stringify(output, null, 2)); - } - while (next && stations.features.length > 0); - console.log(`Complete: ${state}`); - return true; - } catch (e) { - console.error(`Unable to get state: ${state}`); - return false; - } - }); - } -}; - -// immediately invoked function allows access to async -(async () => { - await start(); -})(); diff --git a/dist/datagenerators/travelcities-raw.json b/dist/datagenerators/travelcities-raw.json deleted file mode 100644 index 30bdcc0..0000000 --- a/dist/datagenerators/travelcities-raw.json +++ /dev/null @@ -1,122 +0,0 @@ -[ - { - "Name": "Atlanta", - "Latitude": 33.749, - "Longitude": -84.388 - }, - { - "Name": "Boston", - "Latitude": 42.3584, - "Longitude": -71.0598 - }, - { - "Name": "Chicago", - "Latitude": 41.9796, - "Longitude": -87.9045 - }, - { - "Name": "Cleveland", - "Latitude": 41.4995, - "Longitude": -81.6954 - }, - { - "Name": "Dallas", - "Latitude": 32.8959, - "Longitude": -97.0372 - }, - { - "Name": "Denver", - "Latitude": 39.7391, - "Longitude": -104.9847 - }, - { - "Name": "Detroit", - "Latitude": 42.3314, - "Longitude": -83.0457 - }, - { - "Name": "Hartford", - "Latitude": 41.7637, - "Longitude": -72.6851 - }, - { - "Name": "Houston", - "Latitude": 29.7633, - "Longitude": -95.3633 - }, - { - "Name": "Indianapolis", - "Latitude": 39.7684, - "Longitude": -86.158 - }, - { - "Name": "Los Angeles", - "Latitude": 34.0522, - "Longitude": -118.2437 - }, - { - "Name": "Miami", - "Latitude": 25.7743, - "Longitude": -80.1937 - }, - { - "Name": "Minneapolis", - "Latitude": 44.98, - "Longitude": -93.2638 - }, - { - "Name": "New York", - "Latitude": 40.7142, - "Longitude": -74.0059 - }, - { - "Name": "Norfolk", - "Latitude": 36.8468, - "Longitude": -76.2852 - }, - { - "Name": "Orlando", - "Latitude": 28.5383, - "Longitude": -81.3792 - }, - { - "Name": "Philadelphia", - "Latitude": 39.9523, - "Longitude": -75.1638 - }, - { - "Name": "Pittsburgh", - "Latitude": 40.4406, - "Longitude": -79.9959 - }, - { - "Name": "St. Louis", - "Latitude": 38.6273, - "Longitude": -90.1979 - }, - { - "Name": "San Francisco", - "Latitude": 37.7749, - "Longitude": -122.4194 - }, - { - "Name": "Seattle", - "Latitude": 47.6062, - "Longitude": -122.3321 - }, - { - "Name": "Syracuse", - "Latitude": 43.0481, - "Longitude": -76.1474 - }, - { - "Name": "Tampa", - "Latitude": 27.9475, - "Longitude": -82.4584 - }, - { - "Name": "Washington DC", - "Latitude": 38.8951, - "Longitude": -77.0364 - } -] \ No newline at end of file diff --git a/dist/datagenerators/travelcities.js b/dist/datagenerators/travelcities.js deleted file mode 100644 index 6e39119..0000000 --- a/dist/datagenerators/travelcities.js +++ /dev/null @@ -1,41 +0,0 @@ -// look up points for each travel city -const fs = require('fs/promises'); -const chunk = require('./chunk'); -const https = require('./https'); - -(async () => { - // source data - const travelCities = JSON.parse(await fs.readFile('./datagenerators/travelcities-raw.json')); - - const result = []; - const dataChunks = chunk(travelCities, 5); - - // for loop intentional for use of await - // this keeps the api from getting overwhelmed - for (let i = 0; i < dataChunks.length; i += 1) { - const cityChunk = dataChunks[i]; - - // eslint-disable-next-line no-await-in-loop - const chunkResult = await Promise.all(cityChunk.map(async (city) => { - try { - const data = await https(`https://api.weather.gov/points/${city.Latitude},${city.Longitude}`); - const point = JSON.parse(data); - return { - ...city, - point: { - x: point.properties.gridX, - y: point.properties.gridY, - wfo: point.properties.gridId, - }, - }; - } catch (e) { - console.error(e); - return city; - } - })); - - result.push(...chunkResult); - } - - await fs.writeFile('./datagenerators/output/travelcities.json', JSON.stringify(result, null, ' ')); -})(); diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 177e99a..0000000 --- a/dist/index.js +++ /dev/null @@ -1,55 +0,0 @@ -// express -const express = require('express'); - -const app = express(); -const port = process.env.WS4KP_PORT ?? 8080; -const path = require('path'); - -// template engine -app.set('view engine', 'ejs'); - -// cors pass through -const fs = require('fs'); -const corsPassThru = require('./cors'); -const radarPassThru = require('./cors/radar'); -const outlookPassThru = require('./cors/outlook'); - -// cors pass-thru to api.weather.gov -app.get('/stations/*', corsPassThru); -app.get('/Conus/*', radarPassThru); -app.get('/products/*', outlookPassThru); - -// version -const { version } = JSON.parse(fs.readFileSync('package.json')); - -const index = (req, res) => { - res.render(path.join(__dirname, 'views/index'), { - production: false, - version, - }); -}; - -// debugging -if (process.env?.DIST === '1') { - // distribution - app.use('/images', express.static(path.join(__dirname, './server/images'))); - app.use('/fonts', express.static(path.join(__dirname, './server/fonts'))); - app.use('/scripts', express.static(path.join(__dirname, './server/scripts'))); - app.use('/', express.static(path.join(__dirname, './dist'))); -} else { - // debugging - app.get('/index.html', index); - app.get('/', index); - app.get('*', express.static(path.join(__dirname, './server'))); -} - -const server = app.listen(port, () => { - console.log(`Server listening on port ${port}`); -}); - -// graceful shutdown -process.on('SIGINT', () => { - server.close(() => { - console.log('Server closed'); - }); -}); diff --git a/dist/server/fonts/ReadMe.txt b/dist/server/fonts/ReadMe.txt deleted file mode 100644 index de5e599..0000000 --- a/dist/server/fonts/ReadMe.txt +++ /dev/null @@ -1,30 +0,0 @@ ---Star 3000-- - -Star3000.ttf - Standard text style for most screens (and Travel Cities title header) -Star3000 Small.ttf - Time/Date and some page headers -Star3000 Large.ttf - Travel Cities Forecast (Forecast portion only) -Star3000 Extra Large.ttf - Only used on some advertiser text -Star3000 Extended.ttf - Only used on some advertiser text -"Heavy" style is an emboldened version of the standard font (used on some STARs) - -Star3000 Outline.ttf - A contrast border (stroke) that surrounds the Star3000.ttf base font. When used, must be as a text layer undeneath the base font (and is usually black in color). -Star3000 Small Outline.ttf - A contrast border (stroke) that surrounds the Star3000 Small.ttf base font. When used, must be as a text layer undeneath the base font (and is usually black in color). -Star3000 Large Outline.ttf - A contrast border (stroke) that surrounds the Star3000 Large.ttf base font. When used, must be as a text layer undeneath the base font (and is usually black in color). - -***Outlines for other font styles are not currently available. - ---Star 4000-- - -Star4000.ttf - Standard text style for zone forecast, observation tables, regional map cities, almanac, extended forecast day/weather/temperature headers, Current Conditions right half data and most page header titles (also Travel Cities title header before Nov. 1992) -Star4000 Small.ttf - Time/Date, NWS Local Update page header, temperature header for Travel Cities Forecast (after Nov. 1992) -Star4000 Large.ttf - City names and temperature data on Travel Cities Forecast (after Nov. 1992), Extended forecast temperature values (after Feb. 1991), Current Conditions temperature value (after Mar. 1991) -Star4000 Large Compressed - Travel Cities Forecast (before Nov. 1992), regional map temperatures -Star4000 Large Compressed Numbers - Temperature values on regional forecast/observation maps -Star4000 Extended - A proportional width font used for the Current Conditions present weather description and wind data -Star 4 Radar.ttf - Radar airport I.D. - ---Star Jr.-- - -StarJr.ttf - Standard text style for most screens (and Travel Cities title header) -StarJr Small.ttf - Time/Date and some page headers -StarJr Compressed.ttf - Travel Cities Forecast \ No newline at end of file diff --git a/dist/server/fonts/Star 4 Radar.ttf b/dist/server/fonts/Star 4 Radar.ttf deleted file mode 100644 index 3b52590..0000000 Binary files a/dist/server/fonts/Star 4 Radar.ttf and /dev/null differ diff --git a/dist/server/fonts/Star 4 Radar.woff b/dist/server/fonts/Star 4 Radar.woff deleted file mode 100644 index 5d2f590..0000000 Binary files a/dist/server/fonts/Star 4 Radar.woff and /dev/null differ diff --git a/dist/server/fonts/Star4000 Extended.ttf b/dist/server/fonts/Star4000 Extended.ttf deleted file mode 100644 index 0f8c962..0000000 Binary files a/dist/server/fonts/Star4000 Extended.ttf and /dev/null differ diff --git a/dist/server/fonts/Star4000 Extended.woff b/dist/server/fonts/Star4000 Extended.woff deleted file mode 100644 index 58a8a39..0000000 Binary files a/dist/server/fonts/Star4000 Extended.woff and /dev/null differ diff --git a/dist/server/fonts/Star4000 Large Compressed Numbers.ttf b/dist/server/fonts/Star4000 Large Compressed Numbers.ttf deleted file mode 100644 index 17459e0..0000000 Binary files a/dist/server/fonts/Star4000 Large Compressed Numbers.ttf and /dev/null differ diff --git a/dist/server/fonts/Star4000 Large Compressed Numbers.woff b/dist/server/fonts/Star4000 Large Compressed Numbers.woff deleted file mode 100644 index 7b0398e..0000000 Binary files a/dist/server/fonts/Star4000 Large Compressed Numbers.woff and /dev/null differ diff --git a/dist/server/fonts/Star4000 Large Compressed.ttf b/dist/server/fonts/Star4000 Large Compressed.ttf deleted file mode 100644 index 936d759..0000000 Binary files a/dist/server/fonts/Star4000 Large Compressed.ttf and /dev/null differ diff --git a/dist/server/fonts/Star4000 Large Compressed.woff b/dist/server/fonts/Star4000 Large Compressed.woff deleted file mode 100644 index 67d03aa..0000000 Binary files a/dist/server/fonts/Star4000 Large Compressed.woff and /dev/null differ diff --git a/dist/server/fonts/Star4000 Large-old.ttf b/dist/server/fonts/Star4000 Large-old.ttf deleted file mode 100644 index 60400ec..0000000 Binary files a/dist/server/fonts/Star4000 Large-old.ttf and /dev/null differ diff --git a/dist/server/fonts/Star4000 Large.ttf b/dist/server/fonts/Star4000 Large.ttf deleted file mode 100644 index 8bf3a4d..0000000 Binary files a/dist/server/fonts/Star4000 Large.ttf and /dev/null differ diff --git a/dist/server/fonts/Star4000 Large.woff b/dist/server/fonts/Star4000 Large.woff deleted file mode 100644 index e207fba..0000000 Binary files a/dist/server/fonts/Star4000 Large.woff and /dev/null differ diff --git a/dist/server/fonts/Star4000 Small.ttf b/dist/server/fonts/Star4000 Small.ttf deleted file mode 100644 index f4428e4..0000000 Binary files a/dist/server/fonts/Star4000 Small.ttf and /dev/null differ diff --git a/dist/server/fonts/Star4000 Small.woff b/dist/server/fonts/Star4000 Small.woff deleted file mode 100644 index 577d009..0000000 Binary files a/dist/server/fonts/Star4000 Small.woff and /dev/null differ diff --git a/dist/server/fonts/Star4000.ttf b/dist/server/fonts/Star4000.ttf deleted file mode 100644 index 638855c..0000000 Binary files a/dist/server/fonts/Star4000.ttf and /dev/null differ diff --git a/dist/server/fonts/Star4000.woff b/dist/server/fonts/Star4000.woff deleted file mode 100644 index cb697b8..0000000 Binary files a/dist/server/fonts/Star4000.woff and /dev/null differ diff --git a/dist/server/fonts/Star4000LCN.woff b/dist/server/fonts/Star4000LCN.woff deleted file mode 100644 index 7b0398e..0000000 Binary files a/dist/server/fonts/Star4000LCN.woff and /dev/null differ diff --git a/dist/server/images/.directory b/dist/server/images/.directory deleted file mode 100644 index 5015231..0000000 --- a/dist/server/images/.directory +++ /dev/null @@ -1,4 +0,0 @@ -[Dolphin] -PreviewsShown=true -Timestamp=2020,10,1,21,36,7 -Version=4 diff --git a/dist/server/images/2/Blowing-Snow.gif b/dist/server/images/2/Blowing-Snow.gif deleted file mode 100644 index 02d6124..0000000 Binary files a/dist/server/images/2/Blowing-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/Clear.gif b/dist/server/images/2/Clear.gif deleted file mode 100644 index fc90f3c..0000000 Binary files a/dist/server/images/2/Clear.gif and /dev/null differ diff --git a/dist/server/images/2/Cloudy.gif b/dist/server/images/2/Cloudy.gif deleted file mode 100644 index 4dcc931..0000000 Binary files a/dist/server/images/2/Cloudy.gif and /dev/null differ diff --git a/dist/server/images/2/First-Quarter.gif b/dist/server/images/2/First-Quarter.gif deleted file mode 100644 index e43c466..0000000 Binary files a/dist/server/images/2/First-Quarter.gif and /dev/null differ diff --git a/dist/server/images/2/Fog.gif b/dist/server/images/2/Fog.gif deleted file mode 100644 index 952c848..0000000 Binary files a/dist/server/images/2/Fog.gif and /dev/null differ diff --git a/dist/server/images/2/Freezing-Rain-Sleet.gif b/dist/server/images/2/Freezing-Rain-Sleet.gif deleted file mode 100644 index 13138a5..0000000 Binary files a/dist/server/images/2/Freezing-Rain-Sleet.gif and /dev/null differ diff --git a/dist/server/images/2/Freezing-Rain.gif b/dist/server/images/2/Freezing-Rain.gif deleted file mode 100644 index 83cccaa..0000000 Binary files a/dist/server/images/2/Freezing-Rain.gif and /dev/null differ diff --git a/dist/server/images/2/Full-Moon.gif b/dist/server/images/2/Full-Moon.gif deleted file mode 100644 index c9e5813..0000000 Binary files a/dist/server/images/2/Full-Moon.gif and /dev/null differ diff --git a/dist/server/images/2/Heavy-Snow.gif b/dist/server/images/2/Heavy-Snow.gif deleted file mode 100644 index e3b6353..0000000 Binary files a/dist/server/images/2/Heavy-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/Ice-Snow.gif b/dist/server/images/2/Ice-Snow.gif deleted file mode 100644 index 85d8b68..0000000 Binary files a/dist/server/images/2/Ice-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/Isolated-Tstorms.gif b/dist/server/images/2/Isolated-Tstorms.gif deleted file mode 100644 index 770c942..0000000 Binary files a/dist/server/images/2/Isolated-Tstorms.gif and /dev/null differ diff --git a/dist/server/images/2/Last-Quarter.gif b/dist/server/images/2/Last-Quarter.gif deleted file mode 100644 index dd04d66..0000000 Binary files a/dist/server/images/2/Last-Quarter.gif and /dev/null differ diff --git a/dist/server/images/2/Light-Snow.gif b/dist/server/images/2/Light-Snow.gif deleted file mode 100644 index 896bfba..0000000 Binary files a/dist/server/images/2/Light-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/Mostly-Clear.gif b/dist/server/images/2/Mostly-Clear.gif deleted file mode 100644 index ce6be75..0000000 Binary files a/dist/server/images/2/Mostly-Clear.gif and /dev/null differ diff --git a/dist/server/images/2/Mostly-Cloudy.gif b/dist/server/images/2/Mostly-Cloudy.gif deleted file mode 100644 index a4b56b5..0000000 Binary files a/dist/server/images/2/Mostly-Cloudy.gif and /dev/null differ diff --git a/dist/server/images/2/New-Moon.gif b/dist/server/images/2/New-Moon.gif deleted file mode 100644 index 4283dd9..0000000 Binary files a/dist/server/images/2/New-Moon.gif and /dev/null differ diff --git a/dist/server/images/2/Partly-Clear.gif b/dist/server/images/2/Partly-Clear.gif deleted file mode 100644 index edd0b09..0000000 Binary files a/dist/server/images/2/Partly-Clear.gif and /dev/null differ diff --git a/dist/server/images/2/Partly-Cloudy.gif b/dist/server/images/2/Partly-Cloudy.gif deleted file mode 100644 index c0c2c1f..0000000 Binary files a/dist/server/images/2/Partly-Cloudy.gif and /dev/null differ diff --git a/dist/server/images/2/Rain-Snow.gif b/dist/server/images/2/Rain-Snow.gif deleted file mode 100644 index f456c20..0000000 Binary files a/dist/server/images/2/Rain-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/Rain.gif b/dist/server/images/2/Rain.gif deleted file mode 100644 index dcd7099..0000000 Binary files a/dist/server/images/2/Rain.gif and /dev/null differ diff --git a/dist/server/images/2/Scattered-Showers.gif b/dist/server/images/2/Scattered-Showers.gif deleted file mode 100644 index d1939a5..0000000 Binary files a/dist/server/images/2/Scattered-Showers.gif and /dev/null differ diff --git a/dist/server/images/2/Scattered-Snow-Showers.gif b/dist/server/images/2/Scattered-Snow-Showers.gif deleted file mode 100644 index b7a43c0..0000000 Binary files a/dist/server/images/2/Scattered-Snow-Showers.gif and /dev/null differ diff --git a/dist/server/images/2/Scattered-Tstorms.gif b/dist/server/images/2/Scattered-Tstorms.gif deleted file mode 100644 index 3f1114f..0000000 Binary files a/dist/server/images/2/Scattered-Tstorms.gif and /dev/null differ diff --git a/dist/server/images/2/Shower.gif b/dist/server/images/2/Shower.gif deleted file mode 100644 index 15ed5ef..0000000 Binary files a/dist/server/images/2/Shower.gif and /dev/null differ diff --git a/dist/server/images/2/Showers.gif b/dist/server/images/2/Showers.gif deleted file mode 100644 index b575f21..0000000 Binary files a/dist/server/images/2/Showers.gif and /dev/null differ diff --git a/dist/server/images/2/Sleet.gif b/dist/server/images/2/Sleet.gif deleted file mode 100644 index 2a098bb..0000000 Binary files a/dist/server/images/2/Sleet.gif and /dev/null differ diff --git a/dist/server/images/2/Snow-Sleet.gif b/dist/server/images/2/Snow-Sleet.gif deleted file mode 100644 index d4b2240..0000000 Binary files a/dist/server/images/2/Snow-Sleet.gif and /dev/null differ diff --git a/dist/server/images/2/Snow-to-Rain.gif b/dist/server/images/2/Snow-to-Rain.gif deleted file mode 100644 index 409510a..0000000 Binary files a/dist/server/images/2/Snow-to-Rain.gif and /dev/null differ diff --git a/dist/server/images/2/Sunny.gif b/dist/server/images/2/Sunny.gif deleted file mode 100644 index 17f3265..0000000 Binary files a/dist/server/images/2/Sunny.gif and /dev/null differ diff --git a/dist/server/images/2/Thunder.gif b/dist/server/images/2/Thunder.gif deleted file mode 100644 index afba50c..0000000 Binary files a/dist/server/images/2/Thunder.gif and /dev/null differ diff --git a/dist/server/images/2/ThunderSnow.gif b/dist/server/images/2/ThunderSnow.gif deleted file mode 100644 index 9ee4acf..0000000 Binary files a/dist/server/images/2/ThunderSnow.gif and /dev/null differ diff --git a/dist/server/images/2/Thunderstorm.gif b/dist/server/images/2/Thunderstorm.gif deleted file mode 100644 index 647fd22..0000000 Binary files a/dist/server/images/2/Thunderstorm.gif and /dev/null differ diff --git a/dist/server/images/2/Thunderstorms.gif b/dist/server/images/2/Thunderstorms.gif deleted file mode 100644 index 634f4ad..0000000 Binary files a/dist/server/images/2/Thunderstorms.gif and /dev/null differ diff --git a/dist/server/images/2/Windy.gif b/dist/server/images/2/Windy.gif deleted file mode 100644 index 4b4fc75..0000000 Binary files a/dist/server/images/2/Windy.gif and /dev/null differ diff --git a/dist/server/images/2/Wintry-Mix.gif b/dist/server/images/2/Wintry-Mix.gif deleted file mode 100644 index b710e61..0000000 Binary files a/dist/server/images/2/Wintry-Mix.gif and /dev/null differ diff --git a/dist/server/images/2/r/AM-Snow-1994.gif b/dist/server/images/2/r/AM-Snow-1994.gif deleted file mode 100644 index 28c8464..0000000 Binary files a/dist/server/images/2/r/AM-Snow-1994.gif and /dev/null differ diff --git a/dist/server/images/2/r/Blowing Snow.gif b/dist/server/images/2/r/Blowing Snow.gif deleted file mode 100644 index 9215046..0000000 Binary files a/dist/server/images/2/r/Blowing Snow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Clear-1992.gif b/dist/server/images/2/r/Clear-1992.gif deleted file mode 100644 index 89cece6..0000000 Binary files a/dist/server/images/2/r/Clear-1992.gif and /dev/null differ diff --git a/dist/server/images/2/r/Clear.gif b/dist/server/images/2/r/Clear.gif deleted file mode 100644 index 6d54b75..0000000 Binary files a/dist/server/images/2/r/Clear.gif and /dev/null differ diff --git a/dist/server/images/2/r/Cloudy 1990.gif b/dist/server/images/2/r/Cloudy 1990.gif deleted file mode 100644 index 846e6d4..0000000 Binary files a/dist/server/images/2/r/Cloudy 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Cloudy-Wind.gif b/dist/server/images/2/r/Cloudy-Wind.gif deleted file mode 100644 index 730ed17..0000000 Binary files a/dist/server/images/2/r/Cloudy-Wind.gif and /dev/null differ diff --git a/dist/server/images/2/r/Cloudy.gif b/dist/server/images/2/r/Cloudy.gif deleted file mode 100644 index 2d88edd..0000000 Binary files a/dist/server/images/2/r/Cloudy.gif and /dev/null differ diff --git a/dist/server/images/2/r/Flurries.gif b/dist/server/images/2/r/Flurries.gif deleted file mode 100644 index 6c5a7a1..0000000 Binary files a/dist/server/images/2/r/Flurries.gif and /dev/null differ diff --git a/dist/server/images/2/r/Fog.gif b/dist/server/images/2/r/Fog.gif deleted file mode 100644 index ed07244..0000000 Binary files a/dist/server/images/2/r/Fog.gif and /dev/null differ diff --git a/dist/server/images/2/r/Freezing-Rain-1991.gif b/dist/server/images/2/r/Freezing-Rain-1991.gif deleted file mode 100644 index f5c9d7e..0000000 Binary files a/dist/server/images/2/r/Freezing-Rain-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Freezing-Rain-1992.gif b/dist/server/images/2/r/Freezing-Rain-1992.gif deleted file mode 100644 index d78a4da..0000000 Binary files a/dist/server/images/2/r/Freezing-Rain-1992.gif and /dev/null differ diff --git a/dist/server/images/2/r/Freezing-Rain-Sleet-1992.gif b/dist/server/images/2/r/Freezing-Rain-Sleet-1992.gif deleted file mode 100644 index f9e29d2..0000000 Binary files a/dist/server/images/2/r/Freezing-Rain-Sleet-1992.gif and /dev/null differ diff --git a/dist/server/images/2/r/Freezing-Rain-Sleet.gif b/dist/server/images/2/r/Freezing-Rain-Sleet.gif deleted file mode 100644 index a653ae7..0000000 Binary files a/dist/server/images/2/r/Freezing-Rain-Sleet.gif and /dev/null differ diff --git a/dist/server/images/2/r/Freezing-Rain-Snow-1992.gif b/dist/server/images/2/r/Freezing-Rain-Snow-1992.gif deleted file mode 100644 index bfcaa9b..0000000 Binary files a/dist/server/images/2/r/Freezing-Rain-Snow-1992.gif and /dev/null differ diff --git a/dist/server/images/2/r/Freezing-Rain-Snow.gif b/dist/server/images/2/r/Freezing-Rain-Snow.gif deleted file mode 100644 index 97d5df1..0000000 Binary files a/dist/server/images/2/r/Freezing-Rain-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Freezing-Rain.gif b/dist/server/images/2/r/Freezing-Rain.gif deleted file mode 100644 index 89526ed..0000000 Binary files a/dist/server/images/2/r/Freezing-Rain.gif and /dev/null differ diff --git a/dist/server/images/2/r/Frigid.gif b/dist/server/images/2/r/Frigid.gif deleted file mode 100644 index 16ef081..0000000 Binary files a/dist/server/images/2/r/Frigid.gif and /dev/null differ diff --git a/dist/server/images/2/r/Frz-Rain-Snow-1991.gif b/dist/server/images/2/r/Frz-Rain-Snow-1991.gif deleted file mode 100644 index b128920..0000000 Binary files a/dist/server/images/2/r/Frz-Rain-Snow-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Heavy Snow.gif b/dist/server/images/2/r/Heavy Snow.gif deleted file mode 100644 index ca80df2..0000000 Binary files a/dist/server/images/2/r/Heavy Snow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Heavy-Snow-1994.gif b/dist/server/images/2/r/Heavy-Snow-1994.gif deleted file mode 100644 index 99ef424..0000000 Binary files a/dist/server/images/2/r/Heavy-Snow-1994.gif and /dev/null differ diff --git a/dist/server/images/2/r/Heavy-Snow.gif b/dist/server/images/2/r/Heavy-Snow.gif deleted file mode 100644 index 3ed01c6..0000000 Binary files a/dist/server/images/2/r/Heavy-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Hot.gif b/dist/server/images/2/r/Hot.gif deleted file mode 100644 index 4c8b4ad..0000000 Binary files a/dist/server/images/2/r/Hot.gif and /dev/null differ diff --git a/dist/server/images/2/r/Isolated-Tstorms.gif b/dist/server/images/2/r/Isolated-Tstorms.gif deleted file mode 100644 index ab11895..0000000 Binary files a/dist/server/images/2/r/Isolated-Tstorms.gif and /dev/null differ diff --git a/dist/server/images/2/r/Light Snow.gif b/dist/server/images/2/r/Light Snow.gif deleted file mode 100644 index de641d2..0000000 Binary files a/dist/server/images/2/r/Light Snow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Light-Snow.gif b/dist/server/images/2/r/Light-Snow.gif deleted file mode 100644 index 23d6294..0000000 Binary files a/dist/server/images/2/r/Light-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Mostly Clear.gif b/dist/server/images/2/r/Mostly Clear.gif deleted file mode 100644 index dbfdb39..0000000 Binary files a/dist/server/images/2/r/Mostly Clear.gif and /dev/null differ diff --git a/dist/server/images/2/r/Mostly-Clear.gif b/dist/server/images/2/r/Mostly-Clear.gif deleted file mode 100644 index d99f9ca..0000000 Binary files a/dist/server/images/2/r/Mostly-Clear.gif and /dev/null differ diff --git a/dist/server/images/2/r/Mostly-Cloudy-1991.gif b/dist/server/images/2/r/Mostly-Cloudy-1991.gif deleted file mode 100644 index a31bb52..0000000 Binary files a/dist/server/images/2/r/Mostly-Cloudy-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Mostly-Cloudy-1994.gif b/dist/server/images/2/r/Mostly-Cloudy-1994.gif deleted file mode 100644 index 62409c1..0000000 Binary files a/dist/server/images/2/r/Mostly-Cloudy-1994.gif and /dev/null differ diff --git a/dist/server/images/2/r/Mostly-Cloudy.gif b/dist/server/images/2/r/Mostly-Cloudy.gif deleted file mode 100644 index ffa2e31..0000000 Binary files a/dist/server/images/2/r/Mostly-Cloudy.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Cloudy 1990.gif b/dist/server/images/2/r/Motionless/Cloudy 1990.gif deleted file mode 100644 index 846e6d4..0000000 Binary files a/dist/server/images/2/r/Motionless/Cloudy 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Flurries.gif b/dist/server/images/2/r/Motionless/Flurries.gif deleted file mode 100644 index 6c5a7a1..0000000 Binary files a/dist/server/images/2/r/Motionless/Flurries.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Fog.gif b/dist/server/images/2/r/Motionless/Fog.gif deleted file mode 100644 index ed07244..0000000 Binary files a/dist/server/images/2/r/Motionless/Fog.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Freezing Rain 1990.gif b/dist/server/images/2/r/Motionless/Freezing Rain 1990.gif deleted file mode 100644 index 8c5d0e9..0000000 Binary files a/dist/server/images/2/r/Motionless/Freezing Rain 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Frigid.gif b/dist/server/images/2/r/Motionless/Frigid.gif deleted file mode 100644 index 16ef081..0000000 Binary files a/dist/server/images/2/r/Motionless/Frigid.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Frz Rain-Snow 1990.gif b/dist/server/images/2/r/Motionless/Frz Rain-Snow 1990.gif deleted file mode 100644 index 6a65519..0000000 Binary files a/dist/server/images/2/r/Motionless/Frz Rain-Snow 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Heavy-Snow.gif b/dist/server/images/2/r/Motionless/Heavy-Snow.gif deleted file mode 100644 index a5c0c27..0000000 Binary files a/dist/server/images/2/r/Motionless/Heavy-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Mostly Cloudy 1990.gif b/dist/server/images/2/r/Motionless/Mostly Cloudy 1990.gif deleted file mode 100644 index a04cc21..0000000 Binary files a/dist/server/images/2/r/Motionless/Mostly Cloudy 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Partly Cloudy 1990.gif b/dist/server/images/2/r/Motionless/Partly Cloudy 1990.gif deleted file mode 100644 index 034864e..0000000 Binary files a/dist/server/images/2/r/Motionless/Partly Cloudy 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Rain 1990.gif b/dist/server/images/2/r/Motionless/Rain 1990.gif deleted file mode 100644 index 3ddcd74..0000000 Binary files a/dist/server/images/2/r/Motionless/Rain 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Rain-Snow 1990.gif b/dist/server/images/2/r/Motionless/Rain-Snow 1990.gif deleted file mode 100644 index bb6046d..0000000 Binary files a/dist/server/images/2/r/Motionless/Rain-Snow 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Scatd Showers 1990.gif b/dist/server/images/2/r/Motionless/Scatd Showers 1990.gif deleted file mode 100644 index 0d525d4..0000000 Binary files a/dist/server/images/2/r/Motionless/Scatd Showers 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Scatd Snow Showers 1990.gif b/dist/server/images/2/r/Motionless/Scatd Snow Showers 1990.gif deleted file mode 100644 index 0bf1392..0000000 Binary files a/dist/server/images/2/r/Motionless/Scatd Snow Showers 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Scattered Tstorms 1990.gif b/dist/server/images/2/r/Motionless/Scattered Tstorms 1990.gif deleted file mode 100644 index 3b92d23..0000000 Binary files a/dist/server/images/2/r/Motionless/Scattered Tstorms 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Shower 1990.gif b/dist/server/images/2/r/Motionless/Shower 1990.gif deleted file mode 100644 index 22a130c..0000000 Binary files a/dist/server/images/2/r/Motionless/Shower 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Sleet 1990.gif b/dist/server/images/2/r/Motionless/Sleet 1990.gif deleted file mode 100644 index 19967d9..0000000 Binary files a/dist/server/images/2/r/Motionless/Sleet 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Snow 1990.gif b/dist/server/images/2/r/Motionless/Snow 1990.gif deleted file mode 100644 index 676ded6..0000000 Binary files a/dist/server/images/2/r/Motionless/Snow 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Sunny 1990.gif b/dist/server/images/2/r/Motionless/Sunny 1990.gif deleted file mode 100644 index 13dbf93..0000000 Binary files a/dist/server/images/2/r/Motionless/Sunny 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Thumbs.db b/dist/server/images/2/r/Motionless/Thumbs.db deleted file mode 100644 index f435203..0000000 Binary files a/dist/server/images/2/r/Motionless/Thumbs.db and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Thunderstorm 1990.gif b/dist/server/images/2/r/Motionless/Thunderstorm 1990.gif deleted file mode 100644 index 2387776..0000000 Binary files a/dist/server/images/2/r/Motionless/Thunderstorm 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Wind.gif b/dist/server/images/2/r/Motionless/Wind.gif deleted file mode 100644 index a5dc99e..0000000 Binary files a/dist/server/images/2/r/Motionless/Wind.gif and /dev/null differ diff --git a/dist/server/images/2/r/Motionless/Wintry Mix 1990.gif b/dist/server/images/2/r/Motionless/Wintry Mix 1990.gif deleted file mode 100644 index 57d5474..0000000 Binary files a/dist/server/images/2/r/Motionless/Wintry Mix 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Partly Clear.gif b/dist/server/images/2/r/Partly Clear.gif deleted file mode 100644 index 5765829..0000000 Binary files a/dist/server/images/2/r/Partly Clear.gif and /dev/null differ diff --git a/dist/server/images/2/r/Partly-Clear-1994.gif b/dist/server/images/2/r/Partly-Clear-1994.gif deleted file mode 100644 index 61c5c37..0000000 Binary files a/dist/server/images/2/r/Partly-Clear-1994.gif and /dev/null differ diff --git a/dist/server/images/2/r/Partly-Clear.gif b/dist/server/images/2/r/Partly-Clear.gif deleted file mode 100644 index 62d9349..0000000 Binary files a/dist/server/images/2/r/Partly-Clear.gif and /dev/null differ diff --git a/dist/server/images/2/r/Partly-Cloudy-1991.gif b/dist/server/images/2/r/Partly-Cloudy-1991.gif deleted file mode 100644 index 555a7ca..0000000 Binary files a/dist/server/images/2/r/Partly-Cloudy-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Partly-Cloudy.gif b/dist/server/images/2/r/Partly-Cloudy.gif deleted file mode 100644 index 10e2ff0..0000000 Binary files a/dist/server/images/2/r/Partly-Cloudy.gif and /dev/null differ diff --git a/dist/server/images/2/r/Rain-1991.gif b/dist/server/images/2/r/Rain-1991.gif deleted file mode 100644 index edf1b66..0000000 Binary files a/dist/server/images/2/r/Rain-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Rain-1992.gif b/dist/server/images/2/r/Rain-1992.gif deleted file mode 100644 index 52afcc2..0000000 Binary files a/dist/server/images/2/r/Rain-1992.gif and /dev/null differ diff --git a/dist/server/images/2/r/Rain-Sleet.gif b/dist/server/images/2/r/Rain-Sleet.gif deleted file mode 100644 index 1d4330d..0000000 Binary files a/dist/server/images/2/r/Rain-Sleet.gif and /dev/null differ diff --git a/dist/server/images/2/r/Rain-Snow-1991.gif b/dist/server/images/2/r/Rain-Snow-1991.gif deleted file mode 100644 index 02bf13b..0000000 Binary files a/dist/server/images/2/r/Rain-Snow-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Rain-Snow-1992.gif b/dist/server/images/2/r/Rain-Snow-1992.gif deleted file mode 100644 index 9d76977..0000000 Binary files a/dist/server/images/2/r/Rain-Snow-1992.gif and /dev/null differ diff --git a/dist/server/images/2/r/Rain-Snow.gif b/dist/server/images/2/r/Rain-Snow.gif deleted file mode 100644 index 801014a..0000000 Binary files a/dist/server/images/2/r/Rain-Snow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Rain-Wind-1994.gif b/dist/server/images/2/r/Rain-Wind-1994.gif deleted file mode 100644 index f57618c..0000000 Binary files a/dist/server/images/2/r/Rain-Wind-1994.gif and /dev/null differ diff --git a/dist/server/images/2/r/Rain.gif b/dist/server/images/2/r/Rain.gif deleted file mode 100644 index 0a10f26..0000000 Binary files a/dist/server/images/2/r/Rain.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scatd-Showers-1991.gif b/dist/server/images/2/r/Scatd-Showers-1991.gif deleted file mode 100644 index 0f7591c..0000000 Binary files a/dist/server/images/2/r/Scatd-Showers-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scatd-Snow-Showers-1991.gif b/dist/server/images/2/r/Scatd-Snow-Showers-1991.gif deleted file mode 100644 index 2f74d4b..0000000 Binary files a/dist/server/images/2/r/Scatd-Snow-Showers-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scattered-Showers-1994.gif b/dist/server/images/2/r/Scattered-Showers-1994.gif deleted file mode 100644 index f888e13..0000000 Binary files a/dist/server/images/2/r/Scattered-Showers-1994.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scattered-Showers.gif b/dist/server/images/2/r/Scattered-Showers.gif deleted file mode 100644 index 2fc63fc..0000000 Binary files a/dist/server/images/2/r/Scattered-Showers.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scattered-Snow-Showers.gif b/dist/server/images/2/r/Scattered-Snow-Showers.gif deleted file mode 100644 index 13a34b7..0000000 Binary files a/dist/server/images/2/r/Scattered-Snow-Showers.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scattered-Tstorms-1991.gif b/dist/server/images/2/r/Scattered-Tstorms-1991.gif deleted file mode 100644 index bc803b6..0000000 Binary files a/dist/server/images/2/r/Scattered-Tstorms-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scattered-Tstorms-1992.gif b/dist/server/images/2/r/Scattered-Tstorms-1992.gif deleted file mode 100644 index 9559ba6..0000000 Binary files a/dist/server/images/2/r/Scattered-Tstorms-1992.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scattered-Tstorms-1994.gif b/dist/server/images/2/r/Scattered-Tstorms-1994.gif deleted file mode 100644 index 7ec06a6..0000000 Binary files a/dist/server/images/2/r/Scattered-Tstorms-1994.gif and /dev/null differ diff --git a/dist/server/images/2/r/Scattered-Tstorms.gif b/dist/server/images/2/r/Scattered-Tstorms.gif deleted file mode 100644 index 2c6fe06..0000000 Binary files a/dist/server/images/2/r/Scattered-Tstorms.gif and /dev/null differ diff --git a/dist/server/images/2/r/Shower-1991.gif b/dist/server/images/2/r/Shower-1991.gif deleted file mode 100644 index 264a475..0000000 Binary files a/dist/server/images/2/r/Shower-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Shower.gif b/dist/server/images/2/r/Shower.gif deleted file mode 100644 index b71afd1..0000000 Binary files a/dist/server/images/2/r/Shower.gif and /dev/null differ diff --git a/dist/server/images/2/r/Sleet-1991.gif b/dist/server/images/2/r/Sleet-1991.gif deleted file mode 100644 index b158042..0000000 Binary files a/dist/server/images/2/r/Sleet-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Sleet.gif b/dist/server/images/2/r/Sleet.gif deleted file mode 100644 index b158042..0000000 Binary files a/dist/server/images/2/r/Sleet.gif and /dev/null differ diff --git a/dist/server/images/2/r/Snow 1990.gif b/dist/server/images/2/r/Snow 1990.gif deleted file mode 100644 index 676ded6..0000000 Binary files a/dist/server/images/2/r/Snow 1990.gif and /dev/null differ diff --git a/dist/server/images/2/r/Snow-Sleet.gif b/dist/server/images/2/r/Snow-Sleet.gif deleted file mode 100644 index cf89b5e..0000000 Binary files a/dist/server/images/2/r/Snow-Sleet.gif and /dev/null differ diff --git a/dist/server/images/2/r/Sunny-Wind-1994.gif b/dist/server/images/2/r/Sunny-Wind-1994.gif deleted file mode 100644 index ac01b02..0000000 Binary files a/dist/server/images/2/r/Sunny-Wind-1994.gif and /dev/null differ diff --git a/dist/server/images/2/r/Sunny.gif b/dist/server/images/2/r/Sunny.gif deleted file mode 100644 index 6a5f1dd..0000000 Binary files a/dist/server/images/2/r/Sunny.gif and /dev/null differ diff --git a/dist/server/images/2/r/Thunder.gif b/dist/server/images/2/r/Thunder.gif deleted file mode 100644 index aff65a3..0000000 Binary files a/dist/server/images/2/r/Thunder.gif and /dev/null differ diff --git a/dist/server/images/2/r/ThunderSnow.gif b/dist/server/images/2/r/ThunderSnow.gif deleted file mode 100644 index dd74e6e..0000000 Binary files a/dist/server/images/2/r/ThunderSnow.gif and /dev/null differ diff --git a/dist/server/images/2/r/Thunderstorm-1991.gif b/dist/server/images/2/r/Thunderstorm-1991.gif deleted file mode 100644 index 5cdd41b..0000000 Binary files a/dist/server/images/2/r/Thunderstorm-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Thunderstorm.gif b/dist/server/images/2/r/Thunderstorm.gif deleted file mode 100644 index 08cd23a..0000000 Binary files a/dist/server/images/2/r/Thunderstorm.gif and /dev/null differ diff --git a/dist/server/images/2/r/Wind.gif b/dist/server/images/2/r/Wind.gif deleted file mode 100644 index 4ffd9e3..0000000 Binary files a/dist/server/images/2/r/Wind.gif and /dev/null differ diff --git a/dist/server/images/2/r/Windy.gif b/dist/server/images/2/r/Windy.gif deleted file mode 100644 index 473fb55..0000000 Binary files a/dist/server/images/2/r/Windy.gif and /dev/null differ diff --git a/dist/server/images/2/r/Wintry-Mix-1991.gif b/dist/server/images/2/r/Wintry-Mix-1991.gif deleted file mode 100644 index cc67d2d..0000000 Binary files a/dist/server/images/2/r/Wintry-Mix-1991.gif and /dev/null differ diff --git a/dist/server/images/2/r/Wintry-Mix-1992.gif b/dist/server/images/2/r/Wintry-Mix-1992.gif deleted file mode 100644 index 52574d7..0000000 Binary files a/dist/server/images/2/r/Wintry-Mix-1992.gif and /dev/null differ diff --git a/dist/server/images/2/r/Wintry-Mix.gif b/dist/server/images/2/r/Wintry-Mix.gif deleted file mode 100644 index 3bf8982..0000000 Binary files a/dist/server/images/2/r/Wintry-Mix.gif and /dev/null differ diff --git a/dist/server/images/4000RadarMap.jpg b/dist/server/images/4000RadarMap.jpg deleted file mode 100644 index de58d31..0000000 Binary files a/dist/server/images/4000RadarMap.jpg and /dev/null differ diff --git a/dist/server/images/4000RadarMap.png b/dist/server/images/4000RadarMap.png deleted file mode 100644 index 3d6778f..0000000 Binary files a/dist/server/images/4000RadarMap.png and /dev/null differ diff --git a/dist/server/images/4000RadarMap2.gif b/dist/server/images/4000RadarMap2.gif deleted file mode 100644 index fb0f0f5..0000000 Binary files a/dist/server/images/4000RadarMap2.gif and /dev/null differ diff --git a/dist/server/images/4000RadarMap2.jpg b/dist/server/images/4000RadarMap2.jpg deleted file mode 100644 index a6f535d..0000000 Binary files a/dist/server/images/4000RadarMap2.jpg and /dev/null differ diff --git a/dist/server/images/4000RadarMap2.png b/dist/server/images/4000RadarMap2.png deleted file mode 100644 index 990ca58..0000000 Binary files a/dist/server/images/4000RadarMap2.png and /dev/null differ diff --git a/dist/server/images/4000RadarMap2_1.jpg b/dist/server/images/4000RadarMap2_1.jpg deleted file mode 100644 index 942bb40..0000000 Binary files a/dist/server/images/4000RadarMap2_1.jpg and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap.gif b/dist/server/images/AlaskaRadarMap.gif deleted file mode 100644 index f1917c9..0000000 Binary files a/dist/server/images/AlaskaRadarMap.gif and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap.png b/dist/server/images/AlaskaRadarMap.png deleted file mode 100644 index 2694bb9..0000000 Binary files a/dist/server/images/AlaskaRadarMap.png and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap1.png b/dist/server/images/AlaskaRadarMap1.png deleted file mode 100644 index 71fa627..0000000 Binary files a/dist/server/images/AlaskaRadarMap1.png and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap2.bmp b/dist/server/images/AlaskaRadarMap2.bmp deleted file mode 100644 index 1301e5f..0000000 Binary files a/dist/server/images/AlaskaRadarMap2.bmp and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap2.png b/dist/server/images/AlaskaRadarMap2.png deleted file mode 100644 index 71fa627..0000000 Binary files a/dist/server/images/AlaskaRadarMap2.png and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap3.png b/dist/server/images/AlaskaRadarMap3.png deleted file mode 100644 index 7f9d268..0000000 Binary files a/dist/server/images/AlaskaRadarMap3.png and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap4.png b/dist/server/images/AlaskaRadarMap4.png deleted file mode 100644 index ead41e1..0000000 Binary files a/dist/server/images/AlaskaRadarMap4.png and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap5.png b/dist/server/images/AlaskaRadarMap5.png deleted file mode 100644 index 4b27dd0..0000000 Binary files a/dist/server/images/AlaskaRadarMap5.png and /dev/null differ diff --git a/dist/server/images/AlaskaRadarMap6.png b/dist/server/images/AlaskaRadarMap6.png deleted file mode 100644 index 2206bd1..0000000 Binary files a/dist/server/images/AlaskaRadarMap6.png and /dev/null differ diff --git a/dist/server/images/BackGround1.png b/dist/server/images/BackGround1.png deleted file mode 100644 index 4e2602a..0000000 Binary files a/dist/server/images/BackGround1.png and /dev/null differ diff --git a/dist/server/images/BackGround1_1.png b/dist/server/images/BackGround1_1.png deleted file mode 100644 index c5b0870..0000000 Binary files a/dist/server/images/BackGround1_1.png and /dev/null differ diff --git a/dist/server/images/BackGround1_1_Chart.png b/dist/server/images/BackGround1_1_Chart.png deleted file mode 100644 index 7aa63fa..0000000 Binary files a/dist/server/images/BackGround1_1_Chart.png and /dev/null differ diff --git a/dist/server/images/BackGround1_1_wide.png b/dist/server/images/BackGround1_1_wide.png deleted file mode 100644 index 6e91241..0000000 Binary files a/dist/server/images/BackGround1_1_wide.png and /dev/null differ diff --git a/dist/server/images/BackGround1_2.png b/dist/server/images/BackGround1_2.png deleted file mode 100644 index fbb3354..0000000 Binary files a/dist/server/images/BackGround1_2.png and /dev/null differ diff --git a/dist/server/images/BackGround1_2_1.png b/dist/server/images/BackGround1_2_1.png deleted file mode 100644 index 7c88c4b..0000000 Binary files a/dist/server/images/BackGround1_2_1.png and /dev/null differ diff --git a/dist/server/images/BackGround1_2_2.png b/dist/server/images/BackGround1_2_2.png deleted file mode 100644 index 331c214..0000000 Binary files a/dist/server/images/BackGround1_2_2.png and /dev/null differ diff --git a/dist/server/images/BackGround1_3_1.png b/dist/server/images/BackGround1_3_1.png deleted file mode 100644 index cd4ed11..0000000 Binary files a/dist/server/images/BackGround1_3_1.png and /dev/null differ diff --git a/dist/server/images/BackGround2.png b/dist/server/images/BackGround2.png deleted file mode 100644 index 031d265..0000000 Binary files a/dist/server/images/BackGround2.png and /dev/null differ diff --git a/dist/server/images/BackGround2_1.png b/dist/server/images/BackGround2_1.png deleted file mode 100644 index adcdebc..0000000 Binary files a/dist/server/images/BackGround2_1.png and /dev/null differ diff --git a/dist/server/images/BackGround2_2.png b/dist/server/images/BackGround2_2.png deleted file mode 100644 index e31dfd0..0000000 Binary files a/dist/server/images/BackGround2_2.png and /dev/null differ diff --git a/dist/server/images/BackGround3.png b/dist/server/images/BackGround3.png deleted file mode 100644 index 65b381b..0000000 Binary files a/dist/server/images/BackGround3.png and /dev/null differ diff --git a/dist/server/images/BackGround3_1.png b/dist/server/images/BackGround3_1.png deleted file mode 100644 index af76a16..0000000 Binary files a/dist/server/images/BackGround3_1.png and /dev/null differ diff --git a/dist/server/images/BackGround3_2.png b/dist/server/images/BackGround3_2.png deleted file mode 100644 index c693a9b..0000000 Binary files a/dist/server/images/BackGround3_2.png and /dev/null differ diff --git a/dist/server/images/BackGround4.png b/dist/server/images/BackGround4.png deleted file mode 100644 index 9d8c5c6..0000000 Binary files a/dist/server/images/BackGround4.png and /dev/null differ diff --git a/dist/server/images/BackGround4_1.png b/dist/server/images/BackGround4_1.png deleted file mode 100644 index 5cf8526..0000000 Binary files a/dist/server/images/BackGround4_1.png and /dev/null differ diff --git a/dist/server/images/BackGround4_1_wide.png b/dist/server/images/BackGround4_1_wide.png deleted file mode 100644 index 70c03a9..0000000 Binary files a/dist/server/images/BackGround4_1_wide.png and /dev/null differ diff --git a/dist/server/images/BackGround4_2.png b/dist/server/images/BackGround4_2.png deleted file mode 100644 index 5cf8526..0000000 Binary files a/dist/server/images/BackGround4_2.png and /dev/null differ diff --git a/dist/server/images/BackGround5.png b/dist/server/images/BackGround5.png deleted file mode 100644 index 849f6b8..0000000 Binary files a/dist/server/images/BackGround5.png and /dev/null differ diff --git a/dist/server/images/BackGround5_1.png b/dist/server/images/BackGround5_1.png deleted file mode 100644 index f116c52..0000000 Binary files a/dist/server/images/BackGround5_1.png and /dev/null differ diff --git a/dist/server/images/BackGround5_2.png b/dist/server/images/BackGround5_2.png deleted file mode 100644 index 4a026fe..0000000 Binary files a/dist/server/images/BackGround5_2.png and /dev/null differ diff --git a/dist/server/images/BackGround6.png b/dist/server/images/BackGround6.png deleted file mode 100644 index 1d8a2ec..0000000 Binary files a/dist/server/images/BackGround6.png and /dev/null differ diff --git a/dist/server/images/BackGround6_1.png b/dist/server/images/BackGround6_1.png deleted file mode 100644 index 9d87bab..0000000 Binary files a/dist/server/images/BackGround6_1.png and /dev/null differ diff --git a/dist/server/images/BackGround6_2.png b/dist/server/images/BackGround6_2.png deleted file mode 100644 index 823716e..0000000 Binary files a/dist/server/images/BackGround6_2.png and /dev/null differ diff --git a/dist/server/images/BackGround7.png b/dist/server/images/BackGround7.png deleted file mode 100644 index bc34232..0000000 Binary files a/dist/server/images/BackGround7.png and /dev/null differ diff --git a/dist/server/images/BackGround8_1 - Copy (2).png b/dist/server/images/BackGround8_1 - Copy (2).png deleted file mode 100644 index 120cc0f..0000000 Binary files a/dist/server/images/BackGround8_1 - Copy (2).png and /dev/null differ diff --git a/dist/server/images/BackGround8_1.png b/dist/server/images/BackGround8_1.png deleted file mode 100644 index 120cc0f..0000000 Binary files a/dist/server/images/BackGround8_1.png and /dev/null differ diff --git a/dist/server/images/BackGround8_1_1.png b/dist/server/images/BackGround8_1_1.png deleted file mode 100644 index 3f8da7e..0000000 Binary files a/dist/server/images/BackGround8_1_1.png and /dev/null differ diff --git a/dist/server/images/BackGround8_2.png b/dist/server/images/BackGround8_2.png deleted file mode 100644 index 45504d3..0000000 Binary files a/dist/server/images/BackGround8_2.png and /dev/null differ diff --git a/dist/server/images/BackGround9_1.png b/dist/server/images/BackGround9_1.png deleted file mode 100644 index b6ac41b..0000000 Binary files a/dist/server/images/BackGround9_1.png and /dev/null differ diff --git a/dist/server/images/BackGround9_2.png b/dist/server/images/BackGround9_2.png deleted file mode 100644 index 5f216af..0000000 Binary files a/dist/server/images/BackGround9_2.png and /dev/null differ diff --git a/dist/server/images/Basemap.png b/dist/server/images/Basemap.png deleted file mode 100644 index 8b2caaa..0000000 Binary files a/dist/server/images/Basemap.png and /dev/null differ diff --git a/dist/server/images/Basemap2.png b/dist/server/images/Basemap2.png deleted file mode 100644 index 911bd92..0000000 Binary files a/dist/server/images/Basemap2.png and /dev/null differ diff --git a/dist/server/images/Blowing-Snow.gif b/dist/server/images/Blowing-Snow.gif deleted file mode 100644 index 02d6124..0000000 Binary files a/dist/server/images/Blowing-Snow.gif and /dev/null differ diff --git a/dist/server/images/CC_Clear0.gif b/dist/server/images/CC_Clear0.gif deleted file mode 100644 index 0287375..0000000 Binary files a/dist/server/images/CC_Clear0.gif and /dev/null differ diff --git a/dist/server/images/CC_Clear1.gif b/dist/server/images/CC_Clear1.gif deleted file mode 100644 index d9551e9..0000000 Binary files a/dist/server/images/CC_Clear1.gif and /dev/null differ diff --git a/dist/server/images/CC_Cloudy.gif b/dist/server/images/CC_Cloudy.gif deleted file mode 100644 index abfeee6..0000000 Binary files a/dist/server/images/CC_Cloudy.gif and /dev/null differ diff --git a/dist/server/images/CC_Fog.gif b/dist/server/images/CC_Fog.gif deleted file mode 100644 index 2e9b089..0000000 Binary files a/dist/server/images/CC_Fog.gif and /dev/null differ diff --git a/dist/server/images/CC_FreezingRain.gif b/dist/server/images/CC_FreezingRain.gif deleted file mode 100644 index 8f1bb74..0000000 Binary files a/dist/server/images/CC_FreezingRain.gif and /dev/null differ diff --git a/dist/server/images/CC_Mix.gif b/dist/server/images/CC_Mix.gif deleted file mode 100644 index 019dfca..0000000 Binary files a/dist/server/images/CC_Mix.gif and /dev/null differ diff --git a/dist/server/images/CC_MostlyCloudy0.gif b/dist/server/images/CC_MostlyCloudy0.gif deleted file mode 100644 index 1efdbbd..0000000 Binary files a/dist/server/images/CC_MostlyCloudy0.gif and /dev/null differ diff --git a/dist/server/images/CC_MostlyCloudy1.gif b/dist/server/images/CC_MostlyCloudy1.gif deleted file mode 100644 index ddfa6b2..0000000 Binary files a/dist/server/images/CC_MostlyCloudy1.gif and /dev/null differ diff --git a/dist/server/images/CC_PartlyCloudy0.gif b/dist/server/images/CC_PartlyCloudy0.gif deleted file mode 100644 index c1621b0..0000000 Binary files a/dist/server/images/CC_PartlyCloudy0.gif and /dev/null differ diff --git a/dist/server/images/CC_PartlyCloudy1.gif b/dist/server/images/CC_PartlyCloudy1.gif deleted file mode 100644 index 00c9390..0000000 Binary files a/dist/server/images/CC_PartlyCloudy1.gif and /dev/null differ diff --git a/dist/server/images/CC_Rain.gif b/dist/server/images/CC_Rain.gif deleted file mode 100644 index 66856c5..0000000 Binary files a/dist/server/images/CC_Rain.gif and /dev/null differ diff --git a/dist/server/images/CC_RainSnow.gif b/dist/server/images/CC_RainSnow.gif deleted file mode 100644 index 09d1fc2..0000000 Binary files a/dist/server/images/CC_RainSnow.gif and /dev/null differ diff --git a/dist/server/images/CC_Showers.gif b/dist/server/images/CC_Showers.gif deleted file mode 100644 index 993eead..0000000 Binary files a/dist/server/images/CC_Showers.gif and /dev/null differ diff --git a/dist/server/images/CC_Snow.gif b/dist/server/images/CC_Snow.gif deleted file mode 100644 index 109102e..0000000 Binary files a/dist/server/images/CC_Snow.gif and /dev/null differ diff --git a/dist/server/images/CC_SnowShowers.gif b/dist/server/images/CC_SnowShowers.gif deleted file mode 100644 index cccdbeb..0000000 Binary files a/dist/server/images/CC_SnowShowers.gif and /dev/null differ diff --git a/dist/server/images/CC_TStorm.gif b/dist/server/images/CC_TStorm.gif deleted file mode 100644 index b401ecd..0000000 Binary files a/dist/server/images/CC_TStorm.gif and /dev/null differ diff --git a/dist/server/images/CC_Thunder.gif b/dist/server/images/CC_Thunder.gif deleted file mode 100644 index 8f378d7..0000000 Binary files a/dist/server/images/CC_Thunder.gif and /dev/null differ diff --git a/dist/server/images/CC_ThunderSnow.gif b/dist/server/images/CC_ThunderSnow.gif deleted file mode 100644 index 568fc4b..0000000 Binary files a/dist/server/images/CC_ThunderSnow.gif and /dev/null differ diff --git a/dist/server/images/CC_Windy.gif b/dist/server/images/CC_Windy.gif deleted file mode 100644 index 887d7aa..0000000 Binary files a/dist/server/images/CC_Windy.gif and /dev/null differ diff --git a/dist/server/images/CC_Windy2.gif b/dist/server/images/CC_Windy2.gif deleted file mode 100644 index 887d7aa..0000000 Binary files a/dist/server/images/CC_Windy2.gif and /dev/null differ diff --git a/dist/server/images/Clear.gif b/dist/server/images/Clear.gif deleted file mode 100644 index fc90f3c..0000000 Binary files a/dist/server/images/Clear.gif and /dev/null differ diff --git a/dist/server/images/Cloudy.gif b/dist/server/images/Cloudy.gif deleted file mode 100644 index 4dcc931..0000000 Binary files a/dist/server/images/Cloudy.gif and /dev/null differ diff --git a/dist/server/images/County-HighwayOverlay.png b/dist/server/images/County-HighwayOverlay.png deleted file mode 100644 index e203f18..0000000 Binary files a/dist/server/images/County-HighwayOverlay.png and /dev/null differ diff --git a/dist/server/images/EF_IsolatedTstorms.gif b/dist/server/images/EF_IsolatedTstorms.gif deleted file mode 100644 index da04f31..0000000 Binary files a/dist/server/images/EF_IsolatedTstorms.gif and /dev/null differ diff --git a/dist/server/images/EF_ScatShowers.gif b/dist/server/images/EF_ScatShowers.gif deleted file mode 100644 index 59ceb33..0000000 Binary files a/dist/server/images/EF_ScatShowers.gif and /dev/null differ diff --git a/dist/server/images/EF_ScatSnowShowers.gif b/dist/server/images/EF_ScatSnowShowers.gif deleted file mode 100644 index 97c1f65..0000000 Binary files a/dist/server/images/EF_ScatSnowShowers.gif and /dev/null differ diff --git a/dist/server/images/EF_ScatTstorms.gif b/dist/server/images/EF_ScatTstorms.gif deleted file mode 100644 index b6489e7..0000000 Binary files a/dist/server/images/EF_ScatTstorms.gif and /dev/null differ diff --git a/dist/server/images/First-Quarter.gif b/dist/server/images/First-Quarter.gif deleted file mode 100644 index e43c466..0000000 Binary files a/dist/server/images/First-Quarter.gif and /dev/null differ diff --git a/dist/server/images/FmQpVYp.jpg b/dist/server/images/FmQpVYp.jpg deleted file mode 100644 index 7ec3cee..0000000 Binary files a/dist/server/images/FmQpVYp.jpg and /dev/null differ diff --git a/dist/server/images/Freezing-Rain-Sleet.gif b/dist/server/images/Freezing-Rain-Sleet.gif deleted file mode 100644 index 13138a5..0000000 Binary files a/dist/server/images/Freezing-Rain-Sleet.gif and /dev/null differ diff --git a/dist/server/images/Freezing-Rain.gif b/dist/server/images/Freezing-Rain.gif deleted file mode 100644 index 83cccaa..0000000 Binary files a/dist/server/images/Freezing-Rain.gif and /dev/null differ diff --git a/dist/server/images/Full-Moon.gif b/dist/server/images/Full-Moon.gif deleted file mode 100644 index c9e5813..0000000 Binary files a/dist/server/images/Full-Moon.gif and /dev/null differ diff --git a/dist/server/images/HawaiiRadarMap.gif b/dist/server/images/HawaiiRadarMap.gif deleted file mode 100644 index cf01135..0000000 Binary files a/dist/server/images/HawaiiRadarMap.gif and /dev/null differ diff --git a/dist/server/images/HawaiiRadarMap.png b/dist/server/images/HawaiiRadarMap.png deleted file mode 100644 index 9eb7440..0000000 Binary files a/dist/server/images/HawaiiRadarMap.png and /dev/null differ diff --git a/dist/server/images/HawaiiRadarMap1.png b/dist/server/images/HawaiiRadarMap1.png deleted file mode 100644 index c223b81..0000000 Binary files a/dist/server/images/HawaiiRadarMap1.png and /dev/null differ diff --git a/dist/server/images/HawaiiRadarMap2.png b/dist/server/images/HawaiiRadarMap2.png deleted file mode 100644 index 740eb23..0000000 Binary files a/dist/server/images/HawaiiRadarMap2.png and /dev/null differ diff --git a/dist/server/images/HawaiiRadarMap3.png b/dist/server/images/HawaiiRadarMap3.png deleted file mode 100644 index f16980f..0000000 Binary files a/dist/server/images/HawaiiRadarMap3.png and /dev/null differ diff --git a/dist/server/images/HawaiiRadarMap4.png b/dist/server/images/HawaiiRadarMap4.png deleted file mode 100644 index f1a17c3..0000000 Binary files a/dist/server/images/HawaiiRadarMap4.png and /dev/null differ diff --git a/dist/server/images/HawaiiRadarMap5.png b/dist/server/images/HawaiiRadarMap5.png deleted file mode 100644 index 52437c9..0000000 Binary files a/dist/server/images/HawaiiRadarMap5.png and /dev/null differ diff --git a/dist/server/images/Heavy-Snow.gif b/dist/server/images/Heavy-Snow.gif deleted file mode 100644 index e3b6353..0000000 Binary files a/dist/server/images/Heavy-Snow.gif and /dev/null differ diff --git a/dist/server/images/Ice-Snow.gif b/dist/server/images/Ice-Snow.gif deleted file mode 100644 index 85d8b68..0000000 Binary files a/dist/server/images/Ice-Snow.gif and /dev/null differ diff --git a/dist/server/images/Last-Quarter.gif b/dist/server/images/Last-Quarter.gif deleted file mode 100644 index dd04d66..0000000 Binary files a/dist/server/images/Last-Quarter.gif and /dev/null differ diff --git a/dist/server/images/Light-Snow.gif b/dist/server/images/Light-Snow.gif deleted file mode 100644 index 896bfba..0000000 Binary files a/dist/server/images/Light-Snow.gif and /dev/null differ diff --git a/dist/server/images/Logo1.png b/dist/server/images/Logo1.png deleted file mode 100644 index 0696b14..0000000 Binary files a/dist/server/images/Logo1.png and /dev/null differ diff --git a/dist/server/images/Logo192.png b/dist/server/images/Logo192.png deleted file mode 100644 index 2d2b6f0..0000000 Binary files a/dist/server/images/Logo192.png and /dev/null differ diff --git a/dist/server/images/Logo2.gif b/dist/server/images/Logo2.gif deleted file mode 100644 index c24f4a4..0000000 Binary files a/dist/server/images/Logo2.gif and /dev/null differ diff --git a/dist/server/images/Logo2.png b/dist/server/images/Logo2.png deleted file mode 100644 index 85cb35d..0000000 Binary files a/dist/server/images/Logo2.png and /dev/null differ diff --git a/dist/server/images/Logo200.png b/dist/server/images/Logo200.png deleted file mode 100644 index 5dc4a5d..0000000 Binary files a/dist/server/images/Logo200.png and /dev/null differ diff --git a/dist/server/images/Logo3.gif b/dist/server/images/Logo3.gif deleted file mode 100644 index 596a652..0000000 Binary files a/dist/server/images/Logo3.gif and /dev/null differ diff --git a/dist/server/images/Logo3.png b/dist/server/images/Logo3.png deleted file mode 100644 index cce7cd4..0000000 Binary files a/dist/server/images/Logo3.png and /dev/null differ diff --git a/dist/server/images/Moon1.gif b/dist/server/images/Moon1.gif deleted file mode 100644 index 6058f38..0000000 Binary files a/dist/server/images/Moon1.gif and /dev/null differ diff --git a/dist/server/images/Moon1.png b/dist/server/images/Moon1.png deleted file mode 100644 index 0ea5bf9..0000000 Binary files a/dist/server/images/Moon1.png and /dev/null differ diff --git a/dist/server/images/Moon2.gif b/dist/server/images/Moon2.gif deleted file mode 100644 index bad9414..0000000 Binary files a/dist/server/images/Moon2.gif and /dev/null differ diff --git a/dist/server/images/Moon2.png b/dist/server/images/Moon2.png deleted file mode 100644 index 98bf31b..0000000 Binary files a/dist/server/images/Moon2.png and /dev/null differ diff --git a/dist/server/images/Moon3.gif b/dist/server/images/Moon3.gif deleted file mode 100644 index a37a7b7..0000000 Binary files a/dist/server/images/Moon3.gif and /dev/null differ diff --git a/dist/server/images/Moon3.png b/dist/server/images/Moon3.png deleted file mode 100644 index 803c66a..0000000 Binary files a/dist/server/images/Moon3.png and /dev/null differ diff --git a/dist/server/images/Moon4.gif b/dist/server/images/Moon4.gif deleted file mode 100644 index 0032615..0000000 Binary files a/dist/server/images/Moon4.gif and /dev/null differ diff --git a/dist/server/images/Moon4.png b/dist/server/images/Moon4.png deleted file mode 100644 index 0a802cc..0000000 Binary files a/dist/server/images/Moon4.png and /dev/null differ diff --git a/dist/server/images/Mostly-Clear.gif b/dist/server/images/Mostly-Clear.gif deleted file mode 100644 index ce6be75..0000000 Binary files a/dist/server/images/Mostly-Clear.gif and /dev/null differ diff --git a/dist/server/images/Mostly-Cloudy.gif b/dist/server/images/Mostly-Cloudy.gif deleted file mode 100644 index a4b56b5..0000000 Binary files a/dist/server/images/Mostly-Cloudy.gif and /dev/null differ diff --git a/dist/server/images/New-Moon.gif b/dist/server/images/New-Moon.gif deleted file mode 100644 index 4283dd9..0000000 Binary files a/dist/server/images/New-Moon.gif and /dev/null differ diff --git a/dist/server/images/Partly-Clear.gif b/dist/server/images/Partly-Clear.gif deleted file mode 100644 index edd0b09..0000000 Binary files a/dist/server/images/Partly-Clear.gif and /dev/null differ diff --git a/dist/server/images/Partly-Cloudy.gif b/dist/server/images/Partly-Cloudy.gif deleted file mode 100644 index c0c2c1f..0000000 Binary files a/dist/server/images/Partly-Cloudy.gif and /dev/null differ diff --git a/dist/server/images/Progress1.gif b/dist/server/images/Progress1.gif deleted file mode 100644 index e3000fb..0000000 Binary files a/dist/server/images/Progress1.gif and /dev/null differ diff --git a/dist/server/images/Progress1.png b/dist/server/images/Progress1.png deleted file mode 100644 index c7c69d1..0000000 Binary files a/dist/server/images/Progress1.png and /dev/null differ diff --git a/dist/server/images/Progress2.png b/dist/server/images/Progress2.png deleted file mode 100644 index 0c670fb..0000000 Binary files a/dist/server/images/Progress2.png and /dev/null differ diff --git a/dist/server/images/Progress3.png b/dist/server/images/Progress3.png deleted file mode 100644 index 639bb14..0000000 Binary files a/dist/server/images/Progress3.png and /dev/null differ diff --git a/dist/server/images/Progress4.png b/dist/server/images/Progress4.png deleted file mode 100644 index 888a7a7..0000000 Binary files a/dist/server/images/Progress4.png and /dev/null differ diff --git a/dist/server/images/Progress5.png b/dist/server/images/Progress5.png deleted file mode 100644 index e24ab7e..0000000 Binary files a/dist/server/images/Progress5.png and /dev/null differ diff --git a/dist/server/images/Progress6.png b/dist/server/images/Progress6.png deleted file mode 100644 index e7855bb..0000000 Binary files a/dist/server/images/Progress6.png and /dev/null differ diff --git a/dist/server/images/Progress7.png b/dist/server/images/Progress7.png deleted file mode 100644 index c7c69d1..0000000 Binary files a/dist/server/images/Progress7.png and /dev/null differ diff --git a/dist/server/images/Rain-Snow.gif b/dist/server/images/Rain-Snow.gif deleted file mode 100644 index f456c20..0000000 Binary files a/dist/server/images/Rain-Snow.gif and /dev/null differ diff --git a/dist/server/images/Rain.gif b/dist/server/images/Rain.gif deleted file mode 100644 index dcd7099..0000000 Binary files a/dist/server/images/Rain.gif and /dev/null differ diff --git a/dist/server/images/Shower.gif b/dist/server/images/Shower.gif deleted file mode 100644 index 15ed5ef..0000000 Binary files a/dist/server/images/Shower.gif and /dev/null differ diff --git a/dist/server/images/Sleet.gif b/dist/server/images/Sleet.gif deleted file mode 100644 index 2a098bb..0000000 Binary files a/dist/server/images/Sleet.gif and /dev/null differ diff --git a/dist/server/images/Snippet1.png b/dist/server/images/Snippet1.png deleted file mode 100644 index 27466e2..0000000 Binary files a/dist/server/images/Snippet1.png and /dev/null differ diff --git a/dist/server/images/Snow-Sleet.gif b/dist/server/images/Snow-Sleet.gif deleted file mode 100644 index d4b2240..0000000 Binary files a/dist/server/images/Snow-Sleet.gif and /dev/null differ diff --git a/dist/server/images/Sunny.gif b/dist/server/images/Sunny.gif deleted file mode 100644 index 17f3265..0000000 Binary files a/dist/server/images/Sunny.gif and /dev/null differ diff --git a/dist/server/images/TaQ4DpT.png b/dist/server/images/TaQ4DpT.png deleted file mode 100644 index 3f24fe1..0000000 Binary files a/dist/server/images/TaQ4DpT.png and /dev/null differ diff --git a/dist/server/images/Thunder.gif b/dist/server/images/Thunder.gif deleted file mode 100644 index afba50c..0000000 Binary files a/dist/server/images/Thunder.gif and /dev/null differ diff --git a/dist/server/images/ThunderSnow.gif b/dist/server/images/ThunderSnow.gif deleted file mode 100644 index 9ee4acf..0000000 Binary files a/dist/server/images/ThunderSnow.gif and /dev/null differ diff --git a/dist/server/images/Thunderstorm.gif b/dist/server/images/Thunderstorm.gif deleted file mode 100644 index 647fd22..0000000 Binary files a/dist/server/images/Thunderstorm.gif and /dev/null differ diff --git a/dist/server/images/Twc_logo_resized.svg.png b/dist/server/images/Twc_logo_resized.svg.png deleted file mode 100644 index c6e2d3f..0000000 Binary files a/dist/server/images/Twc_logo_resized.svg.png and /dev/null differ diff --git a/dist/server/images/Wintry-Mix.gif b/dist/server/images/Wintry-Mix.gif deleted file mode 100644 index b710e61..0000000 Binary files a/dist/server/images/Wintry-Mix.gif and /dev/null differ diff --git a/dist/server/images/alaska.gif b/dist/server/images/alaska.gif deleted file mode 100644 index 631f50f..0000000 Binary files a/dist/server/images/alaska.gif and /dev/null differ diff --git a/dist/server/images/gimp/Radar Basemap.xcf b/dist/server/images/gimp/Radar Basemap.xcf deleted file mode 100644 index b0652bc..0000000 Binary files a/dist/server/images/gimp/Radar Basemap.xcf and /dev/null differ diff --git a/dist/server/images/gimp/Radar Basemap2.xcf b/dist/server/images/gimp/Radar Basemap2.xcf deleted file mode 100644 index 2aa0c36..0000000 Binary files a/dist/server/images/gimp/Radar Basemap2.xcf and /dev/null differ diff --git a/dist/server/images/gimp/Radar Basemap3.xcf b/dist/server/images/gimp/Radar Basemap3.xcf deleted file mode 100644 index a137a69..0000000 Binary files a/dist/server/images/gimp/Radar Basemap3.xcf and /dev/null differ diff --git a/dist/server/images/gimp/Radar Basemap4.xcf b/dist/server/images/gimp/Radar Basemap4.xcf deleted file mode 100644 index 2ddad7c..0000000 Binary files a/dist/server/images/gimp/Radar Basemap4.xcf and /dev/null differ diff --git a/dist/server/images/hawaii.gif b/dist/server/images/hawaii.gif deleted file mode 100644 index 73de389..0000000 Binary files a/dist/server/images/hawaii.gif and /dev/null differ diff --git a/dist/server/images/nav/ic_fullscreen_exit_white_24dp_1x.png b/dist/server/images/nav/ic_fullscreen_exit_white_24dp_1x.png deleted file mode 100644 index 85cf27e..0000000 Binary files a/dist/server/images/nav/ic_fullscreen_exit_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_fullscreen_exit_white_24dp_2x.png b/dist/server/images/nav/ic_fullscreen_exit_white_24dp_2x.png deleted file mode 100644 index 364bad0..0000000 Binary files a/dist/server/images/nav/ic_fullscreen_exit_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_fullscreen_white_24dp_1x.png b/dist/server/images/nav/ic_fullscreen_white_24dp_1x.png deleted file mode 100644 index 2d3bb49..0000000 Binary files a/dist/server/images/nav/ic_fullscreen_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_fullscreen_white_24dp_2x.png b/dist/server/images/nav/ic_fullscreen_white_24dp_2x.png deleted file mode 100644 index 4423c7c..0000000 Binary files a/dist/server/images/nav/ic_fullscreen_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_gps_fixed_black_18dp_1x.png b/dist/server/images/nav/ic_gps_fixed_black_18dp_1x.png deleted file mode 100644 index 03e2fa9..0000000 Binary files a/dist/server/images/nav/ic_gps_fixed_black_18dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_gps_fixed_black_18dp_2x.png b/dist/server/images/nav/ic_gps_fixed_black_18dp_2x.png deleted file mode 100644 index 85e3872..0000000 Binary files a/dist/server/images/nav/ic_gps_fixed_black_18dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_gps_fixed_black_24dp_1x.png b/dist/server/images/nav/ic_gps_fixed_black_24dp_1x.png deleted file mode 100644 index 5684aa7..0000000 Binary files a/dist/server/images/nav/ic_gps_fixed_black_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_gps_fixed_black_24dp_2x.png b/dist/server/images/nav/ic_gps_fixed_black_24dp_2x.png deleted file mode 100644 index 7faa345..0000000 Binary files a/dist/server/images/nav/ic_gps_fixed_black_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_gps_fixed_white_18dp_1x.png b/dist/server/images/nav/ic_gps_fixed_white_18dp_1x.png deleted file mode 100644 index 8af3300..0000000 Binary files a/dist/server/images/nav/ic_gps_fixed_white_18dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_gps_fixed_white_18dp_2x.png b/dist/server/images/nav/ic_gps_fixed_white_18dp_2x.png deleted file mode 100644 index 285b0eb..0000000 Binary files a/dist/server/images/nav/ic_gps_fixed_white_18dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_gps_fixed_white_24dp_1x.png b/dist/server/images/nav/ic_gps_fixed_white_24dp_1x.png deleted file mode 100644 index 28e8ccd..0000000 Binary files a/dist/server/images/nav/ic_gps_fixed_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_gps_fixed_whte_24dp_2x.png b/dist/server/images/nav/ic_gps_fixed_whte_24dp_2x.png deleted file mode 100644 index 68ee3a2..0000000 Binary files a/dist/server/images/nav/ic_gps_fixed_whte_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_hearing_black_24dp_2x.png b/dist/server/images/nav/ic_hearing_black_24dp_2x.png deleted file mode 100644 index 70bfdf7..0000000 Binary files a/dist/server/images/nav/ic_hearing_black_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_hearing_white_24dp_1x.png b/dist/server/images/nav/ic_hearing_white_24dp_1x.png deleted file mode 100644 index 7e57eac..0000000 Binary files a/dist/server/images/nav/ic_hearing_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_hearing_white_24dp_2x.png b/dist/server/images/nav/ic_hearing_white_24dp_2x.png deleted file mode 100644 index f23b685..0000000 Binary files a/dist/server/images/nav/ic_hearing_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_menu_white_24dp_1x.png b/dist/server/images/nav/ic_menu_white_24dp_1x.png deleted file mode 100644 index d3cec05..0000000 Binary files a/dist/server/images/nav/ic_menu_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_menu_white_24dp_2x.png b/dist/server/images/nav/ic_menu_white_24dp_2x.png deleted file mode 100644 index 193185f..0000000 Binary files a/dist/server/images/nav/ic_menu_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_no_hearing_white_24dp_1x.png b/dist/server/images/nav/ic_no_hearing_white_24dp_1x.png deleted file mode 100644 index 875b264..0000000 Binary files a/dist/server/images/nav/ic_no_hearing_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_no_hearing_white_24dp_2x - Copy.png b/dist/server/images/nav/ic_no_hearing_white_24dp_2x - Copy.png deleted file mode 100644 index c56d24c..0000000 Binary files a/dist/server/images/nav/ic_no_hearing_white_24dp_2x - Copy.png and /dev/null differ diff --git a/dist/server/images/nav/ic_no_hearing_white_24dp_2x.png b/dist/server/images/nav/ic_no_hearing_white_24dp_2x.png deleted file mode 100644 index c56d24c..0000000 Binary files a/dist/server/images/nav/ic_no_hearing_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_pause_white_24dp_1x.png b/dist/server/images/nav/ic_pause_white_24dp_1x.png deleted file mode 100644 index 2272d47..0000000 Binary files a/dist/server/images/nav/ic_pause_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_pause_white_24dp_2x.png b/dist/server/images/nav/ic_pause_white_24dp_2x.png deleted file mode 100644 index f49aed7..0000000 Binary files a/dist/server/images/nav/ic_pause_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_play_arrow_white_24dp_1x.png b/dist/server/images/nav/ic_play_arrow_white_24dp_1x.png deleted file mode 100644 index c61e948..0000000 Binary files a/dist/server/images/nav/ic_play_arrow_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_play_arrow_white_24dp_2x.png b/dist/server/images/nav/ic_play_arrow_white_24dp_2x.png deleted file mode 100644 index a3c80e7..0000000 Binary files a/dist/server/images/nav/ic_play_arrow_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_refresh_white_24dp_1x.png b/dist/server/images/nav/ic_refresh_white_24dp_1x.png deleted file mode 100644 index 97e42b5..0000000 Binary files a/dist/server/images/nav/ic_refresh_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_refresh_white_24dp_2x.png b/dist/server/images/nav/ic_refresh_white_24dp_2x.png deleted file mode 100644 index 1989184..0000000 Binary files a/dist/server/images/nav/ic_refresh_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_skip_next_white_24dp_1x.png b/dist/server/images/nav/ic_skip_next_white_24dp_1x.png deleted file mode 100644 index f9c60b7..0000000 Binary files a/dist/server/images/nav/ic_skip_next_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_skip_next_white_24dp_2x.png b/dist/server/images/nav/ic_skip_next_white_24dp_2x.png deleted file mode 100644 index e722d10..0000000 Binary files a/dist/server/images/nav/ic_skip_next_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_skip_previous_white_24dp_1x.png b/dist/server/images/nav/ic_skip_previous_white_24dp_1x.png deleted file mode 100644 index dac3640..0000000 Binary files a/dist/server/images/nav/ic_skip_previous_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_skip_previous_white_24dp_2x.png b/dist/server/images/nav/ic_skip_previous_white_24dp_2x.png deleted file mode 100644 index 01dd12b..0000000 Binary files a/dist/server/images/nav/ic_skip_previous_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_volume_off_white_24dp_1x.png b/dist/server/images/nav/ic_volume_off_white_24dp_1x.png deleted file mode 100644 index 4681ec1..0000000 Binary files a/dist/server/images/nav/ic_volume_off_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_volume_off_white_24dp_2x.png b/dist/server/images/nav/ic_volume_off_white_24dp_2x.png deleted file mode 100644 index 732a1c0..0000000 Binary files a/dist/server/images/nav/ic_volume_off_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_volume_up_white_24dp_1x.png b/dist/server/images/nav/ic_volume_up_white_24dp_1x.png deleted file mode 100644 index 7cfd4c7..0000000 Binary files a/dist/server/images/nav/ic_volume_up_white_24dp_1x.png and /dev/null differ diff --git a/dist/server/images/nav/ic_volume_up_white_24dp_2x.png b/dist/server/images/nav/ic_volume_up_white_24dp_2x.png deleted file mode 100644 index 2ed0034..0000000 Binary files a/dist/server/images/nav/ic_volume_up_white_24dp_2x.png and /dev/null differ diff --git a/dist/server/images/nav1.png b/dist/server/images/nav1.png deleted file mode 100644 index 53d5ebc..0000000 Binary files a/dist/server/images/nav1.png and /dev/null differ diff --git a/dist/server/images/noaa.png b/dist/server/images/noaa.png deleted file mode 100644 index 5b5436f..0000000 Binary files a/dist/server/images/noaa.png and /dev/null differ diff --git a/dist/server/images/noaa2.png b/dist/server/images/noaa2.png deleted file mode 100644 index fc55b14..0000000 Binary files a/dist/server/images/noaa2.png and /dev/null differ diff --git a/dist/server/images/noaa3.png b/dist/server/images/noaa3.png deleted file mode 100644 index 7af58bf..0000000 Binary files a/dist/server/images/noaa3.png and /dev/null differ diff --git a/dist/server/images/noaa4.png b/dist/server/images/noaa4.png deleted file mode 100644 index 62db4be..0000000 Binary files a/dist/server/images/noaa4.png and /dev/null differ diff --git a/dist/server/images/noaa5.gif b/dist/server/images/noaa5.gif deleted file mode 100644 index de28ef0..0000000 Binary files a/dist/server/images/noaa5.gif and /dev/null differ diff --git a/dist/server/images/noaa5.png b/dist/server/images/noaa5.png deleted file mode 100644 index 92f075b..0000000 Binary files a/dist/server/images/noaa5.png and /dev/null differ diff --git a/dist/server/images/off14_prcp.gif b/dist/server/images/off14_prcp.gif deleted file mode 100644 index e74e2b4..0000000 Binary files a/dist/server/images/off14_prcp.gif and /dev/null differ diff --git a/dist/server/images/off14_temp.gif b/dist/server/images/off14_temp.gif deleted file mode 100644 index 007642a..0000000 Binary files a/dist/server/images/off14_temp.gif and /dev/null differ diff --git a/dist/server/images/r/AM-Snow-1994.gif b/dist/server/images/r/AM-Snow-1994.gif deleted file mode 100644 index 28c8464..0000000 Binary files a/dist/server/images/r/AM-Snow-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Blowing Snow.gif b/dist/server/images/r/Blowing Snow.gif deleted file mode 100644 index 9215046..0000000 Binary files a/dist/server/images/r/Blowing Snow.gif and /dev/null differ diff --git a/dist/server/images/r/Clear-1992.gif b/dist/server/images/r/Clear-1992.gif deleted file mode 100644 index 89cece6..0000000 Binary files a/dist/server/images/r/Clear-1992.gif and /dev/null differ diff --git a/dist/server/images/r/Clear-Wind-1994.gif b/dist/server/images/r/Clear-Wind-1994.gif deleted file mode 100644 index d284d64..0000000 Binary files a/dist/server/images/r/Clear-Wind-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Cloudy-Wind.gif b/dist/server/images/r/Cloudy-Wind.gif deleted file mode 100644 index 730ed17..0000000 Binary files a/dist/server/images/r/Cloudy-Wind.gif and /dev/null differ diff --git a/dist/server/images/r/Cloudy.gif b/dist/server/images/r/Cloudy.gif deleted file mode 100644 index 2d88edd..0000000 Binary files a/dist/server/images/r/Cloudy.gif and /dev/null differ diff --git a/dist/server/images/r/Fog.gif b/dist/server/images/r/Fog.gif deleted file mode 100644 index ed07244..0000000 Binary files a/dist/server/images/r/Fog.gif and /dev/null differ diff --git a/dist/server/images/r/Freezing-Rain-1992.gif b/dist/server/images/r/Freezing-Rain-1992.gif deleted file mode 100644 index d78a4da..0000000 Binary files a/dist/server/images/r/Freezing-Rain-1992.gif and /dev/null differ diff --git a/dist/server/images/r/Freezing-Rain-Sleet-1992.gif b/dist/server/images/r/Freezing-Rain-Sleet-1992.gif deleted file mode 100644 index f9e29d2..0000000 Binary files a/dist/server/images/r/Freezing-Rain-Sleet-1992.gif and /dev/null differ diff --git a/dist/server/images/r/Freezing-Rain-Snow-1992.gif b/dist/server/images/r/Freezing-Rain-Snow-1992.gif deleted file mode 100644 index bfcaa9b..0000000 Binary files a/dist/server/images/r/Freezing-Rain-Snow-1992.gif and /dev/null differ diff --git a/dist/server/images/r/Heavy-Snow-1994-2.gif b/dist/server/images/r/Heavy-Snow-1994-2.gif deleted file mode 100644 index 99ef424..0000000 Binary files a/dist/server/images/r/Heavy-Snow-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Heavy-Snow-1994.gif b/dist/server/images/r/Heavy-Snow-1994.gif deleted file mode 100644 index 99ef424..0000000 Binary files a/dist/server/images/r/Heavy-Snow-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Heavy-Snow.gif b/dist/server/images/r/Heavy-Snow.gif deleted file mode 100644 index 3ed01c6..0000000 Binary files a/dist/server/images/r/Heavy-Snow.gif and /dev/null differ diff --git a/dist/server/images/r/Light-Snow.gif b/dist/server/images/r/Light-Snow.gif deleted file mode 100644 index 23d6294..0000000 Binary files a/dist/server/images/r/Light-Snow.gif and /dev/null differ diff --git a/dist/server/images/r/Logo3.gif b/dist/server/images/r/Logo3.gif deleted file mode 100644 index 77cc7ec..0000000 Binary files a/dist/server/images/r/Logo3.gif and /dev/null differ diff --git a/dist/server/images/r/Mostly-Clear.gif b/dist/server/images/r/Mostly-Clear.gif deleted file mode 100644 index d99f9ca..0000000 Binary files a/dist/server/images/r/Mostly-Clear.gif and /dev/null differ diff --git a/dist/server/images/r/Mostly-Cloudy-1994-2.gif b/dist/server/images/r/Mostly-Cloudy-1994-2.gif deleted file mode 100644 index 81b9557..0000000 Binary files a/dist/server/images/r/Mostly-Cloudy-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Mostly-Cloudy-1994.gif b/dist/server/images/r/Mostly-Cloudy-1994.gif deleted file mode 100644 index 62409c1..0000000 Binary files a/dist/server/images/r/Mostly-Cloudy-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Mostly-Cloudy.gif b/dist/server/images/r/Mostly-Cloudy.gif deleted file mode 100644 index ffa2e31..0000000 Binary files a/dist/server/images/r/Mostly-Cloudy.gif and /dev/null differ diff --git a/dist/server/images/r/Partly-Clear-1994-2.gif b/dist/server/images/r/Partly-Clear-1994-2.gif deleted file mode 100644 index ba16cc0..0000000 Binary files a/dist/server/images/r/Partly-Clear-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Partly-Clear-1994.gif b/dist/server/images/r/Partly-Clear-1994.gif deleted file mode 100644 index 61c5c37..0000000 Binary files a/dist/server/images/r/Partly-Clear-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Partly-Clear.gif b/dist/server/images/r/Partly-Clear.gif deleted file mode 100644 index 62d9349..0000000 Binary files a/dist/server/images/r/Partly-Clear.gif and /dev/null differ diff --git a/dist/server/images/r/Partly-Cloudy.gif b/dist/server/images/r/Partly-Cloudy.gif deleted file mode 100644 index 10e2ff0..0000000 Binary files a/dist/server/images/r/Partly-Cloudy.gif and /dev/null differ diff --git a/dist/server/images/r/Rain-1992.gif b/dist/server/images/r/Rain-1992.gif deleted file mode 100644 index 52afcc2..0000000 Binary files a/dist/server/images/r/Rain-1992.gif and /dev/null differ diff --git a/dist/server/images/r/Rain-Sleet.gif b/dist/server/images/r/Rain-Sleet.gif deleted file mode 100644 index 1d4330d..0000000 Binary files a/dist/server/images/r/Rain-Sleet.gif and /dev/null differ diff --git a/dist/server/images/r/Rain-Snow-1992.gif b/dist/server/images/r/Rain-Snow-1992.gif deleted file mode 100644 index 9d76977..0000000 Binary files a/dist/server/images/r/Rain-Snow-1992.gif and /dev/null differ diff --git a/dist/server/images/r/Rain-Wind-1994.gif b/dist/server/images/r/Rain-Wind-1994.gif deleted file mode 100644 index f57618c..0000000 Binary files a/dist/server/images/r/Rain-Wind-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Showers-1994-2.gif b/dist/server/images/r/Scattered-Showers-1994-2.gif deleted file mode 100644 index f888e13..0000000 Binary files a/dist/server/images/r/Scattered-Showers-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Showers-1994.gif b/dist/server/images/r/Scattered-Showers-1994.gif deleted file mode 100644 index f888e13..0000000 Binary files a/dist/server/images/r/Scattered-Showers-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Showers-Night-1994-2.gif b/dist/server/images/r/Scattered-Showers-Night-1994-2.gif deleted file mode 100644 index 6d098bf..0000000 Binary files a/dist/server/images/r/Scattered-Showers-Night-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Showers-Night.gif b/dist/server/images/r/Scattered-Showers-Night.gif deleted file mode 100644 index 516277c..0000000 Binary files a/dist/server/images/r/Scattered-Showers-Night.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Showers.gif b/dist/server/images/r/Scattered-Showers.gif deleted file mode 100644 index 2fc63fc..0000000 Binary files a/dist/server/images/r/Scattered-Showers.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Snow-Showers-1994-2.gif b/dist/server/images/r/Scattered-Snow-Showers-1994-2.gif deleted file mode 100644 index dfcbe33..0000000 Binary files a/dist/server/images/r/Scattered-Snow-Showers-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Snow-Showers-Night-1994-2.gif b/dist/server/images/r/Scattered-Snow-Showers-Night-1994-2.gif deleted file mode 100644 index d3dca09..0000000 Binary files a/dist/server/images/r/Scattered-Snow-Showers-Night-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Snow-Showers-Night.gif b/dist/server/images/r/Scattered-Snow-Showers-Night.gif deleted file mode 100644 index d7b2e05..0000000 Binary files a/dist/server/images/r/Scattered-Snow-Showers-Night.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Snow-Showers.gif b/dist/server/images/r/Scattered-Snow-Showers.gif deleted file mode 100644 index 13a34b7..0000000 Binary files a/dist/server/images/r/Scattered-Snow-Showers.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Tstorms-1992.gif b/dist/server/images/r/Scattered-Tstorms-1992.gif deleted file mode 100644 index 9559ba6..0000000 Binary files a/dist/server/images/r/Scattered-Tstorms-1992.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Tstorms-1994-2.gif b/dist/server/images/r/Scattered-Tstorms-1994-2.gif deleted file mode 100644 index 7ec06a6..0000000 Binary files a/dist/server/images/r/Scattered-Tstorms-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Tstorms-1994.gif b/dist/server/images/r/Scattered-Tstorms-1994.gif deleted file mode 100644 index 7ec06a6..0000000 Binary files a/dist/server/images/r/Scattered-Tstorms-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Tstorms-Night-1994-2.gif b/dist/server/images/r/Scattered-Tstorms-Night-1994-2.gif deleted file mode 100644 index b5a4e08..0000000 Binary files a/dist/server/images/r/Scattered-Tstorms-Night-1994-2.gif and /dev/null differ diff --git a/dist/server/images/r/Scattered-Tstorms-Night.gif b/dist/server/images/r/Scattered-Tstorms-Night.gif deleted file mode 100644 index 94df757..0000000 Binary files a/dist/server/images/r/Scattered-Tstorms-Night.gif and /dev/null differ diff --git a/dist/server/images/r/Shower.gif b/dist/server/images/r/Shower.gif deleted file mode 100644 index b71afd1..0000000 Binary files a/dist/server/images/r/Shower.gif and /dev/null differ diff --git a/dist/server/images/r/Sleet.gif b/dist/server/images/r/Sleet.gif deleted file mode 100644 index b158042..0000000 Binary files a/dist/server/images/r/Sleet.gif and /dev/null differ diff --git a/dist/server/images/r/Snow and Sleet.gif b/dist/server/images/r/Snow and Sleet.gif deleted file mode 100644 index dd5c136..0000000 Binary files a/dist/server/images/r/Snow and Sleet.gif and /dev/null differ diff --git a/dist/server/images/r/Snow-Sleet.gif b/dist/server/images/r/Snow-Sleet.gif deleted file mode 100644 index cf89b5e..0000000 Binary files a/dist/server/images/r/Snow-Sleet.gif and /dev/null differ diff --git a/dist/server/images/r/Sunny-Wind-1994.gif b/dist/server/images/r/Sunny-Wind-1994.gif deleted file mode 100644 index ac01b02..0000000 Binary files a/dist/server/images/r/Sunny-Wind-1994.gif and /dev/null differ diff --git a/dist/server/images/r/Sunny.gif b/dist/server/images/r/Sunny.gif deleted file mode 100644 index 6a5f1dd..0000000 Binary files a/dist/server/images/r/Sunny.gif and /dev/null differ diff --git a/dist/server/images/r/Thunder.gif b/dist/server/images/r/Thunder.gif deleted file mode 100644 index aff65a3..0000000 Binary files a/dist/server/images/r/Thunder.gif and /dev/null differ diff --git a/dist/server/images/r/ThunderSnow.gif b/dist/server/images/r/ThunderSnow.gif deleted file mode 100644 index dd74e6e..0000000 Binary files a/dist/server/images/r/ThunderSnow.gif and /dev/null differ diff --git a/dist/server/images/r/Thunderstorm.gif b/dist/server/images/r/Thunderstorm.gif deleted file mode 100644 index 08cd23a..0000000 Binary files a/dist/server/images/r/Thunderstorm.gif and /dev/null differ diff --git a/dist/server/images/r/Wind.gif b/dist/server/images/r/Wind.gif deleted file mode 100644 index 4ffd9e3..0000000 Binary files a/dist/server/images/r/Wind.gif and /dev/null differ diff --git a/dist/server/images/r/Wintry-Mix-1992.gif b/dist/server/images/r/Wintry-Mix-1992.gif deleted file mode 100644 index 52574d7..0000000 Binary files a/dist/server/images/r/Wintry-Mix-1992.gif and /dev/null differ diff --git a/dist/server/images/r/cold.gif b/dist/server/images/r/cold.gif deleted file mode 100644 index 4fb6c7f..0000000 Binary files a/dist/server/images/r/cold.gif and /dev/null differ diff --git a/dist/server/images/tbW8Rnd.png b/dist/server/images/tbW8Rnd.png deleted file mode 100644 index f7a5886..0000000 Binary files a/dist/server/images/tbW8Rnd.png and /dev/null differ diff --git a/dist/server/images/y6HNy2O.jpg b/dist/server/images/y6HNy2O.jpg deleted file mode 100644 index 53bed3e..0000000 Binary files a/dist/server/images/y6HNy2O.jpg and /dev/null differ diff --git a/dist/server/scripts/custom.sample.js b/dist/server/scripts/custom.sample.js deleted file mode 100644 index 50d0cf9..0000000 --- a/dist/server/scripts/custom.sample.js +++ /dev/null @@ -1,14 +0,0 @@ -// this file is loaded by the main html page (when renamed to custom.js) -// it is intended to allow for customizations that do not get published back to the git repo -// for example, changing the logo - -// start running after all content is loaded -document.addEventListener('DOMContentLoaded', () => { - // get all of the logo images - const logos = document.querySelectorAll('.logo img'); - // loop through each logo - logos.forEach((elem) => { - // change the source - elem.src = 'my-custom-logo.gif'; - }); -}); diff --git a/dist/server/scripts/data/.eslintrc.js b/dist/server/scripts/data/.eslintrc.js deleted file mode 100644 index b90682b..0000000 --- a/dist/server/scripts/data/.eslintrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - rules: { - // unicorn - 'unicorn/numeric-separators-style': 0, - }, -}; diff --git a/dist/server/scripts/data/regionalcities.js b/dist/server/scripts/data/regionalcities.js deleted file mode 100644 index 9ba6632..0000000 --- a/dist/server/scripts/data/regionalcities.js +++ /dev/null @@ -1,1163 +0,0 @@ -// eslint-disable-next-line no-unused-vars -const RegionalCities = [ - { - city: 'Atlanta', - lat: 33.749, - lon: -84.388, - point: { - x: 50, - y: 86, - wfo: 'FFC', - }, - }, - { - city: 'Boston', - lat: 42.3584, - lon: -71.0598, - point: { - x: 71, - y: 90, - wfo: 'BOX', - }, - }, - { - city: 'Chicago', - lat: 41.9796, - lon: -87.9045, - point: { - x: 65, - y: 76, - wfo: 'LOT', - }, - }, - { - city: 'Cleveland', - lat: 41.4995, - lon: -81.6954, - point: { - x: 82, - y: 64, - wfo: 'CLE', - }, - }, - { - city: 'Dallas', - lat: 32.8959, - lon: -97.0372, - point: { - x: 79, - y: 108, - wfo: 'FWD', - }, - }, - { - city: 'Denver', - lat: 39.7391, - lon: -104.9847, - point: { - x: 62, - y: 60, - wfo: 'BOU', - }, - }, - { - city: 'Detroit', - lat: 42.3314, - lon: -83.0457, - point: { - x: 65, - y: 33, - wfo: 'DTX', - }, - }, - { - city: 'Hartford', - lat: 41.7637, - lon: -72.6851, - point: { - x: 21, - y: 54, - wfo: 'BOX', - }, - }, - { - city: 'Houston', - lat: 29.7633, - lon: -95.3633, - point: { - x: 65, - y: 97, - wfo: 'HGX', - }, - }, - { - city: 'Indianapolis', - lat: 39.7684, - lon: -86.158, - point: { - x: 57, - y: 68, - wfo: 'IND', - }, - }, - { - city: 'Los Angeles', - lat: 34.0522, - lon: -118.2437, - point: { - x: 154, - y: 44, - wfo: 'LOX', - }, - }, - { - city: 'Miami', - lat: 25.7743, - lon: -80.1937, - point: { - x: 109, - y: 50, - wfo: 'MFL', - }, - }, - { - city: 'Minneapolis', - lat: 44.98, - lon: -93.2638, - point: { - x: 107, - y: 71, - wfo: 'MPX', - }, - }, - { - city: 'New York', - lat: 40.78, - lon: -73.88, - point: { - x: 36, - y: 38, - wfo: 'OKX', - }, - }, - { - city: 'Norfolk', - lat: 36.8468, - lon: -76.2852, - point: { - x: 89, - y: 51, - wfo: 'AKQ', - }, - }, - { - city: 'Orlando', - lat: 28.5383, - lon: -81.3792, - point: { - x: 26, - y: 68, - wfo: 'MLB', - }, - }, - { - city: 'Philadelphia', - lat: 39.9523, - lon: -75.1638, - point: { - x: 49, - y: 75, - wfo: 'PHI', - }, - }, - { - city: 'Pittsburgh', - lat: 40.4406, - lon: -79.9959, - point: { - x: 77, - y: 65, - wfo: 'PBZ', - }, - }, - { - city: 'St. Louis', - lat: 38.6273, - lon: -90.1979, - point: { - x: 94, - y: 73, - wfo: 'LSX', - }, - }, - { - city: 'San Francisco', - lat: 37.6148, - lon: -122.3918, - point: { - x: 84, - y: 98, - wfo: 'MTR', - }, - }, - { - city: 'Seattle', - lat: 47.6062, - lon: -122.3321, - point: { - x: 124, - y: 67, - wfo: 'SEW', - }, - }, - { - city: 'Syracuse', - lat: 43.0481, - lon: -76.1474, - point: { - x: 51, - y: 98, - wfo: 'BGM', - }, - }, - { - city: 'Tampa', - lat: 27.9756, - lon: -82.5329, - point: { - x: 67, - y: 97, - wfo: 'TBW', - }, - }, - { - city: 'Washington DC', - lat: 38.8951, - lon: -77.0364, - point: { - x: 97, - y: 71, - wfo: 'LWX', - }, - }, - { - city: 'Albany', - lat: 42.6526, - lon: -73.7562, - point: { - x: 58, - y: 58, - wfo: 'ALY', - }, - }, - { - city: 'Albuquerque', - lat: 35.0845, - lon: -106.6511, - point: { - x: 97, - y: 118, - wfo: 'ABQ', - }, - }, - { - city: 'Amarillo', - lat: 35.222, - lon: -101.8313, - point: { - x: 47, - y: 25, - wfo: 'AMA', - }, - }, - { - city: 'Anchorage', - lat: 61.2181, - lon: -149.9003, - point: { - x: 125, - y: 236, - wfo: 'AER', - }, - }, - { - city: 'Austin', - lat: 30.2671, - lon: -97.7431, - point: { - x: 155, - y: 90, - wfo: 'EWX', - }, - }, - { - city: 'Baker', - lat: 44.7502, - lon: -117.6677, - point: { - x: 93, - y: 145, - wfo: 'BOI', - }, - }, - { - city: 'Baltimore', - lat: 39.2904, - lon: -76.6122, - point: { - x: 109, - y: 91, - wfo: 'LWX', - }, - }, - { - city: 'Bangor', - lat: 44.8012, - lon: -68.7778, - point: { - x: 72, - y: 62, - wfo: 'CAR', - }, - }, - { - city: 'Birmingham', - lat: 33.5207, - lon: -86.8025, - point: { - x: 58, - y: 83, - wfo: 'BMX', - }, - }, - { - city: 'Bismarck', - lat: 46.8083, - lon: -100.7837, - point: { - x: 109, - y: 46, - wfo: 'BIS', - }, - }, - { - city: 'Boise', - lat: 43.6135, - lon: -116.2034, - point: { - x: 132, - y: 85, - wfo: 'BOI', - }, - }, - { - city: 'Buffalo', - lat: 42.8864, - lon: -78.8784, - point: { - x: 35, - y: 46, - wfo: 'BUF', - }, - }, - { - city: 'Carlsbad', - lat: 32.4207, - lon: -104.2288, - point: { - x: 44, - y: 156, - wfo: 'MAF', - }, - }, - { - city: 'Charleston', - lat: 32.7766, - lon: -79.9309, - point: { - x: 86, - y: 76, - wfo: 'CHS', - }, - }, - { - city: 'Charleston', - lat: 38.3498, - lon: -81.6326, - point: { - x: 62, - y: 66, - wfo: 'RLX', - }, - }, - { - city: 'Charlotte', - lat: 35.2271, - lon: -80.8431, - point: { - x: 118, - y: 64, - wfo: 'GSP', - }, - }, - { - city: 'Cheyenne', - lat: 41.14, - lon: -104.8202, - point: { - x: 109, - y: 13, - wfo: 'CYS', - }, - }, - { - city: 'Cincinnati', - lat: 39.162, - lon: -84.4569, - point: { - x: 36, - y: 40, - wfo: 'ILN', - }, - }, - { - city: 'Columbia', - lat: 34.0007, - lon: -81.0348, - point: { - x: 65, - y: 61, - wfo: 'CAE', - }, - }, - { - city: 'Columbus', - lat: 39.9612, - lon: -82.9988, - point: { - x: 84, - y: 80, - wfo: 'ILN', - }, - }, - { - city: 'Des Moines', - lat: 41.6005, - lon: -93.6091, - point: { - x: 73, - y: 49, - wfo: 'DMX', - }, - }, - { - city: 'Dubuque', - lat: 42.5006, - lon: -90.6646, - point: { - x: 62, - y: 110, - wfo: 'DVN', - }, - }, - { - city: 'Duluth', - lat: 46.7833, - lon: -92.1066, - point: { - x: 91, - y: 69, - wfo: 'DLH', - }, - }, - { - city: 'Eastport', - lat: 44.9062, - lon: -66.99, - point: { - x: 129, - y: 79, - wfo: 'CAR', - }, - }, - { - city: 'El Centro', - lat: 32.792, - lon: -115.563, - point: { - x: 26, - y: 46, - wfo: 'PSR', - }, - }, - { - city: 'El Paso', - lat: 31.7587, - lon: -106.4869, - point: { - x: 99, - y: 55, - wfo: 'EPZ', - }, - }, - { - city: 'Eugene', - lat: 44.0521, - lon: -123.0867, - point: { - x: 84, - y: 38, - wfo: 'PQR', - }, - }, - { - city: 'Fargo', - lat: 46.8772, - lon: -96.7898, - point: { - x: 99, - y: 56, - wfo: 'FGF', - }, - }, - { - city: 'Flagstaff', - lat: 35.1981, - lon: -111.6513, - point: { - x: 73, - y: 88, - wfo: 'FGZ', - }, - }, - { - city: 'Fresno', - lat: 36.7477, - lon: -119.7724, - point: { - x: 53, - y: 100, - wfo: 'HNX', - }, - }, - { - city: 'Grand Junction', - lat: 39.0639, - lon: -108.5506, - point: { - x: 94, - y: 101, - wfo: 'GJT', - }, - }, - { - city: 'Grand Rapids', - lat: 42.9634, - lon: -85.6681, - point: { - x: 40, - y: 46, - wfo: 'GRR', - }, - }, - { - city: 'Havre', - lat: 48.55, - lon: -109.6841, - point: { - x: 154, - y: 187, - wfo: 'TFX', - }, - }, - { - city: 'Helena', - lat: 46.5927, - lon: -112.0361, - point: { - x: 68, - y: 103, - wfo: 'TFX', - }, - }, - { - city: 'Honolulu', - lat: 21.3069, - lon: -157.8583, - point: { - x: 153, - y: 144, - wfo: 'HFO', - }, - }, - { - city: 'Hot Springs', - lat: 34.5037, - lon: -93.0552, - point: { - x: 53, - y: 60, - wfo: 'LZK', - }, - }, - { - city: 'Idaho Falls', - lat: 43.4666, - lon: -112.0341, - point: { - x: 115, - y: 72, - wfo: 'PIH', - }, - }, - { - city: 'Jackson', - lat: 32.2988, - lon: -90.1848, - point: { - x: 75, - y: 62, - wfo: 'JAN', - }, - }, - { - city: 'Jacksonville', - lat: 30.3322, - lon: -81.6556, - point: { - x: 65, - y: 64, - wfo: 'JAX', - }, - }, - { - city: 'Juneau', - lat: 58.3019, - lon: -134.4197, - point: { - x: 194, - y: 163, - wfo: 'AJK', - }, - }, - { - city: 'Kansas City', - lat: 39.1142, - lon: -94.6275, - point: { - x: 41, - y: 50, - wfo: 'EAX', - }, - }, - { - city: 'Key West', - lat: 24.5557, - lon: -81.7826, - point: { - x: 61, - y: 47, - wfo: 'KEY', - }, - }, - { - city: 'Klamath Falls', - lat: 42.2249, - lon: -121.7817, - point: { - x: 141, - y: 61, - wfo: 'MFR', - }, - }, - { - city: 'Knoxville', - lat: 35.9606, - lon: -83.9207, - point: { - x: 71, - y: 51, - wfo: 'MRX', - }, - }, - { - city: 'Las Vegas', - lat: 36.175, - lon: -115.1372, - point: { - x: 122, - y: 97, - wfo: 'VEF', - }, - }, - { - city: 'Lewiston', - lat: 46.4165, - lon: -117.0177, - point: { - x: 144, - y: 30, - wfo: 'OTX', - }, - }, - { - city: 'Lincoln', - lat: 40.8, - lon: -96.667, - point: { - x: 56, - y: 38, - wfo: 'OAX', - }, - }, - { - city: 'Long Beach', - lat: 33.767, - lon: -118.1892, - point: { - x: 154, - y: 31, - wfo: 'LOX', - }, - }, - { - city: 'Louisville', - lat: 38.2542, - lon: -85.7594, - point: { - x: 49, - y: 77, - wfo: 'LMK', - }, - }, - { - city: 'Manchester', - lat: 42.9956, - lon: -71.4548, - point: { - x: 41, - y: 20, - wfo: 'GYX', - }, - }, - { - city: 'Memphis', - lat: 35.1495, - lon: -90.049, - point: { - x: 41, - y: 66, - wfo: 'MEG', - }, - }, - { - city: 'Milwaukee', - lat: 43.0389, - lon: -87.9065, - point: { - x: 87, - y: 64, - wfo: 'MKX', - }, - }, - { - city: 'Mobile', - lat: 30.6944, - lon: -88.043, - point: { - x: 51, - y: 66, - wfo: 'MOB', - }, - }, - { - city: 'Montgomery', - lat: 32.3668, - lon: -86.3, - point: { - x: 80, - y: 34, - wfo: 'BMX', - }, - }, - { - city: 'Montpelier', - lat: 44.2601, - lon: -72.5754, - point: { - x: 110, - y: 49, - wfo: 'BTV', - }, - }, - { - city: 'Nashville', - lat: 36.1659, - lon: -86.7844, - point: { - x: 49, - y: 56, - wfo: 'OHX', - }, - }, - { - city: 'Newark', - lat: 40.7357, - lon: -74.1724, - point: { - x: 26, - y: 34, - wfo: 'OKX', - }, - }, - { - city: 'New Haven', - lat: 41.3081, - lon: -72.9282, - point: { - x: 65, - y: 67, - wfo: 'OKX', - }, - }, - { - city: 'New Orleans', - lat: 29.9546, - lon: -90.0751, - point: { - x: 68, - y: 88, - wfo: 'LIX', - }, - }, - { - city: 'Nome', - lat: 64.5011, - lon: -165.4064, - point: { - x: 217, - y: 139, - wfo: 'AFG', - }, - }, - { - city: 'Oklahoma City', - lat: 35.4676, - lon: -97.5164, - point: { - x: 97, - y: 93, - wfo: 'OUN', - }, - }, - { - city: 'Omaha', - lat: 41.2586, - lon: -95.9378, - point: { - x: 82, - y: 59, - wfo: 'OAX', - }, - }, - { - city: 'Phoenix', - lat: 33.4484, - lon: -112.074, - point: { - x: 158, - y: 57, - wfo: 'PSR', - }, - }, - { - city: 'Pierre', - lat: 44.3683, - lon: -100.351, - point: { - x: 54, - y: 43, - wfo: 'ABR', - }, - }, - { - city: 'Portland', - lat: 43.6615, - lon: -70.2553, - point: { - x: 75, - y: 58, - wfo: 'GYX', - }, - }, - { - city: 'Portland', - lat: 45.5234, - lon: -122.6762, - point: { - x: 112, - y: 103, - wfo: 'PQR', - }, - }, - { - city: 'Providence', - lat: 41.824, - lon: -71.4128, - point: { - x: 64, - y: 64, - wfo: 'BOX', - }, - }, - { - city: 'Raleigh', - lat: 35.7721, - lon: -78.6386, - point: { - x: 74, - y: 56, - wfo: 'RAH', - }, - }, - { - city: 'Reno', - lat: 39.4986, - lon: -119.7681, - point: { - x: 45, - y: 104, - wfo: 'REV', - }, - }, - { - city: 'Richfield', - lat: 38.7725, - lon: -112.0841, - point: { - x: 81, - y: 86, - wfo: 'SLC', - }, - }, - { - city: 'Richmond', - lat: 37.5538, - lon: -77.4603, - point: { - x: 44, - y: 76, - wfo: 'AKQ', - }, - }, - { - city: 'Roanoke', - lat: 37.271, - lon: -79.9414, - point: { - x: 73, - y: 68, - wfo: 'RNK', - }, - }, - { - city: 'Sacramento', - lat: 38.5816, - lon: -121.4944, - point: { - x: 40, - y: 67, - wfo: 'STO', - }, - }, - { - city: 'Salt Lake City', - lat: 40.7608, - lon: -111.891, - point: { - x: 99, - y: 174, - wfo: 'SLC', - }, - }, - { - city: 'San Antonio', - lat: 29.4241, - lon: -98.4936, - point: { - x: 125, - y: 53, - wfo: 'EWX', - }, - }, - { - city: 'San Diego', - lat: 32.7153, - lon: -117.1573, - point: { - x: 56, - y: 13, - wfo: 'SGX', - }, - }, - { - city: 'San Jose', - lat: 37.3394, - lon: -121.895, - point: { - x: 99, - y: 82, - wfo: 'MTR', - }, - }, - { - city: 'Santa Fe', - lat: 35.687, - lon: -105.9378, - point: { - x: 125, - y: 143, - wfo: 'ABQ', - }, - }, - { - city: 'Savannah', - lat: 32.0835, - lon: -81.0998, - point: { - x: 46, - y: 40, - wfo: 'CHS', - }, - }, - { - city: 'Shreveport', - lat: 32.5251, - lon: -93.7502, - point: { - x: 76, - y: 69, - wfo: 'SHV', - }, - }, - { - city: 'Sioux Falls', - lat: 43.55, - lon: -96.7003, - point: { - x: 99, - y: 65, - wfo: 'FSD', - }, - }, - { - city: 'Sitka', - lat: 57.0531, - lon: -135.33, - point: { - x: 188, - y: 112, - wfo: 'AJK', - }, - }, - { - city: 'Spokane', - lat: 47.6597, - lon: -117.4291, - point: { - x: 140, - y: 90, - wfo: 'OTX', - }, - }, - { - city: 'Springfield', - lat: 39.8017, - lon: -89.6437, - point: { - x: 47, - y: 55, - wfo: 'ILX', - }, - }, - { - city: 'Springfield', - lat: 42.1015, - lon: -72.5898, - point: { - x: 22, - y: 69, - wfo: 'BOX', - }, - }, - { - city: 'Springfield', - lat: 37.2153, - lon: -93.2982, - point: { - x: 66, - y: 34, - wfo: 'SGF', - }, - }, - { - city: 'Toledo', - lat: 41.6639, - lon: -83.5552, - point: { - x: 18, - y: 66, - wfo: 'CLE', - }, - }, - { - city: 'Tulsa', - lat: 36.154, - lon: -95.9928, - point: { - x: 40, - y: 104, - wfo: 'TSA', - }, - }, - { - city: 'Virginia Beach', - lat: 36.8529, - lon: -75.978, - point: { - x: 100, - y: 52, - wfo: 'AKQ', - }, - }, - { - city: 'Wichita', - lat: 37.6922, - lon: -97.3375, - point: { - x: 61, - y: 33, - wfo: 'ICT', - }, - }, - { - city: 'Wilmington', - lat: 34.2257, - lon: -77.9447, - point: { - x: 88, - y: 67, - wfo: 'ILM', - }, - }, - { - city: 'Tuscan', - lat: 32.2216, - lon: -110.9698, - point: { - x: 90, - y: 48, - wfo: 'TWC', - }, - }, -]; diff --git a/dist/server/scripts/data/stations.js b/dist/server/scripts/data/stations.js deleted file mode 100644 index c250351..0000000 --- a/dist/server/scripts/data/stations.js +++ /dev/null @@ -1,15705 +0,0 @@ -// cspell: disable -// eslint-disable-next-line no-unused-vars -const StationInfo = { - KBID: { - id: 'KBID', - city: 'Block Island State Airport', - state: 'RI', - lat: 41.1694699, - lon: -71.5787299, - }, - KOQU: { - id: 'KOQU', - city: 'N. Kingston / Quonset', - state: 'RI', - lat: 41.6, - lon: -71.41667, - }, - KPVD: { - id: 'KPVD', - city: 'Providence, Theodore Francis Green State Airport', - state: 'RI', - lat: 41.72249, - lon: -71.43247, - }, - KSFZ: { - id: 'KSFZ', - city: 'Pawtucket, North Central State Airport', - state: 'RI', - lat: 41.91667, - lon: -71.5, - }, - KUUU: { - id: 'KUUU', - city: 'Newport, Newport State Airport', - state: 'RI', - lat: 41.53, - lon: -71.28361, - }, - KWST: { - id: 'KWST', - city: 'Westerly, Westerly State Airport', - state: 'RI', - lat: 41.34972, - lon: -71.79889, - }, - KBDL: { - id: 'KBDL', - city: 'Windsor Locks, Bradley International Airport', - state: 'CT', - lat: 41.93806, - lon: -72.6825, - }, - KBDR: { - id: 'KBDR', - city: 'Bridgeport, Sikorsky Memorial Airport', - state: 'CT', - lat: 41.16421, - lon: -73.12663, - }, - KDXR: { - id: 'KDXR', - city: 'Danbury, Danbury Municipal Airport', - state: 'CT', - lat: 41.37167, - lon: -73.48444, - }, - KGON: { - id: 'KGON', - city: 'Groton / New London, Groton / New London Airport', - state: 'CT', - lat: 41.3275, - lon: -72.04944, - }, - KHFD: { - id: 'KHFD', - city: 'Hartford, Hartford-Brainard Airport', - state: 'CT', - lat: 41.735, - lon: -72.65167, - }, - KHVN: { - id: 'KHVN', - city: 'New Haven, Tweed-New Haven Airport', - state: 'CT', - lat: 41.26389, - lon: -72.88722, - }, - KIJD: { - id: 'KIJD', - city: 'Willimantic, Windham Airport', - state: 'CT', - lat: 41.74194, - lon: -72.18361, - }, - KMMK: { - id: 'KMMK', - city: 'Meriden, Meriden Markham Municipal Airport', - state: 'CT', - lat: 41.50972, - lon: -72.82778, - }, - KOXC: { - id: 'KOXC', - city: 'Oxford, Waterbury-Oxford Airport', - state: 'CT', - lat: 41.48333, - lon: -73.13333, - }, - KSNC: { - id: 'KSNC', - city: 'Chester, Chester Airport', - state: 'CT', - lat: 41.38389, - lon: -72.50583, - }, - KBTV: { - id: 'KBTV', - city: 'Burlington, Burlington International Airport', - state: 'VT', - lat: 44.46806, - lon: -73.15028, - }, - KCDA: { - id: 'KCDA', - city: 'Caledonia County Airport', - state: 'VT', - lat: 44.5691142, - lon: -72.0179789, - }, - KDDH: { - id: 'KDDH', - city: 'Bennington Morse State Airport', - state: 'VT', - lat: 42.89355, - lon: -73.2486, - }, - KEFK: { - id: 'KEFK', - city: 'Northeast Kingdom International Airport', - state: 'VT', - lat: 44.88846, - lon: -72.23593, - }, - KFSO: { - id: 'KFSO', - city: 'Franklin County State Airport', - state: 'VT', - lat: 44.9402807, - lon: -73.09746, - }, - KMPV: { - id: 'KMPV', - city: 'Barre / Montpelier, Knapp State Airport', - state: 'VT', - lat: 44.20472, - lon: -72.56611, - }, - KMVL: { - id: 'KMVL', - city: 'Morrisville-Stowe State Airport', - state: 'VT', - lat: 44.53589, - lon: -72.6162499, - }, - KRUT: { - id: 'KRUT', - city: 'Rutland-Southern Vermont Regional Airport', - state: 'VT', - lat: 43.53333, - lon: -72.95, - }, - KVSF: { - id: 'KVSF', - city: 'Springfield, Hartness State Springfield Airport', - state: 'VT', - lat: 43.3425, - lon: -72.52167, - }, - PHBK: { - id: 'PHBK', - city: 'Kekaha, Pacific Missile Test Facility Barking Sands', - state: 'HI', - lat: 22.03639, - lon: -159.78639, - }, - PHHI: { - id: 'PHHI', - city: 'Wheeler Air Force Base / Oahu', - state: 'HI', - lat: 21.48333, - lon: -158.03333, - }, - PHJH: { - id: 'PHJH', - city: 'Lahaina - West Maui', - state: 'HI', - lat: 20.9630699, - lon: -156.67466, - }, - PHJR: { - id: 'PHJR', - city: 'Oahu, Kalaeloa Airport', - state: 'HI', - lat: 21.30833, - lon: -158.06806, - }, - PHKO: { - id: 'PHKO', - city: 'Kailua / Kona, Keahole Airport', - state: 'HI', - lat: 19.74083, - lon: -156.05056, - }, - PHLI: { - id: 'PHLI', - city: 'Lihue, Lihue Airport', - state: 'HI', - lat: 21.98389, - lon: -159.3411099, - }, - PHMK: { - id: 'PHMK', - city: 'Kaunakakai, Molokai Airport', - state: 'HI', - lat: 21.15, - lon: -157.1, - }, - PHNG: { - id: 'PHNG', - city: 'Kaneohe, Marine Corps Air Station', - state: 'HI', - lat: 21.45389, - lon: -157.76556, - }, - PHNL: { - id: 'PHNL', - city: 'Daniel K Inouye International Airport', - state: 'HI', - lat: 21.3275, - lon: -157.94306, - }, - PHNY: { - id: 'PHNY', - city: 'Lanai City, Lanai Airport', - state: 'HI', - lat: 20.78556, - lon: -156.95139, - }, - PHOG: { - id: 'PHOG', - city: 'Kahului, Kahului Airport', - state: 'HI', - lat: 20.8924999, - lon: -156.43694, - }, - PHSF: { - id: 'PHSF', - city: 'Bradshaw Army Air Field / Hawaii', - state: 'HI', - lat: 19.78333, - lon: -155.55, - }, - PHTO: { - id: 'PHTO', - city: 'Hilo, Hilo International Airport', - state: 'HI', - lat: 19.72222, - lon: -155.0558299, - }, - KADU: { - id: 'KADU', - city: 'Audubon, Audubon County Airport', - state: 'IA', - lat: 41.70111, - lon: -94.92028, - }, - KAIO: { - id: 'KAIO', - city: 'Atlantic', - state: 'IA', - lat: 41.4, - lon: -95.05, - }, - KALO: { - id: 'KALO', - city: 'Waterloo, Waterloo Municipal Airport', - state: 'IA', - lat: 42.55444, - lon: -92.40111, - }, - KAMW: { - id: 'KAMW', - city: 'Ames, Ames Municipal Airport', - state: 'IA', - lat: 41.99056, - lon: -93.6188899, - }, - KAWG: { - id: 'KAWG', - city: 'Washington', - state: 'IA', - lat: 41.28333, - lon: -91.66667, - }, - KAXA: { - id: 'KAXA', - city: 'Algona', - state: 'IA', - lat: 43.0833299, - lon: -94.26667, - }, - KBNW: { - id: 'KBNW', - city: 'Boone Municipal', - state: 'IA', - lat: 42.05, - lon: -93.85, - }, - KBRL: { - id: 'KBRL', - city: 'Burlington Regional Airport', - state: 'IA', - lat: 40.77293, - lon: -91.12543, - }, - KCAV: { - id: 'KCAV', - city: 'Clarion', - state: 'IA', - lat: 42.75, - lon: -93.76667, - }, - KCBF: { - id: 'KCBF', - city: 'Council Bluffs', - state: 'IA', - lat: 41.2612499, - lon: -95.7604, - }, - KCCY: { - id: 'KCCY', - city: 'Charles City', - state: 'IA', - lat: 43.06667, - lon: -92.61667, - }, - KCID: { - id: 'KCID', - city: 'Cedar Rapids Airport', - state: 'IA', - lat: 41.88295, - lon: -91.72456, - }, - KCIN: { - id: 'KCIN', - city: 'Carroll', - state: 'IA', - lat: 42.05, - lon: -94.78333, - }, - KCKP: { - id: 'KCKP', - city: 'Cherokee, Cherokee Municipal Airport', - state: 'IA', - lat: 42.73167, - lon: -95.55583, - }, - KCNC: { - id: 'KCNC', - city: 'Chariton', - state: 'IA', - lat: 41.03333, - lon: -93.36667, - }, - KCSQ: { - id: 'KCSQ', - city: 'Creston Municipal Airport', - state: 'IA', - lat: 41.0188599, - lon: -94.361, - }, - KCWI: { - id: 'KCWI', - city: 'Clinton Municipal Airport', - state: 'IA', - lat: 41.82954, - lon: -90.33279, - }, - KDBQ: { - id: 'KDBQ', - city: 'Dubuque Regional Airport', - state: 'IA', - lat: 42.39837, - lon: -90.7091, - }, - KDEH: { - id: 'KDEH', - city: 'Decorah', - state: 'IA', - lat: 43.28333, - lon: -91.73333, - }, - KDNS: { - id: 'KDNS', - city: 'Denison', - state: 'IA', - lat: 41.98333, - lon: -95.38333, - }, - KDSM: { - id: 'KDSM', - city: 'Des Moines International Airport', - state: 'IA', - lat: 41.53399, - lon: -93.65307, - }, - KDVN: { - id: 'KDVN', - city: 'Davenport Municipal Airport', - state: 'IA', - lat: 41.61338, - lon: -90.59479, - }, - KEBS: { - id: 'KEBS', - city: 'Webster City Municipal Airport', - state: 'IA', - lat: 42.43724, - lon: -93.87237, - }, - KEOK: { - id: 'KEOK', - city: 'Keokuk Municipal Airport', - state: 'IA', - lat: 40.46149, - lon: -91.42739, - }, - KEST: { - id: 'KEST', - city: 'Estherville, Estherville Municipal Airport', - state: 'IA', - lat: 43.40111, - lon: -94.74722, - }, - KFFL: { - id: 'KFFL', - city: 'Fairfield Municipal Airport', - state: 'IA', - lat: 41.0521, - lon: -91.98339, - }, - KFOD: { - id: 'KFOD', - city: 'Fort Dodge', - state: 'IA', - lat: 42.55, - lon: -94.18333, - }, - KFSW: { - id: 'KFSW', - city: 'Fort Madison Municipal Airport', - state: 'IA', - lat: 40.66154, - lon: -91.32672, - }, - KFXY: { - id: 'KFXY', - city: 'Forest City Municipal Airport', - state: 'IA', - lat: 43.235, - lon: -93.624, - }, - KGGI: { - id: 'KGGI', - city: 'Grinnell Municipal Airfield', - state: 'IA', - lat: 41.7092, - lon: -92.7349, - }, - KHNR: { - id: 'KHNR', - city: 'Harlan, Harlan Municipal Airport', - state: 'IA', - lat: 41.58444, - lon: -95.33972, - }, - KHPT: { - id: 'KHPT', - city: 'Hampton Municipal Airport', - state: 'IA', - lat: 42.72369, - lon: -93.22633, - }, - KICL: { - id: 'KICL', - city: 'Schenck Field Airport', - state: 'IA', - lat: 40.72421, - lon: -95.02224, - }, - KIFA: { - id: 'KIFA', - city: 'Iowa Falls Municipal Airport', - state: 'IA', - lat: 42.4709999, - lon: -93.27, - }, - KIIB: { - id: 'KIIB', - city: 'Independence, Independence Municipal Airport', - state: 'IA', - lat: 42.45, - lon: -91.93333, - }, - KIKV: { - id: 'KIKV', - city: 'Ankeny Regional Airport', - state: 'IA', - lat: 41.68782, - lon: -93.56944, - }, - KIOW: { - id: 'KIOW', - city: 'Iowa City Municipal Airport', - state: 'IA', - lat: 41.6394499, - lon: -91.5445, - }, - KLRJ: { - id: 'KLRJ', - city: 'Le Mars Municipal Airport', - state: 'IA', - lat: 42.77478, - lon: -96.19239, - }, - KLWD: { - id: 'KLWD', - city: 'Lamoni, Lamoni Municipal Airport', - state: 'IA', - lat: 40.63056, - lon: -93.90083, - }, - KMCW: { - id: 'KMCW', - city: 'Mason City Municipal Airport', - state: 'IA', - lat: 43.15442, - lon: -93.32607, - }, - KMIW: { - id: 'KMIW', - city: 'Marshalltown, Marshalltown Municipal Airport', - state: 'IA', - lat: 42.11056, - lon: -92.91611, - }, - KMPZ: { - id: 'KMPZ', - city: 'Mount Pleasant, Mount Pleasant Municipal Airport', - state: 'IA', - lat: 40.94667, - lon: -91.51111, - }, - KMUT: { - id: 'KMUT', - city: 'Muscatine', - state: 'IA', - lat: 41.36667, - lon: -91.15, - }, - KMXO: { - id: 'KMXO', - city: 'Monticello Regional Airport', - state: 'IA', - lat: 42.22035, - lon: -91.16041, - }, - KOLZ: { - id: 'KOLZ', - city: 'Oelwein Municipal Airport', - state: 'IA', - lat: 42.68316, - lon: -91.97595, - }, - KOOA: { - id: 'KOOA', - city: 'Oskaloosa, Oskaloosa Municipal Airport', - state: 'IA', - lat: 41.22611, - lon: -92.49361, - }, - KOTM: { - id: 'KOTM', - city: 'Ottumwa Regional Airport', - state: 'IA', - lat: 41.10082, - lon: -92.4445099, - }, - KOXV: { - id: 'KOXV', - city: 'Knoxville', - state: 'IA', - lat: 41.3, - lon: -93.11667, - }, - KPEA: { - id: 'KPEA', - city: 'Pella, Pella Municipal Airport', - state: 'IA', - lat: 41.4, - lon: -92.93333, - }, - KPRO: { - id: 'KPRO', - city: 'Perry Municipal Airport', - state: 'IA', - lat: 41.828, - lon: -94.1598999, - }, - KRDK: { - id: 'KRDK', - city: 'Red Oak', - state: 'IA', - lat: 41.01667, - lon: -95.26667, - }, - KSDA: { - id: 'KSDA', - city: 'Shenandoah Municipal', - state: 'IA', - lat: 40.75, - lon: -95.41667, - }, - KSHL: { - id: 'KSHL', - city: 'Sheldon', - state: 'IA', - lat: 43.21667, - lon: -95.83333, - }, - KSLB: { - id: 'KSLB', - city: 'Storm Lake', - state: 'IA', - lat: 42.6, - lon: -95.23333, - }, - KSPW: { - id: 'KSPW', - city: 'Spencer Municipal Airport', - state: 'IA', - lat: 43.16825, - lon: -95.21008, - }, - KSUX: { - id: 'KSUX', - city: 'Sioux City, Sioux Gateway Airport', - state: 'IA', - lat: 42.4025, - lon: -96.38444, - }, - KSXK: { - id: 'KSXK', - city: 'Sioux County Regional Airport', - state: 'IA', - lat: 42.98583, - lon: -96.1614, - }, - KTNU: { - id: 'KTNU', - city: 'Newton Municipal Airport - Earl Johnson Field', - state: 'IA', - lat: 41.67014, - lon: -93.01902, - }, - KTVK: { - id: 'KTVK', - city: 'Centerville Municipal Airport', - state: 'IA', - lat: 40.6839, - lon: -92.901, - }, - KVTI: { - id: 'KVTI', - city: 'Vinton, Vinton Veterans Memorial Airpark Airport', - state: 'IA', - lat: 42.21861, - lon: -92.02583, - }, - KAFK: { - id: 'KAFK', - city: 'Nebraska City, Nebraska City Municipal Airport', - state: 'NE', - lat: 40.6, - lon: -95.85, - }, - KAHQ: { - id: 'KAHQ', - city: 'Wahoo', - state: 'NE', - lat: 41.2406, - lon: -96.5946, - }, - KAIA: { - id: 'KAIA', - city: 'Alliance, Alliance Municipal Airport', - state: 'NE', - lat: 42.05722, - lon: -102.8, - }, - KANW: { - id: 'KANW', - city: 'Ainsworth Regional Airport', - state: 'NE', - lat: 42.57484, - lon: -99.99832, - }, - KAUH: { - id: 'KAUH', - city: 'Aurora, Aurora Municipal Airport', - state: 'NE', - lat: 40.89389, - lon: -97.99444, - }, - KBBW: { - id: 'KBBW', - city: 'Broken Bow, Broken Bow Municipal Airport', - state: 'NE', - lat: 41.43333, - lon: -99.65, - }, - KBFF: { - id: 'KBFF', - city: 'Scottsbluff, Heilig Field', - state: 'NE', - lat: 41.86694, - lon: -103.58583, - }, - KBIE: { - id: 'KBIE', - city: 'Beatrice Municipal', - state: 'NE', - lat: 40.3, - lon: -96.75, - }, - KBTA: { - id: 'KBTA', - city: 'Blair Municipal Airport', - state: 'NE', - lat: 41.4148, - lon: -96.109, - }, - KBVN: { - id: 'KBVN', - city: 'Albion Municipal Airport', - state: 'NE', - lat: 41.73016, - lon: -98.05453, - }, - KCDR: { - id: 'KCDR', - city: 'Chadron, Chadron Municipal Airport', - state: 'NE', - lat: 42.8375, - lon: -103.09528, - }, - KEAR: { - id: 'KEAR', - city: 'Kearney, Kearney Municipal Airport', - state: 'NE', - lat: 40.73333, - lon: -99, - }, - KFET: { - id: 'KFET', - city: 'Fremont Municipal Airport', - state: 'NE', - lat: 41.45, - lon: -96.51667, - }, - KFNB: { - id: 'KFNB', - city: 'Falls City, Brenner Field Airport', - state: 'NE', - lat: 40.07889, - lon: -95.5919399, - }, - KGRI: { - id: 'KGRI', - city: 'Grand Island, Central Nebraska Regional Airport', - state: 'NE', - lat: 40.9583299, - lon: -98.3125, - }, - KGRN: { - id: 'KGRN', - city: 'Gordon Municipal', - state: 'NE', - lat: 42.8, - lon: -102.16667, - }, - KHDE: { - id: 'KHDE', - city: 'Brewster Field Airport', - state: 'NE', - lat: 40.45, - lon: -99.33333, - }, - KHJH: { - id: 'KHJH', - city: 'Hebron, Hebron Municipal Airport', - state: 'NE', - lat: 40.15222, - lon: -97.58694, - }, - KHSI: { - id: 'KHSI', - city: 'Hastings, Hastings Municipal Airport', - state: 'NE', - lat: 40.60056, - lon: -98.42583, - }, - KIBM: { - id: 'KIBM', - city: 'Kimball, Kimball Municipal Airport/Robert E Arraj Field', - state: 'NE', - lat: 41.18333, - lon: -103.66667, - }, - KIML: { - id: 'KIML', - city: 'Imperial, Imperial Municipal Airport', - state: 'NE', - lat: 40.51667, - lon: -101.61667, - }, - KJYR: { - id: 'KJYR', - city: 'York, York Municipal Airport', - state: 'NE', - lat: 40.89667, - lon: -97.62278, - }, - KLBF: { - id: 'KLBF', - city: 'North Platte, North Platte Regional Airport', - state: 'NE', - lat: 41.12194, - lon: -100.66833, - }, - KLCG: { - id: 'KLCG', - city: 'Wayne, Wayne Municipal Airport', - state: 'NE', - lat: 42.24167, - lon: -96.98139, - }, - KLNK: { - id: 'KLNK', - city: 'Lincoln, Lincoln Municipal Airport', - state: 'NE', - lat: 40.83111, - lon: -96.7644399, - }, - KLXN: { - id: 'KLXN', - city: 'Lexington, Jim Kelly Field Airport', - state: 'NE', - lat: 40.79111, - lon: -99.77722, - }, - KMCK: { - id: 'KMCK', - city: 'McCook, McCook Municipal Airport', - state: 'NE', - lat: 40.20306, - lon: -100.58833, - }, - KMLE: { - id: 'KMLE', - city: 'Omaha, Millard Airport', - state: 'NE', - lat: 41.19583, - lon: -96.1122199, - }, - KODX: { - id: 'KODX', - city: 'Ord, Evelyn Sharp Field Airport', - state: 'NE', - lat: 41.62417, - lon: -98.9525, - }, - KOFF: { - id: 'KOFF', - city: 'Omaha / Offutt Air Force Base', - state: 'NE', - lat: 41.11667, - lon: -95.9, - }, - KOFK: { - id: 'KOFK', - city: 'Norfolk, Stefan Memorial Airport', - state: 'NE', - lat: 41.9805599, - lon: -97.43694, - }, - KOGA: { - id: 'KOGA', - city: 'Ogallala, Searle Field Airport', - state: 'NE', - lat: 41.11972, - lon: -101.76889, - }, - KOLU: { - id: 'KOLU', - city: 'Columbus, Columbus Municipal Airport', - state: 'NE', - lat: 41.45, - lon: -97.33333, - }, - KOMA: { - id: 'KOMA', - city: 'Omaha - Eppley Airfield', - state: 'NE', - lat: 41.3119, - lon: -95.90185, - }, - KONL: { - id: 'KONL', - city: "O'Neill / Baker Field", - state: 'NE', - lat: 42.46667, - lon: -98.68333, - }, - KPMV: { - id: 'KPMV', - city: 'Plattsmouth, Plattsmouth Municipal Airport', - state: 'NE', - lat: 40.95, - lon: -95.9177799, - }, - KSNY: { - id: 'KSNY', - city: 'Sidney, Sidney Municipal Airport', - state: 'NE', - lat: 41.09944, - lon: -102.98556, - }, - KTIF: { - id: 'KTIF', - city: 'Thedford, Thomas County Airport', - state: 'NE', - lat: 41.96194, - lon: -100.56889, - }, - KTQE: { - id: 'KTQE', - city: 'Tekamah, Tekamah Municipal Airport', - state: 'NE', - lat: 41.76694, - lon: -96.17778, - }, - KVTN: { - id: 'KVTN', - city: 'Valentine, Miller Field', - state: 'NE', - lat: 42.85861, - lon: -100.55139, - }, - KDOV: { - id: 'KDOV', - city: 'Dover Air Force Base', - state: 'DE', - lat: 39.13333, - lon: -75.4666699, - }, - KGED: { - id: 'KGED', - city: 'Georgetown - Delaware Coastal Airport', - state: 'DE', - lat: 38.68974, - lon: -75.36245, - }, - KILG: { - id: 'KILG', - city: 'Wilmington, New Castle County Airport', - state: 'DE', - lat: 39.67442, - lon: -75.60567, - }, - KBKW: { - id: 'KBKW', - city: 'Beckley, Raleigh County Memorial Airport', - state: 'WV', - lat: 37.795, - lon: -81.12472, - }, - KBLF: { - id: 'KBLF', - city: 'Bluefield, Mercer County Airport', - state: 'WV', - lat: 37.29583, - lon: -81.20778, - }, - KCBE: { - id: 'KCBE', - city: 'Cumberland, Greater Cumberland Regional Airport', - state: 'WV', - lat: 39.61528, - lon: -78.76083, - }, - KCKB: { - id: 'KCKB', - city: 'Clarksburg, Clarksburg Benedum Airport', - state: 'WV', - lat: 39.3, - lon: -80.22472, - }, - KCRW: { - id: 'KCRW', - city: 'Charleston, Yeager Airport', - state: 'WV', - lat: 38.37944, - lon: -81.59139, - }, - KEKN: { - id: 'KEKN', - city: 'Elkins, Elkins-Randolph County-Jennings Randolph Field', - state: 'WV', - lat: 38.88528, - lon: -79.85278, - }, - KHLG: { - id: 'KHLG', - city: 'Wheeling, Wheeling Ohio County Airport', - state: 'WV', - lat: 40.17028, - lon: -80.64444, - }, - KHTS: { - id: 'KHTS', - city: 'Huntington, Tri-State Airport', - state: 'WV', - lat: 38.365, - lon: -82.555, - }, - KLWB: { - id: 'KLWB', - city: 'Lewisburg / Greenbrier', - state: 'WV', - lat: 37.86667, - lon: -80.4, - }, - KMGW: { - id: 'KMGW', - city: 'Morgantown Municipal-Hart Field', - state: 'WV', - lat: 39.64985, - lon: -79.92065, - }, - KMRB: { - id: 'KMRB', - city: 'Eastern WV Regional Airport/Shepherd Field', - state: 'WV', - lat: 39.40372, - lon: -77.975, - }, - KPKB: { - id: 'KPKB', - city: 'Parkersburg, Mid-Ohio Valley Regional Airport', - state: 'WV', - lat: 39.345, - lon: -81.43917, - }, - KACQ: { - id: 'KACQ', - city: 'Waseca Municipal Airport', - state: 'MN', - lat: 44.07024, - lon: -93.55342, - }, - KADC: { - id: 'KADC', - city: 'Wadena Municipal Airport', - state: 'MN', - lat: 46.45022, - lon: -95.21353, - }, - KAEL: { - id: 'KAEL', - city: 'Albert Lea, Albert Lea Municipal Airport', - state: 'MN', - lat: 43.68333, - lon: -93.36667, - }, - KAIT: { - id: 'KAIT', - city: 'Aitkin Municipal Airport - Steve Kurtz Field', - state: 'MN', - lat: 46.54899, - lon: -93.67573, - }, - KANE: { - id: 'KANE', - city: 'Minneapolis / Blaine', - state: 'MN', - lat: 45.14258, - lon: -93.21272, - }, - KAQP: { - id: 'KAQP', - city: 'Appleton Municipal Airport', - state: 'MN', - lat: 45.22488, - lon: -96.00412, - }, - KACB: { - id: 'KACB', - city: 'Bellaire, Antrim County Airport', - state: 'MI', - lat: 44.98833, - lon: -85.19833, - }, - KADG: { - id: 'KADG', - city: 'Adrian, Lenawee County Airport', - state: 'MI', - lat: 41.86778, - lon: -84.07944, - }, - KAMN: { - id: 'KAMN', - city: 'Alma, Gratiot Community Airport', - state: 'MI', - lat: 43.32194, - lon: -84.68778, - }, - KANJ: { - id: 'KANJ', - city: 'Sault Ste. Marie', - state: 'MI', - lat: 46.4794399, - lon: -84.35722, - }, - KAPN: { - id: 'KAPN', - city: 'Alpena, Alpena County Regional Airport', - state: 'MI', - lat: 45.07167, - lon: -83.56444, - }, - KARB: { - id: 'KARB', - city: 'Ann Arbor, Ann Arbor Municipal Airport', - state: 'MI', - lat: 42.22389, - lon: -83.74, - }, - KAZO: { - id: 'KAZO', - city: 'Kalamazoo/Battle Creek International Airport', - state: 'MI', - lat: 42.2283, - lon: -85.54595, - }, - KBAX: { - id: 'KBAX', - city: 'Huron County Memorial Airport', - state: 'MI', - lat: 43.77741, - lon: -82.98271, - }, - KBEH: { - id: 'KBEH', - city: 'Southwest Michigan Regional Airport', - state: 'MI', - lat: 42.12896, - lon: -86.41515, - }, - KBIV: { - id: 'KBIV', - city: 'Holland - West Michigan Regional Airport', - state: 'MI', - lat: 42.74611, - lon: -86.09667, - }, - KBTL: { - id: 'KBTL', - city: 'Battle Creek Executive Airport', - state: 'MI', - lat: 42.31197, - lon: -85.24144, - }, - KCAD: { - id: 'KCAD', - city: 'Wexford County Airport', - state: 'MI', - lat: 44.27847, - lon: -85.4206899, - }, - KCFS: { - id: 'KCFS', - city: 'Caro, Tuscola Area Airport', - state: 'MI', - lat: 43.45861, - lon: -83.44528, - }, - KCIU: { - id: 'KCIU', - city: 'Sault Ste Marie, Chippewa County International Airport', - state: 'MI', - lat: 46.25, - lon: -84.4666699, - }, - KCMX: { - id: 'KCMX', - city: 'Houghton County Memorial Airport', - state: 'MI', - lat: 47.16597, - lon: -88.48072, - }, - KCVX: { - id: 'KCVX', - city: 'Charlevoix, Charlevoix Municipal Airport', - state: 'MI', - lat: 45.30472, - lon: -85.27472, - }, - KDET: { - id: 'KDET', - city: 'Coleman A Young Municipal Airport', - state: 'MI', - lat: 42.40729, - lon: -83.00894, - }, - KDRM: { - id: 'KDRM', - city: 'Drummond Island Airport', - state: 'MI', - lat: 46.0072, - lon: -83.7427, - }, - KDTW: { - id: 'KDTW', - city: 'Detroit, Detroit Metropolitan Wayne County Airport', - state: 'MI', - lat: 42.23139, - lon: -83.33083, - }, - KDUH: { - id: 'KDUH', - city: 'Lambertville, Toledo Suburban Airport', - state: 'MI', - lat: 41.73583, - lon: -83.65528, - }, - KERY: { - id: 'KERY', - city: 'Newberry, Luce County Airport', - state: 'MI', - lat: 46.31111, - lon: -85.45722, - }, - KESC: { - id: 'KESC', - city: 'Delta County Airport', - state: 'MI', - lat: 45.7226799, - lon: -87.09372, - }, - KFFX: { - id: 'KFFX', - city: 'Fremont Municipal Airport', - state: 'MI', - lat: 43.43933, - lon: -85.9948299, - }, - KFKS: { - id: 'KFKS', - city: 'Frankfort, Frankfort Dow Memorial Field Airport', - state: 'MI', - lat: 44.625, - lon: -86.20056, - }, - KFNT: { - id: 'KFNT', - city: 'Flint, Bishop International Airport', - state: 'MI', - lat: 42.96667, - lon: -83.74944, - }, - KFPK: { - id: 'KFPK', - city: 'Charlotte, Fitch H Beach Airport', - state: 'MI', - lat: 42.57444, - lon: -84.81139, - }, - KGLR: { - id: 'KGLR', - city: 'Gaylord Regional Airport', - state: 'MI', - lat: 45.01658, - lon: -84.68937, - }, - KGOV: { - id: 'KGOV', - city: 'Grayling, Grayling Army Airfield', - state: 'MI', - lat: 44.68028, - lon: -84.72889, - }, - KGRR: { - id: 'KGRR', - city: 'Grand Rapids, Gerald R. Ford International Airport', - state: 'MI', - lat: 42.88083, - lon: -85.52278, - }, - KHAI: { - id: 'KHAI', - city: 'Haines Memorial Airport', - state: 'MI', - lat: 41.9598, - lon: -85.5934, - }, - KHTL: { - id: 'KHTL', - city: 'Houghton Lake, Roscommon County Airport', - state: 'MI', - lat: 44.35111, - lon: -84.67417, - }, - KABR: { - id: 'KABR', - city: 'Aberdeen, Aberdeen Regional Airport', - state: 'SD', - lat: 45.44333, - lon: -98.41306, - }, - KAGZ: { - id: 'KAGZ', - city: 'WAGNERMUNC', - state: 'SD', - lat: 43.06332, - lon: -98.29618, - }, - KATY: { - id: 'KATY', - city: 'Watertown, Watertown Municipal Airport', - state: 'SD', - lat: 44.90472, - lon: -97.14944, - }, - KBKX: { - id: 'KBKX', - city: 'Brookings, Brookings Municipal Airport', - state: 'SD', - lat: 44.3, - lon: -96.81667, - }, - KCUT: { - id: 'KCUT', - city: 'Custer, Custer County Airport', - state: 'SD', - lat: 43.73306, - lon: -103.6175, - }, - KEFC: { - id: 'KEFC', - city: 'BELLEFCHE', - state: 'SD', - lat: 44.7342, - lon: -103.86199, - }, - KFSD: { - id: 'KFSD', - city: 'Sioux Falls, Foss Field', - state: 'SD', - lat: 43.57694, - lon: -96.75361, - }, - KHON: { - id: 'KHON', - city: 'Huron, Huron Regional Airport', - state: 'SD', - lat: 44.38806, - lon: -98.22833, - }, - KICR: { - id: 'KICR', - city: 'Winner, Bob Wiley Field Airport', - state: 'SD', - lat: 43.39056, - lon: -99.8425, - }, - KIEN: { - id: 'KIEN', - city: 'Pine Ridge, Pine Ridge Airport', - state: 'SD', - lat: 43.02556, - lon: -102.52306, - }, - KLEM: { - id: 'KLEM', - city: 'LEMMON', - state: 'SD', - lat: 45.91869, - lon: -102.10617, - }, - KMBG: { - id: 'KMBG', - city: 'Mobridge, Mobridge Municipal Airport', - state: 'SD', - lat: 45.55, - lon: -100.40861, - }, - KMDS: { - id: 'KMDS', - city: 'Madison Municipal Airport', - state: 'SD', - lat: 44.0164147, - lon: -97.0855992, - }, - KMHE: { - id: 'KMHE', - city: 'Mitchell, Mitchell Municipal Airport', - state: 'SD', - lat: 43.76667, - lon: -98.03333, - }, - KMKA: { - id: 'KMKA', - city: 'MILLERMUNC', - state: 'SD', - lat: 44.5252399, - lon: -98.95811, - }, - KPHP: { - id: 'KPHP', - city: 'Philip, Philip Airport', - state: 'SD', - lat: 44.05111, - lon: -101.60111, - }, - KPIR: { - id: 'KPIR', - city: 'Pierre, Pierre Regional Airport', - state: 'SD', - lat: 44.3827799, - lon: -100.28583, - }, - KRAP: { - id: 'KRAP', - city: 'Rapid City, Rapid City Regional Airport', - state: 'SD', - lat: 44.04556, - lon: -103.05389, - }, - KRCA: { - id: 'KRCA', - city: 'Ellsworth Air Force Base', - state: 'SD', - lat: 44.15, - lon: -103.1, - }, - KSPF: { - id: 'KSPF', - city: 'Spearfish / Clyde Ice', - state: 'SD', - lat: 44.48333, - lon: -103.78333, - }, - KUNR: { - id: 'KUNR', - city: 'Rapid City/WFO', - state: 'SD', - lat: 44.0727, - lon: -103.2108, - }, - KVMR: { - id: 'KVMR', - city: 'VERMILLION', - state: 'SD', - lat: 42.76528, - lon: -96.93425, - }, - KYKN: { - id: 'KYKN', - city: 'Yankton, Chan Gurney Municipal Airport', - state: 'SD', - lat: 42.91667, - lon: -97.38333, - }, - KALX: { - id: 'KALX', - city: 'Alexander City, Thomas C Russell Field Airport', - state: 'AL', - lat: 32.91472, - lon: -85.96278, - }, - KANB: { - id: 'KANB', - city: 'Anniston Metro Airport', - state: 'AL', - lat: 33.59045, - lon: -85.84789, - }, - KASN: { - id: 'KASN', - city: 'Talladega Municipal Airport', - state: 'AL', - lat: 33.5695, - lon: -86.0512, - }, - KAUO: { - id: 'KAUO', - city: 'Auburn-Opelika Airport', - state: 'AL', - lat: 32.61667, - lon: -85.43333, - }, - KBFM: { - id: 'KBFM', - city: 'Mobile, Mobile Downtown Airport', - state: 'AL', - lat: 30.61389, - lon: -88.0633299, - }, - KBHM: { - id: 'KBHM', - city: 'Birmingham, Birmingham International Airport', - state: 'AL', - lat: 33.56556, - lon: -86.745, - }, - KCMD: { - id: 'KCMD', - city: 'Cullman Regional Folsom Field', - state: 'AL', - lat: 34.2687, - lon: -86.858, - }, - KCQF: { - id: 'KCQF', - city: 'Sonny Callahan Airport', - state: 'AL', - lat: 30.461, - lon: -87.877, - }, - KDCU: { - id: 'KDCU', - city: 'Decatur, Pryor Field', - state: 'AL', - lat: 34.65806, - lon: -86.94333, - }, - KDHN: { - id: 'KDHN', - city: 'Dothan, Dothan Regional Airport', - state: 'AL', - lat: 31.32139, - lon: -85.44972, - }, - KDYA: { - id: 'KDYA', - city: 'Demopolis Municipal Airport', - state: 'AL', - lat: 32.4638, - lon: -87.9541, - }, - KEDN: { - id: 'KEDN', - city: 'Enterprise Municipal Airport', - state: 'AL', - lat: 31.2982, - lon: -85.9048, - }, - KEET: { - id: 'KEET', - city: 'Alabaster, Shelby County Airport', - state: 'AL', - lat: 33.17833, - lon: -86.78167, - }, - KEKY: { - id: 'KEKY', - city: 'Bessemer Airport', - state: 'AL', - lat: 33.3126, - lon: -86.9263, - }, - KEUF: { - id: 'KEUF', - city: 'Eufaula Municipal Airport', - state: 'AL', - lat: 31.951, - lon: -85.129, - }, - KGAD: { - id: 'KGAD', - city: 'Gadsden, Gadsden Municipal Airport', - state: 'AL', - lat: 33.96667, - lon: -86.08333, - }, - KGZH: { - id: 'KGZH', - city: 'Evergreen, Middleton Field', - state: 'AL', - lat: 31.41889, - lon: -87.04806, - }, - KHEY: { - id: 'KHEY', - city: 'Hanchey AHP / Ozark', - state: 'AL', - lat: 31.35, - lon: -85.66667, - }, - KHSV: { - id: 'KHSV', - city: 'Huntsville, Huntsville International / Jones Field', - state: 'AL', - lat: 34.64361, - lon: -86.78556, - }, - KHUA: { - id: 'KHUA', - city: 'Redstone Airfield', - state: 'AL', - lat: 34.6786, - lon: -86.6847, - }, - KJFX: { - id: 'KJFX', - city: 'Jasper Walker County Airport & Bevill Field', - state: 'AL', - lat: 33.902, - lon: -87.31417, - }, - KJKA: { - id: 'KJKA', - city: 'Jack Edwards Airport', - state: 'AL', - lat: 30.2896, - lon: -87.6718, - }, - KLOR: { - id: 'KLOR', - city: 'Fort Rucker, Lowe Army Heliport', - state: 'AL', - lat: 31.35889, - lon: -85.74833, - }, - KMDQ: { - id: 'KMDQ', - city: 'Huntsville, Madison County Executive Airport', - state: 'AL', - lat: 34.86139, - lon: -86.55722, - }, - KMGM: { - id: 'KMGM', - city: 'Montgomery, Dannelly Field', - state: 'AL', - lat: 32.30028, - lon: -86.40611, - }, - KMOB: { - id: 'KMOB', - city: 'Mobile, Mobile Regional Airport', - state: 'AL', - lat: 30.68833, - lon: -88.24556, - }, - KMSL: { - id: 'KMSL', - city: 'Muscle Shoals, North West Alabama Regional Airport', - state: 'AL', - lat: 34.74389, - lon: -87.59944, - }, - KMXF: { - id: 'KMXF', - city: 'Maxwell Air Force Base / Montgomery', - state: 'AL', - lat: 32.38333, - lon: -86.36667, - }, - KOZR: { - id: 'KOZR', - city: 'Cairns Army Air Field / Ozark', - state: 'AL', - lat: 31.27672, - lon: -85.71099, - }, - KPLR: { - id: 'KPLR', - city: 'St Clair County Airport', - state: 'AL', - lat: 33.5588, - lon: -86.2491, - }, - KPRN: { - id: 'KPRN', - city: 'Mac Crenshaw Memorial Airport', - state: 'AL', - lat: 31.8457, - lon: -86.6107, - }, - KSCD: { - id: 'KSCD', - city: 'Merkel Field Sylacauga Municipal Airport', - state: 'AL', - lat: 33.1718, - lon: -86.3055, - }, - KSEM: { - id: 'KSEM', - city: 'Craig Field / Selma', - state: 'AL', - lat: 32.35, - lon: -86.98333, - }, - KSXS: { - id: 'KSXS', - city: 'SCHELL AHP', - state: 'AL', - lat: 31.35, - lon: -85.85, - }, - KTCL: { - id: 'KTCL', - city: 'Tuscaloosa Regional Airport', - state: 'AL', - lat: 33.21215, - lon: -87.61554, - }, - KTOI: { - id: 'KTOI', - city: 'Troy, Troy Municipal Airport', - state: 'AL', - lat: 31.86056, - lon: -86.01222, - }, - KAFN: { - id: 'KAFN', - city: 'Jaffrey Airport-Silver Ranch', - state: 'NH', - lat: 42.8066699, - lon: -72.00127, - }, - KASH: { - id: 'KASH', - city: 'Nashua - Boire Field Airport', - state: 'NH', - lat: 42.77981, - lon: -71.51409, - }, - KBML: { - id: 'KBML', - city: 'Berlin, Berlin Municipal Airport', - state: 'NH', - lat: 44.57611, - lon: -71.17861, - }, - KCON: { - id: 'KCON', - city: 'Concord Municipal Airport', - state: 'NH', - lat: 43.20489, - lon: -71.50257, - }, - KDAW: { - id: 'KDAW', - city: 'Rochester - Skyhaven Airport', - state: 'NH', - lat: 43.27939, - lon: -70.92426, - }, - KEEN: { - id: 'KEEN', - city: 'Keene, Dillant-Hopkins Airport', - state: 'NH', - lat: 42.9, - lon: -72.26667, - }, - KHIE: { - id: 'KHIE', - city: 'Whitefield - Mount Washington Regional Airport', - state: 'NH', - lat: 44.36595, - lon: -71.55218, - }, - KLCI: { - id: 'KLCI', - city: 'Laconia, Laconia Municipal Airport', - state: 'NH', - lat: 43.56667, - lon: -71.41667, - }, - KLEB: { - id: 'KLEB', - city: 'Lebanon Municipal Airport', - state: 'NH', - lat: 43.6271, - lon: -72.30537, - }, - KMHT: { - id: 'KMHT', - city: 'Manchester Airport', - state: 'NH', - lat: 42.92964, - lon: -71.43559, - }, - KMWN: { - id: 'KMWN', - city: 'Mount Washington', - state: 'NH', - lat: 44.27086, - lon: -71.30337, - }, - KPSM: { - id: 'KPSM', - city: 'Pease Air Force Base / Portsmouth', - state: 'NH', - lat: 43.0833299, - lon: -70.81667, - }, - KAIZ: { - id: 'KAIZ', - city: 'Kaiser Lake Ozark, Lee C Fine Memorial Airport', - state: 'MO', - lat: 38.1, - lon: -92.55, - }, - KBBG: { - id: 'KBBG', - city: 'Branson', - state: 'MO', - lat: 36.5321, - lon: -93.2005, - }, - KCDJ: { - id: 'KCDJ', - city: 'Chillicothe, Chillicothe Agri-Science Center', - state: 'MO', - lat: 39.81667, - lon: -93.58333, - }, - KCGI: { - id: 'KCGI', - city: 'Cape Girardeau, Cape Girardeau Regional Airport', - state: 'MO', - lat: 37.22556, - lon: -89.5783299, - }, - KCOU: { - id: 'KCOU', - city: 'Columbia, Columbia Regional Airport', - state: 'MO', - lat: 38.81694, - lon: -92.21833, - }, - KDMO: { - id: 'KDMO', - city: 'Sedalia, Sedalia Memorial Airport', - state: 'MO', - lat: 38.71222, - lon: -93.17444, - }, - KEOS: { - id: 'KEOS', - city: 'NEOSHOAIRPORT', - state: 'MO', - lat: 36.8108, - lon: -94.39169, - }, - KEVU: { - id: 'KEVU', - city: 'Maryville Northwest Missouri Regional Airport', - state: 'MO', - lat: 40.3525, - lon: -94.915, - }, - KEZZ: { - id: 'KEZZ', - city: 'Cameron Memorial Airport', - state: 'MO', - lat: 39.7275599, - lon: -94.27639, - }, - KFAM: { - id: 'KFAM', - city: 'Farmington Airport', - state: 'MO', - lat: 37.76667, - lon: -90.43333, - }, - KFWB: { - id: 'KFWB', - city: 'Branson West Muni - Emerson Field', - state: 'MO', - lat: 36.6985, - lon: -93.4021999, - }, - KFYG: { - id: 'KFYG', - city: 'Washington Regional Airport', - state: 'MO', - lat: 38.5876, - lon: -90.9937999, - }, - KBGF: { - id: 'KBGF', - city: 'Winchester Municipal Airport', - state: 'TN', - lat: 35.1775, - lon: -86.0662, - }, - KBNA: { - id: 'KBNA', - city: 'Nashville, Nashville International Airport', - state: 'TN', - lat: 36.11889, - lon: -86.68917, - }, - KCHA: { - id: 'KCHA', - city: 'Chattanooga, Lovell Field', - state: 'TN', - lat: 35.03333, - lon: -85.2, - }, - KCKV: { - id: 'KCKV', - city: 'Clarksville Outlaw Field', - state: 'TN', - lat: 36.61689, - lon: -87.41174, - }, - KCSV: { - id: 'KCSV', - city: 'Crossville, Crossville Memorial-Whitson Field Airport', - state: 'TN', - lat: 35.95139, - lon: -85.0849999, - }, - KDKX: { - id: 'KDKX', - city: 'Knoxville Downtown Airport', - state: 'TN', - lat: 35.96581, - lon: -83.87169, - }, - KDYR: { - id: 'KDYR', - city: 'Dyersburg, Dyersburg Municipal Airport', - state: 'TN', - lat: 36, - lon: -89.4, - }, - KFYE: { - id: 'KFYE', - city: 'Somerville - Fayette County Airport', - state: 'TN', - lat: 35.2061, - lon: -89.3929, - }, - KFYM: { - id: 'KFYM', - city: 'Fayetteville Municipal Airport', - state: 'TN', - lat: 35.0597, - lon: -86.5639999, - }, - KGCY: { - id: 'KGCY', - city: 'Greeneville-Greene County Municipal Airport', - state: 'TN', - lat: 36.19601, - lon: -82.81099, - }, - KGKT: { - id: 'KGKT', - city: 'Sevierville Gatlinburg - Pigeon Forge Airport', - state: 'TN', - lat: 35.85681, - lon: -83.53334, - }, - KGZS: { - id: 'KGZS', - city: 'Pulaski Abernathy Field Airport', - state: 'TN', - lat: 35.1537, - lon: -87.0568, - }, - KHZD: { - id: 'KHZD', - city: 'Huntingdon Carroll County Airport', - state: 'TN', - lat: 36.08896, - lon: -88.46538, - }, - KJAU: { - id: 'KJAU', - city: 'Jacksboro Campbell County Airport', - state: 'TN', - lat: 36.3341, - lon: -84.163, - }, - KJWN: { - id: 'KJWN', - city: 'John C Tune Airport', - state: 'TN', - lat: 36.18521, - lon: -86.88331, - }, - KLUG: { - id: 'KLUG', - city: 'Ellington Airport', - state: 'TN', - lat: 35.50697, - lon: -86.80389, - }, - KMBT: { - id: 'KMBT', - city: 'Murfreesboro Municipal Airport', - state: 'TN', - lat: 35.87866, - lon: -86.37749, - }, - KMEG: { - id: 'KMEG', - city: 'Memphis WFO', - state: 'TN', - lat: 35.0563999, - lon: -89.9863, - }, - KMEM: { - id: 'KMEM', - city: 'Memphis International Airport', - state: 'TN', - lat: 35.05644, - lon: -89.98634, - }, - KMKL: { - id: 'KMKL', - city: 'Jackson, McKellar-Sipes Regional Airport', - state: 'TN', - lat: 35.59306, - lon: -88.91667, - }, - KMMI: { - id: 'KMMI', - city: 'Athens McMinn County Airport', - state: 'TN', - lat: 35.3973, - lon: -84.5626, - }, - KMNV: { - id: 'KMNV', - city: 'Monroe County Airport', - state: 'TN', - lat: 35.54522, - lon: -84.38039, - }, - KMOR: { - id: 'KMOR', - city: 'Morristown Moore-Murrell Airport', - state: 'TN', - lat: 36.1794, - lon: -83.3754, - }, - KMQY: { - id: 'KMQY', - city: 'Smyrna, Smyrna Airport', - state: 'TN', - lat: 36.00889, - lon: -86.52, - }, - KMRC: { - id: 'KMRC', - city: 'Columbia / Maury County', - state: 'TN', - lat: 35.55, - lon: -87.18333, - }, - KNQA: { - id: 'KNQA', - city: 'Millington, Millington Municipal Airport', - state: 'TN', - lat: 35.35667, - lon: -89.8702799, - }, - KOQT: { - id: 'KOQT', - city: 'Oak Ridge', - state: 'TN', - lat: 36.02278, - lon: -84.23333, - }, - KPHT: { - id: 'KPHT', - city: 'Paris - Henry County Airport', - state: 'TN', - lat: 36.34, - lon: -88.38, - }, - KPVE: { - id: 'KPVE', - city: 'Lexington-Parsons Beech River Regional Airport', - state: 'TN', - lat: 35.6564, - lon: -88.1954, - }, - KRKW: { - id: 'KRKW', - city: 'Rockwood Municipal Airport', - state: 'TN', - lat: 35.92501, - lon: -84.691, - }, - KRNC: { - id: 'KRNC', - city: 'McMinnville Warren County Memorial Airport', - state: 'TN', - lat: 35.6991, - lon: -85.8402, - }, - KSCX: { - id: 'KSCX', - city: 'Scott Municipal Airport', - state: 'TN', - lat: 36.45569, - lon: -84.58575, - }, - KSNH: { - id: 'KSNH', - city: 'SAVANNAH/HARDIN CO', - state: 'TN', - lat: 35.17, - lon: -88.22, - }, - KSRB: { - id: 'KSRB', - city: 'Sparta Upper Cumberland Regional Airport', - state: 'TN', - lat: 36.0559, - lon: -85.5307, - }, - KSYI: { - id: 'KSYI', - city: 'Shelbyville Bomar Field & Shelbyville Municipal Airport', - state: 'TN', - lat: 35.5593999, - lon: -86.4425, - }, - KTHA: { - id: 'KTHA', - city: 'Tullahoma Regional Airport/William Northern Field', - state: 'TN', - lat: 35.38, - lon: -86.2467, - }, - KTRI: { - id: 'KTRI', - city: 'Bristol / Johnson / Kingsport, Tri-City Regional Airport', - state: 'TN', - lat: 36.47972, - lon: -82.39889, - }, - KTYS: { - id: 'KTYS', - city: 'Knoxville, McGhee Tyson Airport', - state: 'TN', - lat: 35.81806, - lon: -83.98583, - }, - KUCY: { - id: 'KUCY', - city: 'Union City - Everett-Stewart Regional Airport', - state: 'TN', - lat: 36.38, - lon: -88.98, - }, - KXNX: { - id: 'KXNX', - city: 'Sumner County Regional Airport', - state: 'TN', - lat: 36.3750799, - lon: -86.40842, - }, - KBAC: { - id: 'KBAC', - city: 'Valley City', - state: 'ND', - lat: 46.9412, - lon: -98.018, - }, - KBIS: { - id: 'KBIS', - city: 'Bismarck, Bismarck Municipal Airport', - state: 'ND', - lat: 46.7825, - lon: -100.75722, - }, - KBWP: { - id: 'KBWP', - city: 'Wahpeton, Harry Stern Airport', - state: 'ND', - lat: 46.24389, - lon: -96.60722, - }, - KBWW: { - id: 'KBWW', - city: 'Bowman Regional Airport', - state: 'ND', - lat: 46.16551, - lon: -103.30074, - }, - KDIK: { - id: 'KDIK', - city: 'Dickinson, Dickinson Municipal Airport', - state: 'ND', - lat: 46.79722, - lon: -102.80194, - }, - KDVL: { - id: 'KDVL', - city: 'Devils Lake, Devils Lake Municipal Airport', - state: 'ND', - lat: 48.11667, - lon: -98.91667, - }, - KFAR: { - id: 'KFAR', - city: 'Fargo, Hector International Airport', - state: 'ND', - lat: 46.92528, - lon: -96.81111, - }, - KGAF: { - id: 'KGAF', - city: 'GRAFTON', - state: 'ND', - lat: 48.4, - lon: -97.37, - }, - KGFK: { - id: 'KGFK', - city: 'Grand Forks, Grand Forks International Airport', - state: 'ND', - lat: 47.94806, - lon: -97.1825, - }, - KGWR: { - id: 'KGWR', - city: 'Gwinner', - state: 'ND', - lat: 46.2187, - lon: -97.6435, - }, - KHEI: { - id: 'KHEI', - city: 'Hettinger, Hettinger Municipal Airport', - state: 'ND', - lat: 46.01056, - lon: -102.64972, - }, - KHZE: { - id: 'KHZE', - city: 'HAZEN', - state: 'ND', - lat: 47.28, - lon: -101.58, - }, - KJMS: { - id: 'KJMS', - city: 'Jamestown, Jamestown Municipal Airport', - state: 'ND', - lat: 46.92972, - lon: -98.67833, - }, - KMIB: { - id: 'KMIB', - city: 'Minot Air Force Base', - state: 'ND', - lat: 48.41667, - lon: -101.35, - }, - KMOT: { - id: 'KMOT', - city: 'Minot International Airport', - state: 'ND', - lat: 48.25203, - lon: -101.2689, - }, - KRDR: { - id: 'KRDR', - city: 'Grand Forks Air Force Base', - state: 'ND', - lat: 47.96667, - lon: -97.4, - }, - KRUG: { - id: 'KRUG', - city: 'RUGBY', - state: 'ND', - lat: 48.38, - lon: -100.02, - }, - KXWA: { - id: 'KXWA', - city: 'Williston Basin International Airport', - state: 'ND', - lat: 48.26086, - lon: -103.75114, - }, - KACK: { - id: 'KACK', - city: 'Nantucket, Nantucket Memorial Airport', - state: 'MA', - lat: 41.25389, - lon: -70.05972, - }, - KAQW: { - id: 'KAQW', - city: 'North Adams Harriman-and-West Airport', - state: 'MA', - lat: 42.69731, - lon: -73.16955, - }, - KBAF: { - id: 'KBAF', - city: 'Westfield, Barnes Municipal Airport', - state: 'MA', - lat: 42.15972, - lon: -72.71278, - }, - KBED: { - id: 'KBED', - city: 'Laurence G Hanscom Field Airport', - state: 'MA', - lat: 42.46811, - lon: -71.29463, - }, - KBOS: { - id: 'KBOS', - city: 'Boston, Logan International Airport', - state: 'MA', - lat: 42.36056, - lon: -71.01056, - }, - KBVY: { - id: 'KBVY', - city: 'Beverly, Beverly Municipal Airport', - state: 'MA', - lat: 42.58361, - lon: -70.91639, - }, - KCEF: { - id: 'KCEF', - city: 'Chicopee Falls / Westover Air Force Base', - state: 'MA', - lat: 42.2, - lon: -72.53333, - }, - KCQX: { - id: 'KCQX', - city: 'Chatham, Chatham Municipal Airport', - state: 'MA', - lat: 41.6875, - lon: -69.99333, - }, - KEWB: { - id: 'KEWB', - city: 'New Bedford, New Bedford Regional Airport', - state: 'MA', - lat: 41.67528, - lon: -70.95694, - }, - KFIT: { - id: 'KFIT', - city: 'Fitchburg, Fitchburg Municipal Airport', - state: 'MA', - lat: 42.55194, - lon: -71.75583, - }, - KFMH: { - id: 'KFMH', - city: 'Otis Air National Guard Base', - state: 'MA', - lat: 41.65, - lon: -70.51667, - }, - KGHG: { - id: 'KGHG', - city: 'Marshfield Airport', - state: 'MA', - lat: 42.0983, - lon: -70.6722, - }, - KHYA: { - id: 'KHYA', - city: 'Hyannis, Barnstable Municipal-Boardman Airport', - state: 'MA', - lat: 41.67194, - lon: -70.26972, - }, - KLWM: { - id: 'KLWM', - city: 'Lawrence Municipal Airport', - state: 'MA', - lat: 42.7126, - lon: -71.12553, - }, - KMVY: { - id: 'KMVY', - city: 'Marthas Vineyard Airport', - state: 'MA', - lat: 41.39298, - lon: -70.61588, - }, - KORE: { - id: 'KORE', - city: 'Orange Municipal Airport', - state: 'MA', - lat: 42.57, - lon: -72.28693, - }, - KORH: { - id: 'KORH', - city: 'Worcester, Worcester Regional Airport', - state: 'MA', - lat: 42.27056, - lon: -71.87306, - }, - KOWD: { - id: 'KOWD', - city: 'Norwood, Norwood Memorial Airport', - state: 'MA', - lat: 42.19083, - lon: -71.17389, - }, - KPSF: { - id: 'KPSF', - city: 'Pittsfield Municipal Airport', - state: 'MA', - lat: 42.42691, - lon: -73.28897, - }, - KPVC: { - id: 'KPVC', - city: 'Provincetown Municipal Airport', - state: 'MA', - lat: 42.07436, - lon: -70.21816, - }, - KPYM: { - id: 'KPYM', - city: 'Plymouth, Plymouth Municipal Airport', - state: 'MA', - lat: 41.90861, - lon: -70.72806, - }, - KTAN: { - id: 'KTAN', - city: 'Taunton, Taunton Municipal Airport', - state: 'MA', - lat: 41.87556, - lon: -71.0211099, - }, - KACY: { - id: 'KACY', - city: 'Atlantic City, Atlantic City International Airport', - state: 'NJ', - lat: 39.45202, - lon: -74.56699, - }, - KBLM: { - id: 'KBLM', - city: 'Belmar-Farmingdale', - state: 'NJ', - lat: 40.18333, - lon: -74.13333, - }, - KCDW: { - id: 'KCDW', - city: 'Caldwell, Essex County Airport', - state: 'NJ', - lat: 40.87639, - lon: -74.28306, - }, - KEWR: { - id: 'KEWR', - city: 'Newark, Newark International Airport', - state: 'NJ', - lat: 40.6825, - lon: -74.16944, - }, - KFWN: { - id: 'KFWN', - city: 'Sussex, Sussex Airport', - state: 'NJ', - lat: 41.19925, - lon: -74.62594, - }, - KLDJ: { - id: 'KLDJ', - city: 'Linden Airport', - state: 'NJ', - lat: 40.6174, - lon: -74.2446, - }, - KMIV: { - id: 'KMIV', - city: 'Millville, Millville Municipal Airport', - state: 'NJ', - lat: 39.36623, - lon: -75.0778, - }, - KMJX: { - id: 'KMJX', - city: 'Miller Air Park', - state: 'NJ', - lat: 39.927, - lon: -74.292, - }, - KMMU: { - id: 'KMMU', - city: 'Morristown Municipal', - state: 'NJ', - lat: 40.8, - lon: -74.41667, - }, - KNEL: { - id: 'KNEL', - city: 'Lakehurst Naval Air Station', - state: 'NJ', - lat: 40.03661, - lon: -74.35251, - }, - KSMQ: { - id: 'KSMQ', - city: 'Somerville, Somerset Airport', - state: 'NJ', - lat: 40.6240499, - lon: -74.66898, - }, - KTEB: { - id: 'KTEB', - city: 'Teterboro, Teterboro Airport', - state: 'NJ', - lat: 40.85889, - lon: -74.05667, - }, - KTTN: { - id: 'KTTN', - city: 'Trenton, Mercer County Airport', - state: 'NJ', - lat: 40.27639, - lon: -74.81639, - }, - KVAY: { - id: 'KVAY', - city: 'Mount Holly, South Jersey Regional Airport', - state: 'NJ', - lat: 39.94076, - lon: -74.84071, - }, - KWRI: { - id: 'KWRI', - city: 'Mcguire Air Force Base', - state: 'NJ', - lat: 40.01667, - lon: -74.6, - }, - KWWD: { - id: 'KWWD', - city: 'Wildwood, Cape May County Airport', - state: 'NJ', - lat: 39.01667, - lon: -74.91667, - }, - KADW: { - id: 'KADW', - city: 'Camp Springs / Andrews Air Force Base', - state: 'MD', - lat: 38.81667, - lon: -76.85, - }, - KANP: { - id: 'KANP', - city: 'LEEAIRPORT', - state: 'MD', - lat: 38.94287, - lon: -76.5683899, - }, - KAPG: { - id: 'KAPG', - city: 'Phillips Army Air Field / Aberdeen', - state: 'MD', - lat: 39.46667, - lon: -76.16667, - }, - KBWI: { - id: 'KBWI', - city: 'Baltimore, Baltimore-Washington International Airport', - state: 'MD', - lat: 39.17329, - lon: -76.68404, - }, - KCGE: { - id: 'KCGE', - city: 'Cambridge-Dorchester Airport', - state: 'MD', - lat: 38.5393, - lon: -76.0304, - }, - KCGS: { - id: 'KCGS', - city: 'College Park Airport', - state: 'MD', - lat: 38.9806, - lon: -76.9223, - }, - KDMW: { - id: 'KDMW', - city: 'Carroll County Regional Jack B Poage Field', - state: 'MD', - lat: 39.6083, - lon: -77.0077, - }, - KEDG: { - id: 'KEDG', - city: 'WEIDE', - state: 'MD', - lat: 39.39205, - lon: -76.29106, - }, - KESN: { - id: 'KESN', - city: 'Easton / Newman Field', - state: 'MD', - lat: 38.8, - lon: -76.06667, - }, - KFDK: { - id: 'KFDK', - city: 'Frederick Municipal Airport', - state: 'MD', - lat: 39.41775, - lon: -77.36982, - }, - KFME: { - id: 'KFME', - city: 'Fort Meade / Tipton', - state: 'MD', - lat: 39.0833299, - lon: -76.76667, - }, - KGAI: { - id: 'KGAI', - city: 'Gaithersburg - Montgomery County Airport', - state: 'MD', - lat: 39.16957, - lon: -77.16551, - }, - KHGR: { - id: 'KHGR', - city: 'Hagerstown, Washington County Regional Airport', - state: 'MD', - lat: 39.70583, - lon: -77.73, - }, - KMTN: { - id: 'KMTN', - city: 'Baltimore / Martin', - state: 'MD', - lat: 39.3333299, - lon: -76.41667, - }, - KNAK: { - id: 'KNAK', - city: 'Annapolis, United States Naval Academy', - state: 'MD', - lat: 38.99125, - lon: -76.48907, - }, - KNHK: { - id: 'KNHK', - city: 'Patuxent River, Naval Air Station', - state: 'MD', - lat: 38.27861, - lon: -76.41389, - }, - KNUI: { - id: 'KNUI', - city: 'St. Inigoes, Webster Field, Naval Electronic Systems Engineering Activity', - state: 'MD', - lat: 38.14889, - lon: -76.42, - }, - KOXB: { - id: 'KOXB', - city: 'Ocean City, Ocean City Municipal Airport', - state: 'MD', - lat: 38.31056, - lon: -75.12389, - }, - KRSP: { - id: 'KRSP', - city: 'Camp David', - state: 'MD', - lat: 39.645, - lon: -77.468, - }, - KSBY: { - id: 'KSBY', - city: 'Salisbury, Salisbury-Ocean City Wicomico County Regional Airport', - state: 'MD', - lat: 38.34056, - lon: -75.51028, - }, - KVKX: { - id: 'KVKX', - city: 'POTOMAC', - state: 'MD', - lat: 38.74761, - lon: -76.95719, - }, - KAIK: { - id: 'KAIK', - city: 'Aiken Municipal Airport', - state: 'SC', - lat: 33.649, - lon: -81.685, - }, - KAND: { - id: 'KAND', - city: 'Anderson, Anderson County Airport', - state: 'SC', - lat: 34.49778, - lon: -82.70972, - }, - KAQX: { - id: 'KAQX', - city: 'Allendale County Airport', - state: 'SC', - lat: 32.9951, - lon: -81.2703, - }, - KARW: { - id: 'KARW', - city: 'Beaufort County Airport', - state: 'SC', - lat: 32.412, - lon: -80.634, - }, - KBBP: { - id: 'KBBP', - city: 'Marlboro County Jetport', - state: 'SC', - lat: 34.622, - lon: -79.734, - }, - KBNL: { - id: 'KBNL', - city: 'Barnwell Regional Airport', - state: 'SC', - lat: 33.258, - lon: -81.388, - }, - KCAE: { - id: 'KCAE', - city: 'Columbia, Columbia Metropolitan Airport', - state: 'SC', - lat: 33.94194, - lon: -81.11806, - }, - KCDN: { - id: 'KCDN', - city: 'Camden Woodward Field', - state: 'SC', - lat: 34.284, - lon: -80.565, - }, - KCEU: { - id: 'KCEU', - city: 'Clemson, Clemson-Oconee County Airport', - state: 'SC', - lat: 34.67222, - lon: -82.88139, - }, - KCHS: { - id: 'KCHS', - city: 'Charleston, Charleston Air Force Base', - state: 'SC', - lat: 32.89889, - lon: -80.04056, - }, - KCKI: { - id: 'KCKI', - city: 'Kingstree Williamsburg Regional Airport', - state: 'SC', - lat: 33.717, - lon: -79.857, - }, - KCQW: { - id: 'KCQW', - city: 'Cheraw Municipal Lynch Bellinger Field', - state: 'SC', - lat: 34.713, - lon: -79.9569999, - }, - KCRE: { - id: 'KCRE', - city: 'North Myrtle Beach Grand Strand Airport', - state: 'SC', - lat: 33.81619, - lon: -78.7204299, - }, - KCUB: { - id: 'KCUB', - city: 'Columbia - Jim Hamilton L.B. Owens Airport', - state: 'SC', - lat: 33.97083, - lon: -80.99444, - }, - KDCM: { - id: 'KDCM', - city: 'Chester Catawba Regional Airport', - state: 'SC', - lat: 34.789, - lon: -81.196, - }, - KDYB: { - id: 'KDYB', - city: 'Summerville Airport', - state: 'SC', - lat: 33.063, - lon: -80.279, - }, - KEOE: { - id: 'KEOE', - city: 'Newberry County Airport', - state: 'SC', - lat: 34.309, - lon: -81.64, - }, - KFDW: { - id: 'KFDW', - city: 'Winnsboro/Fairfield County Airport', - state: 'SC', - lat: 34.315, - lon: -81.109, - }, - KFLO: { - id: 'KFLO', - city: 'Florence - Florence Regional Airport', - state: 'SC', - lat: 34.1877799, - lon: -79.73083, - }, - KGGE: { - id: 'KGGE', - city: 'Georgetown County Airport ', - state: 'SC', - lat: 33.3117, - lon: -79.3196, - }, - KGMU: { - id: 'KGMU', - city: 'Greenville Downtown Airport', - state: 'SC', - lat: 34.84873, - lon: -82.35004, - }, - KGRD: { - id: 'KGRD', - city: 'Greenwood, Greenwood County Airport', - state: 'SC', - lat: 34.24722, - lon: -82.15472, - }, - KGSP: { - id: 'KGSP', - city: 'Greer, Greenville-Spartanburg Airport', - state: 'SC', - lat: 34.88389, - lon: -82.22083, - }, - KGYH: { - id: 'KGYH', - city: 'Greenville-Donaldson Center Airport', - state: 'SC', - lat: 34.7583, - lon: -82.3764, - }, - KHVS: { - id: 'KHVS', - city: 'Hartsville Regional Airport', - state: 'SC', - lat: 34.403, - lon: -80.119, - }, - KHXD: { - id: 'KHXD', - city: 'Hilton Head Island, Hilton Head Airport', - state: 'SC', - lat: 32.21667, - lon: -80.7, - }, - KHYW: { - id: 'KHYW', - city: 'Conway Horry County Airport', - state: 'SC', - lat: 33.829, - lon: -79.122, - }, - KJZI: { - id: 'KJZI', - city: 'Charleston Executive Airport', - state: 'SC', - lat: 32.701, - lon: -80.003, - }, - KLKR: { - id: 'KLKR', - city: 'Lancaster County-mc Whirter Field', - state: 'SC', - lat: 34.723, - lon: -80.855, - }, - KLQK: { - id: 'KLQK', - city: 'Pickens County Airport', - state: 'SC', - lat: 34.80997, - lon: -82.70289, - }, - KLRO: { - id: 'KLRO', - city: 'Mount Pleasant Regional-Faison Field', - state: 'SC', - lat: 32.898, - lon: -79.783, - }, - KLUX: { - id: 'KLUX', - city: 'Laurens County Airport', - state: 'SC', - lat: 34.507, - lon: -81.947, - }, - KMAO: { - id: 'KMAO', - city: 'Marion County Airport', - state: 'SC', - lat: 34.181, - lon: -79.3349999, - }, - KMKS: { - id: 'KMKS', - city: 'Moncks Corner Berkeley County', - state: 'SC', - lat: 33.1855, - lon: -80.0361999, - }, - KMMT: { - id: 'KMMT', - city: 'McEntire Air National Guard Weather Facility Base', - state: 'SC', - lat: 33.91667, - lon: -80.8, - }, - KMNI: { - id: 'KMNI', - city: 'Manning / Cooper Regional', - state: 'SC', - lat: 33.5833299, - lon: -80.2166699, - }, - KMYR: { - id: 'KMYR', - city: 'Myrtle Beach International Airport', - state: 'SC', - lat: 33.67975, - lon: -78.92833, - }, - KNBC: { - id: 'KNBC', - city: 'Beaufort, Marine Corps Air Station', - state: 'SC', - lat: 32.4936099, - lon: -80.7030599, - }, - KOGB: { - id: 'KOGB', - city: 'Orangeburg, Orangeburg Municipal Airport', - state: 'SC', - lat: 33.46389, - lon: -80.85361, - }, - KRBW: { - id: 'KRBW', - city: 'Walterboro Lowcountry Regional Airport', - state: 'SC', - lat: 32.921, - lon: -80.641, - }, - KSMS: { - id: 'KSMS', - city: 'Sumter Airport', - state: 'SC', - lat: 33.995, - lon: -80.361, - }, - KSPA: { - id: 'KSPA', - city: 'Spartanburg Memorial', - state: 'SC', - lat: 34.91667, - lon: -81.95, - }, - KSSC: { - id: 'KSSC', - city: 'Shaw Air Force Base', - state: 'SC', - lat: 33.96667, - lon: -80.48333, - }, - KUDG: { - id: 'KUDG', - city: 'Darlington, Darlington County Jetport Airport', - state: 'SC', - lat: 34.44917, - lon: -79.89028, - }, - KUZA: { - id: 'KUZA', - city: 'Rock Hill, Rock Hill - York County Airport', - state: 'SC', - lat: 34.98389, - lon: -81.05583, - }, - KXNO: { - id: 'KXNO', - city: 'North Air Force Auxiliary Field', - state: 'SC', - lat: 33.60949, - lon: -81.08118, - }, - KAUG: { - id: 'KAUG', - city: 'Augusta, Augusta State Airport', - state: 'ME', - lat: 44.32056, - lon: -69.79722, - }, - KBGR: { - id: 'KBGR', - city: 'Bangor, Bangor International Airport', - state: 'ME', - lat: 44.79722, - lon: -68.81861, - }, - KBHB: { - id: 'KBHB', - city: 'Bar Harbor, Hancock County-Bar Harbor Airport', - state: 'ME', - lat: 44.45, - lon: -68.36667, - }, - KBXM: { - id: 'KBXM', - city: 'BRUNSWICK', - state: 'ME', - lat: 43.8923599, - lon: -69.93883, - }, - KCAR: { - id: 'KCAR', - city: 'Caribou, Caribou Municipal Airport', - state: 'ME', - lat: 46.86722, - lon: -68.01333, - }, - KFVE: { - id: 'KFVE', - city: 'Frenchville, Northern Aroostook Regional Airport', - state: 'ME', - lat: 47.2849999, - lon: -68.30722, - }, - KGNR: { - id: 'KGNR', - city: 'Greenville', - state: 'ME', - lat: 45.4646199, - lon: -69.5538, - }, - KHUL: { - id: 'KHUL', - city: 'Houlton, Houlton International Airport', - state: 'ME', - lat: 46.12306, - lon: -67.79194, - }, - KIWI: { - id: 'KIWI', - city: 'Wiscasset Airport', - state: 'ME', - lat: 43.96401, - lon: -69.7107599, - }, - KIZG: { - id: 'KIZG', - city: 'Fryeburg, Eastern Slopes Regional Airport', - state: 'ME', - lat: 43.98917, - lon: -70.95028, - }, - KLEW: { - id: 'KLEW', - city: 'Auburn-Lewiston', - state: 'ME', - lat: 44.05, - lon: -70.28333, - }, - KMLT: { - id: 'KMLT', - city: 'Millinocket, Millinocket Municipal Airport', - state: 'ME', - lat: 45.64778, - lon: -68.69194, - }, - KPQI: { - id: 'KPQI', - city: 'Presque Isle', - state: 'ME', - lat: 46.68333, - lon: -68.05, - }, - KPWM: { - id: 'KPWM', - city: 'Portland, Portland International Jetport', - state: 'ME', - lat: 43.64222, - lon: -70.30444, - }, - KRKD: { - id: 'KRKD', - city: 'Rockland, Knox County Regional Airport', - state: 'ME', - lat: 44.06667, - lon: -69.1, - }, - KSFM: { - id: 'KSFM', - city: 'Sanford, Sanford Regional Airport', - state: 'ME', - lat: 43.4, - lon: -70.7166699, - }, - KWVL: { - id: 'KWVL', - city: 'Waterville, Waterville Robert LaFleur Airport', - state: 'ME', - lat: 44.53333, - lon: -69.68333, - }, - KBIX: { - id: 'KBIX', - city: 'Keesler Air Force Base / Biloxi', - state: 'MS', - lat: 30.41667, - lon: -88.91667, - }, - KCBM: { - id: 'KCBM', - city: 'Columbus Air Force Base', - state: 'MS', - lat: 33.65, - lon: -88.45, - }, - KCKM: { - id: 'KCKM', - city: 'Fletcher Field, Clarksdale', - state: 'MS', - lat: 34.2997, - lon: -90.5123, - }, - KCRX: { - id: 'KCRX', - city: 'Corinth', - state: 'MS', - lat: 34.915, - lon: -88.6035, - }, - KDLP: { - id: 'KDLP', - city: 'WEST DELTA OIL PLATFORM', - state: 'MS', - lat: 29.12, - lon: -89.55, - }, - KGLH: { - id: 'KGLH', - city: 'Greenville, Mid Delta Regional Airport', - state: 'MS', - lat: 33.48278, - lon: -90.98556, - }, - KGPT: { - id: 'KGPT', - city: 'Gulfport - Gulfport-Biloxi International Airport', - state: 'MS', - lat: 30.41194, - lon: -89.08083, - }, - KGTR: { - id: 'KGTR', - city: 'Columbus/West Point/Starkville, Golden Triangle Regional Airport', - state: 'MS', - lat: 33.45, - lon: -88.58333, - }, - KGWO: { - id: 'KGWO', - city: 'Greenwood, Greenwood-LeFlore Airport', - state: 'MS', - lat: 33.4925, - lon: -90.0836099, - }, - KHBG: { - id: 'KHBG', - city: 'Hattiesburg, Bobby L Chain Municipal Airport', - state: 'MS', - lat: 31.26945, - lon: -89.25613, - }, - KHEZ: { - id: 'KHEZ', - city: 'Natchez, Hardy-Anders Field Natchez-Adams County Airport', - state: 'MS', - lat: 31.61593, - lon: -91.29724, - }, - KHKS: { - id: 'KHKS', - city: 'Jackson, Hawkins Field Airport', - state: 'MS', - lat: 32.33472, - lon: -90.2225, - }, - KHSA: { - id: 'KHSA', - city: 'Bay St. Louis, Stennis International Airport', - state: 'MS', - lat: 30.36778, - lon: -89.45472, - }, - KJAN: { - id: 'KJAN', - city: 'Jackson, Jackson International Airport', - state: 'MS', - lat: 32.3197199, - lon: -90.0775, - }, - KJVW: { - id: 'KJVW', - city: 'JB Williams Airport', - state: 'MS', - lat: 32.30447, - lon: -90.41053, - }, - KLUL: { - id: 'KLUL', - city: 'LAUREL/NOBLE FIELD', - state: 'MS', - lat: 31.67, - lon: -89.17, - }, - KMBO: { - id: 'KMBO', - city: 'Madison Bruce Campbell Field Airport', - state: 'MS', - lat: 32.4384, - lon: -90.1014, - }, - KMCB: { - id: 'KMCB', - city: 'McComb, McComb / Pike County / John E Lewis Field Airport', - state: 'MS', - lat: 31.17833, - lon: -90.47194, - }, - KMEI: { - id: 'KMEI', - city: 'Meridian, Key Field', - state: 'MS', - lat: 32.33806, - lon: -88.74778, - }, - KMJD: { - id: 'KMJD', - city: 'Picayune Municipal Airport', - state: 'MS', - lat: 30.48747, - lon: -89.65119, - }, - KNMM: { - id: 'KNMM', - city: 'Meridian, Meridian Naval Air Station - McCain Field', - state: 'MS', - lat: 32.55194, - lon: -88.55528, - }, - KOLV: { - id: 'KOLV', - city: 'Olive Branch, Olive Branch Airport', - state: 'MS', - lat: 34.97889, - lon: -89.78694, - }, - KPIB: { - id: 'KPIB', - city: 'Hattiesburg/Laurel, Hattiesburg-Laurel Regional Airport', - state: 'MS', - lat: 31.46667, - lon: -89.33333, - }, - KPMU: { - id: 'KPMU', - city: 'Batesville Panola County', - state: 'MS', - lat: 34.3635, - lon: -89.8929, - }, - KPQL: { - id: 'KPQL', - city: 'Moss Point - Trent Lott International Airport', - state: 'MS', - lat: 30.46305, - lon: -88.53155, - }, - KSTF: { - id: 'KSTF', - city: 'George M Bryan Airport, Starkville', - state: 'MS', - lat: 33.4331, - lon: -88.8486, - }, - KTUP: { - id: 'KTUP', - city: 'Tupelo, Tupelo Regional Airport', - state: 'MS', - lat: 34.26806, - lon: -88.77, - }, - KUOX: { - id: 'KUOX', - city: 'Oxford, University-Oxford Airport', - state: 'MS', - lat: 34.38444, - lon: -89.53556, - }, - KUTA: { - id: 'KUTA', - city: 'Tunica, Tunica Municipal Airport', - state: 'MS', - lat: 34.68083, - lon: -90.34639, - }, - KVKS: { - id: 'KVKS', - city: 'Vicksburg Municipal', - state: 'MS', - lat: 32.23333, - lon: -90.93333, - }, - KBAM: { - id: 'KBAM', - city: 'Battle Mountain - Lander County Airport', - state: 'NV', - lat: 40.5989999, - lon: -116.8743, - }, - KBVU: { - id: 'KBVU', - city: 'Boulder City Municipal Airport', - state: 'NV', - lat: 35.9475, - lon: -114.8611, - }, - KCXP: { - id: 'KCXP', - city: 'Carson City Airport', - state: 'NV', - lat: 39.19056, - lon: -119.73191, - }, - KDRA: { - id: 'KDRA', - city: 'Mercury, Desert Rock Airport', - state: 'NV', - lat: 36.6207, - lon: -116.02868, - }, - KEKO: { - id: 'KEKO', - city: 'Elko, Elko Regional Airport', - state: 'NV', - lat: 40.8240399, - lon: -115.78635, - }, - KELY: { - id: 'KELY', - city: 'Ely, Ely Airport', - state: 'NV', - lat: 39.295, - lon: -114.84528, - }, - KHND: { - id: 'KHND', - city: 'Las Vegas - Henderson Executive Airport', - state: 'NV', - lat: 35.97665, - lon: -115.13221, - }, - KHTH: { - id: 'KHTH', - city: 'Hawthorne Industrial Airport', - state: 'NV', - lat: 38.54482, - lon: -118.63137, - }, - KINS: { - id: 'KINS', - city: 'Nellis AFB - Indian Springs Auxiliary Airfield', - state: 'NV', - lat: 36.58573, - lon: -115.69008, - }, - KLAS: { - id: 'KLAS', - city: 'Las Vegas, McCarran International Airport', - state: 'NV', - lat: 36.07188, - lon: -115.1634, - }, - KLOL: { - id: 'KLOL', - city: 'Lovelock, Derby Field Airport', - state: 'NV', - lat: 40.0683999, - lon: -118.57017, - }, - KLSV: { - id: 'KLSV', - city: 'Nellis Air Force Base', - state: 'NV', - lat: 36.23333, - lon: -115.03333, - }, - KMEV: { - id: 'KMEV', - city: 'Minden-Tahoe Airport', - state: 'NV', - lat: 38.9963, - lon: -119.75, - }, - KNFL: { - id: 'KNFL', - city: 'Fallon, Naval Air Station', - state: 'NV', - lat: 39.43222, - lon: -118.68556, - }, - KRNO: { - id: 'KRNO', - city: 'Reno, Reno Tahoe International Airport', - state: 'NV', - lat: 39.50776, - lon: -119.76819, - }, - KRTS: { - id: 'KRTS', - city: 'Reno/Stead', - state: 'NV', - lat: 39.6682, - lon: -119.8764, - }, - KTMT: { - id: 'KTMT', - city: 'Austin Airport', - state: 'NV', - lat: 39.46794, - lon: -117.19745, - }, - KTPH: { - id: 'KTPH', - city: 'Tonopah, Tonopah Airport', - state: 'NV', - lat: 38.06028, - lon: -117.08722, - }, - KVGT: { - id: 'KVGT', - city: 'Las Vegas, North Las Vegas Airport', - state: 'NV', - lat: 36.21205, - lon: -115.19395, - }, - KWMC: { - id: 'KWMC', - city: 'Winnemucca, Winnemucca Municipal Airport', - state: 'NV', - lat: 40.90194, - lon: -117.80722, - }, - KAFO: { - id: 'KAFO', - city: 'Afton WY', - state: 'WY', - lat: 42.7113299, - lon: -110.94217, - }, - KARL: { - id: 'KARL', - city: 'I80 - Arlington', - state: 'WY', - lat: 41.5980599, - lon: -106.21487, - }, - KBFU: { - id: 'KBFU', - city: 'WY59 - Belle Fourche', - state: 'WY', - lat: 43.93253, - lon: -105.4467, - }, - KBIT: { - id: 'KBIT', - city: 'I80/US30 - Bitter Creek', - state: 'WY', - lat: 41.64599, - lon: -108.5836, - }, - KBPI: { - id: 'KBPI', - city: 'Big Piney - Marbleton Airport', - state: 'WY', - lat: 42.57805, - lon: -110.10972, - }, - KBRX: { - id: 'KBRX', - city: 'I25/US87 - Bordeaux Interchange', - state: 'WY', - lat: 41.93066, - lon: -104.9436, - }, - KBVR: { - id: 'KBVR', - city: 'US287/WY789 - Beaver Rim', - state: 'WY', - lat: 42.58565, - lon: -108.28199, - }, - KBYG: { - id: 'KBYG', - city: 'Buffalo - Johnson County Airport', - state: 'WY', - lat: 44.38122, - lon: -106.71947, - }, - KCHJ: { - id: 'KCHJ', - city: 'WY296 - Chief Joseph', - state: 'WY', - lat: 44.73997, - lon: -109.38088, - }, - KCMS: { - id: 'KCMS', - city: 'I80/US30 - Peru Hill', - state: 'WY', - lat: 41.54958, - lon: -109.60197, - }, - KCOD: { - id: 'KCOD', - city: 'Cody', - state: 'WY', - lat: 44.51667, - lon: -109.01667, - }, - KCPR: { - id: 'KCPR', - city: 'Casper, Natrona County International Airport', - state: 'WY', - lat: 42.8975, - lon: -106.47306, - }, - KCTD: { - id: 'KCTD', - city: 'I80/US30 - Continental Divide', - state: 'WY', - lat: 41.71586, - lon: -107.78256, - }, - KCYS: { - id: 'KCYS', - city: 'Cheyenne, Cheyenne Airport', - state: 'WY', - lat: 41.15789, - lon: -104.80812, - }, - KDGW: { - id: 'KDGW', - city: 'Douglas, Converse County Airport', - state: 'WY', - lat: 42.79417, - lon: -105.38194, - }, - KDHS: { - id: 'KDHS', - city: 'I90 - Dead Horse', - state: 'WY', - lat: 44.21906, - lon: -106.10478, - }, - KDRC: { - id: 'KDRC', - city: 'I25 - Deer Creek', - state: 'WY', - lat: 42.83687, - lon: -105.86063, - }, - KDUB: { - id: 'KDUB', - city: 'Dubois Municipal Airport', - state: 'WY', - lat: 43.5484, - lon: -109.6903, - }, - KDWX: { - id: 'KDWX', - city: 'Dixon Airport', - state: 'WY', - lat: 41.03704, - lon: -107.49976, - }, - KEAN: { - id: 'KEAN', - city: 'Phifer Airfield - Wheatland', - state: 'WY', - lat: 42.05472, - lon: -104.93711, - }, - KECS: { - id: 'KECS', - city: 'Mondell Field', - state: 'WY', - lat: 43.8854, - lon: -104.3179, - }, - KEHY: { - id: 'KEHY', - city: 'Elk Mountain AWOS', - state: 'WY', - lat: 41.7253, - lon: -106.4594, - }, - KEMM: { - id: 'KEMM', - city: 'KEMMERER', - state: 'WY', - lat: 41.82, - lon: -110.56, - }, - KEVW: { - id: 'KEVW', - city: 'Evanston, Evanston-Uinta County Burns Field', - state: 'WY', - lat: 41.27306, - lon: -111.03056, - }, - KFBR: { - id: 'KFBR', - city: 'Fort Bridger WY', - state: 'WY', - lat: 41.392, - lon: -110.40683, - }, - KFEW: { - id: 'KFEW', - city: 'Francis E Warren Air Force Base Heliport', - state: 'WY', - lat: 41.13332, - lon: -104.8671899, - }, - KFIR: { - id: 'KFIR', - city: 'I80/US189 - First Divide', - state: 'WY', - lat: 41.27649, - lon: -110.80066, - }, - KGCC: { - id: 'KGCC', - city: 'Gillette, Gillette-Campbell County Airport', - state: 'WY', - lat: 44.33944, - lon: -105.54194, - }, - KGEY: { - id: 'KGEY', - city: 'South Big Horn County Airport', - state: 'WY', - lat: 44.5174, - lon: -108.0752, - }, - KGUN: { - id: 'KGUN', - city: 'US85 - Gun Barrel', - state: 'WY', - lat: 41.44368, - lon: -104.34428, - }, - KGUR: { - id: 'KGUR', - city: 'Camp Guernsey', - state: 'WY', - lat: 42.2597, - lon: -104.7283, - }, - KHLD: { - id: 'KHLD', - city: 'US20/US26 - Hiland', - state: 'WY', - lat: 43.0923, - lon: -107.32198, - }, - KHSG: { - id: 'KHSG', - city: 'Hot Springs County Airport', - state: 'WY', - lat: 43.7136, - lon: -108.3897, - }, - KIDV: { - id: 'KIDV', - city: 'I25/US87 - I-25 Divide', - state: 'WY', - lat: 43.89864, - lon: -106.63833, - }, - KIKA: { - id: 'KIKA', - city: 'I90 - Inyan Kara', - state: 'WY', - lat: 44.29414, - lon: -104.62926, - }, - KJAC: { - id: 'KJAC', - city: 'Jackson, Jackson Hole Airport', - state: 'WY', - lat: 43.6, - lon: -110.73333, - }, - KLAR: { - id: 'KLAR', - city: 'Laramie Regional Airport', - state: 'WY', - lat: 41.3165, - lon: -105.67287, - }, - KLND: { - id: 'KLND', - city: 'Lander', - state: 'WY', - lat: 42.81472, - lon: -108.72806, - }, - KMTR: { - id: 'KMTR', - city: 'WY120 - Meeteetse Rim', - state: 'WY', - lat: 44.27011, - lon: -108.87343, - }, - KPAT: { - id: 'KPAT', - city: 'WY220 - Pathfinder', - state: 'WY', - lat: 42.5581, - lon: -106.8453399, - }, - KPER: { - id: 'KPER', - city: 'I80/US30 - Green River Tunnel East', - state: 'WY', - lat: 41.53186, - lon: -109.45995, - }, - KPNA: { - id: 'KPNA', - city: 'Pinedale, Ralph Wenz Field Airport', - state: 'WY', - lat: 42.79528, - lon: -109.80694, - }, - KPOY: { - id: 'KPOY', - city: 'Powell Municipal Airport', - state: 'WY', - lat: 44.8671999, - lon: -108.7934, - }, - KPUM: { - id: 'KPUM', - city: 'US287 - Pumpkin Vine', - state: 'WY', - lat: 41.05218, - lon: -105.46906, - }, - KREC: { - id: 'KREC', - city: 'WY28 - Lower Red Canyon', - state: 'WY', - lat: 42.61795, - lon: -108.61093, - }, - KRIW: { - id: 'KRIW', - city: 'Riverton Regional Airport', - state: 'WY', - lat: 43.06219, - lon: -108.44701, - }, - KRKS: { - id: 'KRKS', - city: 'Rock Springs, Rock Springs-Sweetwater County Airport', - state: 'WY', - lat: 41.59417, - lon: -109.06528, - }, - KRWL: { - id: 'KRWL', - city: 'Rawlins Municipal Airport', - state: 'WY', - lat: 41.80648, - lon: -107.19516, - }, - KSAA: { - id: 'KSAA', - city: 'Saratoga WY', - state: 'WY', - lat: 41.44483, - lon: -106.8235, - }, - KSGE: { - id: 'KSGE', - city: 'US30 - Sage Junction', - state: 'WY', - lat: 41.82447, - lon: -110.90764, - }, - KSHC: { - id: 'KSHC', - city: 'WY372 - Shute Creek', - state: 'WY', - lat: 41.94409, - lon: -110.00399, - }, - KSHR: { - id: 'KSHR', - city: 'Sheridan County Airport', - state: 'WY', - lat: 44.7603099, - lon: -106.97411, - }, - KSKL: { - id: 'KSKL', - city: 'WY230 - Skyline', - state: 'WY', - lat: 41.13753, - lon: -106.57687, - }, - KSOU: { - id: 'KSOU', - city: 'WY28 - South Pass', - state: 'WY', - lat: 42.47752, - lon: -108.8444, - }, - KTBX: { - id: 'KTBX', - city: 'Boysen', - state: 'WY', - lat: 43.4667, - lon: -108.2333, - }, - KTET: { - id: 'KTET', - city: 'WY22 - Teton Pass', - state: 'WY', - lat: 43.49873, - lon: -110.9562, - }, - KTMH: { - id: 'KTMH', - city: 'I25/US87 - Twenty Mile Hill', - state: 'WY', - lat: 43.12271, - lon: -106.33705, - }, - KTOR: { - id: 'KTOR', - city: 'Torrington Municipal Airport', - state: 'WY', - lat: 42.06134, - lon: -104.15842, - }, - KVDW: { - id: 'KVDW', - city: 'I80/US30 - Vedauwoo', - state: 'WY', - lat: 41.15687, - lon: -105.40237, - }, - KWRL: { - id: 'KWRL', - city: 'Worland, Worland Municipal Airport', - state: 'WY', - lat: 43.9658299, - lon: -107.95083, - }, - KWTR: { - id: 'KWTR', - city: 'I25/US87 - Whitaker', - state: 'WY', - lat: 41.41772, - lon: -104.87502, - }, - KWYH: { - id: 'KWYH', - city: 'I25/US87 - Wyo Hill', - state: 'WY', - lat: 41.04746, - lon: -104.8901, - }, - KAAS: { - id: 'KAAS', - city: 'Taylor County Airport', - state: 'KY', - lat: 37.35828, - lon: -85.30942, - }, - KBRY: { - id: 'KBRY', - city: 'Samuels Field Airport', - state: 'KY', - lat: 37.81433, - lon: -85.49964, - }, - KBWG: { - id: 'KBWG', - city: 'Bowling Green, Bowling Green-Warren County Regional Airport', - state: 'KY', - lat: 36.96444, - lon: -86.41944, - }, - KBYL: { - id: 'KBYL', - city: 'Williamsburg-Whitley County Airport', - state: 'KY', - lat: 36.7954099, - lon: -84.2012699, - }, - KCEY: { - id: 'KCEY', - city: 'Murray Kyle Oakley Field, KY', - state: 'KY', - lat: 36.6646, - lon: -88.3728, - }, - KCPF: { - id: 'KCPF', - city: 'Wendell H Ford Airport', - state: 'KY', - lat: 37.38736, - lon: -83.26161, - }, - KCVG: { - id: 'KCVG', - city: 'Cincinnati/Northern Kentucky International Airport', - state: 'KY', - lat: 39.04456, - lon: -84.67229, - }, - KDVK: { - id: 'KDVK', - city: 'Stuart Powell Field Airport', - state: 'KY', - lat: 37.5775751, - lon: -84.7694978, - }, - KDWU: { - id: 'KDWU', - city: 'Ashland Regional Airport', - state: 'KY', - lat: 38.5545, - lon: -82.738, - }, - KEHR: { - id: 'KEHR', - city: 'Henderson City', - state: 'KY', - lat: 37.81667, - lon: -87.68333, - }, - KEKQ: { - id: 'KEKQ', - city: 'Monticello, Wayne County Airport', - state: 'KY', - lat: 36.85528, - lon: -84.85611, - }, - KEKX: { - id: 'KEKX', - city: 'Elizabethtown Addington Field Airport', - state: 'KY', - lat: 37.686, - lon: -85.925, - }, - KFFT: { - id: 'KFFT', - city: 'Frankfort, Capital City Airport', - state: 'KY', - lat: 38.18472, - lon: -84.90333, - }, - KFGX: { - id: 'KFGX', - city: 'Flemingsburg Fleming-Mason Airport', - state: 'KY', - lat: 38.5418, - lon: -83.7434, - }, - KFTK: { - id: 'KFTK', - city: 'Fort Knox', - state: 'KY', - lat: 37.9, - lon: -85.9666699, - }, - KGLW: { - id: 'KGLW', - city: 'Glasgow, Glasgow Municipal Airport', - state: 'KY', - lat: 37.03167, - lon: -85.95361, - }, - KHOP: { - id: 'KHOP', - city: 'Fort Campbell U. S. Army Airfield', - state: 'KY', - lat: 36.66667, - lon: -87.5, - }, - KIOB: { - id: 'KIOB', - city: 'Mount Sterling-Montgomery County Airport', - state: 'KY', - lat: 38.0575, - lon: -83.9829, - }, - KJKL: { - id: 'KJKL', - city: 'Jackson, Carroll Airport', - state: 'KY', - lat: 37.5913899, - lon: -83.31444, - }, - KLEX: { - id: 'KLEX', - city: 'Lexington Blue Grass Airport', - state: 'KY', - lat: 38.0339, - lon: -84.6114599, - }, - KLOU: { - id: 'KLOU', - city: 'Louisville, Bowman Field Airport', - state: 'KY', - lat: 38.22778, - lon: -85.66361, - }, - KLOZ: { - id: 'KLOZ', - city: 'London, London-Corbin Airport-Magee Field', - state: 'KY', - lat: 37.08944, - lon: -84.06861, - }, - KOWB: { - id: 'KOWB', - city: 'Owensboro, Owensboro-Daviess County Airport', - state: 'KY', - lat: 37.74, - lon: -87.16667, - }, - KPAH: { - id: 'KPAH', - city: 'Paducah, Barkley Regional Airport', - state: 'KY', - lat: 37.05639, - lon: -88.77389, - }, - KPBX: { - id: 'KPBX', - city: 'Pikeville Pike County Airport and Hatcher Field', - state: 'KY', - lat: 37.5587, - lon: -82.5674, - }, - KRGA: { - id: 'KRGA', - city: 'Central Kentucky Regional Airport', - state: 'KY', - lat: 37.6308475, - lon: -84.3323372, - }, - KSDF: { - id: 'KSDF', - city: 'Louisville Muhammad Ali International Airport', - state: 'KY', - lat: 38.17406, - lon: -85.7365, - }, - KSJS: { - id: 'KSJS', - city: 'Big Sandy Regional Airport', - state: 'KY', - lat: 37.751, - lon: -82.6367, - }, - KSME: { - id: 'KSME', - city: 'Somerset, Somerset-Pulaski County - J.T. Wilson Field Airport', - state: 'KY', - lat: 37.05417, - lon: -84.615, - }, - KSYM: { - id: 'KSYM', - city: 'Clyde A. Thomas Regional Airport', - state: 'KY', - lat: 38.215, - lon: -83.5874, - }, - KTWT: { - id: 'KTWT', - city: 'Sturgis, Sturgis Municipal Airport', - state: 'KY', - lat: 37.54083, - lon: -87.9516699, - }, - KADF: { - id: 'KADF', - city: 'Dexter B Florence Memorial Field', - state: 'AR', - lat: 34.0998, - lon: -93.0661, - }, - KARG: { - id: 'KARG', - city: 'Walnut Ridge Regional Airport', - state: 'AR', - lat: 36.12562, - lon: -90.92148, - }, - KASG: { - id: 'KASG', - city: 'Springdale Municipal', - state: 'AR', - lat: 36.18333, - lon: -94.11667, - }, - KAWM: { - id: 'KAWM', - city: 'West Memphis, West Memphis Municipal Airport', - state: 'AR', - lat: 35.13333, - lon: -90.23333, - }, - KBPK: { - id: 'KBPK', - city: 'Baxter County Airport', - state: 'AR', - lat: 36.37056, - lon: -92.47194, - }, - KBVX: { - id: 'KBVX', - city: 'Batesville, Batesville Regional Airport', - state: 'AR', - lat: 35.73333, - lon: -91.65, - }, - KBYH: { - id: 'KBYH', - city: 'Eaker Air Force Base', - state: 'AR', - lat: 35.96667, - lon: -89.95, - }, - KCCA: { - id: 'KCCA', - city: 'Clinton Memorial Airfield', - state: 'AR', - lat: 35.598, - lon: -92.4516, - }, - KCDH: { - id: 'KCDH', - city: 'Camden / Harrell Field', - state: 'AR', - lat: 33.61667, - lon: -92.76667, - }, - KCXW: { - id: 'KCXW', - city: 'Conway - Cantrell Field', - state: 'AR', - lat: 35.0199, - lon: -92.5551, - }, - KDEQ: { - id: 'KDEQ', - city: 'De Queen, J Lynn Helms Sevier County Airport', - state: 'AR', - lat: 34.04694, - lon: -94.39944, - }, - KELD: { - id: 'KELD', - city: 'South Arkansas Regional Airport', - state: 'AR', - lat: 33.22075, - lon: -92.8139999, - }, - KFLP: { - id: 'KFLP', - city: 'Flippin, Marion County Regional Airport', - state: 'AR', - lat: 36.3, - lon: -92.58333, - }, - KFSM: { - id: 'KFSM', - city: 'Fort Smith Regional Airport', - state: 'AR', - lat: 35.3335, - lon: -94.36524, - }, - KFYV: { - id: 'KFYV', - city: 'Fayetteville, Drake Field', - state: 'AR', - lat: 36.01028, - lon: -94.1677799, - }, - KHKA: { - id: 'KHKA', - city: 'Blytheville, Blytheville Municipal Airport', - state: 'AR', - lat: 35.93889, - lon: -89.8325, - }, - KHOT: { - id: 'KHOT', - city: 'Hot Springs, Memorial Field Airport', - state: 'AR', - lat: 34.47806, - lon: -93.09611, - }, - KHRO: { - id: 'KHRO', - city: 'Harrison, Boone County Airport', - state: 'AR', - lat: 36.26167, - lon: -93.15472, - }, - KJBR: { - id: 'KJBR', - city: 'Jonesboro, Jonesboro Municipal Airport', - state: 'AR', - lat: 35.83722, - lon: -90.64306, - }, - KLIT: { - id: 'KLIT', - city: 'Little Rock, Adams Field', - state: 'AR', - lat: 34.72667, - lon: -92.23611, - }, - KLLQ: { - id: 'KLLQ', - city: 'Monticello, Monticello Municipal Airport/Ellis Field', - state: 'AR', - lat: 33.63833, - lon: -91.75111, - }, - KLRF: { - id: 'KLRF', - city: 'Little Rock Air Force Base', - state: 'AR', - lat: 34.91667, - lon: -92.15, - }, - KMEZ: { - id: 'KMEZ', - city: 'Mena, Mena Intermountain Municipal Airport', - state: 'AR', - lat: 34.54528, - lon: -94.2025, - }, - KMWT: { - id: 'KMWT', - city: 'Mount Ida', - state: 'AR', - lat: 34.55, - lon: -93.58333, - }, - KORK: { - id: 'KORK', - city: 'North Little Rock Municipal Airport', - state: 'AR', - lat: 34.83314, - lon: -92.25414, - }, - KPBF: { - id: 'KPBF', - city: 'Pine Bluff, Grider Field Airport', - state: 'AR', - lat: 34.175, - lon: -91.93472, - }, - KROG: { - id: 'KROG', - city: 'Rogers - Rogers Executive Airport - Carter Field', - state: 'AR', - lat: 36.36667, - lon: -94.1, - }, - KRUE: { - id: 'KRUE', - city: 'Russelville Municipal Airport', - state: 'AR', - lat: 35.25737, - lon: -93.0949399, - }, - KSGT: { - id: 'KSGT', - city: 'Stuttgart, Stuttgart Municipal Airport', - state: 'AR', - lat: 34.6, - lon: -91.56667, - }, - KSLG: { - id: 'KSLG', - city: 'Siloam Springs, Smith Field Airport', - state: 'AR', - lat: 36.2, - lon: -94.48333, - }, - KSRC: { - id: 'KSRC', - city: 'Searcy Municipal Airport', - state: 'AR', - lat: 35.21349, - lon: -91.7392799, - }, - KSUZ: { - id: 'KSUZ', - city: 'Saline County Regional Airport', - state: 'AR', - lat: 34.59039, - lon: -92.47944, - }, - KTXK: { - id: 'KTXK', - city: 'Texarkana, Texarkana Regional-Webb Field', - state: 'AR', - lat: 33.45611, - lon: -93.9875, - }, - KVBT: { - id: 'KVBT', - city: 'Bentonville, Bentonville Municipal Airport/Louise M Thaden Field', - state: 'AR', - lat: 36.35, - lon: -94.2166699, - }, - KXNA: { - id: 'KXNA', - city: 'Northwest Arkansas Regional Airport', - state: 'AR', - lat: 36.28977, - lon: -94.3114499, - }, - KBOI: { - id: 'KBOI', - city: 'Boise Air Terminal', - state: 'ID', - lat: 43.56704, - lon: -116.24053, - }, - KBYI: { - id: 'KBYI', - city: 'Burley Municipal Airport', - state: 'ID', - lat: 42.54525, - lon: -113.7686, - }, - KCOE: { - id: 'KCOE', - city: "Coeur d'Alene Airport - Pappy Boyington Field", - state: 'ID', - lat: 47.76667, - lon: -116.81667, - }, - KDIJ: { - id: 'KDIJ', - city: 'Driggs, Driggs-Reed Memorial Airport', - state: 'ID', - lat: 43.74167, - lon: -111.09778, - }, - KEUL: { - id: 'KEUL', - city: 'Caldwell - Caldwell Industrial Airport', - state: 'ID', - lat: 43.64055, - lon: -116.63017, - }, - KGIC: { - id: 'KGIC', - city: 'Grangeville - Idaho County Airport', - state: 'ID', - lat: 45.94111, - lon: -116.13257, - }, - KGNG: { - id: 'KGNG', - city: 'Gooding Municipal Airport', - state: 'ID', - lat: 42.91716, - lon: -114.76516, - }, - KIDA: { - id: 'KIDA', - city: 'Idaho Falls Regional Airport', - state: 'ID', - lat: 43.5208299, - lon: -112.06611, - }, - KJER: { - id: 'KJER', - city: 'Jerome County Airport', - state: 'ID', - lat: 42.72736, - lon: -114.45469, - }, - KLLJ: { - id: 'KLLJ', - city: 'Challis - Challis Airport', - state: 'ID', - lat: 44.523, - lon: -114.21611, - }, - KLWS: { - id: 'KLWS', - city: 'Lewiston, Lewiston-Nez Perce County Airport', - state: 'ID', - lat: 46.37472, - lon: -117.01444, - }, - KMAN: { - id: 'KMAN', - city: 'Nampa Municipal Airport', - state: 'ID', - lat: 43.5813, - lon: -116.5231, - }, - KMUO: { - id: 'KMUO', - city: 'Mountain Home Air Force Base', - state: 'ID', - lat: 43.05, - lon: -115.86667, - }, - KMYL: { - id: 'KMYL', - city: 'McCall Airport', - state: 'ID', - lat: 44.89425, - lon: -116.09978, - }, - KPIH: { - id: 'KPIH', - city: 'Pocatello, Pocatello Regional Airport', - state: 'ID', - lat: 42.92028, - lon: -112.57111, - }, - KRXE: { - id: 'KRXE', - city: 'Rexburg, Rexburg-Madison County Airport', - state: 'ID', - lat: 43.83167, - lon: -111.80611, - }, - KSMN: { - id: 'KSMN', - city: 'Salmon, Lemhi County Airport', - state: 'ID', - lat: 45.11667, - lon: -113.88333, - }, - KSNT: { - id: 'KSNT', - city: 'Stanley, Stanley Ranger Station', - state: 'ID', - lat: 44.20861, - lon: -114.93444, - }, - KSUN: { - id: 'KSUN', - city: 'Hailey, Friedman Memorial Airport', - state: 'ID', - lat: 43.5, - lon: -114.3, - }, - KAID: { - id: 'KAID', - city: 'Anderson Municipal Airport', - state: 'IN', - lat: 40.10612, - lon: -85.60977, - }, - KANQ: { - id: 'KANQ', - city: 'Angola Tri-State Steuben County Airport', - state: 'IN', - lat: 41.6404, - lon: -85.0851, - }, - KASW: { - id: 'KASW', - city: 'Warsaw, Warsaw Municipal Airport', - state: 'IN', - lat: 41.27444, - lon: -85.84, - }, - KBAK: { - id: 'KBAK', - city: 'Columbus / Bakalar', - state: 'IN', - lat: 39.26667, - lon: -85.9, - }, - KBMG: { - id: 'KBMG', - city: 'Bloomington, Monroe County Airport', - state: 'IN', - lat: 39.14306, - lon: -86.61667, - }, - KCFJ: { - id: 'KCFJ', - city: 'Crawfordsville Municipal Airport', - state: 'IN', - lat: 39.9756, - lon: -86.9199, - }, - KDCY: { - id: 'KDCY', - city: 'Daviess County Airport', - state: 'IN', - lat: 38.7004, - lon: -87.1297, - }, - KEKM: { - id: 'KEKM', - city: 'Elkhart Municipal', - state: 'IN', - lat: 41.71667, - lon: -86, - }, - KEVV: { - id: 'KEVV', - city: 'Evansville, Evansville Regional Airport', - state: 'IN', - lat: 38.0430599, - lon: -87.52028, - }, - KEYE: { - id: 'KEYE', - city: 'Indianapolis, Eagle Creek Airpark', - state: 'IN', - lat: 39.825, - lon: -86.29583, - }, - KFKR: { - id: 'KFKR', - city: 'Frankfort Municipal Airport', - state: 'IN', - lat: 40.2734, - lon: -86.5622, - }, - KFRH: { - id: 'KFRH', - city: 'French Lick Municipal Airport', - state: 'IN', - lat: 38.50622, - lon: -86.63694, - }, - KFWA: { - id: 'KFWA', - city: 'Fort Wayne International Airport', - state: 'IN', - lat: 40.97251, - lon: -85.20637, - }, - KGEZ: { - id: 'KGEZ', - city: 'Shelbyville Municipal Airport', - state: 'IN', - lat: 39.58546, - lon: -85.79982, - }, - KGGP: { - id: 'KGGP', - city: 'Logansport/Cass County Airport', - state: 'IN', - lat: 40.711, - lon: -86.373, - }, - KGPC: { - id: 'KGPC', - city: 'Putnam County Regional Airport', - state: 'IN', - lat: 39.6354, - lon: -86.8155, - }, - KGSH: { - id: 'KGSH', - city: 'Goshen, Goshen Municipal Airport', - state: 'IN', - lat: 41.52611, - lon: -85.78667, - }, - KGUS: { - id: 'KGUS', - city: 'Grissom Air Force Base / Peru', - state: 'IN', - lat: 40.65, - lon: -86.15, - }, - KGWB: { - id: 'KGWB', - city: 'Auburn De Kalb County Airport', - state: 'IN', - lat: 41.307, - lon: -85.0639999, - }, - KGYY: { - id: 'KGYY', - city: 'Gary Regional Airport', - state: 'IN', - lat: 41.61212, - lon: -87.40908, - }, - KHHG: { - id: 'KHHG', - city: 'Huntington Municipal Airport', - state: 'IN', - lat: 40.8529, - lon: -85.4571, - }, - KHLB: { - id: 'KHLB', - city: 'Batesville Airport', - state: 'IN', - lat: 39.34313, - lon: -85.25843, - }, - KHNB: { - id: 'KHNB', - city: 'Huntingburg', - state: 'IN', - lat: 38.25, - lon: -86.95, - }, - KHUF: { - id: 'KHUF', - city: 'Terre Haute Regional Airport', - state: 'IN', - lat: 39.4429, - lon: -87.32207, - }, - KIMS: { - id: 'KIMS', - city: 'Madison Municipal Airport', - state: 'IN', - lat: 38.7589, - lon: -85.4655, - }, - KIND: { - id: 'KIND', - city: 'Indianapolis International Airport', - state: 'IN', - lat: 39.72518, - lon: -86.2816, - }, - KJVY: { - id: 'KJVY', - city: 'Clark Regional Airport', - state: 'IN', - lat: 38.36661, - lon: -85.73814, - }, - KLAF: { - id: 'KLAF', - city: 'Lafayette, Purdue University Airport', - state: 'IN', - lat: 40.4125, - lon: -86.9475, - }, - KMCX: { - id: 'KMCX', - city: 'Monticello White County Airport', - state: 'IN', - lat: 40.7087999, - lon: -86.7668, - }, - KMGC: { - id: 'KMGC', - city: 'Michigan City Municipal Airport', - state: 'IN', - lat: 41.7033, - lon: -86.8212, - }, - KMIE: { - id: 'KMIE', - city: 'Muncie, Delaware County-Johnson Field', - state: 'IN', - lat: 40.23417, - lon: -85.39361, - }, - KMQJ: { - id: 'KMQJ', - city: 'Indianapolis Mount Comfort Airport', - state: 'IN', - lat: 39.8435, - lon: -85.8971, - }, - KMZZ: { - id: 'KMZZ', - city: 'Marion Municipal Airport', - state: 'IN', - lat: 40.49, - lon: -85.68, - }, - KOKK: { - id: 'KOKK', - city: 'Kokomo, Kokomo Municipal Airport', - state: 'IN', - lat: 40.53333, - lon: -86.06667, - }, - KOXI: { - id: 'KOXI', - city: 'Starke County Airport', - state: 'IN', - lat: 41.33, - lon: -86.665, - }, - KPLD: { - id: 'KPLD', - city: 'Portland Municipal Airport', - state: 'IN', - lat: 40.45158, - lon: -84.98903, - }, - KPPO: { - id: 'KPPO', - city: 'La Porte Municipal Airport', - state: 'IN', - lat: 41.5725, - lon: -86.7345, - }, - KRCR: { - id: 'KRCR', - city: 'Rochester Fulton County Airport', - state: 'IN', - lat: 41.06553, - lon: -86.18169, - }, - KRID: { - id: 'KRID', - city: 'Richmond Municipal Airport', - state: 'IN', - lat: 39.7572, - lon: -84.8428, - }, - KRZL: { - id: 'KRZL', - city: 'Rensselaer Jasper County Airport', - state: 'IN', - lat: 40.94789, - lon: -87.18258, - }, - KSBN: { - id: 'KSBN', - city: 'South Bend International Airport', - state: 'IN', - lat: 41.7088899, - lon: -86.31861, - }, - KTYQ: { - id: 'KTYQ', - city: 'INDIANAPOLIS', - state: 'IN', - lat: 40.03066, - lon: -86.2514999, - }, - KVPZ: { - id: 'KVPZ', - city: 'Valparaiso Porter County Municipal Airport', - state: 'IN', - lat: 41.45349, - lon: -86.99805, - }, - KABQ: { - id: 'KABQ', - city: 'Albuquerque, Albuquerque International Airport', - state: 'NM', - lat: 35.04167, - lon: -106.61472, - }, - KAEG: { - id: 'KAEG', - city: 'Albuquerque, Double Eagle II Airport', - state: 'NM', - lat: 35.145, - lon: -106.795, - }, - KALM: { - id: 'KALM', - city: 'Alamogordo-White', - state: 'NM', - lat: 32.83512, - lon: -105.99408, - }, - KATS: { - id: 'KATS', - city: 'Artesia Municipal Airport', - state: 'NM', - lat: 32.85239, - lon: -104.46444, - }, - KAXX: { - id: 'KAXX', - city: 'Angel Fire Airport', - state: 'NM', - lat: 36.42586, - lon: -105.29028, - }, - KBRG: { - id: 'KBRG', - city: 'Belen Regional Airport', - state: 'NM', - lat: 34.64586, - lon: -106.83634, - }, - KCAO: { - id: 'KCAO', - city: 'Clayton Municipal Airpark', - state: 'NM', - lat: 36.44834, - lon: -103.15367, - }, - KCNM: { - id: 'KCNM', - city: 'Carlsbad, Cavern City Air Terminal Airport', - state: 'NM', - lat: 32.3375, - lon: -104.26333, - }, - KCQC: { - id: 'KCQC', - city: 'Clines Corners', - state: 'NM', - lat: 35, - lon: -105.66667, - }, - KCVN: { - id: 'KCVN', - city: 'Clovis Municipal Airport', - state: 'NM', - lat: 34.42274, - lon: -103.0802, - }, - KCVS: { - id: 'KCVS', - city: 'Cannon Air Force Base / Clovis', - state: 'NM', - lat: 34.38333, - lon: -103.31667, - }, - KDMN: { - id: 'KDMN', - city: 'Deming Municipal Airport', - state: 'NM', - lat: 32.25927, - lon: -107.72051, - }, - KDNA: { - id: 'KDNA', - city: 'Dona Ana County Jetport, Santa Teresa', - state: 'NM', - lat: 31.87495, - lon: -106.69385, - }, - KFMN: { - id: 'KFMN', - city: 'Farmington, Four Corners Regional Airport', - state: 'NM', - lat: 36.7436099, - lon: -108.22917, - }, - KGNT: { - id: 'KGNT', - city: 'Grants, Grants-Milan Municipal Airport', - state: 'NM', - lat: 35.16528, - lon: -107.90222, - }, - KGUP: { - id: 'KGUP', - city: 'Gallup Municipal Airport', - state: 'NM', - lat: 35.50859, - lon: -108.79316, - }, - KHMN: { - id: 'KHMN', - city: 'Holloman Air Force Base', - state: 'NM', - lat: 32.85, - lon: -106.1, - }, - KHOB: { - id: 'KHOB', - city: 'Hobbs / Lea County', - state: 'NM', - lat: 32.68333, - lon: -103.2166699, - }, - KLAM: { - id: 'KLAM', - city: 'Los Alamos Airport', - state: 'NM', - lat: 35.8796899, - lon: -106.26869, - }, - KLRU: { - id: 'KLRU', - city: 'Las Cruces, Las Cruces International Airport', - state: 'NM', - lat: 32.28944, - lon: -106.92194, - }, - KLVS: { - id: 'KLVS', - city: 'Las Vegas Municipal Airport', - state: 'NM', - lat: 35.65584, - lon: -105.13852, - }, - KONM: { - id: 'KONM', - city: 'Socorro Municipal Airport', - state: 'NM', - lat: 34.02633, - lon: -106.90372, - }, - KROW: { - id: 'KROW', - city: 'Roswell International Air Center Airport', - state: 'NM', - lat: 33.30737, - lon: -104.50816, - }, - KRTN: { - id: 'KRTN', - city: 'Raton Municipal - Crews Field Airport', - state: 'NM', - lat: 36.741528, - lon: -104.502183, - }, - KSAF: { - id: 'KSAF', - city: 'Santa Fe County Municipal Airport', - state: 'NM', - lat: 35.61097, - lon: -106.09573, - }, - KSKX: { - id: 'KSKX', - city: 'Taos, Taos Regional Airport', - state: 'NM', - lat: 36.45, - lon: -105.66667, - }, - KSRR: { - id: 'KSRR', - city: 'Sierra Blanca Regional Airport', - state: 'NM', - lat: 33.4667699, - lon: -105.52778, - }, - KSVC: { - id: 'KSVC', - city: 'Grant County Airport', - state: 'NM', - lat: 32.63099, - lon: -108.14658, - }, - KSXU: { - id: 'KSXU', - city: 'Santa Rosa Route 66 Airport', - state: 'NM', - lat: 34.93567, - lon: -104.64256, - }, - KTCC: { - id: 'KTCC', - city: 'Tucumcari Municipal Airport', - state: 'NM', - lat: 35.18053, - lon: -103.60145, - }, - KTCS: { - id: 'KTCS', - city: 'Truth Or Consequences, Truth Or Consequences Municipal Airport', - state: 'NM', - lat: 33.2366699, - lon: -107.26806, - }, - KADH: { - id: 'KADH', - city: 'Ada, Ada Municipal Airport', - state: 'OK', - lat: 34.80444, - lon: -96.67139, - }, - KADM: { - id: 'KADM', - city: 'Ardmore, Ardmore Municipal Airport', - state: 'OK', - lat: 34.30306, - lon: -97.01944, - }, - KAVK: { - id: 'KAVK', - city: 'Alva, Alva Regional Airport', - state: 'OK', - lat: 36.77306, - lon: -98.67, - }, - KAXS: { - id: 'KAXS', - city: 'Altus, Altus/Quartz Mountain Regional Airport', - state: 'OK', - lat: 34.69861, - lon: -99.33806, - }, - KBKN: { - id: 'KBKN', - city: 'Blackwell-Tonkawa Municipal Airport', - state: 'OK', - lat: 36.7451099, - lon: -97.34958, - }, - KBVO: { - id: 'KBVO', - city: 'Bartlesville, Bartlesville Municipal Airport', - state: 'OK', - lat: 36.76833, - lon: -96.02611, - }, - KCHK: { - id: 'KCHK', - city: 'Chickasha, Chickasha Municipal Airport', - state: 'OK', - lat: 35.09611, - lon: -97.96611, - }, - KCLK: { - id: 'KCLK', - city: 'Clinton, Clinton Regional Airport', - state: 'OK', - lat: 35.53806, - lon: -98.92139, - }, - KCQB: { - id: 'KCQB', - city: 'Chandler, Chandler Municipal Airport', - state: 'OK', - lat: 35.72389, - lon: -96.82028, - }, - KCSM: { - id: 'KCSM', - city: 'Clinton, Clinton-Sherman Airport', - state: 'OK', - lat: 35.35667, - lon: -99.20361, - }, - KCUH: { - id: 'KCUH', - city: 'Cushing, Cushing Municipal Airport', - state: 'OK', - lat: 35.94972, - lon: -96.77278, - }, - KDUA: { - id: 'KDUA', - city: 'Durant, Eaker Field Airport', - state: 'OK', - lat: 33.94222, - lon: -96.39444, - }, - KDUC: { - id: 'KDUC', - city: 'Duncan, Halliburton Field Airport', - state: 'OK', - lat: 34.47083, - lon: -97.9599999, - }, - KELK: { - id: 'KELK', - city: 'Elk City Regional Business Airport', - state: 'OK', - lat: 35.4308, - lon: -99.3943, - }, - KEND: { - id: 'KEND', - city: 'Vance Air Force Base / Enid', - state: 'OK', - lat: 36.3333299, - lon: -97.91667, - }, - KFDR: { - id: 'KFDR', - city: 'Frederick, Frederick Municipal Airport', - state: 'OK', - lat: 34.34444, - lon: -98.98306, - }, - KFSI: { - id: 'KFSI', - city: 'Fort Sill', - state: 'OK', - lat: 34.6, - lon: -98.4, - }, - KGAG: { - id: 'KGAG', - city: 'Gage, Gage Airport', - state: 'OK', - lat: 36.29667, - lon: -99.76889, - }, - KGCM: { - id: 'KGCM', - city: 'Claremore, Claremore Regional Airport', - state: 'OK', - lat: 36.29444, - lon: -95.47972, - }, - KGMJ: { - id: 'KGMJ', - city: 'Grove, Grove Municipal Airport', - state: 'OK', - lat: 36.60528, - lon: -94.73861, - }, - KGOK: { - id: 'KGOK', - city: 'Guthrie, Guthrie Municipal Airport', - state: 'OK', - lat: 35.85194, - lon: -97.4075, - }, - KGUY: { - id: 'KGUY', - city: 'Guymon / Guymon Municipal Airport', - state: 'OK', - lat: 36.6816699, - lon: -101.50528, - }, - KGZL: { - id: 'KGZL', - city: 'Stigler', - state: 'OK', - lat: 35.2891, - lon: -95.0939, - }, - KHBR: { - id: 'KHBR', - city: 'Hobart, Hobart Municipal Airport', - state: 'OK', - lat: 34.98944, - lon: -99.0525, - }, - KHHW: { - id: 'KHHW', - city: 'Hugo Stan Stamper Municipal Airport', - state: 'OK', - lat: 34.0348, - lon: -95.5419, - }, - KHMY: { - id: 'KHMY', - city: 'MULDROWARMY', - state: 'OK', - lat: 35.02638, - lon: -97.23163, - }, - KHSD: { - id: 'KHSD', - city: 'Sundance Airport', - state: 'OK', - lat: 35.60183, - lon: -97.70616, - }, - KJSV: { - id: 'KJSV', - city: 'Sallisaw, Sallisaw Municipal Airport', - state: 'OK', - lat: 35.43806, - lon: -94.80278, - }, - KJWG: { - id: 'KJWG', - city: 'Watonga, Watonga Airport', - state: 'OK', - lat: 35.86472, - lon: -98.42083, - }, - KLAW: { - id: 'KLAW', - city: 'Lawton, Lawton Municipal Airport', - state: 'OK', - lat: 34.5575, - lon: -98.41667, - }, - KLTS: { - id: 'KLTS', - city: 'Altus Air Force Base', - state: 'OK', - lat: 34.65, - lon: -99.26667, - }, - KMIO: { - id: 'KMIO', - city: 'Miami Regional Airport', - state: 'OK', - lat: 36.90922, - lon: -94.8875, - }, - KMKO: { - id: 'KMKO', - city: 'Muskogee-Davis Regional Airport', - state: 'OK', - lat: 35.65694, - lon: -95.35972, - }, - KMLC: { - id: 'KMLC', - city: 'McAlester, McAlester Regional Airport', - state: 'OK', - lat: 34.8822199, - lon: -95.78306, - }, - KOJA: { - id: 'KOJA', - city: 'Weatherford, Thomas P Stafford Airport', - state: 'OK', - lat: 35.54472, - lon: -98.66833, - }, - KOKC: { - id: 'KOKC', - city: 'Oklahoma City, Will Rogers World Airport', - state: 'OK', - lat: 35.38861, - lon: -97.60028, - }, - KOKM: { - id: 'KOKM', - city: 'Okmulgee, Okmulgee Municipal Airport', - state: 'OK', - lat: 35.6680599, - lon: -95.94861, - }, - KOUN: { - id: 'KOUN', - city: 'Norman / Max Westheimer', - state: 'OK', - lat: 35.2435, - lon: -97.4708, - }, - KOWP: { - id: 'KOWP', - city: 'William R Pogue Municipal Airport', - state: 'OK', - lat: 36.1753, - lon: -96.1518, - }, - KPNC: { - id: 'KPNC', - city: 'Ponca City, Ponca City Municipal Airport', - state: 'OK', - lat: 36.7305599, - lon: -97.09972, - }, - KPVJ: { - id: 'KPVJ', - city: 'Pauls Valley, Pauls Valley Municipal Airport', - state: 'OK', - lat: 34.71111, - lon: -97.22333, - }, - KPWA: { - id: 'KPWA', - city: 'Oklahoma City, Wiley Post Airport', - state: 'OK', - lat: 35.54111, - lon: -97.64667, - }, - KRCE: { - id: 'KRCE', - city: 'Clarence E Page Municipal Airport', - state: 'OK', - lat: 35.4880799, - lon: -97.82356, - }, - KRKR: { - id: 'KRKR', - city: 'Poteau, Robert S Kerr Airport', - state: 'OK', - lat: 35.02167, - lon: -94.62139, - }, - KRQO: { - id: 'KRQO', - city: 'El Reno, El Reno Regional Airport', - state: 'OK', - lat: 35.4724999, - lon: -98.00556, - }, - KRVS: { - id: 'KRVS', - city: 'Tulsa - Jones Jr. Airport', - state: 'OK', - lat: 36.04255, - lon: -95.99005, - }, - KSNL: { - id: 'KSNL', - city: 'Shawnee, Shawnee Municipal Airport', - state: 'OK', - lat: 35.35722, - lon: -96.94278, - }, - KSRE: { - id: 'KSRE', - city: 'Seminole, Seminole Municipal Airport', - state: 'OK', - lat: 35.27444, - lon: -96.675, - }, - KSWO: { - id: 'KSWO', - city: 'Stillwater, Stillwater Regional Airport', - state: 'OK', - lat: 36.16222, - lon: -97.08917, - }, - KTIK: { - id: 'KTIK', - city: 'Tinker Air Force Base', - state: 'OK', - lat: 35.41667, - lon: -97.38333, - }, - KTQH: { - id: 'KTQH', - city: 'Tahlequah, Tahlequah Municipal Airport', - state: 'OK', - lat: 35.92889, - lon: -95.00444, - }, - KTUL: { - id: 'KTUL', - city: 'Tulsa, Tulsa International Airport', - state: 'OK', - lat: 36.1975, - lon: -95.88639, - }, - KWDG: { - id: 'KWDG', - city: 'Enid, Enid Woodring Regional Airport', - state: 'OK', - lat: 36.37917, - lon: -97.79111, - }, - KWWR: { - id: 'KWWR', - city: 'Woodward, West Woodward Airport', - state: 'OK', - lat: 36.43667, - lon: -99.5211099, - }, - KAIG: { - id: 'KAIG', - city: 'Langlade County Airport', - state: 'WI', - lat: 45.15659, - lon: -89.11144, - }, - KARV: { - id: 'KARV', - city: 'Minocqua/Woodruff, Lakeland Airport/Noble F. Lee Memorial Field', - state: 'WI', - lat: 45.93333, - lon: -89.73333, - }, - KASX: { - id: 'KASX', - city: 'John F Kennedy Memorial Airport', - state: 'WI', - lat: 46.54679, - lon: -90.91841, - }, - KATW: { - id: 'KATW', - city: 'Appleton-Outagamie', - state: 'WI', - lat: 44.2595, - lon: -88.51567, - }, - KAUW: { - id: 'KAUW', - city: 'Wausau Downtown Airport', - state: 'WI', - lat: 44.92759, - lon: -89.62512, - }, - KBCK: { - id: 'KBCK', - city: 'Black River Falls Area Airport', - state: 'WI', - lat: 44.24996, - lon: -90.84999, - }, - KBUU: { - id: 'KBUU', - city: 'Burlington Municipal Airport', - state: 'WI', - lat: 42.69088, - lon: -88.308, - }, - KCMY: { - id: 'KCMY', - city: 'Sparta, Sparta / Fort McCoy Airport', - state: 'WI', - lat: 43.9583299, - lon: -90.73778, - }, - KCWA: { - id: 'KCWA', - city: 'Mosinee', - state: 'WI', - lat: 44.77944, - lon: -89.67098, - }, - KDLL: { - id: 'KDLL', - city: 'Baraboo Wisconsin Dells Airport', - state: 'WI', - lat: 43.52372, - lon: -89.77345, - }, - KEAU: { - id: 'KEAU', - city: 'Chippewa Valley Regional Airport', - state: 'WI', - lat: 44.86668, - lon: -91.488, - }, - KEFT: { - id: 'KEFT', - city: 'Monroe Municipal Airport', - state: 'WI', - lat: 42.61959, - lon: -89.59309, - }, - KEGV: { - id: 'KEGV', - city: 'Eagle River Union Airport', - state: 'WI', - lat: 45.9309299, - lon: -89.26702, - }, - KENW: { - id: 'KENW', - city: 'Kenosha, Kenosha Regional Airport', - state: 'WI', - lat: 42.595, - lon: -87.9380599, - }, - KETB: { - id: 'KETB', - city: 'West Bend Municipal Airport', - state: 'WI', - lat: 43.42256, - lon: -88.1326, - }, - KEZS: { - id: 'KEZS', - city: 'Shawano Municipal Airport', - state: 'WI', - lat: 44.787, - lon: -88.56, - }, - KFLD: { - id: 'KFLD', - city: 'Fond Du Lac County Airport', - state: 'WI', - lat: 43.76955, - lon: -88.49072, - }, - KGRB: { - id: 'KGRB', - city: 'Green Bay, Austin Straubel International Airport', - state: 'WI', - lat: 44.4794399, - lon: -88.13667, - }, - KHYR: { - id: 'KHYR', - city: 'Sawyer County Airport', - state: 'WI', - lat: 46.03029, - lon: -91.44259, - }, - KISW: { - id: 'KISW', - city: 'Wisconsin Rapids, Alexander Field South Wood County Airport', - state: 'WI', - lat: 44.35917, - lon: -89.83694, - }, - KJVL: { - id: 'KJVL', - city: 'Janesville-Rock County', - state: 'WI', - lat: 42.62135, - lon: -89.04186, - }, - KLNL: { - id: 'KLNL', - city: "Land O' Lakes, Kings Land O' Lakes Airport", - state: 'WI', - lat: 46.1538899, - lon: -89.21194, - }, - KLNR: { - id: 'KLNR', - city: 'Lone Rock Tri-County Regional Airport', - state: 'WI', - lat: 43.21108, - lon: -90.18735, - }, - KLSE: { - id: 'KLSE', - city: 'La Crosse - La Crosse Regional Airport', - state: 'WI', - lat: 43.87944, - lon: -91.25667, - }, - KLUM: { - id: 'KLUM', - city: 'Menomonie Municipal Airport-Score Field', - state: 'WI', - lat: 44.89363, - lon: -91.86652, - }, - KMDZ: { - id: 'KMDZ', - city: 'Taylor County Airport', - state: 'WI', - lat: 45.10462, - lon: -90.30253, - }, - KMFI: { - id: 'KMFI', - city: 'Marshfield, Marshfield Municipal Airport', - state: 'WI', - lat: 44.63806, - lon: -90.1875, - }, - KMKE: { - id: 'KMKE', - city: 'Milwaukee, General Mitchell International Airport', - state: 'WI', - lat: 42.955, - lon: -87.9044399, - }, - KMRJ: { - id: 'KMRJ', - city: 'Iowa County Airport', - state: 'WI', - lat: 42.88754, - lon: -90.23147, - }, - KMSN: { - id: 'KMSN', - city: 'Madison, Dane County Regional-Truax Field', - state: 'WI', - lat: 43.14056, - lon: -89.34528, - }, - KMTW: { - id: 'KMTW', - city: 'Manitowoc, Manitowoc County Airport', - state: 'WI', - lat: 44.13333, - lon: -87.68333, - }, - KMWC: { - id: 'KMWC', - city: 'Milwaukee-Timmerman', - state: 'WI', - lat: 43.10961, - lon: -88.03048, - }, - KOCQ: { - id: 'KOCQ', - city: 'Oconto J. Douglas Bake Municipal Airport', - state: 'WI', - lat: 44.8742, - lon: -87.9096, - }, - KOEO: { - id: 'KOEO', - city: 'L O Simenstad Municipal Airport', - state: 'WI', - lat: 45.31084, - lon: -92.6948, - }, - KOLG: { - id: 'KOLG', - city: 'Solon Springs Municipal Airport', - state: 'WI', - lat: 46.3148, - lon: -91.8164, - }, - KOSH: { - id: 'KOSH', - city: 'Wittman Regional Airport', - state: 'WI', - lat: 43.96701, - lon: -88.55814, - }, - KOVS: { - id: 'KOVS', - city: 'Boscobel, Boscobel Airport', - state: 'WI', - lat: 43.15611, - lon: -90.6775, - }, - KPBH: { - id: 'KPBH', - city: 'Phillips / Price County', - state: 'WI', - lat: 45.7, - lon: -90.4, - }, - KPCZ: { - id: 'KPCZ', - city: 'Waupaca Municipal Airport', - state: 'WI', - lat: 44.33425, - lon: -89.02023, - }, - KPDC: { - id: 'KPDC', - city: 'Prairie Du Chien Municipal Airport', - state: 'WI', - lat: 43.01938, - lon: -91.12112, - }, - KPVB: { - id: 'KPVB', - city: 'Platteville Municipal Airport', - state: 'WI', - lat: 42.69092, - lon: -90.4412399, - }, - KRAC: { - id: 'KRAC', - city: 'Racine, Batten International Airport', - state: 'WI', - lat: 42.75861, - lon: -87.81778, - }, - KRCX: { - id: 'KRCX', - city: 'Ladysmith - Rusk County Airport', - state: 'WI', - lat: 45.4935, - lon: -90.9985, - }, - KRGK: { - id: 'KRGK', - city: 'Red Wing - Red Wing Regional Airport', - state: 'WI', - lat: 44.5926, - lon: -92.48439, - }, - KRHI: { - id: 'KRHI', - city: 'Rhinelander, Rhinelander-Oneida County Airport', - state: 'WI', - lat: 45.63167, - lon: -89.48222, - }, - KRNH: { - id: 'KRNH', - city: 'New Richmond Municipal Airport', - state: 'WI', - lat: 45.14762, - lon: -92.53349, - }, - KRPD: { - id: 'KRPD', - city: "Rice Lake, Rice Lake Regional-Carl's Field Airport", - state: 'WI', - lat: 45.4180599, - lon: -91.77361, - }, - KRRL: { - id: 'KRRL', - city: 'Merrill, Merrill Municipal Airport', - state: 'WI', - lat: 45.19844, - lon: -89.70996, - }, - KRYV: { - id: 'KRYV', - city: 'Watertown', - state: 'WI', - lat: 43.17016, - lon: -88.72497, - }, - KRZN: { - id: 'KRZN', - city: 'Siren, Burnett County Airport', - state: 'WI', - lat: 45.82278, - lon: -92.3725, - }, - KSBM: { - id: 'KSBM', - city: 'Sheboygan County Memorial Airport', - state: 'WI', - lat: 43.77483, - lon: -87.84897, - }, - KSTE: { - id: 'KSTE', - city: 'Stevens Point Municipal Airport', - state: 'WI', - lat: 44.54371, - lon: -89.53468, - }, - KSUE: { - id: 'KSUE', - city: 'Door County Cherryland Airport', - state: 'WI', - lat: 44.83941, - lon: -87.42188, - }, - KSUW: { - id: 'KSUW', - city: 'Richard I. Bong Airport', - state: 'WI', - lat: 46.68335, - lon: -92.09254, - }, - KTKV: { - id: 'KTKV', - city: 'Tomahawk Regional Airport', - state: 'WI', - lat: 45.46801, - lon: -89.80962, - }, - KUBE: { - id: 'KUBE', - city: 'Cumberland', - state: 'WI', - lat: 45.506, - lon: -91.9811, - }, - KUES: { - id: 'KUES', - city: 'Waukesha County Airport', - state: 'WI', - lat: 43.04245, - lon: -88.24607, - }, - KUNU: { - id: 'KUNU', - city: 'Juneau, Dodge County Airport', - state: 'WI', - lat: 43.42667, - lon: -88.7033299, - }, - KVOK: { - id: 'KVOK', - city: 'Volk / Camp Douglas', - state: 'WI', - lat: 43.93333, - lon: -90.26667, - }, - KACP: { - id: 'KACP', - city: 'Oakdale, Allen Parish Airport', - state: 'LA', - lat: 30.75056, - lon: -92.68861, - }, - KAEX: { - id: 'KAEX', - city: 'Alexandria, Alexandria International Airport', - state: 'LA', - lat: 31.33472, - lon: -92.55861, - }, - KAPS: { - id: 'KAPS', - city: 'Port of South Louisiana Executive Regional Airport', - state: 'LA', - lat: 30.08747, - lon: -90.58283, - }, - KAQV: { - id: 'KAQV', - city: 'Ft. Polk - Peason Ridge', - state: 'LA', - lat: 31.4, - lon: -93.2833, - }, - KARA: { - id: 'KARA', - city: 'Acadiana Regional Airport', - state: 'LA', - lat: 30.02918, - lon: -91.88451, - }, - KASD: { - id: 'KASD', - city: 'Slidell, Slidell Airport', - state: 'LA', - lat: 30.34306, - lon: -89.82194, - }, - KATP: { - id: 'KATP', - city: 'Green Canyon 787 Atlantis', - state: 'LA', - lat: 27.195, - lon: -90.027, - }, - KBAD: { - id: 'KBAD', - city: 'Barksdale Air Force Base', - state: 'LA', - lat: 32.5, - lon: -93.66667, - }, - KBKB: { - id: 'KBKB', - city: 'Ft. Polk - Fullerton Landing Strip', - state: 'LA', - lat: 31.0217, - lon: -92.9107, - }, - KBTR: { - id: 'KBTR', - city: 'Baton Rouge, Baton Rouge Metropolitan, Ryan Field', - state: 'LA', - lat: 30.53722, - lon: -91.14694, - }, - KBXA: { - id: 'KBXA', - city: 'Bogalusa, George R Carr Memorial Air Field', - state: 'LA', - lat: 30.81361, - lon: -89.86472, - }, - KCWF: { - id: 'KCWF', - city: 'Chenault Airpark', - state: 'LA', - lat: 30.21667, - lon: -93.15, - }, - KDRI: { - id: 'KDRI', - city: 'De Ridder, Beauregard Parish Airport', - state: 'LA', - lat: 30.83167, - lon: -93.33972, - }, - KDSF: { - id: 'KDSF', - city: 'Mississippi Canyon', - state: 'LA', - lat: 28.35, - lon: -88.26667, - }, - KDTN: { - id: 'KDTN', - city: 'Shreveport, Shreveport Downtown Airport', - state: 'LA', - lat: 32.5424999, - lon: -93.74472, - }, - KEIR: { - id: 'KEIR', - city: 'Eugene Island', - state: 'LA', - lat: 28.634, - lon: -91.489, - }, - KESF: { - id: 'KESF', - city: 'Alexandria Esler Regional Airport', - state: 'LA', - lat: 31.39634, - lon: -92.28273, - }, - KGAO: { - id: 'KGAO', - city: 'Galliano, South Lafourche Airport', - state: 'LA', - lat: 29.44472, - lon: -90.26111, - }, - KGHB: { - id: 'KGHB', - city: 'GB172/Salsa (Shell E-P)', - state: 'LA', - lat: 27.84, - lon: -91.988, - }, - KGRY: { - id: 'KGRY', - city: 'Green Canyon 338 Front Runner', - state: 'LA', - lat: 27.625, - lon: -90.441, - }, - KHDC: { - id: 'KHDC', - city: 'Hammond, Hammond Municipal Airport', - state: 'LA', - lat: 30.52083, - lon: -90.4175, - }, - KHUM: { - id: 'KHUM', - city: 'Houma-Terrebonne Airport', - state: 'LA', - lat: 29.56341, - lon: -90.66283, - }, - KHZR: { - id: 'KHZR', - city: 'New Roads False River Regional Airport', - state: 'LA', - lat: 30.7183, - lon: -91.4787, - }, - KIER: { - id: 'KIER', - city: 'Natchitoches, Natchitoches Regional Airport', - state: 'LA', - lat: 31.73583, - lon: -93.09917, - }, - KIYA: { - id: 'KIYA', - city: 'Abbeville Chris Crusta Memorial Airport', - state: 'LA', - lat: 29.97578, - lon: -92.08422, - }, - KLCH: { - id: 'KLCH', - city: 'Lake Charles Regional Airport', - state: 'LA', - lat: 30.12556, - lon: -93.22767, - }, - KLFT: { - id: 'KLFT', - city: 'Lafayette, Lafayette Regional Airport', - state: 'LA', - lat: 30.20222, - lon: -91.99306, - }, - KLNQ: { - id: 'KLNQ', - city: 'Boothville Heliport', - state: 'LA', - lat: 29.35414, - lon: -89.43591, - }, - KMDJ: { - id: 'KMDJ', - city: 'MISS CANYON OIL PLATFORM', - state: 'LA', - lat: 28.65, - lon: -89.8, - }, - KMIS: { - id: 'KMIS', - city: 'Main Pass 140B (Apache Corp)', - state: 'LA', - lat: 29.296, - lon: -88.842, - }, - KMLU: { - id: 'KMLU', - city: 'Monroe Regional Airport', - state: 'LA', - lat: 32.5155699, - lon: -92.02995, - }, - KMNE: { - id: 'KMNE', - city: 'Minden Airport', - state: 'LA', - lat: 32.64603, - lon: -93.29808, - }, - KMSY: { - id: 'KMSY', - city: 'New Orleans, New Orleans International Airport', - state: 'LA', - lat: 29.99278, - lon: -90.2508299, - }, - KNBG: { - id: 'KNBG', - city: 'New Orleans Naval Air Station - Alvin Callender Field', - state: 'LA', - lat: 29.83736, - lon: -90.02445, - }, - KNEW: { - id: 'KNEW', - city: 'New Orleans, New Orleans Lakefront Airport', - state: 'LA', - lat: 30.04944, - lon: -90.02889, - }, - KOPL: { - id: 'KOPL', - city: 'Opelousas St Landry Parish Airport', - state: 'LA', - lat: 30.5584, - lon: -92.0994, - }, - KPOE: { - id: 'KPOE', - city: 'Fort Polk, Polk AAF Ft Polk', - state: 'LA', - lat: 31.05, - lon: -93.19389, - }, - KPTN: { - id: 'KPTN', - city: 'Patterson Memorial', - state: 'LA', - lat: 29.71667, - lon: -91.33333, - }, - KREG: { - id: 'KREG', - city: 'Louisiana Regional Airport', - state: 'LA', - lat: 30.1714, - lon: -90.9404, - }, - KRSN: { - id: 'KRSN', - city: 'Ruston, Ruston Regional Airport', - state: 'LA', - lat: 32.51444, - lon: -92.58833, - }, - KSHV: { - id: 'KSHV', - city: 'Shreveport, Shreveport Regional Airport', - state: 'LA', - lat: 32.44694, - lon: -93.82417, - }, - KTVR: { - id: 'KTVR', - city: 'Vicksburg, Vicksburg / Tallulah Regional Airport', - state: 'LA', - lat: 32.3480599, - lon: -91.03, - }, - KUXL: { - id: 'KUXL', - city: 'Southland Field', - state: 'LA', - lat: 30.1314, - lon: -93.3760999, - }, - KVKY: { - id: 'KVKY', - city: 'Main Pass 289C (Apache Corp)', - state: 'LA', - lat: 29.248, - lon: -88.441, - }, - KVOA: { - id: 'KVOA', - city: 'VK 786/Petronius (Chevron)', - state: 'LA', - lat: 29.229, - lon: -87.781, - }, - KBHK: { - id: 'KBHK', - city: 'Baker, Baker Municipal Airport', - state: 'MT', - lat: 46.34778, - lon: -104.2574999, - }, - KBIL: { - id: 'KBIL', - city: 'Billings, Billings Logan International Airport', - state: 'MT', - lat: 45.80694, - lon: -108.54222, - }, - KBTM: { - id: 'KBTM', - city: 'Butte, Bert Mooney Airport', - state: 'MT', - lat: 45.95472, - lon: -112.4975, - }, - KBZN: { - id: 'KBZN', - city: 'Bozeman, Gallatin Field', - state: 'MT', - lat: 45.78806, - lon: -111.16083, - }, - KCII: { - id: 'KCII', - city: 'Choteau Airport', - state: 'MT', - lat: 47.82835, - lon: -112.16834, - }, - KCTB: { - id: 'KCTB', - city: 'Cut Bank, Cut Bank Municipal Airport', - state: 'MT', - lat: 48.60833, - lon: -112.37611, - }, - KDLN: { - id: 'KDLN', - city: 'Dillon, Dillon Airport', - state: 'MT', - lat: 45.2575, - lon: -112.55444, - }, - KEKS: { - id: 'KEKS', - city: 'Ennis - Big Sky Airport', - state: 'MT', - lat: 45.27436, - lon: -111.64886, - }, - KGDV: { - id: 'KGDV', - city: 'Glendive, Dawson Community Airport', - state: 'MT', - lat: 47.13333, - lon: -104.8, - }, - KGFA: { - id: 'KGFA', - city: 'Malmstrom Air Force Base', - state: 'MT', - lat: 47.5, - lon: -111.18333, - }, - KGGW: { - id: 'KGGW', - city: 'Glasgow, Glasgow International Airport', - state: 'MT', - lat: 48.21389, - lon: -106.62139, - }, - KGPI: { - id: 'KGPI', - city: 'Kalispell, Glacier Park International Airport', - state: 'MT', - lat: 48.30417, - lon: -114.26361, - }, - KGTF: { - id: 'KGTF', - city: 'Great Falls, Great Falls International Airport', - state: 'MT', - lat: 47.47333, - lon: -111.38222, - }, - KHLN: { - id: 'KHLN', - city: 'Helena Regional Airport', - state: 'MT', - lat: 46.60445, - lon: -111.9892, - }, - KHVR: { - id: 'KHVR', - city: 'Havre, Havre City-County Airport', - state: 'MT', - lat: 48.54278, - lon: -109.76333, - }, - KJDN: { - id: 'KJDN', - city: 'Jordan, Jordan Airport', - state: 'MT', - lat: 47.32583, - lon: -106.9475, - }, - KLVM: { - id: 'KLVM', - city: 'Livingston, Mission Field Airport', - state: 'MT', - lat: 45.69944, - lon: -110.44833, - }, - KLWT: { - id: 'KLWT', - city: 'Lewistown, Lewistown Municipal Airport', - state: 'MT', - lat: 47.0491699, - lon: -109.46639, - }, - KMLP: { - id: 'KMLP', - city: 'Mullan Pass, Mullan Pass Vor', - state: 'MT', - lat: 47.45417, - lon: -115.66972, - }, - KMLS: { - id: 'KMLS', - city: 'Miles City, Frank Wiley Field Airport', - state: 'MT', - lat: 46.42806, - lon: -105.88639, - }, - KMSO: { - id: 'KMSO', - city: 'Missoula, Missoula International Airport', - state: 'MT', - lat: 46.92083, - lon: -114.0925, - }, - KMVH: { - id: 'KMVH', - city: 'N BAR Ranch Airport', - state: 'MT', - lat: 46.8381, - lon: -108.9368, - }, - KOLF: { - id: 'KOLF', - city: 'Wolf Point, Clayton Airport', - state: 'MT', - lat: 48.09444, - lon: -105.57722, - }, - KPWD: { - id: 'KPWD', - city: 'Sher-Wood Airport', - state: 'MT', - lat: 48.789, - lon: -104.52297, - }, - KRPX: { - id: 'KRPX', - city: 'ROUNDUP', - state: 'MT', - lat: 46.47499, - lon: -108.54339, - }, - KRVF: { - id: 'KRVF', - city: 'Ruby Valley Field Airport', - state: 'MT', - lat: 45.53542, - lon: -112.30228, - }, - KSDY: { - id: 'KSDY', - city: 'Sidney-Richland', - state: 'MT', - lat: 47.7, - lon: -104.2, - }, - KTHM: { - id: 'KTHM', - city: 'THOMPSON FALLS', - state: 'MT', - lat: 47.5735, - lon: -115.28066, - }, - KWYS: { - id: 'KWYS', - city: 'West Yellowstone', - state: 'MT', - lat: 44.68333, - lon: -111.11667, - }, - KHYX: { - id: 'KHYX', - city: 'Saginaw County H W Browne Airport', - state: 'MI', - lat: 43.43191, - lon: -83.86476, - }, - KIKW: { - id: 'KIKW', - city: 'Jack Barstow Airport', - state: 'MI', - lat: 43.6624, - lon: -84.26213, - }, - KIMT: { - id: 'KIMT', - city: 'Iron Mountain / Kingsford, Ford Airport', - state: 'MI', - lat: 45.81417, - lon: -88.10889, - }, - KIRS: { - id: 'KIRS', - city: 'Sturgis, Kirsch Municipal Airport', - state: 'MI', - lat: 41.8127799, - lon: -85.43917, - }, - KISQ: { - id: 'KISQ', - city: 'Manistique, Schoolcraft County Airport', - state: 'MI', - lat: 45.97472, - lon: -86.17194, - }, - KIWD: { - id: 'KIWD', - city: 'Ironwood, Gogebic-Iron County Airport', - state: 'MI', - lat: 46.53333, - lon: -90.13333, - }, - KJXN: { - id: 'KJXN', - city: 'Jackson County Airport - Reynolds Field', - state: 'MI', - lat: 42.26171, - lon: -84.46147, - }, - KJYM: { - id: 'KJYM', - city: 'Hillsdale Municipal Airport', - state: 'MI', - lat: 41.91972, - lon: -84.58528, - }, - KLAN: { - id: 'KLAN', - city: 'Capital Region International Airport', - state: 'MI', - lat: 42.77616, - lon: -84.5997, - }, - KLDM: { - id: 'KLDM', - city: 'Ludington, Mason County Airport', - state: 'MI', - lat: 43.96667, - lon: -86.4, - }, - KLWA: { - id: 'KLWA', - city: 'South Haven, South Haven Area Regional Airport', - state: 'MI', - lat: 42.35083, - lon: -86.25611, - }, - KMBL: { - id: 'KMBL', - city: 'Manistee County - Blacker Airport', - state: 'MI', - lat: 44.27142, - lon: -86.23773, - }, - KMBS: { - id: 'KMBS', - city: 'MBS International Airport', - state: 'MI', - lat: 43.5281, - lon: -84.08129, - }, - KMCD: { - id: 'KMCD', - city: 'Mackinac Island Airport', - state: 'MI', - lat: 45.86628, - lon: -84.63437, - }, - KMGN: { - id: 'KMGN', - city: 'Harbor Springs, Harbor Springs Airport', - state: 'MI', - lat: 45.42556, - lon: -84.91333, - }, - KMKG: { - id: 'KMKG', - city: 'Muskegon, Muskegon County Airport', - state: 'MI', - lat: 43.17111, - lon: -86.23667, - }, - KMNM: { - id: 'KMNM', - city: 'Menominee - Marinette Twin County Airport', - state: 'MI', - lat: 45.12628, - lon: -87.64438, - }, - KMOP: { - id: 'KMOP', - city: 'Mount Pleasant, Mount Pleasant Municipal Airport', - state: 'MI', - lat: 43.61667, - lon: -84.73333, - }, - KMTC: { - id: 'KMTC', - city: 'Selfridge Air National Guard Base', - state: 'MI', - lat: 42.60458, - lon: -82.83528, - }, - KOEB: { - id: 'KOEB', - city: 'Branch County Memorial Airport', - state: 'MI', - lat: 41.93085, - lon: -85.05429, - }, - KONZ: { - id: 'KONZ', - city: 'Detroit/Grosse Ile, Grosse Ile Airport', - state: 'MI', - lat: 42.09861, - lon: -83.1611099, - }, - KOSC: { - id: 'KOSC', - city: 'Oscoda, Oscoda-Wurtsmith Airport', - state: 'MI', - lat: 44.45, - lon: -83.36667, - }, - KOZW: { - id: 'KOZW', - city: 'Howell, Livingston County Airport', - state: 'MI', - lat: 42.62944, - lon: -83.98417, - }, - KPHN: { - id: 'KPHN', - city: 'St Clair County International Airport', - state: 'MI', - lat: 42.91031, - lon: -82.53315, - }, - KPLN: { - id: 'KPLN', - city: 'Pellston Regional Airport of Emmet County', - state: 'MI', - lat: 45.56443, - lon: -84.7928699, - }, - KPTK: { - id: 'KPTK', - city: 'Pontiac, Oakland County International Airport', - state: 'MI', - lat: 42.66306, - lon: -83.41, - }, - KPZQ: { - id: 'KPZQ', - city: 'Rogers City, Presque Isle County Airport', - state: 'MI', - lat: 45.40694, - lon: -83.81278, - }, - KRMY: { - id: 'KRMY', - city: 'Brooks Field Airport', - state: 'MI', - lat: 42.25238, - lon: -84.95253, - }, - KRNP: { - id: 'KRNP', - city: 'Owosso, Owosso Community Airport', - state: 'MI', - lat: 42.99278, - lon: -84.13889, - }, - KRQB: { - id: 'KRQB', - city: 'Big Rapids, Roben-Hood Airport', - state: 'MI', - lat: 43.7224999, - lon: -85.50417, - }, - KSAW: { - id: 'KSAW', - city: 'Marquette, Sawyer International Airport', - state: 'MI', - lat: 46.35361, - lon: -87.39528, - }, - KSJX: { - id: 'KSJX', - city: 'Beaver Island, Beaver Island Airport', - state: 'MI', - lat: 45.69222, - lon: -85.56639, - }, - KSLH: { - id: 'KSLH', - city: 'Cheboygan, Cheboygan County Airport', - state: 'MI', - lat: 45.65361, - lon: -84.51917, - }, - KTEW: { - id: 'KTEW', - city: 'Mason, Mason Jewett Field Airport', - state: 'MI', - lat: 42.56583, - lon: -84.42333, - }, - KTTF: { - id: 'KTTF', - city: 'Monroe, Custer Airport', - state: 'MI', - lat: 41.94, - lon: -83.43472, - }, - KTVC: { - id: 'KTVC', - city: 'Cherry Capital Airport', - state: 'MI', - lat: 44.73898, - lon: -85.56788, - }, - KVLL: { - id: 'KVLL', - city: 'Troy, Oakland/Troy Airport', - state: 'MI', - lat: 42.54278, - lon: -83.17778, - }, - KYIP: { - id: 'KYIP', - city: 'Detroit, Willow Run Airport', - state: 'MI', - lat: 42.2366699, - lon: -83.52611, - }, - KAFP: { - id: 'KAFP', - city: 'Anson County Airport', - state: 'NC', - lat: 35.01944, - lon: -80.07836, - }, - KAKH: { - id: 'KAKH', - city: 'Gastonia Municipal Airport', - state: 'NC', - lat: 35.1968699, - lon: -81.15545, - }, - KASJ: { - id: 'KASJ', - city: 'Ahoskie, Tri-County Airport', - state: 'NC', - lat: 36.2975, - lon: -77.17083, - }, - KAVL: { - id: 'KAVL', - city: 'Asheville, Asheville Regional Airport', - state: 'NC', - lat: 35.43194, - lon: -82.5375, - }, - KBUY: { - id: 'KBUY', - city: 'Burlington Alamance Regional Airport', - state: 'NC', - lat: 36.04753, - lon: -79.47375, - }, - KCLT: { - id: 'KCLT', - city: 'Charlotte, Charlotte / Douglas International Airport', - state: 'NC', - lat: 35.21333, - lon: -80.94861, - }, - KCPC: { - id: 'KCPC', - city: 'Whiteville, Columbus County Municipal Airport', - state: 'NC', - lat: 34.27278, - lon: -78.715, - }, - KCTZ: { - id: 'KCTZ', - city: 'Sampson County Airport', - state: 'NC', - lat: 34.97522, - lon: -78.36276, - }, - KDPL: { - id: 'KDPL', - city: 'Duplin County Airport', - state: 'NC', - lat: 34.99942, - lon: -77.97995, - }, - KECG: { - id: 'KECG', - city: 'Elizabeth City C/G Regional Airport', - state: 'NC', - lat: 36.25771, - lon: -76.1716, - }, - KEDE: { - id: 'KEDE', - city: 'Edenton, Northeastern Regional Airport', - state: 'NC', - lat: 36.02778, - lon: -76.56722, - }, - KEHO: { - id: 'KEHO', - city: 'Shelby Municipal Airport', - state: 'NC', - lat: 35.2556299, - lon: -81.59858, - }, - KEQY: { - id: 'KEQY', - city: 'Monroe, Monroe Airport', - state: 'NC', - lat: 35.01694, - lon: -80.62056, - }, - KETC: { - id: 'KETC', - city: 'Tarboro-Edgecombe Airport', - state: 'NC', - lat: 35.9373, - lon: -77.54648, - }, - KEWN: { - id: 'KEWN', - city: 'New Bern, Craven County Regional Airport', - state: 'NC', - lat: 35.0675, - lon: -77.04722, - }, - KEXX: { - id: 'KEXX', - city: 'Lexington, Davidson County Airport', - state: 'NC', - lat: 35.78111, - lon: -80.30389, - }, - KEYF: { - id: 'KEYF', - city: 'Curtis L Brown Jr. Field Airport', - state: 'NC', - lat: 34.60418, - lon: -78.57902, - }, - KFAY: { - id: 'KFAY', - city: 'Fayetteville, Fayetteville Regional Airport', - state: 'NC', - lat: 34.98944, - lon: -78.88, - }, - KFBG: { - id: 'KFBG', - city: 'Fort Bragg / Simmons Army Airfield', - state: 'NC', - lat: 35.1314, - lon: -78.93158, - }, - KFFA: { - id: 'KFFA', - city: 'Kill Devil Hills, First Flight Airport', - state: 'NC', - lat: 36.01667, - lon: -75.66667, - }, - KFQD: { - id: 'KFQD', - city: 'Rutherfordton, Rutherford County-Marchman Field Airport', - state: 'NC', - lat: 35.42833, - lon: -81.935, - }, - KGEV: { - id: 'KGEV', - city: 'Jefferson - Ashe County Airport', - state: 'NC', - lat: 36.43333, - lon: -81.41667, - }, - KGSB: { - id: 'KGSB', - city: 'Seymour-Johnson Air Force Base', - state: 'NC', - lat: 35.34457, - lon: -77.94583, - }, - KGSO: { - id: 'KGSO', - city: 'Greensboro, Piedmont Triad International Airport', - state: 'NC', - lat: 36.0974999, - lon: -79.94361, - }, - KGWW: { - id: 'KGWW', - city: 'Goldsboro, Goldsboro-Wayne Municipal Airport', - state: 'NC', - lat: 35.46056, - lon: -77.965, - }, - KHBI: { - id: 'KHBI', - city: 'Asheboro, Asheboro Municipal Airport', - state: 'NC', - lat: 35.6538899, - lon: -79.895, - }, - KHFF: { - id: 'KHFF', - city: 'Mackall U. S. Army Airfield', - state: 'NC', - lat: 35.03333, - lon: -79.5, - }, - KHKY: { - id: 'KHKY', - city: 'Hickory, Hickory Regional Airport', - state: 'NC', - lat: 35.74222, - lon: -81.38222, - }, - KHNZ: { - id: 'KHNZ', - city: 'Henderson-Oxford Airport', - state: 'NC', - lat: 36.36352, - lon: -78.52889, - }, - KHRJ: { - id: 'KHRJ', - city: 'Erwin, Harnett County Airport', - state: 'NC', - lat: 35.37861, - lon: -78.73361, - }, - KHSE: { - id: 'KHSE', - city: 'Hatteras, Mitchell Field', - state: 'NC', - lat: 35.23222, - lon: -75.6225, - }, - KILM: { - id: 'KILM', - city: 'Wilmington International Airport', - state: 'NC', - lat: 34.26681, - lon: -77.89987, - }, - KINT: { - id: 'KINT', - city: 'Winston Salem, Smith Reynolds Airport', - state: 'NC', - lat: 36.13333, - lon: -80.22472, - }, - KIPJ: { - id: 'KIPJ', - city: 'Lincolnton, Lincolnton-Lincoln County Regional Airport', - state: 'NC', - lat: 35.48306, - lon: -81.16139, - }, - KISO: { - id: 'KISO', - city: 'Kinston, Kinston Regional Jetport at Stallings Field', - state: 'NC', - lat: 35.3333299, - lon: -77.61667, - }, - KIXA: { - id: 'KIXA', - city: 'Halifax-Northampton Regional Airport', - state: 'NC', - lat: 36.33, - lon: -77.635, - }, - KJNX: { - id: 'KJNX', - city: 'Smithfield, Johnston County Airport', - state: 'NC', - lat: 35.54083, - lon: -78.39028, - }, - KJQF: { - id: 'KJQF', - city: 'Concord Regional Airport', - state: 'NC', - lat: 35.3896299, - lon: -80.70735, - }, - KLHZ: { - id: 'KLHZ', - city: 'Franklin County Airport', - state: 'NC', - lat: 36.02288, - lon: -78.33405, - }, - KMEB: { - id: 'KMEB', - city: 'Laurinburg Maxton Airport', - state: 'NC', - lat: 34.79132, - lon: -79.3683, - }, - KMQI: { - id: 'KMQI', - city: 'Manteo / Dare County Regional', - state: 'NC', - lat: 35.91667, - lon: -75.7, - }, - KMRH: { - id: 'KMRH', - city: 'Beaufort Smith Field', - state: 'NC', - lat: 34.73259, - lon: -76.6566, - }, - KMRN: { - id: 'KMRN', - city: 'Morganton-Lenoir Airport', - state: 'NC', - lat: 35.81922, - lon: -81.60971, - }, - KMWK: { - id: 'KMWK', - city: 'Mount Airy/Surry County Airport', - state: 'NC', - lat: 36.45675, - lon: -80.55483, - }, - KNBT: { - id: 'KNBT', - city: 'Piney Island, Bt-11 Bombing Range', - state: 'NC', - lat: 35.02222, - lon: -76.4625, - }, - KNCA: { - id: 'KNCA', - city: 'MCAS New River', - state: 'NC', - lat: 34.70627, - lon: -77.44066, - }, - KNJM: { - id: 'KNJM', - city: 'Bogue Field Marine Corps Auxiliary Field', - state: 'NC', - lat: 34.69403, - lon: -77.02945, - }, - KNKT: { - id: 'KNKT', - city: 'Cherry Point Marine Corps Air Station', - state: 'NC', - lat: 34.89719, - lon: -76.88135, - }, - KOAJ: { - id: 'KOAJ', - city: 'Jacksonville, Albert J Ellis Airport', - state: 'NC', - lat: 34.8333299, - lon: -77.61667, - }, - KOCW: { - id: 'KOCW', - city: 'Washington, Warren Field Airport', - state: 'NC', - lat: 35.57056, - lon: -77.0497199, - }, - KONX: { - id: 'KONX', - city: 'Currituck, Currituck County Airport', - state: 'NC', - lat: 36.39889, - lon: -76.01611, - }, - KPGV: { - id: 'KPGV', - city: 'Pitt-Greenville Airport', - state: 'NC', - lat: 35.63742, - lon: -77.38506, - }, - KPOB: { - id: 'KPOB', - city: 'Pope Air Force Base', - state: 'NC', - lat: 35.17531, - lon: -79.00771, - }, - KRCZ: { - id: 'KRCZ', - city: 'Rockingham-Hamlet Airport', - state: 'NC', - lat: 34.8954499, - lon: -79.75755, - }, - KRDU: { - id: 'KRDU', - city: 'Raleigh / Durham, Raleigh-Durham International Airport', - state: 'NC', - lat: 35.89223, - lon: -78.78185, - }, - KRHP: { - id: 'KRHP', - city: 'Andrews-Murphy Airport', - state: 'NC', - lat: 35.19394, - lon: -83.86182, - }, - KRUQ: { - id: 'KRUQ', - city: 'Rowan County Airport', - state: 'NC', - lat: 35.64417, - lon: -80.52359, - }, - KRWI: { - id: 'KRWI', - city: 'Rocky Mount, Rocky Mount-Wilson Regional Airport', - state: 'NC', - lat: 35.8549999, - lon: -77.89306, - }, - KSCR: { - id: 'KSCR', - city: 'Siler City Municipal Airport', - state: 'NC', - lat: 35.7043, - lon: -79.5043, - }, - KSIF: { - id: 'KSIF', - city: 'Reidsville, Rockingham County NC Shiloh Airport', - state: 'NC', - lat: 36.43722, - lon: -79.85083, - }, - KSOP: { - id: 'KSOP', - city: 'Pinehurst/Southern Pines, Moore County Airport', - state: 'NC', - lat: 35.23333, - lon: -79.4, - }, - KSUT: { - id: 'KSUT', - city: 'Brunswick County Airport', - state: 'NC', - lat: 33.92921, - lon: -78.07223, - }, - KSVH: { - id: 'KSVH', - city: 'Statesville Municipal Airport', - state: 'NC', - lat: 35.76362, - lon: -80.9473, - }, - KTDF: { - id: 'KTDF', - city: 'Roxboro, Person County Airport', - state: 'NC', - lat: 36.2849999, - lon: -78.98417, - }, - KTNB: { - id: 'KTNB', - city: 'Watauga County Hospital Heliport', - state: 'NC', - lat: 36.19856, - lon: -81.65171, - }, - KTTA: { - id: 'KTTA', - city: 'Sanford, Sanford-Lee County Regional Airport', - state: 'NC', - lat: 35.5825, - lon: -79.10139, - }, - KUKF: { - id: 'KUKF', - city: 'North Wilkesboro, Wilkes County Airport', - state: 'NC', - lat: 36.21667, - lon: -81.08333, - }, - KVUJ: { - id: 'KVUJ', - city: 'Albemarle, Stanly County Airport', - state: 'NC', - lat: 35.41667, - lon: -80.15083, - }, - KAKR: { - id: 'KAKR', - city: 'Akron, Akron Fulton International Airport', - state: 'OH', - lat: 41.0375, - lon: -81.46417, - }, - KAOH: { - id: 'KAOH', - city: 'Lima, Lima Allen County Airport', - state: 'OH', - lat: 40.70806, - lon: -84.02139, - }, - KAXV: { - id: 'KAXV', - city: 'Neil Armstrong Airport', - state: 'OH', - lat: 40.49356, - lon: -84.29808, - }, - KBJJ: { - id: 'KBJJ', - city: 'Wooster, Wayne County Airport', - state: 'OH', - lat: 40.87306, - lon: -81.88667, - }, - KBKL: { - id: 'KBKL', - city: 'Cleveland, Burke Lakefront Airport', - state: 'OH', - lat: 41.52556, - lon: -81.66889, - }, - KCAK: { - id: 'KCAK', - city: 'Akron Canton Regional Airport', - state: 'OH', - lat: 40.91811, - lon: -81.44343, - }, - KCDI: { - id: 'KCDI', - city: 'Cambridge Municipal Airport', - state: 'OH', - lat: 39.975, - lon: -81.5776, - }, - KCGF: { - id: 'KCGF', - city: 'Cleveland / Cuyahoga', - state: 'OH', - lat: 41.56667, - lon: -81.48333, - }, - KCLE: { - id: 'KCLE', - city: 'Cleveland Hopkins International Airport', - state: 'OH', - lat: 41.40569, - lon: -81.85193, - }, - KCMH: { - id: 'KCMH', - city: 'John Glenn Columbus International Airport', - state: 'OH', - lat: 39.9906999, - lon: -82.87691, - }, - KDAY: { - id: 'KDAY', - city: 'Dayton, Cox Dayton International Airport', - state: 'OH', - lat: 39.90611, - lon: -84.21861, - }, - KDFI: { - id: 'KDFI', - city: 'Defiance, Defiance Memorial Airport', - state: 'OH', - lat: 41.33639, - lon: -84.42944, - }, - KDLZ: { - id: 'KDLZ', - city: 'Delaware Municipal Airport', - state: 'OH', - lat: 40.2797, - lon: -83.1148, - }, - KEDJ: { - id: 'KEDJ', - city: 'Bellefontaine Regional Airport', - state: 'OH', - lat: 40.3723, - lon: -83.8192, - }, - KFDY: { - id: 'KFDY', - city: 'Findlay, Findlay Airport', - state: 'OH', - lat: 41.01361, - lon: -83.66861, - }, - KFFO: { - id: 'KFFO', - city: 'Dayton / Wright-Patterson Air Force Base', - state: 'OH', - lat: 39.8333299, - lon: -84.05, - }, - KHAO: { - id: 'KHAO', - city: 'Butler County Regional Airport', - state: 'OH', - lat: 39.36121, - lon: -84.52061, - }, - KHZY: { - id: 'KHZY', - city: 'Ashtabula - Northeast Ohio Regional Airport', - state: 'OH', - lat: 41.77944, - lon: -80.69667, - }, - KILN: { - id: 'KILN', - city: 'Wilmington, Airborne Airpark Airport', - state: 'OH', - lat: 39.42833, - lon: -83.7791699, - }, - KLCK: { - id: 'KLCK', - city: 'Rickenbacker Air National Guard Base', - state: 'OH', - lat: 39.81667, - lon: -82.93333, - }, - KLHQ: { - id: 'KLHQ', - city: 'Lancaster, Fairfield County Airport', - state: 'OH', - lat: 39.7572199, - lon: -82.66333, - }, - KLNN: { - id: 'KLNN', - city: 'Willoughby', - state: 'OH', - lat: 41.68333, - lon: -81.38333, - }, - KLPR: { - id: 'KLPR', - city: 'Lorain / Elyria, Lorain County Regional Airport', - state: 'OH', - lat: 41.34611, - lon: -82.17944, - }, - KLUK: { - id: 'KLUK', - city: 'Cincinnati, Cincinnati Municipal Airport Lunken Field', - state: 'OH', - lat: 39.10583, - lon: -84.41583, - }, - KMFD: { - id: 'KMFD', - city: 'Mansfield - Mansfield Lahm Regional Airport', - state: 'OH', - lat: 40.8202799, - lon: -82.51778, - }, - KMGY: { - id: 'KMGY', - city: 'Dayton, Dayton-Wright Brothers Airport', - state: 'OH', - lat: 39.58889, - lon: -84.22472, - }, - KMNN: { - id: 'KMNN', - city: 'Marion, Marion Municipal Airport', - state: 'OH', - lat: 40.61667, - lon: -83.06833, - }, - KMRT: { - id: 'KMRT', - city: 'Marysville Union County Airport', - state: 'OH', - lat: 40.2247, - lon: -83.3516, - }, - KMWO: { - id: 'KMWO', - city: 'Hook Field Municipal Airport', - state: 'OH', - lat: 39.531, - lon: -84.3953, - }, - KOSU: { - id: 'KOSU', - city: 'Columbus, Ohio State University Airport', - state: 'OH', - lat: 40.07806, - lon: -83.0780599, - }, - KOWX: { - id: 'KOWX', - city: 'Ottawa Putnam County Airport', - state: 'OH', - lat: 41.0356, - lon: -83.982, - }, - KPCW: { - id: 'KPCW', - city: 'Port Clinton Carl R Keller Field Airport', - state: 'OH', - lat: 41.5163, - lon: -82.8687, - }, - KPHD: { - id: 'KPHD', - city: 'New Philadelphia, Harry Clever Field', - state: 'OH', - lat: 40.4719399, - lon: -81.42361, - }, - KPMH: { - id: 'KPMH', - city: 'Greater Portsmouth Regional Airport', - state: 'OH', - lat: 38.84047, - lon: -82.8473099, - }, - KPOV: { - id: 'KPOV', - city: 'Portage County Airport', - state: 'OH', - lat: 41.21, - lon: -81.252, - }, - KRZT: { - id: 'KRZT', - city: 'Chillicothe Ross County Airport', - state: 'OH', - lat: 39.4403999, - lon: -83.0231, - }, - KSGH: { - id: 'KSGH', - city: 'Springfield, Springfield-Beckley Municipal Airport', - state: 'OH', - lat: 39.84028, - lon: -83.84, - }, - KTDZ: { - id: 'KTDZ', - city: 'Toledo - Toledo Executive Airport', - state: 'OH', - lat: 41.56306, - lon: -83.47639, - }, - KTOL: { - id: 'KTOL', - city: 'Toledo - Toledo Express Airport', - state: 'OH', - lat: 41.58704, - lon: -83.80539, - }, - KTZR: { - id: 'KTZR', - city: 'Columbus, Bolton Field Airport', - state: 'OH', - lat: 39.90083, - lon: -83.13722, - }, - KUNI: { - id: 'KUNI', - city: 'OHIO U/ATHEN-ALBANY', - state: 'OH', - lat: 39.22, - lon: -82.23, - }, - KUSE: { - id: 'KUSE', - city: 'Wauseon Fulton County Airport', - state: 'OH', - lat: 41.6101, - lon: -84.1272, - }, - KUYF: { - id: 'KUYF', - city: 'London Madison County Airport', - state: 'OH', - lat: 39.9326999, - lon: -83.462, - }, - KVES: { - id: 'KVES', - city: 'Versailles Darke County Airport', - state: 'OH', - lat: 40.2044, - lon: -84.5318999, - }, - KVNW: { - id: 'KVNW', - city: 'Van Wert County Airport', - state: 'OH', - lat: 40.86383, - lon: -84.60636, - }, - KVTA: { - id: 'KVTA', - city: 'Newark, Newark Heath Airport', - state: 'OH', - lat: 40.02278, - lon: -82.4625, - }, - KYNG: { - id: 'KYNG', - city: 'Youngstown, Youngstown-Warren Regional Airport', - state: 'OH', - lat: 41.25444, - lon: -80.67389, - }, - KZZV: { - id: 'KZZV', - city: 'Zanesville, Zanesville Municipal Airport', - state: 'OH', - lat: 39.94444, - lon: -81.89222, - }, - KAST: { - id: 'KAST', - city: 'Astoria, Astoria Regional Airport', - state: 'OR', - lat: 46.15694, - lon: -123.8825, - }, - KBDN: { - id: 'KBDN', - city: 'Bend Airport AWOS', - state: 'OR', - lat: 44.0948, - lon: -121.2006, - }, - KBKE: { - id: 'KBKE', - city: 'Baker Municipal Airport', - state: 'OR', - lat: 44.84302, - lon: -117.80987, - }, - KBNO: { - id: 'KBNO', - city: 'Burns Municipal Airport', - state: 'OR', - lat: 43.59488, - lon: -118.95791, - }, - KBOK: { - id: 'KBOK', - city: 'Brookings, Brookings Airport', - state: 'OR', - lat: 42.07444, - lon: -124.29, - }, - KCVO: { - id: 'KCVO', - city: 'Corvallis, Corvallis Municipal Airport', - state: 'OR', - lat: 44.5, - lon: -123.28333, - }, - KEUG: { - id: 'KEUG', - city: 'Eugene, Mahlon Sweet Field', - state: 'OR', - lat: 44.13333, - lon: -123.21444, - }, - KGCD: { - id: 'KGCD', - city: 'Grant County Regional Airport', - state: 'OR', - lat: 44.40287, - lon: -118.96715, - }, - KHIO: { - id: 'KHIO', - city: 'Portland-Hillsboro Airport', - state: 'OR', - lat: 45.54765, - lon: -122.95568, - }, - KHRI: { - id: 'KHRI', - city: 'Hermiston, Hermiston Municipal Airport', - state: 'OR', - lat: 45.82583, - lon: -119.26111, - }, - KABE: { - id: 'KABE', - city: 'Allentown, Lehigh Valley International Airport', - state: 'PA', - lat: 40.64985, - lon: -75.44771, - }, - KAFJ: { - id: 'KAFJ', - city: 'Washington - Washington County Airport', - state: 'PA', - lat: 40.13333, - lon: -80.28333, - }, - KAGC: { - id: 'KAGC', - city: 'Pittsburgh - Allegheny County Airport', - state: 'PA', - lat: 40.35521, - lon: -79.92144, - }, - KAOO: { - id: 'KAOO', - city: 'Altoona - Blair County Airport', - state: 'PA', - lat: 40.29994, - lon: -78.3168, - }, - KAVP: { - id: 'KAVP', - city: 'Wilkes-Barre - Scranton, Wilkes-Barre / Scranton International Airport', - state: 'PA', - lat: 41.33889, - lon: -75.72667, - }, - KBFD: { - id: 'KBFD', - city: 'Bradford Regional Airport', - state: 'PA', - lat: 41.79838, - lon: -78.63539, - }, - KBTP: { - id: 'KBTP', - city: 'Butler, Butler County Airport/K W Scholter Field', - state: 'PA', - lat: 40.78333, - lon: -79.95, - }, - KBVI: { - id: 'KBVI', - city: 'Beaver County Airport', - state: 'PA', - lat: 40.77351, - lon: -80.38248, - }, - KCKZ: { - id: 'KCKZ', - city: 'Pennridge Airport', - state: 'PA', - lat: 40.38919, - lon: -75.29047, - }, - KCXY: { - id: 'KCXY', - city: 'Harrisburg, Capital City Airport', - state: 'PA', - lat: 40.21843, - lon: -76.8552, - }, - KDUJ: { - id: 'KDUJ', - city: 'Du Bois - Jefferson County Airport', - state: 'PA', - lat: 41.17948, - lon: -78.89326, - }, - KDYL: { - id: 'KDYL', - city: 'Doylestown, Doylestown Airport', - state: 'PA', - lat: 40.33016, - lon: -75.12286, - }, - KERI: { - id: 'KERI', - city: 'Erie, Erie International Airport', - state: 'PA', - lat: 42.08, - lon: -80.1825, - }, - KFIG: { - id: 'KFIG', - city: 'Clearfield, Clearfield-Lawrence Airport', - state: 'PA', - lat: 41.04667, - lon: -78.41167, - }, - KFKL: { - id: 'KFKL', - city: 'Franklin, Venango Regional Airport', - state: 'PA', - lat: 41.38333, - lon: -79.86667, - }, - KGKJ: { - id: 'KGKJ', - city: 'Port Meadville Airport', - state: 'PA', - lat: 41.6258399, - lon: -80.21231, - }, - KHMZ: { - id: 'KHMZ', - city: 'Bedford, Bedford County Airport', - state: 'PA', - lat: 40.08528, - lon: -78.51222, - }, - KHZL: { - id: 'KHZL', - city: 'Hazleton Municipal Airport', - state: 'PA', - lat: 40.98447, - lon: -75.99005, - }, - KIDI: { - id: 'KIDI', - city: 'Indiana / Stewart Field', - state: 'PA', - lat: 40.63333, - lon: -79.1, - }, - KIPT: { - id: 'KIPT', - city: 'Williamsport - Lycoming County Airport', - state: 'PA', - lat: 41.24298, - lon: -76.92173, - }, - KJST: { - id: 'KJST', - city: 'Johnstown - Cambria County Airport', - state: 'PA', - lat: 40.3149, - lon: -78.83074, - }, - KLBE: { - id: 'KLBE', - city: 'Latrobe / Westmoreland', - state: 'PA', - lat: 40.2731, - lon: -79.41033, - }, - KLNS: { - id: 'KLNS', - city: 'Lancaster, Lancaster Airport', - state: 'PA', - lat: 40.1205799, - lon: -76.29446, - }, - KLOM: { - id: 'KLOM', - city: 'Philadelphia - Wings Field Airport', - state: 'PA', - lat: 40.13758, - lon: -75.2684, - }, - KMDT: { - id: 'KMDT', - city: 'Harrisburg, Harrisburg International Airport', - state: 'PA', - lat: 40.19361, - lon: -76.76333, - }, - KMPO: { - id: 'KMPO', - city: 'Mount Pocono, Pocono Mountains Municipal Airport', - state: 'PA', - lat: 41.13821, - lon: -75.37971, - }, - KMQS: { - id: 'KMQS', - city: 'Chester County Airport', - state: 'PA', - lat: 39.98333, - lon: -75.86667, - }, - KMUI: { - id: 'KMUI', - city: 'Muir Army Air Field / Indiantown', - state: 'PA', - lat: 40.43808, - lon: -76.56434, - }, - KOQN: { - id: 'KOQN', - city: 'Brandywine Regional Airport', - state: 'PA', - lat: 39.99011, - lon: -75.5819, - }, - KOYM: { - id: 'KOYM', - city: 'St Marys Municipal Airport', - state: 'PA', - lat: 41.41248, - lon: -78.50263, - }, - KPHL: { - id: 'KPHL', - city: 'Philadelphia, Philadelphia International Airport', - state: 'PA', - lat: 39.87327, - lon: -75.22678, - }, - KPIT: { - id: 'KPIT', - city: 'Pittsburgh, Pittsburgh International Airport', - state: 'PA', - lat: 40.50389, - lon: -80.26639, - }, - KPJC: { - id: 'KPJC', - city: 'Zelienople Municipal Airport', - state: 'PA', - lat: 40.80197, - lon: -80.16086, - }, - KPNE: { - id: 'KPNE', - city: 'Philadelphia, Northeast Philadelphia Airport', - state: 'PA', - lat: 40.07889, - lon: -75.01361, - }, - KPTW: { - id: 'KPTW', - city: 'Pottstown, Pottstown Limerick Airport', - state: 'PA', - lat: 40.23802, - lon: -75.5548699, - }, - KRDG: { - id: 'KRDG', - city: 'Reading, Reading Regional Airport', - state: 'PA', - lat: 40.37333, - lon: -75.95944, - }, - KRVL: { - id: 'KRVL', - city: 'Reedsville / Mifflin', - state: 'PA', - lat: 40.68333, - lon: -77.63333, - }, - KSEG: { - id: 'KSEG', - city: 'Selinsgrove Penn Valley Airport', - state: 'PA', - lat: 40.81929, - lon: -76.86582, - }, - KTHV: { - id: 'KTHV', - city: 'York, York Airport', - state: 'PA', - lat: 39.91944, - lon: -76.87694, - }, - KUCP: { - id: 'KUCP', - city: 'New Castle, New Castle Municipal Airport', - state: 'PA', - lat: 41.02528, - lon: -80.41333, - }, - KUKT: { - id: 'KUKT', - city: 'Quakertown Airport', - state: 'PA', - lat: 40.4368, - lon: -75.38016, - }, - KUNV: { - id: 'KUNV', - city: 'State College - University Park Airport', - state: 'PA', - lat: 40.85344, - lon: -77.8401, - }, - KVVS: { - id: 'KVVS', - city: 'Joseph A Hardy Connellsville Airport', - state: 'PA', - lat: 39.95906, - lon: -79.65742, - }, - KXLL: { - id: 'KXLL', - city: 'Allentown Queen City Municipal Airport', - state: 'PA', - lat: 40.57, - lon: -75.488, - }, - KALB: { - id: 'KALB', - city: 'Albany International Airport', - state: 'NY', - lat: 42.74722, - lon: -73.79912, - }, - KART: { - id: 'KART', - city: 'Watertown, Watertown International Airport', - state: 'NY', - lat: 43.99194, - lon: -76.02167, - }, - KBGM: { - id: 'KBGM', - city: 'Binghamton, Binghamton Regional Airport', - state: 'NY', - lat: 42.20778, - lon: -75.98139, - }, - KBUF: { - id: 'KBUF', - city: 'Buffalo, Greater Buffalo International Airport', - state: 'NY', - lat: 42.93998, - lon: -78.73604, - }, - KDKK: { - id: 'KDKK', - city: 'Dunkirk, Chautauqua County / Dunkirk Airport', - state: 'NY', - lat: 42.49306, - lon: -79.27583, - }, - KDSV: { - id: 'KDSV', - city: 'Dansville, Dansville Municipal Airport', - state: 'NY', - lat: 42.56944, - lon: -77.71444, - }, - KELM: { - id: 'KELM', - city: 'Elmira, Elmira / Corning Regional Airport', - state: 'NY', - lat: 42.15639, - lon: -76.90278, - }, - KELZ: { - id: 'KELZ', - city: 'Wellsville, Wellsville Municipal Airport', - state: 'NY', - lat: 42.1075, - lon: -77.98444, - }, - KFOK: { - id: 'KFOK', - city: 'The Gabreski Airport', - state: 'NY', - lat: 40.85053, - lon: -72.61927, - }, - KFRG: { - id: 'KFRG', - city: 'Farmingdale - Republic Airport', - state: 'NY', - lat: 40.73443, - lon: -73.41639, - }, - KFZY: { - id: 'KFZY', - city: 'Fulton, Oswego County Airport', - state: 'NY', - lat: 43.35083, - lon: -76.38806, - }, - KGFL: { - id: 'KGFL', - city: 'Glens Falls, Floyd Bennett Memorial Airport', - state: 'NY', - lat: 43.34111, - lon: -73.61056, - }, - KGTB: { - id: 'KGTB', - city: 'Fort Drum / Wheeler-Sack U. S. Army Airfield', - state: 'NY', - lat: 44.05, - lon: -75.73333, - }, - KGVQ: { - id: 'KGVQ', - city: 'Genesee County Airport', - state: 'NY', - lat: 43.03175, - lon: -78.16967, - }, - KHPN: { - id: 'KHPN', - city: 'White Plains - Westchester County Airport', - state: 'NY', - lat: 41.06237, - lon: -73.70456, - }, - KHTO: { - id: 'KHTO', - city: 'East Hampton, East Hampton Airport', - state: 'NY', - lat: 40.95944, - lon: -72.25194, - }, - KHWV: { - id: 'KHWV', - city: 'Shirley, Brookhaven Airport', - state: 'NY', - lat: 40.82167, - lon: -72.8688899, - }, - KIAG: { - id: 'KIAG', - city: 'Niagara Falls, Niagara Falls International Airport', - state: 'NY', - lat: 43.1082899, - lon: -78.93818, - }, - KISP: { - id: 'KISP', - city: 'Islip, Long Island Mac Arthur Airport', - state: 'NY', - lat: 40.79389, - lon: -73.10167, - }, - KITH: { - id: 'KITH', - city: 'Ithaca, Ithaca Tompkins Regional Airport', - state: 'NY', - lat: 42.49083, - lon: -76.45833, - }, - KJFK: { - id: 'KJFK', - city: 'New York, Kennedy International Airport', - state: 'NY', - lat: 40.63915, - lon: -73.76393, - }, - KJHW: { - id: 'KJHW', - city: 'Jamestown, Chautauqua County/Jamestown Airport', - state: 'NY', - lat: 42.15, - lon: -79.26667, - }, - KJRB: { - id: 'KJRB', - city: 'New York Downtown Manhattan', - state: 'NY', - lat: 40.7012, - lon: -74.009, - }, - KLGA: { - id: 'KLGA', - city: 'New York, La Guardia Airport', - state: 'NY', - lat: 40.77917, - lon: -73.88, - }, - KMGJ: { - id: 'KMGJ', - city: 'Montgomery, Orange County Airport', - state: 'NY', - lat: 41.50917, - lon: -74.265, - }, - KMSS: { - id: 'KMSS', - city: 'Massena, Massena International-Richards Field', - state: 'NY', - lat: 44.93583, - lon: -74.84556, - }, - KMSV: { - id: 'KMSV', - city: 'Monticello, Sullivan County International Airport', - state: 'NY', - lat: 41.7, - lon: -74.8, - }, - KMTP: { - id: 'KMTP', - city: 'Montauk, Montauk Airport', - state: 'NY', - lat: 41.07306, - lon: -71.92333, - }, - KNYC: { - id: 'KNYC', - city: 'New York City, Central Park', - state: 'NY', - lat: 40.78333, - lon: -73.9666699, - }, - KOGS: { - id: 'KOGS', - city: 'Ogdensburg International Airport', - state: 'NY', - lat: 44.68186, - lon: -75.4655, - }, - KOLE: { - id: 'KOLE', - city: 'Cattaraugus County-Olean Airport', - state: 'NY', - lat: 42.24119, - lon: -78.37136, - }, - KPBG: { - id: 'KPBG', - city: 'Plattsburgh International Airport ', - state: 'NY', - lat: 44.65, - lon: -73.4666699, - }, - KPEO: { - id: 'KPEO', - city: 'Penn Yan, Penn Yan Airport', - state: 'NY', - lat: 42.64306, - lon: -77.04944, - }, - KPOU: { - id: 'KPOU', - city: 'Poughkeepsie, Dutchess County Airport', - state: 'NY', - lat: 41.62667, - lon: -73.88417, - }, - KPTD: { - id: 'KPTD', - city: 'Potsdam Municipal Airport/Damon Field', - state: 'NY', - lat: 44.67667, - lon: -74.94844, - }, - KRME: { - id: 'KRME', - city: 'Griffiss Air Force Base / Rome', - state: 'NY', - lat: 43.23333, - lon: -75.4, - }, - KROC: { - id: 'KROC', - city: 'Rochester, Greater Rochester International Airport', - state: 'NY', - lat: 43.11667, - lon: -77.67667, - }, - KSCH: { - id: 'KSCH', - city: 'Schenectady Airport', - state: 'NY', - lat: 42.85, - lon: -73.93333, - }, - KSDC: { - id: 'KSDC', - city: 'Williamson-Sodus Airport', - state: 'NY', - lat: 43.23459, - lon: -77.11946, - }, - KSLK: { - id: 'KSLK', - city: 'Saranac Lake, Adirondack Regional Airport', - state: 'NY', - lat: 44.39306, - lon: -74.20278, - }, - KSWF: { - id: 'KSWF', - city: 'Newburgh / Stewart', - state: 'NY', - lat: 41.5, - lon: -74.1, - }, - KSYR: { - id: 'KSYR', - city: 'Syracuse, Syracuse Hancock International Airport', - state: 'NY', - lat: 43.10917, - lon: -76.10333, - }, - KVGC: { - id: 'KVGC', - city: 'Hamilton Municipal Airport', - state: 'NY', - lat: 42.84344, - lon: -75.56119, - }, - KGLY: { - id: 'KGLY', - city: 'Clinton, MO', - state: 'MO', - lat: 38.3566, - lon: -93.6842, - }, - KGPH: { - id: 'KGPH', - city: 'Mosby Midwest National Air Center Airport', - state: 'MO', - lat: 39.3325, - lon: -94.3096, - }, - KHAE: { - id: 'KHAE', - city: 'Hannibal Regional Airport', - state: 'MO', - lat: 39.7252, - lon: -91.4439, - }, - KHFJ: { - id: 'KHFJ', - city: 'Monett', - state: 'MO', - lat: 36.9062, - lon: -94.0128, - }, - KIRK: { - id: 'KIRK', - city: 'Kirksville, Kirksville Regional Airport', - state: 'MO', - lat: 40.09722, - lon: -92.54333, - }, - KJEF: { - id: 'KJEF', - city: 'Jefferson City, Jefferson City Memorial Airport', - state: 'MO', - lat: 38.59444, - lon: -92.15583, - }, - KJLN: { - id: 'KJLN', - city: 'Joplin, Joplin Regional Airport', - state: 'MO', - lat: 37.15611, - lon: -94.5005599, - }, - KLBO: { - id: 'KLBO', - city: 'LEBANON', - state: 'MO', - lat: 37.64833, - lon: -92.6525, - }, - KLRY: { - id: 'KLRY', - city: 'Harrisonville Lawrence Smith Memorial Airport', - state: 'MO', - lat: 38.611, - lon: -94.3421, - }, - KLXT: { - id: 'KLXT', - city: "Lee's Summit, Lee's Summit Municipal Airport", - state: 'MO', - lat: 38.95972, - lon: -94.37167, - }, - KMAW: { - id: 'KMAW', - city: 'Malden Municipal Airport', - state: 'MO', - lat: 36.6004999, - lon: -89.9922, - }, - KMBY: { - id: 'KMBY', - city: 'Omar N Bradley Airport', - state: 'MO', - lat: 39.46341, - lon: -92.42638, - }, - KMCI: { - id: 'KMCI', - city: 'Kansas City, Kansas City International Airport', - state: 'MO', - lat: 39.29722, - lon: -94.73056, - }, - KMHL: { - id: 'KMHL', - city: 'Marshall Memorial Municipal Airport', - state: 'MO', - lat: 39.0955, - lon: -93.2028, - }, - KMKC: { - id: 'KMKC', - city: 'Kansas City, Kansas City Downtown Airport', - state: 'MO', - lat: 39.12083, - lon: -94.59694, - }, - KMYJ: { - id: 'KMYJ', - city: 'Mexico Memorial Airport', - state: 'MO', - lat: 39.1575, - lon: -91.8182999, - }, - KOZS: { - id: 'KOZS', - city: 'Camdenton Memorial Airport', - state: 'MO', - lat: 37.9739999, - lon: -92.6912, - }, - KPCD: { - id: 'KPCD', - city: 'Perryville Regional Airport', - state: 'MO', - lat: 37.86867, - lon: -89.86214, - }, - KPOF: { - id: 'KPOF', - city: 'Poplar Bluff, Poplar Bluff Municipal Airport', - state: 'MO', - lat: 36.77056, - lon: -90.32222, - }, - KRAW: { - id: 'KRAW', - city: 'Warsaw Municipal Airport', - state: 'MO', - lat: 38.3469, - lon: -93.3454, - }, - KRCM: { - id: 'KRCM', - city: 'Skyhaven Airport', - state: 'MO', - lat: 38.7842, - lon: -93.8028999, - }, - KSET: { - id: 'KSET', - city: 'St. Charles, St. Charles County Smartt Airport', - state: 'MO', - lat: 38.93056, - lon: -90.4325, - }, - KSGF: { - id: 'KSGF', - city: 'Springfield, Springfield Regional Airport', - state: 'MO', - lat: 37.23972, - lon: -93.38972, - }, - KSIK: { - id: 'KSIK', - city: 'Sikeston Memorial Municipal Airport', - state: 'MO', - lat: 36.8989, - lon: -89.5618, - }, - KSTJ: { - id: 'KSTJ', - city: 'St. Joseph, Rosecrans Memorial Airport', - state: 'MO', - lat: 39.76806, - lon: -94.90917, - }, - KSTL: { - id: 'KSTL', - city: 'St. Louis Lambert International Airport', - state: 'MO', - lat: 38.7525, - lon: -90.37361, - }, - KSUS: { - id: 'KSUS', - city: 'St. Louis, Spirit Of St. Louis Airport', - state: 'MO', - lat: 38.65722, - lon: -90.65583, - }, - KSZL: { - id: 'KSZL', - city: 'Whiteman Air Force Base', - state: 'MO', - lat: 38.73333, - lon: -93.55, - }, - KTBN: { - id: 'KTBN', - city: 'Fort Leonard Wood', - state: 'MO', - lat: 37.73333, - lon: -92.13333, - }, - KTKX: { - id: 'KTKX', - city: 'Kennett - Kennett Memorial Airport', - state: 'MO', - lat: 36.22256, - lon: -90.03671, - }, - KUNO: { - id: 'KUNO', - city: 'West Plains, West Plains Municipal Airport', - state: 'MO', - lat: 36.87917, - lon: -91.905, - }, - KVER: { - id: 'KVER', - city: 'Jesse Viertel Memorial Airport', - state: 'MO', - lat: 38.94672, - lon: -92.68267, - }, - KVIH: { - id: 'KVIH', - city: 'Rolla / Vichy, Rolla National Airport', - state: 'MO', - lat: 38.13194, - lon: -91.76528, - }, - KABY: { - id: 'KABY', - city: 'Southwest Georgia Regional Airport', - state: 'GA', - lat: 31.53652, - lon: -84.19571, - }, - KACJ: { - id: 'KACJ', - city: 'Americus Souther Field Airport', - state: 'GA', - lat: 32.11081, - lon: -84.18886, - }, - KAGS: { - id: 'KAGS', - city: 'Augusta, Bush Field', - state: 'GA', - lat: 33.36444, - lon: -81.96333, - }, - KAHN: { - id: 'KAHN', - city: 'Athens, Athens Airport', - state: 'GA', - lat: 33.95083, - lon: -83.3280599, - }, - KAJR: { - id: 'KAJR', - city: 'Cornelia Habersham County Airport', - state: 'GA', - lat: 34.4998, - lon: -83.5567, - }, - KAMG: { - id: 'KAMG', - city: 'Alma, Bacon County Airport', - state: 'GA', - lat: 31.53611, - lon: -82.50667, - }, - KATL: { - id: 'KATL', - city: 'Atlanta, Hartsfield - Jackson Atlanta International Airport', - state: 'GA', - lat: 33.64028, - lon: -84.42694, - }, - KAYS: { - id: 'KAYS', - city: 'Waycross / Ware County, Ga', - state: 'GA', - lat: 31.25, - lon: -82.4, - }, - KAZE: { - id: 'KAZE', - city: 'Hazlehurst Airport', - state: 'GA', - lat: 31.8847, - lon: -82.6474, - }, - KBGE: { - id: 'KBGE', - city: 'Bainbridge, Decatur County Industrial Air Park Airport', - state: 'GA', - lat: 30.96667, - lon: -84.63333, - }, - KBHC: { - id: 'KBHC', - city: 'Baxley Municipal Airport', - state: 'GA', - lat: 31.7138, - lon: -82.3938, - }, - KBIJ: { - id: 'KBIJ', - city: 'Blakely, Early County Airport', - state: 'GA', - lat: 31.39694, - lon: -84.895, - }, - KBQK: { - id: 'KBQK', - city: 'Brunswick / Glynco', - state: 'GA', - lat: 31.25, - lon: -81.4666699, - }, - KCCO: { - id: 'KCCO', - city: 'Newnan, Newnan Coweta County Airport', - state: 'GA', - lat: 33.31222, - lon: -84.77028, - }, - KCKF: { - id: 'KCKF', - city: 'Cordele Crisp County Airport', - state: 'GA', - lat: 31.9888, - lon: -83.7739, - }, - KCNI: { - id: 'KCNI', - city: 'Canton, Cherokee County Airport', - state: 'GA', - lat: 34.31056, - lon: -84.42389, - }, - KCSG: { - id: 'KCSG', - city: 'Columbus, Columbus Metropolitan Airport', - state: 'GA', - lat: 32.51611, - lon: -84.94222, - }, - KCTJ: { - id: 'KCTJ', - city: 'Carrollton West Georgia Regional Airport', - state: 'GA', - lat: 33.63, - lon: -85.15, - }, - KCVC: { - id: 'KCVC', - city: 'Covington Municipal Airport', - state: 'GA', - lat: 33.632, - lon: -83.85, - }, - KCWV: { - id: 'KCWV', - city: 'Claxton Evans County Airport', - state: 'GA', - lat: 32.1950999, - lon: -81.8696, - }, - KCXU: { - id: 'KCXU', - city: 'Camilla-Mitchell County Airport', - state: 'GA', - lat: 31.2132, - lon: -84.2352, - }, - KCZL: { - id: 'KCZL', - city: 'Calhoun Tom B. David Field Airport', - state: 'GA', - lat: 34.4554, - lon: -84.9392, - }, - KDBN: { - id: 'KDBN', - city: "Dublin, W H 'Bud' Barron Airport", - state: 'GA', - lat: 32.56444, - lon: -82.985, - }, - KDNL: { - id: 'KDNL', - city: 'Augusta Daniel Field', - state: 'GA', - lat: 33.4669, - lon: -82.03836, - }, - KDNN: { - id: 'KDNN', - city: 'Dalton, Dalton Municipal Airport', - state: 'GA', - lat: 34.72167, - lon: -84.86917, - }, - KDQH: { - id: 'KDQH', - city: 'Douglas, Douglas Municipal Airport', - state: 'GA', - lat: 31.47667, - lon: -82.86028, - }, - KDZJ: { - id: 'KDZJ', - city: 'Blairsville Airport', - state: 'GA', - lat: 34.8544, - lon: -83.9973, - }, - KEZM: { - id: 'KEZM', - city: 'Eastman, Heart of Georgia Regional Airport', - state: 'GA', - lat: 32.21417, - lon: -83.12778, - }, - KFFC: { - id: 'KFFC', - city: 'Atlanta Regional Airport-Falcon Field', - state: 'GA', - lat: 33.35436, - lon: -84.56893, - }, - KFTY: { - id: 'KFTY', - city: 'Fulton County Airport-Brown Field', - state: 'GA', - lat: 33.77764, - lon: -84.52461, - }, - KFZG: { - id: 'KFZG', - city: 'Fitzgerald Municipal Airport', - state: 'GA', - lat: 31.6839, - lon: -83.2709, - }, - KGVL: { - id: 'KGVL', - city: 'Gainesville, Gilmer Memorial Airport', - state: 'GA', - lat: 34.27194, - lon: -83.83028, - }, - KHMP: { - id: 'KHMP', - city: 'Henry County Airport', - state: 'GA', - lat: 33.3899, - lon: -84.331, - }, - KHOE: { - id: 'KHOE', - city: 'Homerville Airport', - state: 'GA', - lat: 31.0559, - lon: -82.7741, - }, - KHQU: { - id: 'KHQU', - city: 'Thomson, Thomson-McDuffie County Airport', - state: 'GA', - lat: 33.52944, - lon: -82.51639, - }, - KIIY: { - id: 'KIIY', - city: 'Washington, Washington-Wilkes County Airport', - state: 'GA', - lat: 33.77972, - lon: -82.81639, - }, - KJCA: { - id: 'KJCA', - city: 'Jackson County Airport', - state: 'GA', - lat: 34.17586, - lon: -83.5616, - }, - KJES: { - id: 'KJES', - city: 'Jesup-Wayne County Airport', - state: 'GA', - lat: 31.554, - lon: -81.8824999, - }, - KJYL: { - id: 'KJYL', - city: 'Sylvania, Plantation Airpark', - state: 'GA', - lat: 32.64528, - lon: -81.59639, - }, - KJZP: { - id: 'KJZP', - city: 'Jasper Pickens County Airport', - state: 'GA', - lat: 34.45417, - lon: -84.45971, - }, - KLGC: { - id: 'KLGC', - city: 'LaGrange-Callaway Airport', - state: 'GA', - lat: 33.00617, - lon: -85.06609, - }, - KLHW: { - id: 'KLHW', - city: 'Wright Army Airfield (Fort Stewart)/Midcoast Regional Airport', - state: 'GA', - lat: 31.88724, - lon: -81.56244, - }, - KLSF: { - id: 'KLSF', - city: 'Fort Benning', - state: 'GA', - lat: 32.3333299, - lon: -84.83333, - }, - KLZU: { - id: 'KLZU', - city: 'Gwinnett County Airport-Briscoe Field', - state: 'GA', - lat: 33.98288, - lon: -83.95842, - }, - KMCN: { - id: 'KMCN', - city: 'Middle Georgia Regional Airport', - state: 'GA', - lat: 32.68892, - lon: -83.65293, - }, - KMGE: { - id: 'KMGE', - city: 'Marietta / Dobbins Air Force Base', - state: 'GA', - lat: 33.91667, - lon: -84.51667, - }, - KMGR: { - id: 'KMGR', - city: 'Moultrie, Moultrie Municipal Airport', - state: 'GA', - lat: 31.08472, - lon: -83.80306, - }, - KMHP: { - id: 'KMHP', - city: 'Metter Municipal Airport', - state: 'GA', - lat: 32.37397, - lon: -82.08144, - }, - KMLJ: { - id: 'KMLJ', - city: 'Milledgeville, Baldwin County Airport', - state: 'GA', - lat: 33.15417, - lon: -83.24056, - }, - KOKZ: { - id: 'KOKZ', - city: 'Sandersville Kaolin Field Airport', - state: 'GA', - lat: 32.9667, - lon: -82.8382, - }, - KOPN: { - id: 'KOPN', - city: 'Thomaston, Thomaston-Upson County Airport', - state: 'GA', - lat: 32.955, - lon: -84.2644399, - }, - KPDK: { - id: 'KPDK', - city: 'Atlanta, De Kalb-Peachtree Airport', - state: 'GA', - lat: 33.87833, - lon: -84.29806, - }, - KPIM: { - id: 'KPIM', - city: 'Pine Mountain Harris County Airport', - state: 'GA', - lat: 32.8407, - lon: -84.8824, - }, - KPUJ: { - id: 'KPUJ', - city: 'Dallas Paulding County Regional Airport', - state: 'GA', - lat: 33.9189999, - lon: -84.952, - }, - KPXE: { - id: 'KPXE', - city: 'Perry-Houston County Airport', - state: 'GA', - lat: 32.5105999, - lon: -83.7673, - }, - KRMG: { - id: 'KRMG', - city: 'Rome, R. B. Russell Airport', - state: 'GA', - lat: 34.34778, - lon: -85.1611099, - }, - KRVJ: { - id: 'KRVJ', - city: 'Swinton Smith Field at Reidsville Municipal Airport', - state: 'GA', - lat: 32.0594899, - lon: -82.15358, - }, - KRYY: { - id: 'KRYY', - city: 'Cobb County International Airport - McCollum Field', - state: 'GA', - lat: 34.01467, - lon: -84.59635, - }, - KSAV: { - id: 'KSAV', - city: 'Savannah-Hilton Head International Airport', - state: 'GA', - lat: 32.1313699, - lon: -81.20226, - }, - KSBO: { - id: 'KSBO', - city: 'Swainsboro Emanuel County Airport', - state: 'GA', - lat: 32.6091, - lon: -82.3699, - }, - KSSI: { - id: 'KSSI', - city: 'Brunswick, Malcolm McKinnon Airport', - state: 'GA', - lat: 31.15167, - lon: -81.39139, - }, - KSVN: { - id: 'KSVN', - city: 'Hunter U. S. Army Airfield', - state: 'GA', - lat: 32.01667, - lon: -81.15, - }, - KTBR: { - id: 'KTBR', - city: 'Statesboro, Statesboro-Bulloch County Airport', - state: 'GA', - lat: 32.48306, - lon: -81.7372199, - }, - KTMA: { - id: 'KTMA', - city: 'Tifton Henry Tift Myers', - state: 'GA', - lat: 31.429, - lon: -83.4885, - }, - KTOC: { - id: 'KTOC', - city: 'Toccoa Le Tourneau Airport', - state: 'GA', - lat: 34.5927999, - lon: -83.2964, - }, - KTVI: { - id: 'KTVI', - city: 'Thomasville Regional Airport', - state: 'GA', - lat: 30.90179, - lon: -83.88113, - }, - KVAD: { - id: 'KVAD', - city: 'Moody Air Force Base', - state: 'GA', - lat: 30.97913, - lon: -83.19247, - }, - KVDI: { - id: 'KVDI', - city: 'Vidalia, Vidalia Municipal Airport', - state: 'GA', - lat: 32.1925, - lon: -82.37194, - }, - KVLD: { - id: 'KVLD', - city: 'Valdosta Regional Airport', - state: 'GA', - lat: 30.77632, - lon: -83.27389, - }, - KVPC: { - id: 'KVPC', - city: 'Cartersville Airport', - state: 'GA', - lat: 34.11589, - lon: -84.85064, - }, - KWDR: { - id: 'KWDR', - city: 'Winder, Winder-Barrow Airport', - state: 'GA', - lat: 33.98222, - lon: -83.66806, - }, - KWRB: { - id: 'KWRB', - city: 'Warner Robins Air Force Base', - state: 'GA', - lat: 32.63333, - lon: -83.6, - }, - PAAD: { - id: 'PAAD', - city: 'Point Thomson Airstrip', - state: 'AK', - lat: 70.136, - lon: -146.2901, - }, - PAAQ: { - id: 'PAAQ', - city: 'Palmer, Palmer Municipal Airport', - state: 'AK', - lat: 61.6, - lon: -149.08333, - }, - PABA: { - id: 'PABA', - city: 'Barter Island, Barter Island LRRS Airport', - state: 'AK', - lat: 70.1338899, - lon: -143.57694, - }, - PABE: { - id: 'PABE', - city: 'Bethel, Bethel Airport', - state: 'AK', - lat: 60.77972, - lon: -161.83778, - }, - PABI: { - id: 'PABI', - city: 'Delta Junction/Ft Greely, Allen Army Airfield', - state: 'AK', - lat: 64, - lon: -145.73333, - }, - PABL: { - id: 'PABL', - city: 'Buckland, Buckland Airport', - state: 'AK', - lat: 65.98222, - lon: -161.15194, - }, - PABR: { - id: 'PABR', - city: 'Wiley Post-Will Rogers Memorial Airport', - state: 'AK', - lat: 71.28528, - lon: -156.76583, - }, - PABT: { - id: 'PABT', - city: 'Bettles, Bettles Airport', - state: 'AK', - lat: 66.91667, - lon: -151.51667, - }, - PABV: { - id: 'PABV', - city: 'Birchwood, Birchwood Airport', - state: 'AK', - lat: 61.41667, - lon: -149.51667, - }, - PACD: { - id: 'PACD', - city: 'Cold Bay, Cold Bay Airport', - state: 'AK', - lat: 55.22083, - lon: -162.72778, - }, - PACM: { - id: 'PACM', - city: 'Scammon Bay', - state: 'AK', - lat: 61.8453, - lon: -165.5713, - }, - PACV: { - id: 'PACV', - city: 'Cordova, Merle K (Mudhole) Smith Airport', - state: 'AK', - lat: 60.49167, - lon: -145.47778, - }, - PACZ: { - id: 'PACZ', - city: 'Cape Romanzof, Cape Romanzof LRRS Airport', - state: 'AK', - lat: 61.78333, - lon: -166.03333, - }, - PADG: { - id: 'PADG', - city: 'Red Dog', - state: 'AK', - lat: 68.0321, - lon: -162.8992, - }, - PADK: { - id: 'PADK', - city: 'Adak Island, Adak Airport', - state: 'AK', - lat: 51.87778, - lon: -176.64583, - }, - PADL: { - id: 'PADL', - city: 'Dillingham, Dillingham Airport', - state: 'AK', - lat: 59.05, - lon: -158.51667, - }, - PADM: { - id: 'PADM', - city: 'Marshall', - state: 'AK', - lat: 61.8643, - lon: -162.0261, - }, - PADQ: { - id: 'PADQ', - city: 'Kodiak, Kodiak Airport', - state: 'AK', - lat: 57.75, - lon: -152.5, - }, - PADU: { - id: 'PADU', - city: 'Unalaska, Unalaska Airport', - state: 'AK', - lat: 53.9, - lon: -166.53333, - }, - PAEC: { - id: 'PAEC', - city: 'Chulitna, Chulitna Airport', - state: 'AK', - lat: 62.88333, - lon: -149.83333, - }, - PAED: { - id: 'PAED', - city: 'Anchorage, Elmendorf Air Force Base', - state: 'AK', - lat: 61.25306, - lon: -149.79389, - }, - PAEG: { - id: 'PAEG', - city: 'Eagle, Eagle Airport', - state: 'AK', - lat: 64.77639, - lon: -141.15083, - }, - PAEH: { - id: 'PAEH', - city: 'Cape Newenham, Cape Newenham LRRS Airport', - state: 'AK', - lat: 58.65, - lon: -162.0666699, - }, - PAEI: { - id: 'PAEI', - city: 'Fairbanks, Eielson Air Force Base', - state: 'AK', - lat: 64.65, - lon: -147.1, - }, - PAEL: { - id: 'PAEL', - city: 'Elfin Cove - Elfin Cove Seaplane Base', - state: 'AK', - lat: 58.19467, - lon: -136.34663, - }, - PAEM: { - id: 'PAEM', - city: 'Emmonak, Emmonak Airport', - state: 'AK', - lat: 62.78333, - lon: -164.5, - }, - PAEN: { - id: 'PAEN', - city: 'Kenai, Kenai Municipal Airport', - state: 'AK', - lat: 60.57306, - lon: -151.245, - }, - PAFA: { - id: 'PAFA', - city: 'Fairbanks, Fairbanks International Airport', - state: 'AK', - lat: 64.80389, - lon: -147.87611, - }, - PAFB: { - id: 'PAFB', - city: 'Fort Wainwright AAF', - state: 'AK', - lat: 64.83667, - lon: -147.59556, - }, - PAFE: { - id: 'PAFE', - city: 'Kake - Kake Airport', - state: 'AK', - lat: 56.964, - lon: -133.913, - }, - PAFM: { - id: 'PAFM', - city: 'Ambler, Ambler Airport', - state: 'AK', - lat: 67.1, - lon: -157.85, - }, - PAFR: { - id: 'PAFR', - city: 'Ft. Richardson / Bryant U. S. Army Heliport, Ak', - state: 'AK', - lat: 61.26667, - lon: -149.65, - }, - PAFS: { - id: 'PAFS', - city: 'Nikolai', - state: 'AK', - lat: 63.019, - lon: -154.358, - }, - PAGA: { - id: 'PAGA', - city: 'Galena, Edward G. Pitka Sr. Airport', - state: 'AK', - lat: 64.73333, - lon: -156.93333, - }, - PAGB: { - id: 'PAGB', - city: 'Galbraith Lake, Galbraith Lake Airport', - state: 'AK', - lat: 68.48333, - lon: -149.48333, - }, - PAGH: { - id: 'PAGH', - city: 'Shungnak Airport', - state: 'AK', - lat: 66.8881, - lon: -157.1624, - }, - PAGK: { - id: 'PAGK', - city: 'Gulkana, Gulkana Airport', - state: 'AK', - lat: 62.15, - lon: -145.45, - }, - PAGL: { - id: 'PAGL', - city: 'Golovin, Golovin Airport', - state: 'AK', - lat: 64.54333, - lon: -163.03944, - }, - PAGM: { - id: 'PAGM', - city: 'Gambell, Gambell Airport', - state: 'AK', - lat: 63.76667, - lon: -171.73333, - }, - PAGN: { - id: 'PAGN', - city: 'Angoon', - state: 'AK', - lat: 57.5, - lon: -134.58333, - }, - PAGS: { - id: 'PAGS', - city: 'Gustavus, Gustavus Airport', - state: 'AK', - lat: 58.41667, - lon: -135.7, - }, - PAGY: { - id: 'PAGY', - city: 'Skagway', - state: 'AK', - lat: 59.4544, - lon: -135.3263, - }, - PAHC: { - id: 'PAHC', - city: 'Holy Cross', - state: 'AK', - lat: 62.1873, - lon: -159.77657, - }, - PAHL: { - id: 'PAHL', - city: 'Huslia, Huslia Airport', - state: 'AK', - lat: 65.6975, - lon: -156.35111, - }, - PAHN: { - id: 'PAHN', - city: 'Haines - Haines Airport', - state: 'AK', - lat: 59.2429, - lon: -135.5114, - }, - PAHO: { - id: 'PAHO', - city: 'Homer, Homer Airport', - state: 'AK', - lat: 59.65, - lon: -151.48333, - }, - PAHP: { - id: 'PAHP', - city: 'Hooper Bay, Hooper Bay Airport', - state: 'AK', - lat: 61.51667, - lon: -166.13333, - }, - PAHY: { - id: 'PAHY', - city: 'Hydaburg - Hydaburg Seaplane Base', - state: 'AK', - lat: 55.2, - lon: -132.83333, - }, - PAIG: { - id: 'PAIG', - city: 'Igiugig', - state: 'AK', - lat: 59.32395, - lon: -155.90235, - }, - PAII: { - id: 'PAII', - city: 'Egegik, Egegik Airport', - state: 'AK', - lat: 58.18528, - lon: -157.38556, - }, - PAIK: { - id: 'PAIK', - city: 'Kinana / Bob Baker Me', - state: 'AK', - lat: 66.98333, - lon: -160.43333, - }, - PAIL: { - id: 'PAIL', - city: 'Iliamna, Iliamna Airport', - state: 'AK', - lat: 59.75, - lon: -154.9, - }, - PAIM: { - id: 'PAIM', - city: 'Utopia Creek, Indian Mountain LRRS Airport', - state: 'AK', - lat: 66, - lon: -153.7, - }, - PAIN: { - id: 'PAIN', - city: 'McKinley Park, McKinley National Park Airport', - state: 'AK', - lat: 63.73333, - lon: -148.91667, - }, - PAIW: { - id: 'PAIW', - city: 'Wales', - state: 'AK', - lat: 65.6226, - lon: -168.0949, - }, - PAJC: { - id: 'PAJC', - city: 'Chignik, Chignik Airport', - state: 'AK', - lat: 56.31139, - lon: -158.37333, - }, - PAJK: { - id: 'PAJK', - city: 'NWS Office: Juneau', - state: 'AK', - lat: 58.4, - lon: -134.57001, - }, - PAJN: { - id: 'PAJN', - city: 'Juneau, Juneau International Airport', - state: 'AK', - lat: 58.35472, - lon: -134.57611, - }, - PAJZ: { - id: 'PAJZ', - city: 'Koliganek', - state: 'AK', - lat: 59.727, - lon: -157.2589999, - }, - PAKF: { - id: 'PAKF', - city: 'False Pass Airport', - state: 'AK', - lat: 54.847, - lon: -163.41, - }, - PAKH: { - id: 'PAKH', - city: 'Akhiok', - state: 'AK', - lat: 56.9387, - lon: -154.1826, - }, - PAKI: { - id: 'PAKI', - city: 'Kipnuk, Kipnuk Airport', - state: 'AK', - lat: 59.93278, - lon: -164.03028, - }, - PAKK: { - id: 'PAKK', - city: 'Koyuk, Koyuk Airport', - state: 'AK', - lat: 64.93389, - lon: -161.15806, - }, - PAKN: { - id: 'PAKN', - city: 'King Salmon, King Salmon Airport', - state: 'AK', - lat: 58.67667, - lon: -156.64917, - }, - PAKP: { - id: 'PAKP', - city: 'Anaktuvuk Pass, Anaktuvuk Pass Airport', - state: 'AK', - lat: 68.13361, - lon: -151.7433299, - }, - PAKT: { - id: 'PAKT', - city: 'Ketchikan, Ketchikan International Airport', - state: 'AK', - lat: 55.35556, - lon: -131.71361, - }, - PAKU: { - id: 'PAKU', - city: 'Kuparuk, Ugnu-Kuparuk Airport', - state: 'AK', - lat: 70.31667, - lon: -149.58333, - }, - PAKV: { - id: 'PAKV', - city: 'Kaltag, Kaltag Airport', - state: 'AK', - lat: 64.31667, - lon: -158.73333, - }, - PAKW: { - id: 'PAKW', - city: 'Klawock - Klawock Airport', - state: 'AK', - lat: 55.5839, - lon: -133.067, - }, - PALG: { - id: 'PALG', - city: 'Kalskag', - state: 'AK', - lat: 61.5364, - lon: -160.3414, - }, - PALH: { - id: 'PALH', - city: 'Anchorage, Lake Hood Seaplane Base', - state: 'AK', - lat: 61.18333, - lon: -149.96667, - }, - PALJ: { - id: 'PALJ', - city: 'Port Alsworth, Port Alsworth Airport', - state: 'AK', - lat: 60.2, - lon: -154.3166699, - }, - PALP: { - id: 'PALP', - city: 'Deadhorse, Alpine Airstrip', - state: 'AK', - lat: 70.33333, - lon: -150.93333, - }, - PALU: { - id: 'PALU', - city: 'Cape Lisburne, Cape Lisburne LRRS Airport', - state: 'AK', - lat: 68.88333, - lon: -166.1, - }, - PAMB: { - id: 'PAMB', - city: 'Manokotak', - state: 'AK', - lat: 58.9902, - lon: -159.0499, - }, - PAMC: { - id: 'PAMC', - city: 'McGrath, McGrath Airport', - state: 'AK', - lat: 62.96667, - lon: -155.61667, - }, - PAMD: { - id: 'PAMD', - city: 'Middleton Island Airport', - state: 'AK', - lat: 59.4423, - lon: -146.3166, - }, - PAMH: { - id: 'PAMH', - city: 'Minchumina, Minchumina Airport', - state: 'AK', - lat: 63.88056, - lon: -152.30056, - }, - PAMK: { - id: 'PAMK', - city: 'St Michael Airport', - state: 'AK', - lat: 63.49006, - lon: -162.11039, - }, - PAMM: { - id: 'PAMM', - city: 'Metlakatla, Metlakatla Seaplane Base', - state: 'AK', - lat: 55.13111, - lon: -131.57806, - }, - PAMO: { - id: 'PAMO', - city: 'Mountain Village', - state: 'AK', - lat: 62.0953, - lon: -163.6819, - }, - PAMR: { - id: 'PAMR', - city: 'Anchorage, Merrill Field Airport', - state: 'AK', - lat: 61.21667, - lon: -149.85, - }, - PAMY: { - id: 'PAMY', - city: 'Mekoryuk, Mekoryuk Airport', - state: 'AK', - lat: 60.36667, - lon: -166.26667, - }, - PANA: { - id: 'PANA', - city: 'Napakiak Airport', - state: 'AK', - lat: 60.6903, - lon: -161.9785, - }, - PANC: { - id: 'PANC', - city: 'Anchorage, Ted Stevens Anchorage International Airport', - state: 'AK', - lat: 61.17444, - lon: -149.9961099, - }, - PANI: { - id: 'PANI', - city: 'Aniak, Aniak Airport', - state: 'AK', - lat: 61.58139, - lon: -159.54278, - }, - PANN: { - id: 'PANN', - city: 'Nenana Municipal Airport', - state: 'AK', - lat: 64.54796, - lon: -149.08398, - }, - PANV: { - id: 'PANV', - city: 'Anvik, Anvik Airport', - state: 'AK', - lat: 62.64833, - lon: -160.18972, - }, - PANW: { - id: 'PANW', - city: 'New Stuyahok', - state: 'AK', - lat: 59.45, - lon: -157.328, - }, - PAOH: { - id: 'PAOH', - city: 'Hoonah - Hoonah Seaplane Base', - state: 'AK', - lat: 58.097, - lon: -135.4139999, - }, - PAOM: { - id: 'PAOM', - city: 'Nome, Nome Airport', - state: 'AK', - lat: 64.51194, - lon: -165.445, - }, - PAOO: { - id: 'PAOO', - city: 'Toksook Bay', - state: 'AK', - lat: 60.53352, - lon: -165.1142999, - }, - PAOR: { - id: 'PAOR', - city: 'Northway, Northway Airport', - state: 'AK', - lat: 62.96111, - lon: -141.92889, - }, - PAOT: { - id: 'PAOT', - city: 'Ralph Wien Memorial Airport', - state: 'AK', - lat: 66.88576, - lon: -162.60624, - }, - PAOU: { - id: 'PAOU', - city: 'Nelson Lagoon', - state: 'AK', - lat: 56.008, - lon: -161.16, - }, - PAPB: { - id: 'PAPB', - city: 'St. George, St. George Airport', - state: 'AK', - lat: 56.57861, - lon: -169.66139, - }, - PAPG: { - id: 'PAPG', - city: 'Petersburg', - state: 'AK', - lat: 56.8017, - lon: -132.9453, - }, - PAPH: { - id: 'PAPH', - city: 'Port Heiden, Port Heiden Airport', - state: 'AK', - lat: 56.95, - lon: -158.63333, - }, - PAPM: { - id: 'PAPM', - city: 'Platinum', - state: 'AK', - lat: 59.01667, - lon: -161.8166699, - }, - PAPN: { - id: 'PAPN', - city: 'Pilot Point Airport', - state: 'AK', - lat: 57.58, - lon: -157.572, - }, - PAPO: { - id: 'PAPO', - city: 'Point Hope, Point Hope Airport', - state: 'AK', - lat: 68.35, - lon: -166.8, - }, - PAPR: { - id: 'PAPR', - city: 'Prospect Creek, Prospect Creek Airport', - state: 'AK', - lat: 66.81278, - lon: -150.64389, - }, - PAPT: { - id: 'PAPT', - city: 'Puntilla', - state: 'AK', - lat: 62.1, - lon: -152.75, - }, - PAQH: { - id: 'PAQH', - city: 'Quinhagak Airport', - state: 'AK', - lat: 59.7551, - lon: -161.8454, - }, - PAQT: { - id: 'PAQT', - city: 'Nuiqsut, Nuiqsut Airport', - state: 'AK', - lat: 70.2099999, - lon: -151.00556, - }, - PARC: { - id: 'PARC', - city: 'Arctic Village, Arctic Village Airport', - state: 'AK', - lat: 68.11444, - lon: -145.57917, - }, - PARS: { - id: 'PARS', - city: 'Russian Mission', - state: 'AK', - lat: 61.775, - lon: -161.3194, - }, - PARY: { - id: 'PARY', - city: 'Ruby', - state: 'AK', - lat: 64.7272, - lon: -155.4697, - }, - PASA: { - id: 'PASA', - city: 'Savoonga Airport', - state: 'AK', - lat: 63.68333, - lon: -170.5, - }, - PASC: { - id: 'PASC', - city: 'Deadhorse, Deadhorse Airport', - state: 'AK', - lat: 70.2, - lon: -148.46667, - }, - PASD: { - id: 'PASD', - city: 'Sand Point', - state: 'AK', - lat: 55.31667, - lon: -160.51667, - }, - PASH: { - id: 'PASH', - city: 'Shishmaref, Shishmaref Airport', - state: 'AK', - lat: 66.26667, - lon: -166.08333, - }, - PASI: { - id: 'PASI', - city: 'Sitka - Sitka Airport', - state: 'AK', - lat: 57.048, - lon: -135.3647, - }, - PASK: { - id: 'PASK', - city: 'Selawik', - state: 'AK', - lat: 66.61667, - lon: -160, - }, - PASL: { - id: 'PASL', - city: 'Sleetmute', - state: 'AK', - lat: 61.69735, - lon: -157.16712, - }, - PASM: { - id: 'PASM', - city: "St. Mary's, St. Mary's Airport", - state: 'AK', - lat: 62.05, - lon: -163.3, - }, - PASN: { - id: 'PASN', - city: 'St. Paul Island, St. Paul Island Airport', - state: 'AK', - lat: 57.16667, - lon: -170.21667, - }, - PASO: { - id: 'PASO', - city: 'Seldovia, Seldovia Airport', - state: 'AK', - lat: 59.45, - lon: -151.7, - }, - PASV: { - id: 'PASV', - city: 'Sparrevohn Airways Facilities Sector', - state: 'AK', - lat: 61.1, - lon: -155.5666699, - }, - PASX: { - id: 'PASX', - city: 'Soldotna', - state: 'AK', - lat: 60.48333, - lon: -151.03333, - }, - PASY: { - id: 'PASY', - city: 'Shemya, Eareckson AFB', - state: 'AK', - lat: 52.71667, - lon: 174.11667, - }, - PATA: { - id: 'PATA', - city: 'Tanana, Calhoun Memorial Airport', - state: 'AK', - lat: 65.16667, - lon: -152.1, - }, - PATC: { - id: 'PATC', - city: 'Tin City Airways Facilities Sector', - state: 'AK', - lat: 65.56667, - lon: -167.91667, - }, - PATE: { - id: 'PATE', - city: 'Teller', - state: 'AK', - lat: 65.2403999, - lon: -166.3393, - }, - PATG: { - id: 'PATG', - city: 'Togiac Village, Togiak Airport', - state: 'AK', - lat: 59.05, - lon: -160.4, - }, - PATK: { - id: 'PATK', - city: 'Talkeetna, Talkeetna Airport', - state: 'AK', - lat: 62.32056, - lon: -150.09361, - }, - PATL: { - id: 'PATL', - city: 'Takotna, Tatalina LRRS Airport', - state: 'AK', - lat: 62.9, - lon: -155.98333, - }, - PATO: { - id: 'PATO', - city: 'Portage, Portage Glacier', - state: 'AK', - lat: 60.78333, - lon: -148.83333, - }, - PATQ: { - id: 'PATQ', - city: 'Atqasuk', - state: 'AK', - lat: 70.4673, - lon: -157.4357, - }, - PAUN: { - id: 'PAUN', - city: 'Unalakleet', - state: 'AK', - lat: 63.88333, - lon: -160.8, - }, - PAUT: { - id: 'PAUT', - city: 'Akun Airport', - state: 'AK', - lat: 54.1446, - lon: -165.6041, - }, - PAVA: { - id: 'PAVA', - city: 'Chevak Airport', - state: 'AK', - lat: 61.5408, - lon: -165.6009, - }, - PAVC: { - id: 'PAVC', - city: 'King Cove', - state: 'AK', - lat: 55.116, - lon: -162.266, - }, - PAVD: { - id: 'PAVD', - city: 'Valdez 2', - state: 'AK', - lat: 61.13333, - lon: -146.26667, - }, - PAVL: { - id: 'PAVL', - city: 'Kivalina, Kivalina Airport', - state: 'AK', - lat: 67.73333, - lon: -164.55, - }, - PAWD: { - id: 'PAWD', - city: 'Seward', - state: 'AK', - lat: 60.11667, - lon: -149.45, - }, - PAWG: { - id: 'PAWG', - city: 'Wrangell', - state: 'AK', - lat: 56.48333, - lon: -132.36667, - }, - PAWI: { - id: 'PAWI', - city: 'Wainwright, Wainwright Airport', - state: 'AK', - lat: 70.63333, - lon: -159.85, - }, - PAWM: { - id: 'PAWM', - city: 'White Mountain Airport', - state: 'AK', - lat: 64.6892, - lon: -163.4127, - }, - PAWN: { - id: 'PAWN', - city: 'Noatak, Noatak Airport', - state: 'AK', - lat: 67.56667, - lon: -162.98333, - }, - PAWS: { - id: 'PAWS', - city: 'Wasilla, Wasilla Airport', - state: 'AK', - lat: 61.57194, - lon: -149.54056, - }, - PAYA: { - id: 'PAYA', - city: 'Yakutat', - state: 'AK', - lat: 59.51667, - lon: -139.66667, - }, - PAZK: { - id: 'PAZK', - city: 'Eureka, Skelton Airport', - state: 'AK', - lat: 61.93333, - lon: -147.16667, - }, - PFCL: { - id: 'PFCL', - city: 'Clarks Point Airport', - state: 'AK', - lat: 58.8337, - lon: -158.5294, - }, - PFEL: { - id: 'PFEL', - city: 'Elim Airport', - state: 'AK', - lat: 64.615, - lon: -162.2705, - }, - PFKT: { - id: 'PFKT', - city: 'Brevig Mission Airport', - state: 'AK', - lat: 65.3313, - lon: -166.4657, - }, - PFKW: { - id: 'PFKW', - city: 'Kwethluk Airport', - state: 'AK', - lat: 60.7903, - lon: -161.4437, - }, - PFNO: { - id: 'PFNO', - city: 'Noorvik', - state: 'AK', - lat: 66.8175, - lon: -161.0223, - }, - PFSH: { - id: 'PFSH', - city: 'Shaktoolik Airport', - state: 'AK', - lat: 64.3711, - lon: -161.224, - }, - PFWS: { - id: 'PFWS', - city: 'South Naknek Nr 2 Airport', - state: 'AK', - lat: 58.7021, - lon: -157.0026, - }, - PFYU: { - id: 'PFYU', - city: 'Fort Yukon, Fort Yukon Airport', - state: 'AK', - lat: 66.56667, - lon: -145.26667, - }, - PPIT: { - id: 'PPIT', - city: 'Nunapitchuk Airport', - state: 'AK', - lat: 60.906, - lon: -162.4406, - }, - PPIZ: { - id: 'PPIZ', - city: 'Point Lay, Point Lay LRRS Airport', - state: 'AK', - lat: 69.7166699, - lon: -163, - }, - KAAA: { - id: 'KAAA', - city: 'Logan County Airport', - state: 'IL', - lat: 40.15885, - lon: -89.33891, - }, - KAJG: { - id: 'KAJG', - city: 'Mount Carmel, Mount Carmel Municipal Airport', - state: 'IL', - lat: 38.60928, - lon: -87.72508, - }, - KALN: { - id: 'KALN', - city: 'St. Louis Regional Airport', - state: 'IL', - lat: 38.88968, - lon: -90.03163, - }, - KARR: { - id: 'KARR', - city: 'Aurora Municipal Airport', - state: 'IL', - lat: 41.77132, - lon: -88.48147, - }, - KBLV: { - id: 'KBLV', - city: 'Belleville, Scott AFB/MidAmerica Airport', - state: 'IL', - lat: 38.55, - lon: -89.85, - }, - KBMI: { - id: 'KBMI', - city: 'Bloomington/Normal, Central Illinois Regional Airport at Bloomington-Normal', - state: 'IL', - lat: 40.47694, - lon: -88.91583, - }, - KCIR: { - id: 'KCIR', - city: 'Cairo Regional Airport', - state: 'IL', - lat: 37.06388, - lon: -89.2232, - }, - KCMI: { - id: 'KCMI', - city: 'University of Illinois - Willard', - state: 'IL', - lat: 40.03245, - lon: -88.27547, - }, - KCPS: { - id: 'KCPS', - city: 'St. Louis Downtown Airport', - state: 'IL', - lat: 38.56403, - lon: -90.14871, - }, - KCUL: { - id: 'KCUL', - city: 'Carmi Municipal Airport', - state: 'IL', - lat: 38.08875, - lon: -88.12125, - }, - KDEC: { - id: 'KDEC', - city: 'Decatur Airport', - state: 'IL', - lat: 39.8308, - lon: -88.87192, - }, - KDKB: { - id: 'KDKB', - city: 'De Kalb Taylor Municipal Airport', - state: 'IL', - lat: 41.93381, - lon: -88.70657, - }, - KDNV: { - id: 'KDNV', - city: 'Danville, Vermilion County Airport', - state: 'IL', - lat: 40.19944, - lon: -87.59556, - }, - KDPA: { - id: 'KDPA', - city: 'Chicago / West Chicago, Dupage Airport', - state: 'IL', - lat: 41.8963899, - lon: -88.25111, - }, - KENL: { - id: 'KENL', - city: 'Centralia Municipal Airport', - state: 'IL', - lat: 38.50951, - lon: -89.08996, - }, - KFEP: { - id: 'KFEP', - city: 'Albertus Airport', - state: 'IL', - lat: 42.24751, - lon: -89.58104, - }, - KFOA: { - id: 'KFOA', - city: 'Flora Municipal Airport', - state: 'IL', - lat: 38.66726, - lon: -88.4526999, - }, - KFWC: { - id: 'KFWC', - city: 'Fairfield, Fairfield Municipal Airport', - state: 'IL', - lat: 38.37861, - lon: -88.41278, - }, - KGBG: { - id: 'KGBG', - city: 'Galesburg Municipal Airport', - state: 'IL', - lat: 40.9328999, - lon: -90.43339, - }, - KHSB: { - id: 'KHSB', - city: 'Harrisburg-Raleigh Airport', - state: 'IL', - lat: 37.81281, - lon: -88.54486, - }, - KIGQ: { - id: 'KIGQ', - city: 'Lansing Municipal Airport', - state: 'IL', - lat: 41.54125, - lon: -87.52822, - }, - KIJX: { - id: 'KIJX', - city: 'Jacksonville Municipal Airport', - state: 'IL', - lat: 39.7740099, - lon: -90.24187, - }, - KIKK: { - id: 'KIKK', - city: 'Greater Kankakee Airport', - state: 'IL', - lat: 41.06871, - lon: -87.85372, - }, - KJOT: { - id: 'KJOT', - city: 'Joliet Regional Airport', - state: 'IL', - lat: 41.51755, - lon: -88.17903, - }, - KLOT: { - id: 'KLOT', - city: 'Lewis University Airport', - state: 'IL', - lat: 41.60307, - lon: -88.10164, - }, - KLWV: { - id: 'KLWV', - city: 'Lawrenceville-Vincennes International Airport', - state: 'IL', - lat: 38.76046, - lon: -87.59903, - }, - KMDH: { - id: 'KMDH', - city: 'Southern Illinois Airport', - state: 'IL', - lat: 37.78328, - lon: -89.24532, - }, - KMDW: { - id: 'KMDW', - city: 'Chicago, Chicago Midway Airport', - state: 'IL', - lat: 41.78417, - lon: -87.75528, - }, - KMLI: { - id: 'KMLI', - city: 'Moline Quad-City Airport', - state: 'IL', - lat: 41.4482, - lon: -90.52359, - }, - KMQB: { - id: 'KMQB', - city: 'Macomb Municipal Airport', - state: 'IL', - lat: 40.5176299, - lon: -90.64807, - }, - KMTO: { - id: 'KMTO', - city: 'Mattoon / Charleston, Coles County Memorial Airport', - state: 'IL', - lat: 39.47806, - lon: -88.2791699, - }, - KMVN: { - id: 'KMVN', - city: 'Mount Vernon Airport', - state: 'IL', - lat: 38.32842, - lon: -88.85292, - }, - KMWA: { - id: 'KMWA', - city: 'Marion - Williamson County Regional Airport', - state: 'IL', - lat: 37.76671, - lon: -89.00993, - }, - KOLY: { - id: 'KOLY', - city: 'Olney-Noble Airport', - state: 'IL', - lat: 38.72133, - lon: -88.1799, - }, - KORD: { - id: 'KORD', - city: "Chicago, Chicago-O'Hare International Airport", - state: 'IL', - lat: 41.97972, - lon: -87.9044399, - }, - KPIA: { - id: 'KPIA', - city: 'Peoria - General Downing-Peoria International Airport', - state: 'IL', - lat: 40.6674999, - lon: -89.68389, - }, - KPNT: { - id: 'KPNT', - city: 'Pontiac Municipal Airport', - state: 'IL', - lat: 40.92327, - lon: -88.6213, - }, - KPPQ: { - id: 'KPPQ', - city: 'Pittsfield, Pittsfield Penstone Municipal Airport', - state: 'IL', - lat: 39.63889, - lon: -90.77833, - }, - KPRG: { - id: 'KPRG', - city: 'Edgar County Airport', - state: 'IL', - lat: 39.69817, - lon: -87.6669, - }, - KPWK: { - id: 'KPWK', - city: 'Chicago / Wheeling, Pal-Waukee Airport', - state: 'IL', - lat: 42.12083, - lon: -87.90472, - }, - KRFD: { - id: 'KRFD', - city: 'Rockford, Greater Rockford Airport', - state: 'IL', - lat: 42.19278, - lon: -89.09333, - }, - KRPJ: { - id: 'KRPJ', - city: 'Rochelle, Rochelle Municipal-Koritz Field Airport', - state: 'IL', - lat: 41.8905699, - lon: -89.08175, - }, - KRSV: { - id: 'KRSV', - city: 'Robinson Municipal Airport', - state: 'IL', - lat: 39.01361, - lon: -87.64846, - }, - KSAR: { - id: 'KSAR', - city: 'Sparta Community-Hunter Field Airport', - state: 'IL', - lat: 38.14624, - lon: -89.70243, - }, - KSFY: { - id: 'KSFY', - city: 'Tri-Township Airport', - state: 'IL', - lat: 42.04544, - lon: -90.11009, - }, - KSLO: { - id: 'KSLO', - city: 'Salem, Salem-Leckrone Airport', - state: 'IL', - lat: 38.64278, - lon: -88.96417, - }, - KSPI: { - id: 'KSPI', - city: 'Springfield - Abraham Lincoln Capital Airport', - state: 'IL', - lat: 39.84527, - lon: -89.68405, - }, - KSQI: { - id: 'KSQI', - city: 'Sterling Rockfalls', - state: 'IL', - lat: 41.7432, - lon: -89.66547, - }, - KTAZ: { - id: 'KTAZ', - city: 'Taylorville, Taylorville Municipal Airport', - state: 'IL', - lat: 39.53417, - lon: -89.32778, - }, - KTIP: { - id: 'KTIP', - city: 'Rantoul National Aviation Center Airport', - state: 'IL', - lat: 40.28952, - lon: -88.1473, - }, - KUGN: { - id: 'KUGN', - city: 'Chicago/Waukegan Regional Airport', - state: 'IL', - lat: 42.42546, - lon: -87.86339, - }, - KUIN: { - id: 'KUIN', - city: 'Quincy Regional Airport-Baldwin Field', - state: 'IL', - lat: 39.9371, - lon: -91.19659, - }, - KVYS: { - id: 'KVYS', - city: 'Illinois Valley Regional Airport', - state: 'IL', - lat: 41.35175, - lon: -89.14963, - }, - KSZT: { - id: 'KSZT', - city: 'Sandpoint, Sandpoint Airport', - state: 'ID', - lat: 48.29944, - lon: -116.56, - }, - KTBI: { - id: 'KTBI', - city: 'Kettle Butte', - state: 'ID', - lat: 43.5486099, - lon: -112.32583, - }, - KTWF: { - id: 'KTWF', - city: 'Joslin Field - Magic Valley Regional Airport', - state: 'ID', - lat: 42.4784999, - lon: -114.47739, - }, - PICI: { - id: 'PICI', - city: 'PICABO', - state: 'ID', - lat: 43.31167, - lon: -114.16583, - }, - PMAI: { - id: 'PMAI', - city: 'PARMA', - state: 'ID', - lat: 43.8, - lon: -116.93333, - }, - KAAO: { - id: 'KAAO', - city: 'Wichita Jabara Airport', - state: 'KS', - lat: 37.74969, - lon: -97.21908, - }, - KADT: { - id: 'KADT', - city: 'Atwood-Rawlins County City-County Airport', - state: 'KS', - lat: 39.84034, - lon: -101.04248, - }, - KBEC: { - id: 'KBEC', - city: 'Beech Factory Airport', - state: 'KS', - lat: 37.69392, - lon: -97.21492, - }, - KCBK: { - id: 'KCBK', - city: 'Colby Shaltz Field Airport', - state: 'KS', - lat: 39.43, - lon: -101.0511, - }, - KCFV: { - id: 'KCFV', - city: 'Coffeyville, Coffeyville Municipal Airport', - state: 'KS', - lat: 37.09111, - lon: -95.56639, - }, - KCNK: { - id: 'KCNK', - city: 'Concordia, Blosser Municipal Airport', - state: 'KS', - lat: 39.55139, - lon: -97.65056, - }, - KCNU: { - id: 'KCNU', - city: 'Chanute, Chanute Martin Johnson Airport', - state: 'KS', - lat: 37.67028, - lon: -95.48417, - }, - KDDC: { - id: 'KDDC', - city: 'Dodge City, Dodge City Regional Airport', - state: 'KS', - lat: 37.77278, - lon: -99.96972, - }, - KEHA: { - id: 'KEHA', - city: 'Elkhart, Elkhart-Morton County Airport', - state: 'KS', - lat: 37, - lon: -101.88333, - }, - KEMP: { - id: 'KEMP', - city: 'Emporia, Emporia Municipal Airport', - state: 'KS', - lat: 38.32889, - lon: -96.19389, - }, - KEQA: { - id: 'KEQA', - city: 'El Dorado Captain Jack Thomas Airport', - state: 'KS', - lat: 37.77534, - lon: -96.81449, - }, - KEWK: { - id: 'KEWK', - city: 'Newton, Newton City/County Airport', - state: 'KS', - lat: 38.05, - lon: -97.28333, - }, - KFOE: { - id: 'KFOE', - city: 'Topeka, Forbes Field', - state: 'KS', - lat: 38.94139, - lon: -95.65056, - }, - KFRI: { - id: 'KFRI', - city: 'Fort Riley - Marshall AAF', - state: 'KS', - lat: 39.05586, - lon: -96.76166, - }, - KGBD: { - id: 'KGBD', - city: 'Great Bend, Great Bend Municipal Airport', - state: 'KS', - lat: 38.35, - lon: -98.86667, - }, - KGCK: { - id: 'KGCK', - city: 'Garden City Regional Airport', - state: 'KS', - lat: 37.9275, - lon: -100.72444, - }, - KGLD: { - id: 'KGLD', - city: 'Goodland, Renner Field', - state: 'KS', - lat: 39.3675, - lon: -101.69306, - }, - KHLC: { - id: 'KHLC', - city: 'Hill City, Hill City Municipal Airport', - state: 'KS', - lat: 39.37472, - lon: -99.82972, - }, - KHQG: { - id: 'KHQG', - city: 'Hugoton Municipal Airport', - state: 'KS', - lat: 37.16308, - lon: -101.37052, - }, - KHUT: { - id: 'KHUT', - city: 'Hutchinson, Hutchinson Municipal Airport', - state: 'KS', - lat: 38.06806, - lon: -97.86056, - }, - KHYS: { - id: 'KHYS', - city: 'Hays, Hays Regional Airport', - state: 'KS', - lat: 38.85, - lon: -99.26667, - }, - KIAB: { - id: 'KIAB', - city: 'McConnell Air Force Base', - state: 'KS', - lat: 37.61667, - lon: -97.26667, - }, - KICT: { - id: 'KICT', - city: 'Wichita - Wichita Dwight D. Eisenhower National Airport', - state: 'KS', - lat: 37.64722, - lon: -97.42944, - }, - KIDP: { - id: 'KIDP', - city: 'INDEPENDENCE', - state: 'KS', - lat: 37.1584, - lon: -95.7784, - }, - KIXD: { - id: 'KIXD', - city: 'Olathe, New Century Aircenter', - state: 'KS', - lat: 38.82444, - lon: -94.88694, - }, - KJHN: { - id: 'KJHN', - city: 'Stanton County Municipal Airport', - state: 'KS', - lat: 37.5782, - lon: -101.7304, - }, - KLBL: { - id: 'KLBL', - city: 'Liberal, Liberal Municipal Airport', - state: 'KS', - lat: 37.05, - lon: -100.9666699, - }, - KLWC: { - id: 'KLWC', - city: 'Lawrence, Lawrence Municipal Airport', - state: 'KS', - lat: 39.00833, - lon: -95.21167, - }, - KLYO: { - id: 'KLYO', - city: 'Lyons-Rice County Municipal Airport', - state: 'KS', - lat: 38.34025, - lon: -98.22856, - }, - KMHK: { - id: 'KMHK', - city: 'Manhattan, Manhattan Municipal Airport', - state: 'KS', - lat: 39.13528, - lon: -96.67778, - }, - KMYZ: { - id: 'KMYZ', - city: 'Marysville Municipal Airport', - state: 'KS', - lat: 39.8553, - lon: -96.6306, - }, - KNRN: { - id: 'KNRN', - city: 'Norton Municipal Airport', - state: 'KS', - lat: 39.85047, - lon: -99.89469, - }, - KOEL: { - id: 'KOEL', - city: 'Oakley Municipal Airport', - state: 'KS', - lat: 39.11178, - lon: -100.81667, - }, - KOIN: { - id: 'KOIN', - city: 'Oberlin Municipal Airport', - state: 'KS', - lat: 39.83489, - lon: -100.5397799, - }, - KOJC: { - id: 'KOJC', - city: 'Olathe, Johnson County Executive Airport', - state: 'KS', - lat: 38.85, - lon: -94.73917, - }, - KOWI: { - id: 'KOWI', - city: 'Ottawa Municipal Airport', - state: 'KS', - lat: 38.5409, - lon: -95.2542, - }, - KPPF: { - id: 'KPPF', - city: 'Parsons, Tri-City Airport', - state: 'KS', - lat: 37.32778, - lon: -95.50417, - }, - KPTS: { - id: 'KPTS', - city: 'Atkinson Municipal Airport', - state: 'KS', - lat: 37.4494, - lon: -94.7311, - }, - KPTT: { - id: 'KPTT', - city: 'Pratt Municipal', - state: 'KS', - lat: 37.7, - lon: -98.75, - }, - KRSL: { - id: 'KRSL', - city: 'Russell, Russell Municipal Airport', - state: 'KS', - lat: 38.87278, - lon: -98.8130599, - }, - KSLN: { - id: 'KSLN', - city: 'Salina, Salina Municipal Airport', - state: 'KS', - lat: 38.78, - lon: -97.64417, - }, - KSYF: { - id: 'KSYF', - city: 'ST FRANCIS', - state: 'KS', - lat: 39.763884, - lon: -101.797861, - }, - KTOP: { - id: 'KTOP', - city: 'Topeka, Philip Billard Municipal Airport', - state: 'KS', - lat: 39.0725, - lon: -95.6258299, - }, - KTQK: { - id: 'KTQK', - city: 'Scott City Municipal Airport', - state: 'KS', - lat: 38.47502, - lon: -100.88444, - }, - KUKL: { - id: 'KUKL', - city: 'Coffey County Airport', - state: 'KS', - lat: 38.30247, - lon: -95.72497, - }, - KULS: { - id: 'KULS', - city: 'Ulysses Airport', - state: 'KS', - lat: 37.604, - lon: -101.37356, - }, - KWLD: { - id: 'KWLD', - city: 'Winfield / Arkansas City, Strother Field', - state: 'KS', - lat: 37.1680599, - lon: -97.03694, - }, - KAUM: { - id: 'KAUM', - city: 'Austin Municipal', - state: 'MN', - lat: 43.66667, - lon: -92.93333, - }, - KAXN: { - id: 'KAXN', - city: 'Alexandria, Chandler Field', - state: 'MN', - lat: 45.8686099, - lon: -95.39417, - }, - KBBB: { - id: 'KBBB', - city: 'Benson Municipal Airport', - state: 'MN', - lat: 45.3309799, - lon: -95.64692, - }, - KBDE: { - id: 'KBDE', - city: 'Baudette International Airport', - state: 'MN', - lat: 48.72605, - lon: -94.61215, - }, - KBDH: { - id: 'KBDH', - city: 'Willmar Municipal Airport - John L. Rice Field', - state: 'MN', - lat: 45.11113, - lon: -95.1258299, - }, - KBJI: { - id: 'KBJI', - city: 'Bemidji', - state: 'MN', - lat: 47.50762, - lon: -94.92783, - }, - KBRD: { - id: 'KBRD', - city: 'Brainerd - Crow Wing County Airport', - state: 'MN', - lat: 46.40205, - lon: -94.12734, - }, - KCDD: { - id: 'KCDD', - city: 'Crane Lake - Scotts Seaplane Base', - state: 'MN', - lat: 48.26014, - lon: -92.47485, - }, - KCFE: { - id: 'KCFE', - city: 'Buffalo, Buffalo Municipal Airport', - state: 'MN', - lat: 45.15889, - lon: -93.84306, - }, - KCKC: { - id: 'KCKC', - city: 'Grand Marais/Cook County Airport', - state: 'MN', - lat: 47.83665, - lon: -90.3864399, - }, - KCKN: { - id: 'KCKN', - city: 'Crookston Municipal Field', - state: 'MN', - lat: 47.84042, - lon: -96.6200999, - }, - KCNB: { - id: 'KCNB', - city: 'Canby Airfield', - state: 'MN', - lat: 44.7295, - lon: -96.266, - }, - KCOQ: { - id: 'KCOQ', - city: 'Cloquet Carlton County Airport', - state: 'MN', - lat: 46.69869, - lon: -92.5034, - }, - KCQM: { - id: 'KCQM', - city: 'Cook Municipal Airport', - state: 'MN', - lat: 47.81997, - lon: -92.68169, - }, - KDLH: { - id: 'KDLH', - city: 'Duluth International Airport', - state: 'MN', - lat: 46.84347, - lon: -92.1866, - }, - KDTL: { - id: 'KDTL', - city: 'Detroit Lakes Airport-Wething Field', - state: 'MN', - lat: 46.8285399, - lon: -95.88567, - }, - KDVP: { - id: 'KDVP', - city: 'Slayton Municipal Airport', - state: 'MN', - lat: 43.99055, - lon: -95.78102, - }, - KDXX: { - id: 'KDXX', - city: 'Madison, Madison-Lac Qui Parle County Airport', - state: 'MN', - lat: 44.9839399, - lon: -96.1788399, - }, - KDYT: { - id: 'KDYT', - city: 'Duluth - Sky Harbor Airport', - state: 'MN', - lat: 46.72452, - lon: -92.0444799, - }, - KELO: { - id: 'KELO', - city: 'Ely, Ely Municipal Airport', - state: 'MN', - lat: 47.81667, - lon: -91.83333, - }, - KETH: { - id: 'KETH', - city: 'Wheaton Municipal Airport', - state: 'MN', - lat: 45.78284, - lon: -96.54607, - }, - KEVM: { - id: 'KEVM', - city: 'Eveleth-Virginia Municipal Airport', - state: 'MN', - lat: 47.4274, - lon: -92.49717, - }, - KFBL: { - id: 'KFBL', - city: 'Faribault, Faribault Municipal Airport', - state: 'MN', - lat: 44.32983, - lon: -93.31186, - }, - KFCM: { - id: 'KFCM', - city: 'Minneapolis - Flying Cloud Airport', - state: 'MN', - lat: 44.83217, - lon: -93.47051, - }, - KFFM: { - id: 'KFFM', - city: 'Fergus Falls Municipal Airport-Einar Mickel', - state: 'MN', - lat: 46.28655, - lon: -96.15338, - }, - KFGN: { - id: 'KFGN', - city: 'Flag Island', - state: 'MN', - lat: 49.31667, - lon: -94.9, - }, - KFKA: { - id: 'KFKA', - city: 'Preston, Fillmore County Airport', - state: 'MN', - lat: 43.67701, - lon: -92.17422, - }, - KFOZ: { - id: 'KFOZ', - city: 'Bigfork Municipal Airport', - state: 'MN', - lat: 47.78317, - lon: -93.65326, - }, - KFRM: { - id: 'KFRM', - city: 'Fairmont, Fairmont Municipal Airport', - state: 'MN', - lat: 43.65, - lon: -94.41667, - }, - KFSE: { - id: 'KFSE', - city: 'Fosston, Fosston Municipal Airport', - state: 'MN', - lat: 47.59278, - lon: -95.77333, - }, - KGDB: { - id: 'KGDB', - city: 'Granite Falls, Granite Falls Municipal Airport/Lenzen-Roe Memorial Field', - state: 'MN', - lat: 44.75306, - lon: -95.55583, - }, - KGHW: { - id: 'KGHW', - city: 'Glenwood Municipal Airport', - state: 'MN', - lat: 45.64564, - lon: -95.31876, - }, - KGNA: { - id: 'KGNA', - city: 'Grand Marais, The Bay of Grand Marais', - state: 'MN', - lat: 47.7472, - lon: -90.3443999, - }, - KGPZ: { - id: 'KGPZ', - city: 'Grand Rapids, Grand Rapids/Itasca County Airport-Gordon Newstrom Field', - state: 'MN', - lat: 47.21667, - lon: -93.51667, - }, - KGYL: { - id: 'KGYL', - city: 'Glencoe Municipal Airport', - state: 'MN', - lat: 44.7588, - lon: -94.0905, - }, - KHCD: { - id: 'KHCD', - city: 'Hutchinson, Hutchinson Municipal Airport-Butler Field', - state: 'MN', - lat: 44.85961, - lon: -94.38551, - }, - KHCO: { - id: 'KHCO', - city: 'Hallock Municipal Airport', - state: 'MN', - lat: 48.75245, - lon: -96.93759, - }, - KHIB: { - id: 'KHIB', - city: 'Chisholm-Hibbing Airport', - state: 'MN', - lat: 47.38039, - lon: -92.83245, - }, - KHZX: { - id: 'KHZX', - city: 'Mc Gregor - Isedor Iverson Airport', - state: 'MN', - lat: 46.61904, - lon: -93.31267, - }, - KINL: { - id: 'KINL', - city: 'Falls International Airport', - state: 'MN', - lat: 48.55944, - lon: -93.39556, - }, - KJKJ: { - id: 'KJKJ', - city: 'Moorhead Municipal Airport', - state: 'MN', - lat: 46.8404, - lon: -96.65442, - }, - KJMR: { - id: 'KJMR', - city: 'Mora Municipal Airport', - state: 'MN', - lat: 45.88863, - lon: -93.26901, - }, - KJYG: { - id: 'KJYG', - city: 'St. James Municipal Airport', - state: 'MN', - lat: 43.98558, - lon: -94.55299, - }, - KLJF: { - id: 'KLJF', - city: 'Litchfield Municipal Airport', - state: 'MN', - lat: 45.09485, - lon: -94.50837, - }, - KLVN: { - id: 'KLVN', - city: 'Minneapolis, Airlake Airport', - state: 'MN', - lat: 44.62778, - lon: -93.22806, - }, - KLXL: { - id: 'KLXL', - city: 'Little Falls, Little Falls/Morrison County Airport-Lindbergh Field', - state: 'MN', - lat: 45.95, - lon: -94.35, - }, - KLYV: { - id: 'KLYV', - city: 'Quentin Aanenson Field Airport', - state: 'MN', - lat: 43.62166, - lon: -96.2139399, - }, - KMGG: { - id: 'KMGG', - city: 'Maple Lake, Maple Lake Municipal Airport', - state: 'MN', - lat: 45.2353499, - lon: -93.98959, - }, - KMIC: { - id: 'KMIC', - city: 'Minneapolis, Crystal Airport', - state: 'MN', - lat: 45.0625, - lon: -93.35083, - }, - KMJQ: { - id: 'KMJQ', - city: 'Jackson, Jackson Municipal Airport', - state: 'MN', - lat: 43.65, - lon: -94.98333, - }, - KMKT: { - id: 'KMKT', - city: 'Mankato, Mankato Regional Airport', - state: 'MN', - lat: 44.21667, - lon: -93.91667, - }, - KMML: { - id: 'KMML', - city: 'Marshall, Southwest Minnesota Regional Airport - Marshall/Ryan Field', - state: 'MN', - lat: 44.45, - lon: -95.81667, - }, - KMOX: { - id: 'KMOX', - city: 'Morris, Morris Municipal Airport', - state: 'MN', - lat: 45.56667, - lon: -95.9666699, - }, - KMSP: { - id: 'KMSP', - city: 'Minneapolis, Minneapolis-St. Paul International Airport', - state: 'MN', - lat: 44.88306, - lon: -93.22889, - }, - KMVE: { - id: 'KMVE', - city: 'Montevideo-Chippewa County Airport', - state: 'MN', - lat: 44.96749, - lon: -95.71159, - }, - KMWM: { - id: 'KMWM', - city: 'Windom Municipal Airport', - state: 'MN', - lat: 43.90999, - lon: -95.10723, - }, - KMZH: { - id: 'KMZH', - city: 'Moose Lake Carlton County Airport', - state: 'MN', - lat: 46.41632, - lon: -92.80491, - }, - KONA: { - id: 'KONA', - city: 'Winona, Winona Municipal Airport-Max Conrad Field', - state: 'MN', - lat: 44.0833299, - lon: -91.7, - }, - KORB: { - id: 'KORB', - city: 'Orr Regional Airport', - state: 'MN', - lat: 48.0170699, - lon: -92.85376, - }, - KOTG: { - id: 'KOTG', - city: 'Worthington, Worthington Municipal Airport', - state: 'MN', - lat: 43.65, - lon: -95.58333, - }, - KOVL: { - id: 'KOVL', - city: 'Olivia Regional Airport', - state: 'MN', - lat: 44.77923, - lon: -95.03033, - }, - KOWA: { - id: 'KOWA', - city: 'Owatonna Degner Regional Airport', - state: 'MN', - lat: 44.11907, - lon: -93.25687, - }, - KPEX: { - id: 'KPEX', - city: 'Paynesville, Paynesville Municipal Airport', - state: 'MN', - lat: 45.37247, - lon: -94.73878, - }, - KPKD: { - id: 'KPKD', - city: 'Park Rapids Municipal Airport', - state: 'MN', - lat: 46.8996799, - lon: -95.06681, - }, - KPNM: { - id: 'KPNM', - city: 'Princeton', - state: 'MN', - lat: 45.56425, - lon: -93.6080099, - }, - KPQN: { - id: 'KPQN', - city: 'Pipestone Municipal Airport', - state: 'MN', - lat: 43.98542, - lon: -96.29764, - }, - KPWC: { - id: 'KPWC', - city: 'Pine River Regional Airport', - state: 'MN', - lat: 46.72654, - lon: -94.38485, - }, - KROS: { - id: 'KROS', - city: 'Rush City Regional Airport', - state: 'MN', - lat: 45.69628, - lon: -92.95424, - }, - KROX: { - id: 'KROX', - city: 'Roseau, Roseau Municipal Airport/Rudy Billberg Field', - state: 'MN', - lat: 48.85, - lon: -95.7, - }, - KRRT: { - id: 'KRRT', - city: 'Warroad International Memorial Airport', - state: 'MN', - lat: 48.93183, - lon: -95.3404599, - }, - KRST: { - id: 'KRST', - city: 'Rochester, Rochester International Airport', - state: 'MN', - lat: 43.90417, - lon: -92.49167, - }, - KRWF: { - id: 'KRWF', - city: 'Redwood Falls Municipal Airport', - state: 'MN', - lat: 44.54828, - lon: -95.08042, - }, - KRYM: { - id: 'KRYM', - city: 'Ray S Miller Army Airfield', - state: 'MN', - lat: 46.08997, - lon: -94.35986, - }, - KSAZ: { - id: 'KSAZ', - city: 'Staples, Staples Municipal Airport', - state: 'MN', - lat: 46.38083, - lon: -94.80667, - }, - KSGS: { - id: 'KSGS', - city: 'South St. Paul Municipal-Richard E. Flemi', - state: 'MN', - lat: 44.86006, - lon: -93.03203, - }, - KSTC: { - id: 'KSTC', - city: 'St. Cloud Regional Airport', - state: 'MN', - lat: 45.54415, - lon: -94.05165, - }, - KSTP: { - id: 'KSTP', - city: 'Downtown Holman Field', - state: 'MN', - lat: 44.93237, - lon: -93.05588, - }, - KSYN: { - id: 'KSYN', - city: 'Stanton Airfield', - state: 'MN', - lat: 44.4736199, - lon: -93.01448, - }, - KTKC: { - id: 'KTKC', - city: 'Tracy, Tracy Municipal Airport', - state: 'MN', - lat: 44.24951, - lon: -95.61189, - }, - KTOB: { - id: 'KTOB', - city: 'Dodge Center Airport', - state: 'MN', - lat: 44.02026, - lon: -92.8295, - }, - KTVF: { - id: 'KTVF', - city: 'Thief River Falls, Thief River Falls Regional Airport', - state: 'MN', - lat: 48.06667, - lon: -96.18333, - }, - KTWM: { - id: 'KTWM', - city: 'Two Harbors', - state: 'MN', - lat: 47.05, - lon: -91.75, - }, - KULM: { - id: 'KULM', - city: 'New Ulm Municipal Airport', - state: 'MN', - lat: 44.32274, - lon: -94.50244, - }, - KVVV: { - id: 'KVVV', - city: 'Ortonville, Ortonville Muncipal-Martinson Field Airport', - state: 'MN', - lat: 45.30556, - lon: -96.42444, - }, - KVWU: { - id: 'KVWU', - city: 'Waskish Municipal Airport', - state: 'MN', - lat: 48.15014, - lon: -94.512, - }, - KXVG: { - id: 'KXVG', - city: 'Longville, Longville Municipal Airport', - state: 'MN', - lat: 46.99028, - lon: -94.20389, - }, - KAKQ: { - id: 'KAKQ', - city: 'Wakefield Municipal Airport', - state: 'VA', - lat: 36.98274, - lon: -77.00137, - }, - KAVC: { - id: 'KAVC', - city: 'South Hill, Mecklenburg-Brunswick Regional Airport', - state: 'VA', - lat: 36.68861, - lon: -78.05417, - }, - KBCB: { - id: 'KBCB', - city: 'Virginia Tech Airport', - state: 'VA', - lat: 37.21667, - lon: -80.41667, - }, - KBKT: { - id: 'KBKT', - city: 'Ft. Pickett / Blackstone', - state: 'VA', - lat: 37.0833299, - lon: -77.95, - }, - KCHO: { - id: 'KCHO', - city: 'Charlottesville-Albemarle Airport', - state: 'VA', - lat: 38.13738, - lon: -78.45516, - }, - KCJR: { - id: 'KCJR', - city: 'Culpeper Regional Airport', - state: 'VA', - lat: 38.52607, - lon: -77.85738, - }, - KCPK: { - id: 'KCPK', - city: 'Chesapeake, Chesapeake Municipal Airport', - state: 'VA', - lat: 36.66556, - lon: -76.32056, - }, - KCXE: { - id: 'KCXE', - city: 'Chase City Municipal Airport', - state: 'VA', - lat: 36.7883, - lon: -78.5016, - }, - KDAA: { - id: 'KDAA', - city: 'Fort Belvoir', - state: 'VA', - lat: 38.71667, - lon: -77.18333, - }, - KDAN: { - id: 'KDAN', - city: 'Danville, Danville Regional Airport', - state: 'VA', - lat: 36.57278, - lon: -79.33611, - }, - KDCA: { - id: 'KDCA', - city: 'Washington/Reagan National Airport, DC', - state: 'VA', - lat: 38.84833, - lon: -77.03417, - }, - KEMV: { - id: 'KEMV', - city: 'Emporia, Emporia-Greensville Regional Airport', - state: 'VA', - lat: 36.68694, - lon: -77.48278, - }, - KEZF: { - id: 'KEZF', - city: 'Fredericksburg, Shannon Airport', - state: 'VA', - lat: 38.26667, - lon: -77.45, - }, - KFAF: { - id: 'KFAF', - city: 'Fort Eustis / Felker', - state: 'VA', - lat: 37.13333, - lon: -76.61667, - }, - KFCI: { - id: 'KFCI', - city: 'Chesterfield County Airport', - state: 'VA', - lat: 37.406444, - lon: -77.524833, - }, - KFKN: { - id: 'KFKN', - city: 'Franklin / J B Rose', - state: 'VA', - lat: 36.7, - lon: -76.9, - }, - KFRR: { - id: 'KFRR', - city: 'Front Royal-warren County Airport', - state: 'VA', - lat: 38.9174999, - lon: -78.2535, - }, - KFVX: { - id: 'KFVX', - city: 'Farmville', - state: 'VA', - lat: 37.35, - lon: -78.43333, - }, - KFYJ: { - id: 'KFYJ', - city: 'West Point, Middle Peninsula Regional Airport', - state: 'VA', - lat: 37.52111, - lon: -76.7644399, - }, - KGVE: { - id: 'KGVE', - city: 'Gordonsville Municipal Airport', - state: 'VA', - lat: 38.156, - lon: -78.1658, - }, - KHEF: { - id: 'KHEF', - city: 'Manassas, Manassas Regional Airport/Harry P. Davis Field', - state: 'VA', - lat: 38.71667, - lon: -77.51667, - }, - KHLX: { - id: 'KHLX', - city: 'Hillsville', - state: 'VA', - lat: 36.76667, - lon: -80.81667, - }, - KHSP: { - id: 'KHSP', - city: 'Hot Springs / Ingalls', - state: 'VA', - lat: 37.95, - lon: -79.83333, - }, - KHWY: { - id: 'KHWY', - city: 'Warrenton-Fauquier Airport', - state: 'VA', - lat: 38.5876499, - lon: -77.71501, - }, - KIAD: { - id: 'KIAD', - city: 'Washington/Dulles International Airport, DC', - state: 'VA', - lat: 38.93472, - lon: -77.4475, - }, - KJFZ: { - id: 'KJFZ', - city: 'Tazewell County Airport', - state: 'VA', - lat: 37.064, - lon: -81.798, - }, - KJGG: { - id: 'KJGG', - city: 'Williamsburg-Jamestown Airport', - state: 'VA', - lat: 37.24157, - lon: -76.71672, - }, - KJYO: { - id: 'KJYO', - city: 'Leesburg / Godfrey', - state: 'VA', - lat: 39.0833299, - lon: -77.56667, - }, - KLFI: { - id: 'KLFI', - city: 'Langley Air Force Base', - state: 'VA', - lat: 37.0833299, - lon: -76.35, - }, - KLKU: { - id: 'KLKU', - city: 'Louisa, Louisa County Airport/Freeman Field', - state: 'VA', - lat: 38.00972, - lon: -77.97028, - }, - KLNP: { - id: 'KLNP', - city: 'Wise / Lonesome Pine', - state: 'VA', - lat: 36.98333, - lon: -82.53333, - }, - KLUA: { - id: 'KLUA', - city: 'Luray Caverns', - state: 'VA', - lat: 38.6671, - lon: -78.5006, - }, - KLVL: { - id: 'KLVL', - city: 'Lawrenceville/Brunswick Municipal Airport', - state: 'VA', - lat: 36.7727999, - lon: -77.7943, - }, - KLYH: { - id: 'KLYH', - city: 'Lynchburg, Lynchburg Regional Airport', - state: 'VA', - lat: 37.32083, - lon: -79.20667, - }, - KMFV: { - id: 'KMFV', - city: 'Melfa / Accomack Airport', - state: 'VA', - lat: 37.65, - lon: -75.76667, - }, - KMKJ: { - id: 'KMKJ', - city: 'Marion / Wytheville', - state: 'VA', - lat: 36.9, - lon: -81.35, - }, - KMTV: { - id: 'KMTV', - city: 'Martinsville', - state: 'VA', - lat: 36.63333, - lon: -80.01667, - }, - KNFE: { - id: 'KNFE', - city: 'Fentress, Naval Auxiliary Landing Field', - state: 'VA', - lat: 36.70083, - lon: -76.12833, - }, - KNGU: { - id: 'KNGU', - city: 'Norfolk, Naval Air Station', - state: 'VA', - lat: 36.93361, - lon: -76.29583, - }, - KNTU: { - id: 'KNTU', - city: 'Virginia Beach, Oceana, Naval Air Station', - state: 'VA', - lat: 36.82111, - lon: -76.02833, - }, - KNYG: { - id: 'KNYG', - city: 'Quantico Marine Corps Airfield - Turner Field', - state: 'VA', - lat: 38.50326, - lon: -77.30129, - }, - KOFP: { - id: 'KOFP', - city: 'Ashland, Hanover County Municipal Airport', - state: 'VA', - lat: 37.70806, - lon: -77.43444, - }, - KOKV: { - id: 'KOKV', - city: 'Winchester Regional', - state: 'VA', - lat: 39.15, - lon: -78.15, - }, - KOMH: { - id: 'KOMH', - city: 'Orange, Orange County Airport', - state: 'VA', - lat: 38.24722, - lon: -78.04556, - }, - KORF: { - id: 'KORF', - city: 'Norfolk, Norfolk International Airport', - state: 'VA', - lat: 36.90361, - lon: -76.19194, - }, - KPHF: { - id: 'KPHF', - city: 'Newport News, Newport News / Williamsburg International Airport', - state: 'VA', - lat: 37.13194, - lon: -76.49306, - }, - KPSK: { - id: 'KPSK', - city: 'Dublin / New River Valley', - state: 'VA', - lat: 37.13333, - lon: -80.68333, - }, - KPTB: { - id: 'KPTB', - city: 'Petersburg, Dinwiddie County Airport', - state: 'VA', - lat: 37.18333, - lon: -77.51667, - }, - KPVG: { - id: 'KPVG', - city: 'Norfolk Hampton Roads Executive Airport', - state: 'VA', - lat: 36.7801, - lon: -76.4488, - }, - KRIC: { - id: 'KRIC', - city: 'Richmond, Richmond International Airport', - state: 'VA', - lat: 37.51111, - lon: -77.32333, - }, - KRMN: { - id: 'KRMN', - city: 'Stafford, Stafford Regional Airport', - state: 'VA', - lat: 38.39806, - lon: -77.45528, - }, - KROA: { - id: 'KROA', - city: 'Roanoke, Roanoke Regional Airport', - state: 'VA', - lat: 37.31694, - lon: -79.97417, - }, - KSFQ: { - id: 'KSFQ', - city: 'Suffolk, Suffolk Municipal Airport', - state: 'VA', - lat: 36.68222, - lon: -76.60194, - }, - KSHD: { - id: 'KSHD', - city: 'Staunton / Shenandoah', - state: 'VA', - lat: 38.26667, - lon: -78.9, - }, - KTGI: { - id: 'KTGI', - city: 'Tangier Island Airport', - state: 'VA', - lat: 37.82587, - lon: -75.99766, - }, - KVBW: { - id: 'KVBW', - city: 'Bridgewater Air Park', - state: 'VA', - lat: 38.36674, - lon: -78.96033, - }, - KVJI: { - id: 'KVJI', - city: 'Abingdon', - state: 'VA', - lat: 36.68333, - lon: -82.03333, - }, - KWAL: { - id: 'KWAL', - city: 'Wallops Flight Facility Airport', - state: 'VA', - lat: 37.9372, - lon: -75.46619, - }, - KXSA: { - id: 'KXSA', - city: 'Tappahannock-Essex County Airport', - state: 'VA', - lat: 37.859611, - lon: -76.894111, - }, - KBCE: { - id: 'KBCE', - city: 'Bryce Canyon Airport', - state: 'UT', - lat: 37.7012799, - lon: -112.14897, - }, - KBDG: { - id: 'KBDG', - city: 'Blanding Municipal Airport', - state: 'UT', - lat: 37.586, - lon: -109.482, - }, - KBMC: { - id: 'KBMC', - city: 'Brigham City Regional Airport', - state: 'UT', - lat: 41.5464, - lon: -112.0601, - }, - KCDC: { - id: 'KCDC', - city: 'Cedar City Municipal Airport', - state: 'UT', - lat: 37.70675, - lon: -113.09695, - }, - KCNY: { - id: 'KCNY', - city: 'Moab, Canyonlands Field', - state: 'UT', - lat: 38.76, - lon: -109.74472, - }, - KDPG: { - id: 'KDPG', - city: 'Michael Army Airfield - Dugway Proving Ground', - state: 'UT', - lat: 40.18376, - lon: -112.9217, - }, - KDTA: { - id: 'KDTA', - city: 'Delta, Delta Municipal Airport', - state: 'UT', - lat: 39.38333, - lon: -112.50967, - }, - KENV: { - id: 'KENV', - city: 'Wendover / Air Force Auxillary Field', - state: 'UT', - lat: 40.72056, - lon: -114.03583, - }, - KHCR: { - id: 'KHCR', - city: 'Heber City Municipal-Russ McDonald Field Airport', - state: 'UT', - lat: 40.47742, - lon: -111.43295, - }, - KHIF: { - id: 'KHIF', - city: 'Hill Air Force Base', - state: 'UT', - lat: 41.11112, - lon: -111.96229, - }, - KHVE: { - id: 'KHVE', - city: 'Hanksville', - state: 'UT', - lat: 38.418037, - lon: -110.704038, - }, - KKNB: { - id: 'KKNB', - city: 'KANAB MUNICIPAL AIRPORT', - state: 'UT', - lat: 37.01, - lon: -112.53, - }, - KLGU: { - id: 'KLGU', - city: 'Logan-Cache Airport', - state: 'UT', - lat: 41.78652, - lon: -111.85187, - }, - KMLF: { - id: 'KMLF', - city: 'Milford Municipal Airport', - state: 'UT', - lat: 38.42252, - lon: -113.01089, - }, - KOGD: { - id: 'KOGD', - city: 'Ogden-Hinckley Airport', - state: 'UT', - lat: 41.19406, - lon: -112.01681, - }, - KPUC: { - id: 'KPUC', - city: 'Price - Carbon County Regional Airport', - state: 'UT', - lat: 39.60886, - lon: -110.75548, - }, - KPVU: { - id: 'KPVU', - city: 'Provo, Provo Municipal Airport', - state: 'UT', - lat: 40.21667, - lon: -111.71667, - }, - KRIF: { - id: 'KRIF', - city: 'Richfield Municipal Airport', - state: 'UT', - lat: 38.73411, - lon: -112.10158, - }, - KSGU: { - id: 'KSGU', - city: 'St George Municipal Airport', - state: 'UT', - lat: 37.0451, - lon: -113.50561, - }, - KSLC: { - id: 'KSLC', - city: 'Salt Lake City, Salt Lake City International Airport', - state: 'UT', - lat: 40.77069, - lon: -111.96503, - }, - KSPK: { - id: 'KSPK', - city: 'Spanish Fork Municipal Airport', - state: 'UT', - lat: 40.145, - lon: -111.6677, - }, - KTVY: { - id: 'KTVY', - city: 'Bolinder Field-Tooele Valley Airport', - state: 'UT', - lat: 40.61269, - lon: -112.35362, - }, - KVEL: { - id: 'KVEL', - city: 'Vernal Airport', - state: 'UT', - lat: 40.44295, - lon: -109.51273, - }, - KJSY: { - id: 'KJSY', - city: 'Joseph State Airport AWOS', - state: 'OR', - lat: 45.355889, - lon: -117.254083, - }, - KLGD: { - id: 'KLGD', - city: 'La Grande/Union County Airport', - state: 'OR', - lat: 45.29066, - lon: -118.00884, - }, - KLKV: { - id: 'KLKV', - city: 'Lake County Airport', - state: 'OR', - lat: 42.15664, - lon: -120.39721, - }, - KLMT: { - id: 'KLMT', - city: 'Klamath Falls International Airport', - state: 'OR', - lat: 42.14703, - lon: -121.72548, - }, - KMEH: { - id: 'KMEH', - city: 'Meacham', - state: 'OR', - lat: 45.51176, - lon: -118.42466, - }, - KMFR: { - id: 'KMFR', - city: 'Rogue Valley International Airport', - state: 'OR', - lat: 42.37503, - lon: -122.87696, - }, - KMMV: { - id: 'KMMV', - city: 'McMinnville, McMinnville Municipal Airport', - state: 'OR', - lat: 45.19611, - lon: -123.13222, - }, - KONO: { - id: 'KONO', - city: 'Ontario Municipal Airport', - state: 'OR', - lat: 44.01424, - lon: -117.00808, - }, - KONP: { - id: 'KONP', - city: 'Newport, Newport Municipal Airport', - state: 'OR', - lat: 44.58028, - lon: -124.05806, - }, - KOTH: { - id: 'KOTH', - city: 'Southwest Oregon Regional Airport', - state: 'OR', - lat: 43.41948, - lon: -124.2437, - }, - KPDT: { - id: 'KPDT', - city: 'Eastern Oregon Regional Airport at Pendleton', - state: 'OR', - lat: 45.69757, - lon: -118.83444, - }, - KPDX: { - id: 'KPDX', - city: 'Portland, Portland International Airport', - state: 'OR', - lat: 45.59578, - lon: -122.60917, - }, - KRBG: { - id: 'KRBG', - city: 'Roseburg Regional Airport', - state: 'OR', - lat: 43.23368, - lon: -123.3577, - }, - KRDM: { - id: 'KRDM', - city: 'Redmond Roberts Field', - state: 'OR', - lat: 44.25588, - lon: -121.14059, - }, - KREO: { - id: 'KREO', - city: 'Rome', - state: 'OR', - lat: 42.5901799, - lon: -117.86458, - }, - KSLE: { - id: 'KSLE', - city: 'Salem - McNary Field', - state: 'OR', - lat: 44.90493, - lon: -123.00096, - }, - KSPB: { - id: 'KSPB', - city: 'Scappoose Industrial Airpark', - state: 'OR', - lat: 45.7691, - lon: -122.86365, - }, - KSXT: { - id: 'KSXT', - city: 'Sexton Summit', - state: 'OR', - lat: 42.6, - lon: -123.3656, - }, - KTMK: { - id: 'KTMK', - city: 'Tillamook, Tillamook Airport', - state: 'OR', - lat: 45.4180599, - lon: -123.81444, - }, - KTTD: { - id: 'KTTD', - city: 'Portland, Portland-Troutdale Airport', - state: 'OR', - lat: 45.55111, - lon: -122.40889, - }, - KUAO: { - id: 'KUAO', - city: 'Aurora State Airport', - state: 'OR', - lat: 45.24658, - lon: -122.77095, - }, - PARO: { - id: 'PARO', - city: 'PARKDALE', - state: 'OR', - lat: 45.54444, - lon: -121.61667, - }, - PCYO: { - id: 'PCYO', - city: 'PRARIE CITY', - state: 'OR', - lat: 44.44083, - lon: -118.62778, - }, - PNGO: { - id: 'PNGO', - city: 'PINEGROVE', - state: 'OR', - lat: 45.65222, - lon: -121.50917, - }, - POBO: { - id: 'POBO', - city: 'POWELL BUTTE', - state: 'OR', - lat: 44.24833, - lon: -120.94972, - }, - KAAF: { - id: 'KAAF', - city: 'Apalachicola, Apalachicola', - state: 'FL', - lat: 29.72694, - lon: -85.02472, - }, - KAPF: { - id: 'KAPF', - city: 'Naples, Naples Municipal Airport', - state: 'FL', - lat: 26.15, - lon: -81.76667, - }, - KBCT: { - id: 'KBCT', - city: 'Boca Raton, Boca Raton Airport', - state: 'FL', - lat: 26.3786099, - lon: -80.10778, - }, - KBKV: { - id: 'KBKV', - city: 'Brooksville-Tampa Bay Regional Airport', - state: 'FL', - lat: 28.47361, - lon: -82.45444, - }, - KBOW: { - id: 'KBOW', - city: 'Bartow Municipal', - state: 'FL', - lat: 27.95, - lon: -81.78333, - }, - KCEW: { - id: 'KCEW', - city: 'Crestview, Sikes Airport', - state: 'FL', - lat: 30.77222, - lon: -86.52, - }, - KCGC: { - id: 'KCGC', - city: 'Crystal River Airport', - state: 'FL', - lat: 28.8673, - lon: -82.5712999, - }, - KCLW: { - id: 'KCLW', - city: 'Clearwater Air Park', - state: 'FL', - lat: 27.9742, - lon: -82.7563, - }, - KCOF: { - id: 'KCOF', - city: 'Cocoa - Patrick Air Force Base', - state: 'FL', - lat: 28.24219, - lon: -80.60799, - }, - KCRG: { - id: 'KCRG', - city: 'Jacksonville Craig Municipal Airport', - state: 'FL', - lat: 30.33709, - lon: -81.51275, - }, - KCTY: { - id: 'KCTY', - city: 'Cross City Airport', - state: 'FL', - lat: 29.633326, - lon: -83.105458, - }, - KDAB: { - id: 'KDAB', - city: 'Daytona Beach International Airport', - state: 'FL', - lat: 29.17354, - lon: -81.07186, - }, - KDED: { - id: 'KDED', - city: 'DeLand Municipal Airport', - state: 'FL', - lat: 29.067, - lon: -81.2837, - }, - KDTS: { - id: 'KDTS', - city: 'Destin, Destin-Ft. Walton Beach Airport', - state: 'FL', - lat: 30.39333, - lon: -86.4675, - }, - KECP: { - id: 'KECP', - city: 'Panama City - Northwest Florida Beaches International Airport', - state: 'FL', - lat: 30.3582, - lon: -85.7955999, - }, - KEGI: { - id: 'KEGI', - city: 'Duke Field / Eglin Auxiliary', - state: 'FL', - lat: 30.65, - lon: -86.51667, - }, - KEVB: { - id: 'KEVB', - city: 'New Smyrna Beach Municipal Airport', - state: 'FL', - lat: 29.05687, - lon: -80.94909, - }, - KEYW: { - id: 'KEYW', - city: 'Key West International Airport', - state: 'FL', - lat: 24.55707, - lon: -81.75539, - }, - KFHB: { - id: 'KFHB', - city: 'Fernandina Beach Municipal Airport', - state: 'FL', - lat: 30.61183, - lon: -81.46119, - }, - KFIN: { - id: 'KFIN', - city: 'Flagler County Airport', - state: 'FL', - lat: 29.4657, - lon: -81.20872, - }, - KFLL: { - id: 'KFLL', - city: 'Fort Lauderdale/Hollywood International Airport', - state: 'FL', - lat: 26.07874, - lon: -80.1622, - }, - KFMY: { - id: 'KFMY', - city: 'Fort Myers, Page Field', - state: 'FL', - lat: 26.58417, - lon: -81.8625, - }, - KFPR: { - id: 'KFPR', - city: 'Fort Pierce, St. Lucie County International Airport', - state: 'FL', - lat: 27.49806, - lon: -80.37667, - }, - KFPY: { - id: 'KFPY', - city: 'Perry-Foley Airport', - state: 'FL', - lat: 30.07081, - lon: -83.58154, - }, - KFXE: { - id: 'KFXE', - city: 'Fort Lauderdale, Fort Lauderdale Executive Airport', - state: 'FL', - lat: 26.2, - lon: -80.18333, - }, - KGIF: { - id: 'KGIF', - city: 'Winter Havens Gilbert Airport', - state: 'FL', - lat: 28.06138, - lon: -81.75684, - }, - KGNV: { - id: 'KGNV', - city: 'Gainesville, Gainesville Regional Airport', - state: 'FL', - lat: 29.69194, - lon: -82.27556, - }, - KHRT: { - id: 'KHRT', - city: 'Hurlburt Field', - state: 'FL', - lat: 30.41667, - lon: -86.68333, - }, - KHST: { - id: 'KHST', - city: 'Homestead Air Reserve Base', - state: 'FL', - lat: 25.4948799, - lon: -80.37324, - }, - KHWO: { - id: 'KHWO', - city: 'Hollywood, North Perry Airport', - state: 'FL', - lat: 25.99889, - lon: -80.24111, - }, - KIMM: { - id: 'KIMM', - city: 'IMMOKALEE', - state: 'FL', - lat: 26.43, - lon: -81.4, - }, - KINF: { - id: 'KINF', - city: 'Inverness Airport', - state: 'FL', - lat: 28.8086, - lon: -82.3165, - }, - KISM: { - id: 'KISM', - city: 'Kissimmee Gateway Airport', - state: 'FL', - lat: 28.29236, - lon: -81.43716, - }, - KJAX: { - id: 'KJAX', - city: 'Jacksonville International Airport', - state: 'FL', - lat: 30.49534, - lon: -81.6937, - }, - KLAL: { - id: 'KLAL', - city: 'Lakeland Regional', - state: 'FL', - lat: 27.98333, - lon: -82.01667, - }, - KLCQ: { - id: 'KLCQ', - city: 'Lake City Municipal Airport', - state: 'FL', - lat: 30.1821, - lon: -82.5769, - }, - KLEE: { - id: 'KLEE', - city: 'Leesburg International Airport', - state: 'FL', - lat: 28.82142, - lon: -81.80964, - }, - KLNA: { - id: 'KLNA', - city: 'Palm Beach County Park Airport', - state: 'FL', - lat: 26.59305, - lon: -80.08506, - }, - KMAI: { - id: 'KMAI', - city: 'Marianna Municipal Airport', - state: 'FL', - lat: 30.83698, - lon: -85.18347, - }, - KMCF: { - id: 'KMCF', - city: 'Macdill Air Force Base, Fl.', - state: 'FL', - lat: 27.85, - lon: -82.5, - }, - KMCO: { - id: 'KMCO', - city: 'Orlando International Airport', - state: 'FL', - lat: 28.41826, - lon: -81.32413, - }, - KMIA: { - id: 'KMIA', - city: 'Miami, Miami International Airport', - state: 'FL', - lat: 25.79056, - lon: -80.31639, - }, - KMKY: { - id: 'KMKY', - city: 'Marco Island Airport', - state: 'FL', - lat: 25.995, - lon: -81.6725, - }, - KMLB: { - id: 'KMLB', - city: 'Melbourne International Airport', - state: 'FL', - lat: 28.09973, - lon: -80.6356, - }, - KMTH: { - id: 'KMTH', - city: 'The Florida Keys - Marathon International Airport', - state: 'FL', - lat: 24.72626, - lon: -81.04765, - }, - KNDZ: { - id: 'KNDZ', - city: 'Milton, Whiting Field South', - state: 'FL', - lat: 30.69722, - lon: -87.02, - }, - KNIP: { - id: 'KNIP', - city: 'Jacksonville Naval Air Station', - state: 'FL', - lat: 30.23468, - lon: -81.67462, - }, - KNPA: { - id: 'KNPA', - city: 'Pensacola Naval Air Station', - state: 'FL', - lat: 30.35641, - lon: -87.32326, - }, - KNQX: { - id: 'KNQX', - city: 'Key West Naval Air Station', - state: 'FL', - lat: 24.5800899, - lon: -81.68293, - }, - KNRB: { - id: 'KNRB', - city: 'Mayport Naval Station - Adm David L. McDonald Field', - state: 'FL', - lat: 30.39589, - lon: -81.42286, - }, - KNSE: { - id: 'KNSE', - city: 'Milton - Whiting Field Naval Air Station North', - state: 'FL', - lat: 30.72848, - lon: -87.02192, - }, - KOBE: { - id: 'KOBE', - city: 'Okeechobee County Airport', - state: 'FL', - lat: 27.2628, - lon: -80.8498, - }, - KOCF: { - id: 'KOCF', - city: 'Ocala International Airport - Jim Taylor Field', - state: 'FL', - lat: 29.16372, - lon: -82.22097, - }, - KOMN: { - id: 'KOMN', - city: 'Ormond Beach, Ormond Beach Municipal Airport', - state: 'FL', - lat: 29.30111, - lon: -81.11361, - }, - KOPF: { - id: 'KOPF', - city: 'Miami, Opa Locka Airport', - state: 'FL', - lat: 25.91, - lon: -80.28306, - }, - KORL: { - id: 'KORL', - city: 'Orlando Executive Airport', - state: 'FL', - lat: 28.54655, - lon: -81.33543, - }, - KPAM: { - id: 'KPAM', - city: 'Tyndall Air Force Base', - state: 'FL', - lat: 30.06444, - lon: -85.5637, - }, - KPBI: { - id: 'KPBI', - city: 'West Palm Beach - Palm Beach International Airport', - state: 'FL', - lat: 26.6850999, - lon: -80.0991899, - }, - KPCM: { - id: 'KPCM', - city: 'Plant City, Plant City Municipal Airport', - state: 'FL', - lat: 28, - lon: -82.15, - }, - KPGD: { - id: 'KPGD', - city: 'Punta Gorda, Charlotte County Airport', - state: 'FL', - lat: 26.91778, - lon: -81.99361, - }, - KPIE: { - id: 'KPIE', - city: 'St. Petersburg/Clearwater Airport', - state: 'FL', - lat: 27.91259, - lon: -82.68554, - }, - KPMP: { - id: 'KPMP', - city: 'Pompano Beach, Pompano Beach Airpark', - state: 'FL', - lat: 26.24556, - lon: -80.11139, - }, - KPNS: { - id: 'KPNS', - city: 'Pensacola - Pensacola International Airport', - state: 'FL', - lat: 30.47806, - lon: -87.18694, - }, - KRSW: { - id: 'KRSW', - city: 'Fort Myers, Southwest Florida International Airport', - state: 'FL', - lat: 26.52694, - lon: -81.76639, - }, - KSEF: { - id: 'KSEF', - city: 'Sebring Regional Airport', - state: 'FL', - lat: 27.45639, - lon: -81.34239, - }, - KSFB: { - id: 'KSFB', - city: 'Orlando / Sanford Airport', - state: 'FL', - lat: 28.78333, - lon: -81.25, - }, - KSGJ: { - id: 'KSGJ', - city: 'Northeast Florida Regional Airport', - state: 'FL', - lat: 29.95924, - lon: -81.34105, - }, - KSPG: { - id: 'KSPG', - city: 'Albert Whitted Airport', - state: 'FL', - lat: 27.76852, - lon: -82.62564, - }, - KSRQ: { - id: 'KSRQ', - city: 'Sarasota / Bradenton, Sarasota-Bradenton International Airport', - state: 'FL', - lat: 27.40139, - lon: -82.55861, - }, - KSUA: { - id: 'KSUA', - city: 'Witham Field Airport', - state: 'FL', - lat: 27.18157, - lon: -80.22519, - }, - KTDR: { - id: 'KTDR', - city: 'Tyndall Drone Runway', - state: 'FL', - lat: 30.0333, - lon: -85.5333, - }, - KTIX: { - id: 'KTIX', - city: 'Titusville', - state: 'FL', - lat: 28.51667, - lon: -80.8, - }, - KTLH: { - id: 'KTLH', - city: 'Tallahassee International Airport', - state: 'FL', - lat: 30.39675, - lon: -84.35087, - }, - KTMB: { - id: 'KTMB', - city: 'Miami, Kendall-Tamiami Executive Airport', - state: 'FL', - lat: 25.64194, - lon: -80.43472, - }, - KTPA: { - id: 'KTPA', - city: 'Tampa, Tampa International Airport', - state: 'FL', - lat: 27.96139, - lon: -82.54028, - }, - KTPF: { - id: 'KTPF', - city: 'Tampa, Peter O Knight Airport', - state: 'FL', - lat: 27.91556, - lon: -82.44917, - }, - KTTS: { - id: 'KTTS', - city: 'Titusville, NASA Shuttle Landing Facility', - state: 'FL', - lat: 28.61667, - lon: -80.7, - }, - KVDF: { - id: 'KVDF', - city: 'Tampa, Vandenberg Airport', - state: 'FL', - lat: 28.01983, - lon: -82.3415, - }, - KVNC: { - id: 'KVNC', - city: 'Venice Municipal Airport', - state: 'FL', - lat: 27.0716, - lon: -82.44033, - }, - KVPS: { - id: 'KVPS', - city: 'Valparaiso / Eglin Air Force Base', - state: 'FL', - lat: 30.48333, - lon: -86.51667, - }, - KVQQ: { - id: 'KVQQ', - city: 'Cecil Airport', - state: 'FL', - lat: 30.21292, - lon: -81.8707, - }, - KVRB: { - id: 'KVRB', - city: 'Vero Beach, Vero Beach Municipal Airport', - state: 'FL', - lat: 27.65556, - lon: -80.41806, - }, - KXMR: { - id: 'KXMR', - city: 'Cocoa Beach, Cape Canaveral Air Force Station Skid Strip', - state: 'FL', - lat: 28.46667, - lon: -80.56667, - }, - KZPH: { - id: 'KZPH', - city: 'Zephyrhills Airport', - state: 'FL', - lat: 28.2281, - lon: -82.1559, - }, - KABH: { - id: 'KABH', - city: 'ELLICOTT-B AFA', - state: 'CO', - lat: 38.7578, - lon: -104.3013, - }, - KAEJ: { - id: 'KAEJ', - city: 'Central Colorado Regional Airport', - state: 'CO', - lat: 38.81416, - lon: -106.12069, - }, - KAFF: { - id: 'KAFF', - city: 'Air Force Academy', - state: 'CO', - lat: 38.96667, - lon: -104.81667, - }, - KAJZ: { - id: 'KAJZ', - city: 'Delta/Blake Field Airport', - state: 'CO', - lat: 38.7868799, - lon: -108.06584, - }, - KAKO: { - id: 'KAKO', - city: 'Colorado Plains Regional Airport', - state: 'CO', - lat: 40.17428, - lon: -103.21459, - }, - KALS: { - id: 'KALS', - city: 'San Luis Valley Regional Airport', - state: 'CO', - lat: 37.43933, - lon: -105.8618, - }, - KANK: { - id: 'KANK', - city: 'Harriet Alexander Field Airport', - state: 'CO', - lat: 38.53828, - lon: -106.04864, - }, - KAPA: { - id: 'KAPA', - city: 'Denver - Centennial Airport', - state: 'CO', - lat: 39.55991, - lon: -104.84841, - }, - KASE: { - id: 'KASE', - city: 'Aspen-Pitkin County Airport', - state: 'CO', - lat: 39.22992, - lon: -106.87051, - }, - KBDU: { - id: 'KBDU', - city: 'Boulder Municipal Airport', - state: 'CO', - lat: 40.0394297, - lon: -105.2258217, - }, - KBJC: { - id: 'KBJC', - city: 'Broomfield / Jeffco', - state: 'CO', - lat: 39.90085, - lon: -105.10417, - }, - KBKF: { - id: 'KBKF', - city: 'Buckley Air Force Base Airport', - state: 'CO', - lat: 39.71331, - lon: -104.75806, - }, - KCAG: { - id: 'KCAG', - city: 'Craig-Moffat Airport', - state: 'CO', - lat: 40.49297, - lon: -107.52394, - }, - KCCU: { - id: 'KCCU', - city: 'Copper Mountain - Red Cliff Pass', - state: 'CO', - lat: 39.47523, - lon: -106.15228, - }, - KCEZ: { - id: 'KCEZ', - city: 'Cortez-Montezuma County Airport', - state: 'CO', - lat: 37.30706, - lon: -108.62644, - }, - KCFO: { - id: 'KCFO', - city: 'Colorado Air and Space Port Airport', - state: 'CO', - lat: 39.78419, - lon: -104.53764, - }, - KCOS: { - id: 'KCOS', - city: 'City of Colorado Springs Municipal Airport', - state: 'CO', - lat: 38.8094899, - lon: -104.68873, - }, - KCPW: { - id: 'KCPW', - city: 'Pagosa Springs, Wolf Creek Pass', - state: 'CO', - lat: 37.45139, - lon: -106.80028, - }, - KCWN: { - id: 'KCWN', - city: 'Cheyenne Mountain', - state: 'CO', - lat: 38.7434299, - lon: -104.84334, - }, - KDEN: { - id: 'KDEN', - city: 'Denver, Denver International Airport', - state: 'CO', - lat: 39.84658, - lon: -104.65622, - }, - KDRO: { - id: 'KDRO', - city: 'Durango-La Plata County Airport', - state: 'CO', - lat: 37.14312, - lon: -107.76023, - }, - KEEO: { - id: 'KEEO', - city: 'Meeker Airport', - state: 'CO', - lat: 40.0444, - lon: -107.88832, - }, - KEGE: { - id: 'KEGE', - city: 'Eagle County Regional', - state: 'CO', - lat: 39.65, - lon: -106.91667, - }, - KEIK: { - id: 'KEIK', - city: 'Erie Municipal Airport', - state: 'CO', - lat: 40.01169, - lon: -105.05033, - }, - KFCS: { - id: 'KFCS', - city: 'Butts Army Airfield (Fort Carson)', - state: 'CO', - lat: 38.68312, - lon: -104.75977, - }, - KFLY: { - id: 'KFLY', - city: 'Meadow Lake Airport', - state: 'CO', - lat: 38.94391, - lon: -104.5684, - }, - KFMM: { - id: 'KFMM', - city: 'Fort Morgan Municipal Airport', - state: 'CO', - lat: 40.33148, - lon: -103.80704, - }, - KFNL: { - id: 'KFNL', - city: 'Fort Collins/Loveland - Northern Colorado Regional Airport', - state: 'CO', - lat: 40.45, - lon: -105.01667, - }, - KGJT: { - id: 'KGJT', - city: 'Grand Junction Regional Airport', - state: 'CO', - lat: 39.13389, - lon: -108.53861, - }, - KGNB: { - id: 'KGNB', - city: 'Granby-Grand County Airport', - state: 'CO', - lat: 40.09006, - lon: -105.91664, - }, - KGUC: { - id: 'KGUC', - city: 'Gunnison, Gunnison-Crested Butte Regional Airport', - state: 'CO', - lat: 38.53333, - lon: -106.93333, - }, - KGXY: { - id: 'KGXY', - city: 'Greeley, Greeley-Weld County Airport', - state: 'CO', - lat: 40.43333, - lon: -104.63333, - }, - KHDN: { - id: 'KHDN', - city: 'Hayden, Yampa Valley Airport', - state: 'CO', - lat: 40.48333, - lon: -107.2166699, - }, - KHEQ: { - id: 'KHEQ', - city: 'Holyoke Airport', - state: 'CO', - lat: 40.57155, - lon: -102.27676, - }, - KITR: { - id: 'KITR', - city: 'Burlington - Carson County Airport', - state: 'CO', - lat: 39.24149, - lon: -102.2818999, - }, - KLAA: { - id: 'KLAA', - city: 'Lamar Municipal Airport', - state: 'CO', - lat: 38.0717799, - lon: -102.68745, - }, - KLHX: { - id: 'KLHX', - city: 'La Junta Municipal Airport', - state: 'CO', - lat: 38.04949, - lon: -103.51334, - }, - KLIC: { - id: 'KLIC', - city: 'Limon Municipal Airport', - state: 'CO', - lat: 39.27334, - lon: -103.66738, - }, - KLMO: { - id: 'KLMO', - city: 'Vance Brand Airport', - state: 'CO', - lat: 40.16115, - lon: -105.16042, - }, - KLXV: { - id: 'KLXV', - city: 'Leadville, Lake County Airport', - state: 'CO', - lat: 39.22806, - lon: -106.31611, - }, - KMNH: { - id: 'KMNH', - city: 'Elbert Mountain - Monument Pass', - state: 'CO', - lat: 39.22317, - lon: -104.6422599, - }, - KMTJ: { - id: 'KMTJ', - city: 'Montrose, Montrose Regional Airport', - state: 'CO', - lat: 38.505, - lon: -107.8975, - }, - KMYP: { - id: 'KMYP', - city: 'Salida - Monarch Pass', - state: 'CO', - lat: 38.4972, - lon: -106.3197, - }, - KPSO: { - id: 'KPSO', - city: 'Stevens Field, Pagosa Springs', - state: 'CO', - lat: 37.2862, - lon: -107.056, - }, - KPUB: { - id: 'KPUB', - city: 'Pueblo Memorial Airport', - state: 'CO', - lat: 38.28869, - lon: -104.5057, - }, - KRCV: { - id: 'KRCV', - city: 'Astronaut Kent Rominger - Del Norte', - state: 'CO', - lat: 37.7138, - lon: -106.352, - }, - KRIL: { - id: 'KRIL', - city: 'Garfield County Regional Airport', - state: 'CO', - lat: 39.52793, - lon: -107.71961, - }, - KSBS: { - id: 'KSBS', - city: 'Steamboat Springs', - state: 'CO', - lat: 40.5153, - lon: -106.86767, - }, - KSPD: { - id: 'KSPD', - city: 'Springfield, Comanche National Grassland', - state: 'CO', - lat: 37.28333, - lon: -102.61667, - }, - KSTK: { - id: 'KSTK', - city: 'Sterling Municipal Airport', - state: 'CO', - lat: 40.61331, - lon: -103.26109, - }, - KTAD: { - id: 'KTAD', - city: 'Perry Stokes Airport', - state: 'CO', - lat: 37.26218, - lon: -104.33184, - }, - KTEX: { - id: 'KTEX', - city: 'Telluride, Telluride Regional Airport', - state: 'CO', - lat: 37.95389, - lon: -107.90861, - }, - KVTP: { - id: 'KVTP', - city: 'La Veta Mountain, La Veta Pass', - state: 'CO', - lat: 37.50111, - lon: -105.16694, - }, - KALW: { - id: 'KALW', - city: 'Walla Walla Regional Airport', - state: 'WA', - lat: 46.09462, - lon: -118.2858, - }, - KAWO: { - id: 'KAWO', - city: 'Arlington Municipal Airport', - state: 'WA', - lat: 48.1584999, - lon: -122.15909, - }, - KBFI: { - id: 'KBFI', - city: 'Boeing Field - King County International Airport', - state: 'WA', - lat: 47.54548, - lon: -122.3147, - }, - KBLI: { - id: 'KBLI', - city: 'Bellingham, Bellingham International Airport', - state: 'WA', - lat: 48.79911, - lon: -122.54064, - }, - KBVS: { - id: 'KBVS', - city: 'Burlington/Mount Vernon, Skagit Regional Airport', - state: 'WA', - lat: 48.47083, - lon: -122.42083, - }, - KCLM: { - id: 'KCLM', - city: 'Port Angeles Fairchild International Airport', - state: 'WA', - lat: 48.12194, - lon: -123.50661, - }, - KCLS: { - id: 'KCLS', - city: 'Chehalis-Centralia Airport', - state: 'WA', - lat: 46.677, - lon: -122.9827, - }, - KDEW: { - id: 'KDEW', - city: 'Deer Park, Deer Park Airport', - state: 'WA', - lat: 47.97417, - lon: -117.42833, - }, - KDLS: { - id: 'KDLS', - city: 'The Dalles Municipal Airport', - state: 'WA', - lat: 45.61901, - lon: -121.16572, - }, - KEAT: { - id: 'KEAT', - city: 'Wenatchee - Pangborn Memorial Airport', - state: 'WA', - lat: 47.39749, - lon: -120.20121, - }, - KELN: { - id: 'KELN', - city: 'Ellensburg, Ellensburg Bowers Field', - state: 'WA', - lat: 47.0337699, - lon: -120.53132, - }, - KEPH: { - id: 'KEPH', - city: 'Ephrata, Ephrata Municipal Airport', - state: 'WA', - lat: 47.3075, - lon: -119.51583, - }, - KFHR: { - id: 'KFHR', - city: 'Friday Harbor Airport', - state: 'WA', - lat: 48.52, - lon: -123.02637, - }, - KFLW: { - id: 'KFLW', - city: 'Kettle Falls', - state: 'WA', - lat: 48.595, - lon: -118.12417, - }, - KGEG: { - id: 'KGEG', - city: 'Spokane, Spokane International Airport', - state: 'WA', - lat: 47.62139, - lon: -117.52778, - }, - KGRF: { - id: 'KGRF', - city: 'Fort Lewis / Gray U. S. Army Airfield', - state: 'WA', - lat: 47.11667, - lon: -122.55, - }, - KHQM: { - id: 'KHQM', - city: 'Hoquiam, Bowerman Airport', - state: 'WA', - lat: 46.97111, - lon: -123.92, - }, - KKLS: { - id: 'KKLS', - city: 'Southwest Washington Regional Airport', - state: 'WA', - lat: 46.11553, - lon: -122.89273, - }, - KMWH: { - id: 'KMWH', - city: 'Grant County Airport', - state: 'WA', - lat: 47.19299, - lon: -119.31451, - }, - KNOW: { - id: 'KNOW', - city: 'Port Angeles Coast Guard Air Station', - state: 'WA', - lat: 48.13333, - lon: -123.4, - }, - KNUW: { - id: 'KNUW', - city: 'Whidbey Island Naval Air Station - Ault Field', - state: 'WA', - lat: 48.35525, - lon: -122.66352, - }, - KOLM: { - id: 'KOLM', - city: 'Olympia, Olympia Airport', - state: 'WA', - lat: 46.97333, - lon: -122.90333, - }, - KOMK: { - id: 'KOMK', - city: 'Omak Airport', - state: 'WA', - lat: 48.46116, - lon: -119.52086, - }, - KORS: { - id: 'KORS', - city: 'Eastsound, Orcas Island Airport', - state: 'WA', - lat: 48.70806, - lon: -122.91028, - }, - KPAE: { - id: 'KPAE', - city: 'Everett Snohomish County', - state: 'WA', - lat: 47.92331, - lon: -122.28305, - }, - KPLU: { - id: 'KPLU', - city: 'Pierce County-Thun Field', - state: 'WA', - lat: 47.104, - lon: -122.287, - }, - KPSC: { - id: 'KPSC', - city: 'Tri-Cities Airport', - state: 'WA', - lat: 46.26955, - lon: -119.11813, - }, - KPUW: { - id: 'KPUW', - city: 'Pullman / Moscow Regional Airport', - state: 'WA', - lat: 46.74377, - lon: -117.11579, - }, - KPWT: { - id: 'KPWT', - city: 'Bremerton, Bremerton National Airport', - state: 'WA', - lat: 47.5, - lon: -122.75, - }, - KRLD: { - id: 'KRLD', - city: 'Richland Airport', - state: 'WA', - lat: 46.30859, - lon: -119.3058, - }, - KRNT: { - id: 'KRNT', - city: 'Renton Municipal Airport', - state: 'WA', - lat: 47.49509, - lon: -122.21437, - }, - KSEA: { - id: 'KSEA', - city: 'Seattle, Seattle-Tacoma International Airport', - state: 'WA', - lat: 47.4447199, - lon: -122.31361, - }, - KSFF: { - id: 'KSFF', - city: 'Spokane, Felts Field', - state: 'WA', - lat: 47.68556, - lon: -117.32028, - }, - KSHN: { - id: 'KSHN', - city: 'Shelton, Shelton Sanderson Field', - state: 'WA', - lat: 47.23806, - lon: -123.14083, - }, - KSKA: { - id: 'KSKA', - city: 'Fairchild Air Force Base', - state: 'WA', - lat: 47.61667, - lon: -117.65, - }, - KSMP: { - id: 'KSMP', - city: 'Stampede Pass', - state: 'WA', - lat: 47.27648, - lon: -121.33817, - }, - KTCM: { - id: 'KTCM', - city: 'Tacoma / McChord Air Force Base', - state: 'WA', - lat: 47.15, - lon: -122.48333, - }, - KTIW: { - id: 'KTIW', - city: 'Tacoma, Tacoma Narrows Airport', - state: 'WA', - lat: 47.2675, - lon: -122.57611, - }, - KUIL: { - id: 'KUIL', - city: 'Quillayute, Quillayute State Airport', - state: 'WA', - lat: 47.9375, - lon: -124.555, - }, - KVUO: { - id: 'KVUO', - city: 'Pearson Airfield', - state: 'WA', - lat: 45.62103, - lon: -122.65419, - }, - KYKM: { - id: 'KYKM', - city: 'Yakima Air Terminal - McAllister Field', - state: 'WA', - lat: 46.56402, - lon: -120.53484, - }, - KALK: { - id: 'KALK', - city: 'Pioneer Airfield', - state: 'AZ', - lat: 31.60564, - lon: -110.4281, - }, - KAVQ: { - id: 'KAVQ', - city: 'Tucson Marana Regional Airport', - state: 'AZ', - lat: 32.4096, - lon: -111.2184, - }, - KAZC: { - id: 'KAZC', - city: 'Colorado City, Colorado City Municipal Airport', - state: 'AZ', - lat: 36.95, - lon: -113, - }, - KBXK: { - id: 'KBXK', - city: 'Buckeye Municipal Airport', - state: 'AZ', - lat: 33.4204, - lon: -112.6862, - }, - KCGZ: { - id: 'KCGZ', - city: 'Casa Grande, Casa Grande Municipal Airport', - state: 'AZ', - lat: 32.95, - lon: -111.76667, - }, - KCHD: { - id: 'KCHD', - city: 'Chandler, Chandler Municipal Airport', - state: 'AZ', - lat: 33.26917, - lon: -111.81111, - }, - KCMR: { - id: 'KCMR', - city: 'Williams/Clark Memorial Airport', - state: 'AZ', - lat: 35.3054721, - lon: -112.1943889, - }, - KDMA: { - id: 'KDMA', - city: 'Davis-Monthan Air Force Base', - state: 'AZ', - lat: 32.16667, - lon: -110.88333, - }, - KDVT: { - id: 'KDVT', - city: 'Phoenix, Phoenix-Deer Valley Municipal Airport', - state: 'AZ', - lat: 33.69026, - lon: -112.06618, - }, - KFFZ: { - id: 'KFFZ', - city: 'Mesa / Falcon Field', - state: 'AZ', - lat: 33.46667, - lon: -111.73333, - }, - KFHU: { - id: 'KFHU', - city: 'Fort Huachuca, Libby AAF Ft Huachuca', - state: 'AZ', - lat: 31.58333, - lon: -110.33333, - }, - KFLG: { - id: 'KFLG', - city: 'Flagstaff Pulliam Airport', - state: 'AZ', - lat: 35.1443299, - lon: -111.66637, - }, - KGCN: { - id: 'KGCN', - city: 'Grand Canyon National Park Airport', - state: 'AZ', - lat: 35.94582, - lon: -112.15538, - }, - KGEU: { - id: 'KGEU', - city: 'Glendale, Glendale Municipal Airport', - state: 'AZ', - lat: 33.52722, - lon: -112.29528, - }, - KGXF: { - id: 'KGXF', - city: 'Gila Bend Air Force Auxiliary Field', - state: 'AZ', - lat: 32.8875, - lon: -112.72, - }, - KGYR: { - id: 'KGYR', - city: 'Goodyear Municipal', - state: 'AZ', - lat: 33.41667, - lon: -112.38333, - }, - KHII: { - id: 'KHII', - city: 'Havasu City Airport', - state: 'AZ', - lat: 34.56595, - lon: -114.35224, - }, - KIFP: { - id: 'KIFP', - city: 'Bullhead City, Laughlin/Bullhead International Airport', - state: 'AZ', - lat: 35.1575, - lon: -114.55944, - }, - KIGM: { - id: 'KIGM', - city: 'Kingman, Kingman Airport', - state: 'AZ', - lat: 35.2577799, - lon: -113.93306, - }, - KINW: { - id: 'KINW', - city: 'Winslow, Winslow Municipal Airport', - state: 'AZ', - lat: 35.02806, - lon: -110.72083, - }, - KIWA: { - id: 'KIWA', - city: 'Phoenix-Mesa Gateway Airport', - state: 'AZ', - lat: 33.31667, - lon: -111.65, - }, - KJTC: { - id: 'KJTC', - city: 'Springerville Municipal Airport', - state: 'AZ', - lat: 34.1293999, - lon: -109.3109, - }, - KLGF: { - id: 'KLGF', - city: 'Laguna Army Airfield', - state: 'AZ', - lat: 32.86459, - lon: -114.39298, - }, - KLUF: { - id: 'KLUF', - city: 'Luke Air Force Base / Phoenix', - state: 'AZ', - lat: 33.53333, - lon: -112.38333, - }, - KMZJ: { - id: 'KMZJ', - city: 'Pinal Airpark', - state: 'AZ', - lat: 32.50983, - lon: -111.32533, - }, - KNOZ: { - id: 'KNOZ', - city: 'Yuma Auxiliary Airfield', - state: 'AZ', - lat: 32.5, - lon: -114.45, - }, - KNYL: { - id: 'KNYL', - city: 'Yuma, Marine Corps Air Station', - state: 'AZ', - lat: 32.6594399, - lon: -114.59306, - }, - KOLS: { - id: 'KOLS', - city: 'Nogales, Nogales International Airport', - state: 'AZ', - lat: 31.42083, - lon: -110.84583, - }, - KPAN: { - id: 'KPAN', - city: 'Payson Airport', - state: 'AZ', - lat: 34.2568364, - lon: -111.3392558, - }, - KPGA: { - id: 'KPGA', - city: 'Page, Page Municipal Airport', - state: 'AZ', - lat: 36.92056, - lon: -111.44806, - }, - KPHX: { - id: 'KPHX', - city: 'Phoenix, Phoenix Sky Harbor International Airport', - state: 'AZ', - lat: 33.427799, - lon: -112.003465, - }, - KPRC: { - id: 'KPRC', - city: 'Prescott, Love Field', - state: 'AZ', - lat: 34.64917, - lon: -112.42222, - }, - KRQE: { - id: 'KRQE', - city: 'Window Rock, Window Rock Airport', - state: 'AZ', - lat: 35.65, - lon: -109.06667, - }, - KRYN: { - id: 'KRYN', - city: 'Tucson Ryan Field Airport', - state: 'AZ', - lat: 32.1422, - lon: -111.1746, - }, - KSAD: { - id: 'KSAD', - city: 'Safford, Safford Municipal Airport', - state: 'AZ', - lat: 32.85722, - lon: -109.63556, - }, - KSDL: { - id: 'KSDL', - city: 'Scottsdale Airport', - state: 'AZ', - lat: 33.61235, - lon: -111.92316, - }, - KSEZ: { - id: 'KSEZ', - city: 'Sedona Airport', - state: 'AZ', - lat: 34.85, - lon: -111.78333, - }, - KSJN: { - id: 'KSJN', - city: 'St. Johns, St. Johns Industrial Airpark', - state: 'AZ', - lat: 34.51833, - lon: -109.37917, - }, - KSOW: { - id: 'KSOW', - city: 'Show Low, Show Low Regional Airport', - state: 'AZ', - lat: 34.26528, - lon: -110.00556, - }, - KTUS: { - id: 'KTUS', - city: 'Tucson, Tucson International Airport', - state: 'AZ', - lat: 32.13153, - lon: -110.95635, - }, - KTYL: { - id: 'KTYL', - city: 'Taylor Airport', - state: 'AZ', - lat: 34.45272, - lon: -110.11503, - }, - KABI: { - id: 'KABI', - city: 'Abilene, Abilene Regional Airport', - state: 'TX', - lat: 32.41028, - lon: -99.68167, - }, - KACT: { - id: 'KACT', - city: 'Waco, Waco Regional Airport', - state: 'TX', - lat: 31.61722, - lon: -97.22778, - }, - KADS: { - id: 'KADS', - city: 'Dallas / Addison Airport', - state: 'TX', - lat: 32.96667, - lon: -96.83333, - }, - KAFW: { - id: 'KAFW', - city: 'Fort Worth, Fort Worth Alliance Airport', - state: 'TX', - lat: 32.97333, - lon: -97.31806, - }, - KALI: { - id: 'KALI', - city: 'Alice, Alice International Airport', - state: 'TX', - lat: 27.74111, - lon: -98.02694, - }, - KAMA: { - id: 'KAMA', - city: 'Amarillo, Amarillo International Airport', - state: 'TX', - lat: 35.22, - lon: -101.71722, - }, - KAPY: { - id: 'KAPY', - city: 'Zapata, TX', - state: 'TX', - lat: 26.969, - lon: -99.249, - }, - KAQO: { - id: 'KAQO', - city: 'Llano, Llano Municipal Airport', - state: 'TX', - lat: 30.78361, - lon: -98.66194, - }, - KARM: { - id: 'KARM', - city: 'Wharton, Wharton Regional Airport', - state: 'TX', - lat: 29.25417, - lon: -96.1541699, - }, - KASL: { - id: 'KASL', - city: 'Marshall', - state: 'TX', - lat: 32.5205, - lon: -94.3078, - }, - KATT: { - id: 'KATT', - city: 'Austin City, Austin Camp Mabry', - state: 'TX', - lat: 30.31667, - lon: -97.76667, - }, - KAUS: { - id: 'KAUS', - city: 'Austin-Bergstrom International Airport', - state: 'TX', - lat: 30.18304, - lon: -97.6798699, - }, - KAXH: { - id: 'KAXH', - city: 'Houston Southwest Airport', - state: 'TX', - lat: 29.50613, - lon: -95.47692, - }, - KBAZ: { - id: 'KBAZ', - city: 'New Braunfels Regional Airport', - state: 'TX', - lat: 29.70861, - lon: -98.04528, - }, - KBBD: { - id: 'KBBD', - city: 'Brady, Curtis Field Airport', - state: 'TX', - lat: 31.17917, - lon: -99.32389, - }, - KBEA: { - id: 'KBEA', - city: 'Beeville Municipal Airport', - state: 'TX', - lat: 28.362, - lon: -97.791, - }, - KBGD: { - id: 'KBGD', - city: 'Borger, Hutchinson County Airport', - state: 'TX', - lat: 35.695, - lon: -101.395, - }, - KBIF: { - id: 'KBIF', - city: 'Biggs Army Air Field - Fort Bliss', - state: 'TX', - lat: 31.86119, - lon: -106.3691599, - }, - KBKD: { - id: 'KBKD', - city: 'Stephens County Airport', - state: 'TX', - lat: 32.719, - lon: -98.891, - }, - KBKS: { - id: 'KBKS', - city: 'Falfurrias, Brooks County Airport', - state: 'TX', - lat: 27.20667, - lon: -98.12111, - }, - KBMQ: { - id: 'KBMQ', - city: 'Burnet, Burnet Municipal Craddock Field', - state: 'TX', - lat: 30.74056, - lon: -98.23528, - }, - KBMT: { - id: 'KBMT', - city: 'Beaumont Municipal Airport', - state: 'TX', - lat: 30.0702, - lon: -94.2151, - }, - KBPC: { - id: 'KBPC', - city: 'Mesa Vista Ranch AP', - state: 'TX', - lat: 35.889, - lon: -101.03, - }, - KBPG: { - id: 'KBPG', - city: 'Big Spring, Big Spring McMahon-Wrinkle Airport', - state: 'TX', - lat: 32.2, - lon: -101.51667, - }, - KBPT: { - id: 'KBPT', - city: 'Beaumont/Port Arthur Southeast Texas Regional Airport', - state: 'TX', - lat: 29.9521, - lon: -94.0261, - }, - KBQX: { - id: 'KBQX', - city: 'BRAZOS 451 OIL PLATFORM', - state: 'TX', - lat: 28.5, - lon: -95.72, - }, - KBRO: { - id: 'KBRO', - city: 'Brownsville, Brownsville / South Padre Island International Airport', - state: 'TX', - lat: 25.91417, - lon: -97.42306, - }, - KBWD: { - id: 'KBWD', - city: 'Brownwood, Brownwood Regional Airport', - state: 'TX', - lat: 31.8, - lon: -98.95, - }, - KBYY: { - id: 'KBYY', - city: 'Bay City, Bay City Municipal Airport', - state: 'TX', - lat: 28.97306, - lon: -95.86333, - }, - KCDS: { - id: 'KCDS', - city: 'Childress, Childress Municipal Airport', - state: 'TX', - lat: 34.4275, - lon: -100.28333, - }, - KCFD: { - id: 'KCFD', - city: 'Bryan Coulter Field', - state: 'TX', - lat: 30.7157, - lon: -96.3314, - }, - KCLL: { - id: 'KCLL', - city: 'College Station, Easterwood Field', - state: 'TX', - lat: 30.58222, - lon: -96.36167, - }, - KCNW: { - id: 'KCNW', - city: 'Waco-James Connally Airport', - state: 'TX', - lat: 31.6378, - lon: -97.0741, - }, - KCOM: { - id: 'KCOM', - city: 'COLEMAN', - state: 'TX', - lat: 31.84, - lon: -99.4, - }, - KCOT: { - id: 'KCOT', - city: 'Cotulla, Cotulla-La Salle County Airport', - state: 'TX', - lat: 28.45833, - lon: -99.22028, - }, - KCPT: { - id: 'KCPT', - city: 'Cleburne, Cleburne Municipal Airport', - state: 'TX', - lat: 32.35361, - lon: -97.43361, - }, - KCRP: { - id: 'KCRP', - city: 'Corpus Christi, Corpus Christi International Airport', - state: 'TX', - lat: 27.77306, - lon: -97.51278, - }, - KCRS: { - id: 'KCRS', - city: 'Corsicana, Campbell Field-Corsicana Municipal Airport', - state: 'TX', - lat: 32.03111, - lon: -96.39889, - }, - KCVB: { - id: 'KCVB', - city: 'Castroville Municipal Airport', - state: 'TX', - lat: 29.34192, - lon: -98.8509, - }, - KCWC: { - id: 'KCWC', - city: 'Kickapoo Downtown Airport', - state: 'TX', - lat: 33.8606, - lon: -98.4903999, - }, - KCXO: { - id: 'KCXO', - city: 'Conroe, Montgomery County Airport', - state: 'TX', - lat: 30.35667, - lon: -95.41389, - }, - KCZT: { - id: 'KCZT', - city: 'Carrizo Springs Dimmit County Airport', - state: 'TX', - lat: 28.5222, - lon: -99.8236, - }, - KDAL: { - id: 'KDAL', - city: 'Dallas Love Field', - state: 'TX', - lat: 32.85416, - lon: -96.85506, - }, - KDFW: { - id: 'KDFW', - city: 'Dallas/Fort Worth International Airport', - state: 'TX', - lat: 32.89743, - lon: -97.02196, - }, - KDHT: { - id: 'KDHT', - city: 'Dalhart, Dalhart Municipal Airport', - state: 'TX', - lat: 36.02333, - lon: -102.54722, - }, - KDKR: { - id: 'KDKR', - city: 'Crockett, Houston County Airport', - state: 'TX', - lat: 31.30694, - lon: -95.40361, - }, - KDLF: { - id: 'KDLF', - city: 'Laughlin Air Force Base Auxiliary Airfield', - state: 'TX', - lat: 29.36652, - lon: -100.78469, - }, - KDRT: { - id: 'KDRT', - city: 'Del Rio, Del Rio International Airport', - state: 'TX', - lat: 29.37472, - lon: -100.92361, - }, - KDTO: { - id: 'KDTO', - city: 'Denton Enterprise Airport', - state: 'TX', - lat: 33.20505, - lon: -97.20061, - }, - KDUX: { - id: 'KDUX', - city: 'Dumas, Moore County Airport', - state: 'TX', - lat: 35.85778, - lon: -102.01306, - }, - KDWH: { - id: 'KDWH', - city: 'Houston, Hooks Memorial Airport', - state: 'TX', - lat: 30.0675, - lon: -95.55611, - }, - KDYS: { - id: 'KDYS', - city: 'Abilene, Dyess Air Force Base', - state: 'TX', - lat: 32.42, - lon: -99.85694, - }, - KDZB: { - id: 'KDZB', - city: 'Horseshoe Bay Resort Airpark', - state: 'TX', - lat: 30.5271, - lon: -98.3588, - }, - KEBG: { - id: 'KEBG', - city: 'Edinburg, Edinburg International Airport', - state: 'TX', - lat: 26.44194, - lon: -98.12944, - }, - KECU: { - id: 'KECU', - city: 'Rocksprings, Edwards County Airport', - state: 'TX', - lat: 29.94667, - lon: -100.17361, - }, - KEDC: { - id: 'KEDC', - city: 'Austin Executive Airport', - state: 'TX', - lat: 30.3925, - lon: -97.5621, - }, - KEFD: { - id: 'KEFD', - city: 'Houston / Ellington', - state: 'TX', - lat: 29.6, - lon: -95.16667, - }, - KELA: { - id: 'KELA', - city: 'Eagle Lake', - state: 'TX', - lat: 29.6006, - lon: -96.3219, - }, - KELP: { - id: 'KELP', - city: 'El Paso, El Paso International Airport', - state: 'TX', - lat: 31.81111, - lon: -106.3758299, - }, - KEMK: { - id: 'KEMK', - city: 'E BREAKS OIL PLATFORM', - state: 'TX', - lat: 27.82, - lon: -94.3199999, - }, - KERV: { - id: 'KERV', - city: 'Kerrville, Kerrville Municipal Airport/Louis Schreiner Field', - state: 'TX', - lat: 29.96667, - lon: -99.08333, - }, - KETN: { - id: 'KETN', - city: 'Eastland Municipal Airport', - state: 'TX', - lat: 32.41489, - lon: -98.80969, - }, - KFST: { - id: 'KFST', - city: 'Fort Stockton, Fort Stockton-Pecos County Airport', - state: 'TX', - lat: 30.91194, - lon: -102.91667, - }, - KFTW: { - id: 'KFTW', - city: 'Fort Worth, Meacham International Airport', - state: 'TX', - lat: 32.82528, - lon: -97.36417, - }, - KFWS: { - id: 'KFWS', - city: 'Fort Worth Spinks Airport', - state: 'TX', - lat: 32.56537, - lon: -97.30837, - }, - KGDJ: { - id: 'KGDJ', - city: 'Granbury, Granbury Municipal Airport', - state: 'TX', - lat: 32.44417, - lon: -97.81667, - }, - KGDP: { - id: 'KGDP', - city: 'Pine Springs, Guadalupe Mountains National Park', - state: 'TX', - lat: 31.83111, - lon: -104.80889, - }, - KGGG: { - id: 'KGGG', - city: 'Longview - East Texas Regional Airport', - state: 'TX', - lat: 32.39056, - lon: -94.71389, - }, - KGKY: { - id: 'KGKY', - city: 'Arlington Municipal Airport', - state: 'TX', - lat: 32.65829, - lon: -97.09509, - }, - KGLE: { - id: 'KGLE', - city: 'Gainesville, Gainesville Municipal Airport', - state: 'TX', - lat: 33.65139, - lon: -97.19694, - }, - KGLS: { - id: 'KGLS', - city: 'Galveston, Scholes Field', - state: 'TX', - lat: 29.27028, - lon: -94.86417, - }, - KGNC: { - id: 'KGNC', - city: 'Seminole, Gaines County Airport', - state: 'TX', - lat: 32.67528, - lon: -102.6525, - }, - KGOP: { - id: 'KGOP', - city: 'Gatesville, City-County Airport', - state: 'TX', - lat: 31.42111, - lon: -97.79694, - }, - KGPM: { - id: 'KGPM', - city: 'Grand Prairie, Grand Prairie Municipal Airport', - state: 'TX', - lat: 32.69861, - lon: -97.04667, - }, - KGRK: { - id: 'KGRK', - city: 'Fort Hood, Robert Gray AAF Ft Hood', - state: 'TX', - lat: 31.06667, - lon: -97.81667, - }, - KGTU: { - id: 'KGTU', - city: 'Georgetown, Georgetown Municipal Airport', - state: 'TX', - lat: 30.68333, - lon: -97.68333, - }, - KGVT: { - id: 'KGVT', - city: 'Greenville / Majors', - state: 'TX', - lat: 33.06667, - lon: -96.06667, - }, - KGYB: { - id: 'KGYB', - city: 'Giddings, Giddings-Lee County Airport', - state: 'TX', - lat: 30.16917, - lon: -96.98, - }, - KGYI: { - id: 'KGYI', - city: 'Sherman/Denison, Grayson County Airport', - state: 'TX', - lat: 33.71667, - lon: -96.66667, - }, - KGZN: { - id: 'KGZN', - city: 'Gregory M Simmons Memorial Airport', - state: 'TX', - lat: 32.3658, - lon: -99.0237, - }, - KHBV: { - id: 'KHBV', - city: 'Hebbronville, Jim Hogg County Airport', - state: 'TX', - lat: 27.33333, - lon: -98.73333, - }, - KHDO: { - id: 'KHDO', - city: 'Hondo, Hondo Municipal Airport', - state: 'TX', - lat: 29.35944, - lon: -99.17417, - }, - KHHF: { - id: 'KHHF', - city: 'Canadian, Hemphill County Airport', - state: 'TX', - lat: 35.9, - lon: -100.4, - }, - KHHV: { - id: 'KHHV', - city: 'Alaminos Canyon 25/H-D (ExxonMobil)', - state: 'TX', - lat: 26.939, - lon: -94.6889999, - }, - KHLR: { - id: 'KHLR', - city: 'Fort Hood, Hood AAF Ft Hood', - state: 'TX', - lat: 31.13333, - lon: -97.7, - }, - KHOU: { - id: 'KHOU', - city: 'Houston, Houston Hobby Airport', - state: 'TX', - lat: 29.6375, - lon: -95.2825, - }, - KHQZ: { - id: 'KHQZ', - city: 'Mesquite, Mesquite Metro Airport', - state: 'TX', - lat: 32.74694, - lon: -96.53028, - }, - KHRL: { - id: 'KHRL', - city: 'Harlingen, Rio Grande Valley International Airport', - state: 'TX', - lat: 26.22972, - lon: -97.65528, - }, - KHRX: { - id: 'KHRX', - city: 'Hereford Municipal Airport', - state: 'TX', - lat: 34.8578, - lon: -102.3264, - }, - KHYI: { - id: 'KHYI', - city: 'San Marcos, San Marcos Municipal Airport', - state: 'TX', - lat: 29.89361, - lon: -97.86472, - }, - KIAH: { - id: 'KIAH', - city: 'Houston Intercontinental Airport', - state: 'TX', - lat: 29.9844, - lon: -95.36074, - }, - KIKG: { - id: 'KIKG', - city: 'Kleberg County Airport', - state: 'TX', - lat: 27.5509, - lon: -98.0309, - }, - KILE: { - id: 'KILE', - city: 'Killeen, Skylark Field Airport', - state: 'TX', - lat: 31.08333, - lon: -97.68333, - }, - KINJ: { - id: 'KINJ', - city: 'Hillsboro, Hillsboro Municipal Airport', - state: 'TX', - lat: 32.0833299, - lon: -97.0972199, - }, - KINK: { - id: 'KINK', - city: 'Wink, Winkler County Airport', - state: 'TX', - lat: 31.77972, - lon: -103.20139, - }, - KJAS: { - id: 'KJAS', - city: 'Jasper, Jasper County-Bell Field Airport', - state: 'TX', - lat: 30.88556, - lon: -94.0347199, - }, - KJCT: { - id: 'KJCT', - city: 'Junction, Kimble County Airport', - state: 'TX', - lat: 30.51083, - lon: -99.76639, - }, - KJDD: { - id: 'KJDD', - city: 'Mineola/Quitman, Wood County Airport', - state: 'TX', - lat: 32.74194, - lon: -95.49639, - }, - KJSO: { - id: 'KJSO', - city: 'Jacksonville, Cherokee County Airport', - state: 'TX', - lat: 31.86917, - lon: -95.21722, - }, - KJWY: { - id: 'KJWY', - city: 'Midlothian/Waxahachie, Mid-Way Regional Airport', - state: 'TX', - lat: 32.45583, - lon: -96.91222, - }, - KJXI: { - id: 'KJXI', - city: 'Gilmer, Fox Stephens Field - Gilmer Municipal Airport', - state: 'TX', - lat: 32.69889, - lon: -94.94861, - }, - KLBB: { - id: 'KLBB', - city: 'Lubbock, Lubbock International Airport', - state: 'TX', - lat: 33.6674999, - lon: -101.8213899, - }, - KLBX: { - id: 'KLBX', - city: 'Angleton / Lake Jackson, Brazoria County Airport', - state: 'TX', - lat: 29.11536, - lon: -95.46323, - }, - KLFK: { - id: 'KLFK', - city: 'Lufkin, Angelina County Airport', - state: 'TX', - lat: 31.23389, - lon: -94.75, - }, - KLHB: { - id: 'KLHB', - city: 'Hearne, Hearne Municipal Airport', - state: 'TX', - lat: 30.87167, - lon: -96.62222, - }, - KLLN: { - id: 'KLLN', - city: 'Levelland Municipal Airport', - state: 'TX', - lat: 33.55253, - lon: -102.37253, - }, - KLNC: { - id: 'KLNC', - city: 'Lancaster Airport', - state: 'TX', - lat: 32.58323, - lon: -96.72091, - }, - KLRD: { - id: 'KLRD', - city: 'Laredo, Laredo International Airport', - state: 'TX', - lat: 27.54361, - lon: -99.46139, - }, - KLUD: { - id: 'KLUD', - city: 'Decatur, Decatur Municipal Airport', - state: 'TX', - lat: 33.25444, - lon: -97.58056, - }, - KLUV: { - id: 'KLUV', - city: 'Lamesa Municipal Airport', - state: 'TX', - lat: 32.75631, - lon: -101.92022, - }, - KLVJ: { - id: 'KLVJ', - city: 'Houston, Pearland Regional Airport', - state: 'TX', - lat: 29.52111, - lon: -95.24194, - }, - KLXY: { - id: 'KLXY', - city: 'Mexia Limestone County Airport', - state: 'TX', - lat: 31.6412, - lon: -96.5145, - }, - KLZZ: { - id: 'KLZZ', - city: 'Lampasas, Lampasas Airport', - state: 'TX', - lat: 31.10611, - lon: -98.19583, - }, - KMAF: { - id: 'KMAF', - city: 'Midland, Midland International Airport', - state: 'TX', - lat: 31.94778, - lon: -102.2086099, - }, - KMCJ: { - id: 'KMCJ', - city: 'John Dunn Helistop', - state: 'TX', - lat: 29.714, - lon: -95.395, - }, - KMDD: { - id: 'KMDD', - city: 'Midland, Midland Airpark', - state: 'TX', - lat: 32.03639, - lon: -102.10083, - }, - KMFE: { - id: 'KMFE', - city: 'McAllen, Miller International Airport', - state: 'TX', - lat: 26.17972, - lon: -98.24444, - }, - KMKN: { - id: 'KMKN', - city: 'Comanche, Comanche County-City Airport', - state: 'TX', - lat: 31.91667, - lon: -98.60028, - }, - KMNZ: { - id: 'KMNZ', - city: 'Hamilton Municipal Airport', - state: 'TX', - lat: 31.6659, - lon: -98.1486, - }, - KMRF: { - id: 'KMRF', - city: 'Marfa', - state: 'TX', - lat: 30.36667, - lon: -104.01667, - }, - KMWL: { - id: 'KMWL', - city: 'Mineral Wells, Mineral Wells Airport', - state: 'TX', - lat: 32.78167, - lon: -98.06028, - }, - KNFW: { - id: 'KNFW', - city: 'Fort Worth, Naval Air Station', - state: 'TX', - lat: 32.76583, - lon: -97.43333, - }, - KNGP: { - id: 'KNGP', - city: 'Corpus Christi, Corpus Christi Naval Air Station/Truax Field', - state: 'TX', - lat: 27.6925, - lon: -97.29111, - }, - KNOG: { - id: 'KNOG', - city: 'Orange Grove NALF', - state: 'TX', - lat: 27.8947, - lon: -98.0425099, - }, - KNQI: { - id: 'KNQI', - city: 'Kingsville, Naval Air Station', - state: 'TX', - lat: 27.50306, - lon: -97.81167, - }, - KOCH: { - id: 'KOCH', - city: 'Nacogdoches, A L Mangham Jr. Regional Airport', - state: 'TX', - lat: 31.58333, - lon: -94.7166699, - }, - KODO: { - id: 'KODO', - city: 'Odessa, Odessa-Schlemeyer Field', - state: 'TX', - lat: 31.92139, - lon: -102.39167, - }, - KORG: { - id: 'KORG', - city: 'Orange, Orange County Airport', - state: 'TX', - lat: 30.06917, - lon: -93.80361, - }, - KOSA: { - id: 'KOSA', - city: 'Mount Pleasant, Mount Pleasant Regional Airport', - state: 'TX', - lat: 33.09528, - lon: -94.96139, - }, - KOZA: { - id: 'KOZA', - city: 'Ozona Municipal Airport', - state: 'TX', - lat: 30.7353, - lon: -101.203, - }, - KPEQ: { - id: 'KPEQ', - city: 'Pecos, Pecos Municipal Airport', - state: 'TX', - lat: 31.38222, - lon: -103.51056, - }, - KPEZ: { - id: 'KPEZ', - city: 'Pleasanton Municipal Airport', - state: 'TX', - lat: 28.9562, - lon: -98.5184, - }, - KPIL: { - id: 'KPIL', - city: 'Port Isabel, Port Isabel-Cameron County Airport', - state: 'TX', - lat: 26.15917, - lon: -97.3375, - }, - KPKV: { - id: 'KPKV', - city: 'Port Lavaca - Calhoun County Airport', - state: 'TX', - lat: 28.65159, - lon: -96.68196, - }, - KPPA: { - id: 'KPPA', - city: 'Pampa, Perry Lefors Field Airport', - state: 'TX', - lat: 35.61278, - lon: -100.99611, - }, - KPRS: { - id: 'KPRS', - city: 'Presidio Lely International Airport', - state: 'TX', - lat: 29.6341, - lon: -104.3616, - }, - KPRX: { - id: 'KPRX', - city: 'Paris / Cox Field', - state: 'TX', - lat: 33.63333, - lon: -95.45, - }, - KPSN: { - id: 'KPSN', - city: 'Palestine, Palestine Municipal Airport', - state: 'TX', - lat: 31.77944, - lon: -95.70611, - }, - KPSX: { - id: 'KPSX', - city: 'Palacios Municipal Airport', - state: 'TX', - lat: 28.72485, - lon: -96.2534699, - }, - KPVW: { - id: 'KPVW', - city: 'Plainview, Hale County Airport', - state: 'TX', - lat: 34.1680599, - lon: -101.71722, - }, - KPWG: { - id: 'KPWG', - city: 'Waco, Mc Gregor Executive Airport', - state: 'TX', - lat: 31.48333, - lon: -97.31667, - }, - KPYX: { - id: 'KPYX', - city: 'Perryton, Perryton Ochiltree County Airport', - state: 'TX', - lat: 36.4, - lon: -100.73333, - }, - KRAS: { - id: 'KRAS', - city: 'Port Aransas, Mustang Beach Airport', - state: 'TX', - lat: 27.81167, - lon: -97.08861, - }, - KRBD: { - id: 'KRBD', - city: 'Dallas, Redbird Airport', - state: 'TX', - lat: 32.67583, - lon: -96.86389, - }, - KRBO: { - id: 'KRBO', - city: 'Robstown, Nueces County Airport', - state: 'TX', - lat: 27.77833, - lon: -97.69028, - }, - KRFI: { - id: 'KRFI', - city: 'Rusk County Airport', - state: 'TX', - lat: 32.1417, - lon: -94.8516999, - }, - KRKP: { - id: 'KRKP', - city: 'Rockport Aransas County Airport', - state: 'TX', - lat: 28.08371, - lon: -97.04664, - }, - KRND: { - id: 'KRND', - city: 'Randolph Air Force Base', - state: 'TX', - lat: 29.53333, - lon: -98.28333, - }, - KRWV: { - id: 'KRWV', - city: 'Caldwell, Caldwell Municipal Airport', - state: 'TX', - lat: 30.51528, - lon: -96.70389, - }, - KRYW: { - id: 'KRYW', - city: 'Lago Vista TX, Rusty Allen Airport', - state: 'TX', - lat: 30.4967, - lon: -97.9659, - }, - KSAT: { - id: 'KSAT', - city: 'San Antonio, San Antonio International Airport', - state: 'TX', - lat: 29.53278, - lon: -98.46361, - }, - KSEP: { - id: 'KSEP', - city: 'Stephenville, Clark Field Municipal Airport', - state: 'TX', - lat: 32.21667, - lon: -98.18333, - }, - KSEQ: { - id: 'KSEQ', - city: 'Seguin - Randolph AFB Auxiliary Field', - state: 'TX', - lat: 29.56579, - lon: -97.90834, - }, - KSGR: { - id: 'KSGR', - city: 'Houston, Sugar Land Municipal / Hull Field Airport', - state: 'TX', - lat: 29.62222, - lon: -95.65667, - }, - KSJT: { - id: 'KSJT', - city: 'San Angelo, Mathis Field', - state: 'TX', - lat: 31.35139, - lon: -100.4938899, - }, - KSKF: { - id: 'KSKF', - city: 'San Antonio - Kelly Field', - state: 'TX', - lat: 29.38333, - lon: -98.58333, - }, - KSLR: { - id: 'KSLR', - city: 'Sulphur Springs, Sulphur Springs Municipal Airport', - state: 'TX', - lat: 33.16111, - lon: -95.62111, - }, - KSNK: { - id: 'KSNK', - city: 'Snyder, Winston Field Airport', - state: 'TX', - lat: 32.69333, - lon: -100.95028, - }, - KSOA: { - id: 'KSOA', - city: 'Sonora, Sonora Municipal Airport', - state: 'TX', - lat: 30.58556, - lon: -100.64833, - }, - KSPS: { - id: 'KSPS', - city: 'Wichita Falls, Sheppard Air Force Base', - state: 'TX', - lat: 33.97861, - lon: -98.49278, - }, - KSSF: { - id: 'KSSF', - city: 'San Antonio, Stinson Municipal Airport', - state: 'TX', - lat: 29.33889, - lon: -98.47167, - }, - KSWW: { - id: 'KSWW', - city: 'Sweetwater, Avenger Field Airport', - state: 'TX', - lat: 32.46722, - lon: -100.46639, - }, - KTFP: { - id: 'KTFP', - city: 'Mc Campbell', - state: 'TX', - lat: 27.913, - lon: -97.2115, - }, - KTKI: { - id: 'KTKI', - city: 'McKinney - McKinney National Airport', - state: 'TX', - lat: 33.17778, - lon: -96.59028, - }, - KTME: { - id: 'KTME', - city: 'Houston Executive Airport', - state: 'TX', - lat: 29.80717, - lon: -95.89791, - }, - KTPL: { - id: 'KTPL', - city: 'Temple, Draughon-Miller Central Texas Regional Airport', - state: 'TX', - lat: 31.15, - lon: -97.4, - }, - KTRL: { - id: 'KTRL', - city: 'Terrell, Terrell Municipal Airport', - state: 'TX', - lat: 32.71361, - lon: -96.26833, - }, - KTXW: { - id: 'KTXW', - city: 'Mid Valley Airport', - state: 'TX', - lat: 26.17871, - lon: -97.97401, - }, - KTYR: { - id: 'KTYR', - city: 'Tyler, Tyler Pounds Field', - state: 'TX', - lat: 32.35861, - lon: -95.40389, - }, - KUTS: { - id: 'KUTS', - city: 'Huntsville, Huntsville Municipal Airport', - state: 'TX', - lat: 30.74389, - lon: -95.58611, - }, - KUVA: { - id: 'KUVA', - city: 'Uvalde, Garner Field Airport', - state: 'TX', - lat: 29.21111, - lon: -99.74333, - }, - KVAF: { - id: 'KVAF', - city: 'East Breaks 643/Boomvang Spar', - state: 'TX', - lat: 27.354, - lon: -94.625, - }, - KVCT: { - id: 'KVCT', - city: 'Victoria, Victoria Regional Airport', - state: 'TX', - lat: 28.8625, - lon: -96.92972, - }, - KVHN: { - id: 'KVHN', - city: 'Culberson County Airport', - state: 'TX', - lat: 31.05783, - lon: -104.78381, - }, - KXBP: { - id: 'KXBP', - city: 'Bridgeport, Bridgeport Municipal Airport', - state: 'TX', - lat: 33.17528, - lon: -97.8283299, - }, - KAAT: { - id: 'KAAT', - city: 'Alturas', - state: 'CA', - lat: 41.48362, - lon: -120.5615, - }, - KACV: { - id: 'KACV', - city: 'Arcata / Eureka, Arcata Airport', - state: 'CA', - lat: 40.97806, - lon: -124.10861, - }, - KAJO: { - id: 'KAJO', - city: 'Corona Airport', - state: 'CA', - lat: 33.8977, - lon: -117.6024, - }, - KAPC: { - id: 'KAPC', - city: 'Napa, Napa County Airport', - state: 'CA', - lat: 38.2075, - lon: -122.27944, - }, - KAPV: { - id: 'KAPV', - city: 'APPLEVALLEY', - state: 'CA', - lat: 34.57533, - lon: -117.18619, - }, - KAUN: { - id: 'KAUN', - city: 'Auburn Municipal Airport', - state: 'CA', - lat: 38.95535, - lon: -121.08636, - }, - KAVX: { - id: 'KAVX', - city: 'Avalon Catalina Airport', - state: 'CA', - lat: 33.40421, - lon: -118.41456, - }, - KBAB: { - id: 'KBAB', - city: 'Marysville, Beale Air Force Base', - state: 'CA', - lat: 39.13333, - lon: -121.43333, - }, - KBAN: { - id: 'KBAN', - city: 'MCMWTC BRIDGEPORT', - state: 'CA', - lat: 38.3557, - lon: -119.5188, - }, - KBFL: { - id: 'KBFL', - city: 'Bakersfield, Meadows Field Airport', - state: 'CA', - lat: 35.43361, - lon: -119.05667, - }, - KBIH: { - id: 'KBIH', - city: 'Bishop, Bishop Airport', - state: 'CA', - lat: 37.37111, - lon: -118.35806, - }, - KBLH: { - id: 'KBLH', - city: 'Blythe, Blythe Airport', - state: 'CA', - lat: 33.6191699, - lon: -114.71694, - }, - KBLU: { - id: 'KBLU', - city: 'Emigrant Gap, Blue Canyon Nyack Airport', - state: 'CA', - lat: 39.27611, - lon: -120.70806, - }, - KBUR: { - id: 'KBUR', - city: 'Burbank - Bob Hope Airport', - state: 'CA', - lat: 34.19967, - lon: -118.36538, - }, - KBYS: { - id: 'KBYS', - city: 'Fort Irwin/Barstow, Bicycle Lake Army Airfield', - state: 'CA', - lat: 35.28333, - lon: -116.61667, - }, - KCCB: { - id: 'KCCB', - city: 'Cable Airport', - state: 'CA', - lat: 34.11161, - lon: -117.68739, - }, - KCCR: { - id: 'KCCR', - city: 'Concord, Buchanan Field', - state: 'CA', - lat: 37.99167, - lon: -122.05194, - }, - KCEC: { - id: 'KCEC', - city: 'Crescent City, Jack McNamara Field Airport', - state: 'CA', - lat: 41.78028, - lon: -124.23667, - }, - KCIC: { - id: 'KCIC', - city: 'Chico Municipal Airport', - state: 'CA', - lat: 39.7987899, - lon: -121.85795, - }, - KCMA: { - id: 'KCMA', - city: 'Camarillo, Camarillo Airport', - state: 'CA', - lat: 34.21667, - lon: -119.08333, - }, - KCNO: { - id: 'KCNO', - city: 'Chino, Chino Airport', - state: 'CA', - lat: 33.97556, - lon: -117.62361, - }, - KCPU: { - id: 'KCPU', - city: 'San Andreas Calaveras County Airport', - state: 'CA', - lat: 38.1460999, - lon: -120.6482, - }, - KCQT: { - id: 'KCQT', - city: 'Los Angeles / USC Campus Downtown', - state: 'CA', - lat: 34.02355, - lon: -118.29122, - }, - KCRQ: { - id: 'KCRQ', - city: 'Carlsbad, McClellan-Palomar Airport', - state: 'CA', - lat: 33.13, - lon: -117.27583, - }, - KCVH: { - id: 'KCVH', - city: 'Hollister, CA', - state: 'CA', - lat: 36.8933, - lon: -121.4103, - }, - KDAG: { - id: 'KDAG', - city: 'Daggett, Barstow-Daggett Airport', - state: 'CA', - lat: 34.85361, - lon: -116.78667, - }, - KDLO: { - id: 'KDLO', - city: 'Delano Municipal Airport', - state: 'CA', - lat: 35.74556, - lon: -119.2365, - }, - KDVO: { - id: 'KDVO', - city: 'Novato / Gnoss Field', - state: 'CA', - lat: 38.14178, - lon: -122.55463, - }, - KDWA: { - id: 'KDWA', - city: 'Yolo County Airport', - state: 'CA', - lat: 38.5793899, - lon: -121.85694, - }, - KEDW: { - id: 'KEDW', - city: 'Edwards Air Force Base', - state: 'CA', - lat: 34.918, - lon: -117.879, - }, - KEED: { - id: 'KEED', - city: 'Needles, Needles Airport', - state: 'CA', - lat: 34.76611, - lon: -114.62333, - }, - KEMT: { - id: 'KEMT', - city: 'El Monte', - state: 'CA', - lat: 34.0833299, - lon: -118.03333, - }, - KFAT: { - id: 'KFAT', - city: 'Fresno, Fresno Air Terminal', - state: 'CA', - lat: 36.78, - lon: -119.71944, - }, - KFOT: { - id: 'KFOT', - city: 'Fortuna Rohnerville Airport', - state: 'CA', - lat: 40.55296, - lon: -124.13338, - }, - KFUL: { - id: 'KFUL', - city: 'Fullerton, Fullerton Municipal Airport', - state: 'CA', - lat: 33.87194, - lon: -117.98472, - }, - KGOO: { - id: 'KGOO', - city: 'Nevada County Air Park', - state: 'CA', - lat: 39.2240279, - lon: -121.003083, - }, - KGXA: { - id: 'KGXA', - city: 'Gray Butte Field Airport', - state: 'CA', - lat: 34.5666, - lon: -117.6704, - }, - KHAF: { - id: 'KHAF', - city: 'Half Moon Bay Airport', - state: 'CA', - lat: 37.5135999, - lon: -122.4996, - }, - KHHR: { - id: 'KHHR', - city: 'Hawthorne, Hawthorne Municipal Airport', - state: 'CA', - lat: 33.9236099, - lon: -118.33194, - }, - KHJO: { - id: 'KHJO', - city: 'Hanford Municipal Airport', - state: 'CA', - lat: 36.31145, - lon: -119.62315, - }, - KHMT: { - id: 'KHMT', - city: 'Hemet-Ryan Airport', - state: 'CA', - lat: 33.73403, - lon: -117.02231, - }, - KHWD: { - id: 'KHWD', - city: 'Hayward, Hayward Air Terminal', - state: 'CA', - lat: 37.66083, - lon: -122.11833, - }, - KIPL: { - id: 'KIPL', - city: 'Imperial, Imperial County Airport', - state: 'CA', - lat: 32.83417, - lon: -115.57861, - }, - KIZA: { - id: 'KIZA', - city: 'Santa Ynez, Santa Ynez Airport', - state: 'CA', - lat: 34.60694, - lon: -120.07556, - }, - KJAQ: { - id: 'KJAQ', - city: 'Westover Field - Amador County Airport', - state: 'CA', - lat: 38.3768, - lon: -120.79391, - }, - KLAX: { - id: 'KLAX', - city: 'Los Angeles, Los Angeles International Airport', - state: 'CA', - lat: 33.93806, - lon: -118.38889, - }, - KLGB: { - id: 'KLGB', - city: 'Long Beach, Long Beach Airport', - state: 'CA', - lat: 33.81167, - lon: -118.14639, - }, - KLHM: { - id: 'KLHM', - city: 'Lincoln Regional Karl Harder Field', - state: 'CA', - lat: 38.9092, - lon: -121.3513, - }, - KLPC: { - id: 'KLPC', - city: 'Lompoc, Lompoc Airport', - state: 'CA', - lat: 34.66667, - lon: -120.46667, - }, - KLVK: { - id: 'KLVK', - city: 'Livermore, Livermore Municipal Airport', - state: 'CA', - lat: 37.69278, - lon: -121.81444, - }, - KMAE: { - id: 'KMAE', - city: 'Madera Municipal Airport', - state: 'CA', - lat: 36.9851, - lon: -120.11064, - }, - KMCC: { - id: 'KMCC', - city: 'Sacramento, McClellan Airfield Airport', - state: 'CA', - lat: 38.66667, - lon: -121.4, - }, - KMCE: { - id: 'KMCE', - city: 'Merced Regional Airport', - state: 'CA', - lat: 37.28306, - lon: -120.50778, - }, - KMER: { - id: 'KMER', - city: 'Merced / Castle Air Force Base', - state: 'CA', - lat: 37.36667, - lon: -120.56667, - }, - KMHR: { - id: 'KMHR', - city: 'Sacramento Mather Airport', - state: 'CA', - lat: 38.5599599, - lon: -121.28397, - }, - KMHS: { - id: 'KMHS', - city: 'Mount Shasta', - state: 'CA', - lat: 41.31494, - lon: -122.31702, - }, - KMHV: { - id: 'KMHV', - city: 'Mojave', - state: 'CA', - lat: 35.06667, - lon: -118.15, - }, - KMMH: { - id: 'KMMH', - city: 'Mammoth Yosemite Airport', - state: 'CA', - lat: 37.6241, - lon: -118.8423, - }, - KMOD: { - id: 'KMOD', - city: 'Modesto City-County Airport - Harry Sham Field', - state: 'CA', - lat: 37.62549, - lon: -120.9549, - }, - KMRY: { - id: 'KMRY', - city: 'Monterey Regional Airport', - state: 'CA', - lat: 36.59047, - lon: -121.84875, - }, - KMYF: { - id: 'KMYF', - city: 'San Diego, Montgomery Field', - state: 'CA', - lat: 32.81444, - lon: -117.13639, - }, - KMYV: { - id: 'KMYV', - city: 'Marysville, Yuba County Airport', - state: 'CA', - lat: 39.09778, - lon: -121.56972, - }, - KNFG: { - id: 'KNFG', - city: 'Oceanside, Camp Pendleton, Marine Corps Air Station', - state: 'CA', - lat: 33.30472, - lon: -117.35389, - }, - KNID: { - id: 'KNID', - city: 'China Lake, Naval Air Facility', - state: 'CA', - lat: 35.68639, - lon: -117.69, - }, - KNJK: { - id: 'KNJK', - city: 'El Centro, Naval Air Facility', - state: 'CA', - lat: 32.825, - lon: -115.66056, - }, - KNKX: { - id: 'KNKX', - city: 'San Diego, Miramar MCAS/Mitscher Field Airport', - state: 'CA', - lat: 32.86833, - lon: -117.1425, - }, - KNLC: { - id: 'KNLC', - city: 'Lemoore Naval Air Station - Reeves Field', - state: 'CA', - lat: 36.30244, - lon: -119.93968, - }, - KNRS: { - id: 'KNRS', - city: 'Imperial Beach Naval Outlying Field - Ream Field', - state: 'CA', - lat: 32.56302, - lon: -117.11091, - }, - KNSI: { - id: 'KNSI', - city: 'San Nicolas Island Naval Outlying Field', - state: 'CA', - lat: 33.23379, - lon: -119.45588, - }, - KNTD: { - id: 'KNTD', - city: 'Point Mugu, Naval Air Warfare Center', - state: 'CA', - lat: 34.12389, - lon: -119.12167, - }, - KNUC: { - id: 'KNUC', - city: 'San Clemente Island NALF', - state: 'CA', - lat: 33.0218, - lon: -118.58266, - }, - KNXP: { - id: 'KNXP', - city: 'Twentynine Palms SELF Airport', - state: 'CA', - lat: 34.29401, - lon: -116.14717, - }, - KNZY: { - id: 'KNZY', - city: 'San Diego, North Island, Naval Air Station', - state: 'CA', - lat: 32.69083, - lon: -117.20889, - }, - KOAK: { - id: 'KOAK', - city: 'Oakland, Metro Oakland International Airport', - state: 'CA', - lat: 37.7177999, - lon: -122.23294, - }, - KOAR: { - id: 'KOAR', - city: 'FORT ORD/FRITZSCHE', - state: 'CA', - lat: 36.68, - lon: -121.77, - }, - KOKB: { - id: 'KOKB', - city: 'Oceanside, Oceanside Municipal Airport', - state: 'CA', - lat: 33.21806, - lon: -117.35139, - }, - KONT: { - id: 'KONT', - city: 'Ontario International Airport', - state: 'CA', - lat: 34.05316, - lon: -117.57685, - }, - KOVE: { - id: 'KOVE', - city: 'Oroville Municipal Airport', - state: 'CA', - lat: 39.49436, - lon: -121.62223, - }, - KOXR: { - id: 'KOXR', - city: 'Oxnard, Oxnard Airport', - state: 'CA', - lat: 34.20056, - lon: -119.20306, - }, - KPAO: { - id: 'KPAO', - city: 'Palo Alto Airport', - state: 'CA', - lat: 37.46667, - lon: -122.11667, - }, - KPMD: { - id: 'KPMD', - city: 'Palmdale, Palmdale Production Flight Plant', - state: 'CA', - lat: 34.62972, - lon: -118.08139, - }, - KPOC: { - id: 'KPOC', - city: 'Brackett Field Airport', - state: 'CA', - lat: 34.09282, - lon: -117.77937, - }, - KPRB: { - id: 'KPRB', - city: 'Paso Robles Municipal Airport', - state: 'CA', - lat: 35.66941, - lon: -120.62912, - }, - KPSP: { - id: 'KPSP', - city: 'Palm Springs Regional Airport', - state: 'CA', - lat: 33.82219, - lon: -116.50431, - }, - KPTV: { - id: 'KPTV', - city: 'Porterville, Porterville Municipal Airport', - state: 'CA', - lat: 36.03333, - lon: -119.06667, - }, - KPVF: { - id: 'KPVF', - city: 'Placerville Airport', - state: 'CA', - lat: 38.7242, - lon: -120.7533, - }, - KRAL: { - id: 'KRAL', - city: 'Riverside Municipal Airport', - state: 'CA', - lat: 33.95189, - lon: -117.44511, - }, - KRBL: { - id: 'KRBL', - city: 'Red Bluff, Red Bluff Municipal Airport', - state: 'CA', - lat: 40.15056, - lon: -122.25222, - }, - KRDD: { - id: 'KRDD', - city: 'Redding Municipal Airport', - state: 'CA', - lat: 40.51461, - lon: -122.2977, - }, - KREI: { - id: 'KREI', - city: 'REDLANDS', - state: 'CA', - lat: 34.08526, - lon: -117.14637, - }, - KRHV: { - id: 'KRHV', - city: 'San Jose / Reid / Hillv', - state: 'CA', - lat: 37.3333299, - lon: -121.81667, - }, - KRIV: { - id: 'KRIV', - city: 'March Air Reserve Base', - state: 'CA', - lat: 33.88194, - lon: -117.25902, - }, - KRNM: { - id: 'KRNM', - city: 'Ramona, Ramona Airport', - state: 'CA', - lat: 33.0375, - lon: -116.91583, - }, - KSAC: { - id: 'KSAC', - city: 'Sacramento Executive Airport', - state: 'CA', - lat: 38.50674, - lon: -121.49597, - }, - KSAN: { - id: 'KSAN', - city: 'San Diego International Airport', - state: 'CA', - lat: 32.73361, - lon: -117.18306, - }, - KSBA: { - id: 'KSBA', - city: 'Santa Barbara, Santa Barbara Municipal Airport', - state: 'CA', - lat: 34.42611, - lon: -119.84361, - }, - KSBD: { - id: 'KSBD', - city: 'San Bernardino Intl. Airport', - state: 'CA', - lat: 34.0902699, - lon: -117.24705, - }, - KSBP: { - id: 'KSBP', - city: 'San Luis Obispo, San Luis Obispo County-Mc Chesney Field', - state: 'CA', - lat: 35.2361099, - lon: -120.63611, - }, - KSCK: { - id: 'KSCK', - city: 'Stockton, Stockton Metropolitan Airport', - state: 'CA', - lat: 37.8897199, - lon: -121.22361, - }, - KSDB: { - id: 'KSDB', - city: 'Sandberg', - state: 'CA', - lat: 34.7436099, - lon: -118.72444, - }, - KSDM: { - id: 'KSDM', - city: 'San Diego, Brown Field Municipal Airport', - state: 'CA', - lat: 32.57528, - lon: -116.99306, - }, - KSEE: { - id: 'KSEE', - city: 'Gillespie Field Airport', - state: 'CA', - lat: 32.82738, - lon: -116.97369, - }, - KSFO: { - id: 'KSFO', - city: 'San Francisco, San Francisco International Airport', - state: 'CA', - lat: 37.61961, - lon: -122.36558, - }, - KSIY: { - id: 'KSIY', - city: 'Montague Siskiyou County Airport', - state: 'CA', - lat: 41.77375, - lon: -122.46817, - }, - KSJC: { - id: 'KSJC', - city: 'San Jose, San Jose International Airport', - state: 'CA', - lat: 37.35917, - lon: -121.92417, - }, - KSLI: { - id: 'KSLI', - city: 'Los Alamitos Army Airfield', - state: 'CA', - lat: 33.79628, - lon: -118.04179, - }, - KSMF: { - id: 'KSMF', - city: 'Sacramento International Airport', - state: 'CA', - lat: 38.70071, - lon: -121.59479, - }, - KSMO: { - id: 'KSMO', - city: 'Santa Monica, Santa Monica Municipal Airport', - state: 'CA', - lat: 34.01583, - lon: -118.45139, - }, - KSMX: { - id: 'KSMX', - city: 'Santa Maria Public Airport/Capt G Allan Hancock Field', - state: 'CA', - lat: 34.89408, - lon: -120.45212, - }, - KSNA: { - id: 'KSNA', - city: 'John Wayne-Orange County Airport', - state: 'CA', - lat: 33.6798, - lon: -117.8674, - }, - KSNS: { - id: 'KSNS', - city: 'Salinas, Salinas Municipal Airport', - state: 'CA', - lat: 36.66361, - lon: -121.60806, - }, - KSQL: { - id: 'KSQL', - city: 'San Carlos Airport', - state: 'CA', - lat: 37.51667, - lon: -122.25, - }, - KSTS: { - id: 'KSTS', - city: 'Santa Rosa, Santa Rosa Sonoma County Airport', - state: 'CA', - lat: 38.5, - lon: -122.81667, - }, - KSUU: { - id: 'KSUU', - city: 'Fairfield / Travis Air Force Base', - state: 'CA', - lat: 38.26667, - lon: -121.95, - }, - KSVE: { - id: 'KSVE', - city: 'Susanville Municipal Airport', - state: 'CA', - lat: 40.37569, - lon: -120.57269, - }, - KTCY: { - id: 'KTCY', - city: 'Tracy Municipal Airport', - state: 'CA', - lat: 37.6888999, - lon: -121.44158, - }, - KTNP: { - id: 'KTNP', - city: '29PALMS', - state: 'CA', - lat: 34.13159, - lon: -115.94582, - }, - KTOA: { - id: 'KTOA', - city: 'Torrance, Zamperini Field Airport', - state: 'CA', - lat: 33.8, - lon: -118.33333, - }, - KTRK: { - id: 'KTRK', - city: 'Truckee-Tahoe', - state: 'CA', - lat: 39.31667, - lon: -120.13333, - }, - KTRM: { - id: 'KTRM', - city: 'Palm Springs, Jacqueline Cochran Regional Airport', - state: 'CA', - lat: 33.62667, - lon: -116.15944, - }, - KTSP: { - id: 'KTSP', - city: 'Tehachapi Municipal Airport', - state: 'CA', - lat: 35.135, - lon: -118.4392, - }, - KTVL: { - id: 'KTVL', - city: 'South Lake Tahoe, Lake Tahoe Airport', - state: 'CA', - lat: 38.8983599, - lon: -119.99615, - }, - KUKI: { - id: 'KUKI', - city: 'Ukiah Municipal Airport', - state: 'CA', - lat: 39.12783, - lon: -123.20011, - }, - KVBG: { - id: 'KVBG', - city: 'Lompoc, Vandenberg Air Force Base', - state: 'CA', - lat: 34.7294399, - lon: -120.57667, - }, - KVCB: { - id: 'KVCB', - city: 'Vacaville Nut Tree Airport', - state: 'CA', - lat: 38.37755, - lon: -121.95853, - }, - KVCV: { - id: 'KVCV', - city: 'Victorville, Southern California Logistics Airport', - state: 'CA', - lat: 34.59722, - lon: -117.38278, - }, - KVIS: { - id: 'KVIS', - city: 'Visalia, Visalia Municipal Airport', - state: 'CA', - lat: 36.31667, - lon: -119.4, - }, - KVNY: { - id: 'KVNY', - city: 'Van Nuys, Van Nuys Airport', - state: 'CA', - lat: 34.2125, - lon: -118.49083, - }, - KWHP: { - id: 'KWHP', - city: 'Los Angeles, Whiteman Airport', - state: 'CA', - lat: 34.25, - lon: -118.4, - }, - KWJF: { - id: 'KWJF', - city: 'General Wm J Fox Airfield', - state: 'CA', - lat: 34.74123, - lon: -118.21251, - }, - KWVI: { - id: 'KWVI', - city: 'Watsonville, Watsonville Municipal Airport', - state: 'CA', - lat: 36.93944, - lon: -121.78889, - }, -}; diff --git a/dist/server/scripts/data/travelcities.js b/dist/server/scripts/data/travelcities.js deleted file mode 100644 index d9b0735..0000000 --- a/dist/server/scripts/data/travelcities.js +++ /dev/null @@ -1,243 +0,0 @@ -// eslint-disable-next-line no-unused-vars -const TravelCities = [ - { - Name: 'Atlanta', - Latitude: 33.749, - Longitude: -84.388, - point: { - x: 50, - y: 86, - wfo: 'FFC', - }, - }, - { - Name: 'Boston', - Latitude: 42.3584, - Longitude: -71.0598, - point: { - x: 71, - y: 90, - wfo: 'BOX', - }, - }, - { - Name: 'Chicago', - Latitude: 41.9796, - Longitude: -87.9045, - point: { - x: 65, - y: 76, - wfo: 'LOT', - }, - }, - { - Name: 'Cleveland', - Latitude: 41.4995, - Longitude: -81.6954, - point: { - x: 82, - y: 64, - wfo: 'CLE', - }, - }, - { - Name: 'Dallas', - Latitude: 32.8959, - Longitude: -97.0372, - point: { - x: 79, - y: 108, - wfo: 'FWD', - }, - }, - { - Name: 'Denver', - Latitude: 39.7391, - Longitude: -104.9847, - point: { - x: 62, - y: 60, - wfo: 'BOU', - }, - }, - { - Name: 'Detroit', - Latitude: 42.3314, - Longitude: -83.0457, - point: { - x: 65, - y: 33, - wfo: 'DTX', - }, - }, - { - Name: 'Hartford', - Latitude: 41.7637, - Longitude: -72.6851, - point: { - x: 21, - y: 54, - wfo: 'BOX', - }, - }, - { - Name: 'Houston', - Latitude: 29.7633, - Longitude: -95.3633, - point: { - x: 65, - y: 97, - wfo: 'HGX', - }, - }, - { - Name: 'Indianapolis', - Latitude: 39.7684, - Longitude: -86.158, - point: { - x: 57, - y: 68, - wfo: 'IND', - }, - }, - { - Name: 'Los Angeles', - Latitude: 34.0522, - Longitude: -118.2437, - point: { - x: 154, - y: 44, - wfo: 'LOX', - }, - }, - { - Name: 'Miami', - Latitude: 25.7743, - Longitude: -80.1937, - point: { - x: 109, - y: 50, - wfo: 'MFL', - }, - }, - { - Name: 'Minneapolis', - Latitude: 44.98, - Longitude: -93.2638, - point: { - x: 107, - y: 71, - wfo: 'MPX', - }, - }, - { - Name: 'New York', - Latitude: 40.7142, - Longitude: -74.0059, - point: { - x: 32, - y: 34, - wfo: 'OKX', - }, - }, - { - Name: 'Norfolk', - Latitude: 36.8468, - Longitude: -76.2852, - point: { - x: 89, - y: 51, - wfo: 'AKQ', - }, - }, - { - Name: 'Orlando', - Latitude: 28.5383, - Longitude: -81.3792, - point: { - x: 26, - y: 68, - wfo: 'MLB', - }, - }, - { - Name: 'Philadelphia', - Latitude: 39.9523, - Longitude: -75.1638, - point: { - x: 49, - y: 75, - wfo: 'PHI', - }, - }, - { - Name: 'Pittsburgh', - Latitude: 40.4406, - Longitude: -79.9959, - point: { - x: 77, - y: 65, - wfo: 'PBZ', - }, - }, - { - Name: 'St. Louis', - Latitude: 38.6273, - Longitude: -90.1979, - point: { - x: 94, - y: 73, - wfo: 'LSX', - }, - }, - { - Name: 'San Francisco', - Latitude: 37.7749, - Longitude: -122.4194, - point: { - x: 85, - y: 105, - wfo: 'MTR', - }, - }, - { - Name: 'Seattle', - Latitude: 47.6062, - Longitude: -122.3321, - point: { - x: 124, - y: 67, - wfo: 'SEW', - }, - }, - { - Name: 'Syracuse', - Latitude: 43.0481, - Longitude: -76.1474, - point: { - x: 51, - y: 98, - wfo: 'BGM', - }, - }, - { - Name: 'Tampa', - Latitude: 27.9475, - Longitude: -82.4584, - point: { - x: 70, - y: 96, - wfo: 'TBW', - }, - }, - { - Name: 'Washington DC', - Latitude: 38.8951, - Longitude: -77.0364, - point: { - x: 97, - y: 71, - wfo: 'LWX', - }, - }, -]; diff --git a/dist/server/scripts/index.mjs b/dist/server/scripts/index.mjs deleted file mode 100644 index de5efb9..0000000 --- a/dist/server/scripts/index.mjs +++ /dev/null @@ -1,414 +0,0 @@ -import { json } from './modules/utils/fetch.mjs'; -import noSleep from './modules/utils/nosleep.mjs'; -import { - message as navMessage, isPlaying, resize, resetStatuses, latLonReceived, stopAutoRefreshTimer, registerRefreshData, -} from './modules/navigation.mjs'; -import { round2 } from './modules/utils/units.mjs'; -import { parseQueryString } from './modules/share.mjs'; -import settings from './modules/settings.mjs'; - -document.addEventListener('DOMContentLoaded', () => { - init(); -}); - -const categories = [ - 'Land Features', - 'Bay', 'Channel', 'Cove', 'Dam', 'Delta', 'Gulf', 'Lagoon', 'Lake', 'Ocean', 'Reef', 'Reservoir', 'Sea', 'Sound', 'Strait', 'Waterfall', 'Wharf', // Water Features - 'Amusement Park', 'Historical Monument', 'Landmark', 'Tourist Attraction', 'Zoo', // POI/Arts and Entertainment - 'College', // POI/Education - 'Beach', 'Campground', 'Golf Course', 'Harbor', 'Nature Reserve', 'Other Parks and Outdoors', 'Park', 'Racetrack', - 'Scenic Overlook', 'Ski Resort', 'Sports Center', 'Sports Field', 'Wildlife Reserve', // POI/Parks and Outdoors - 'Airport', 'Ferry', 'Marina', 'Pier', 'Port', 'Resort', // POI/Travel - 'Postal', 'Populated Place', -]; -const category = categories.join(','); -const TXT_ADDRESS_SELECTOR = '#txtAddress'; -const TOGGLE_FULL_SCREEN_SELECTOR = '#ToggleFullScreen'; -const BNT_GET_GPS_SELECTOR = '#btnGetGps'; - -const init = () => { - document.querySelector(TXT_ADDRESS_SELECTOR).addEventListener('focus', (e) => { - e.target.select(); - }); - - registerRefreshData(loadData); - - document.querySelector('#NavigateMenu').addEventListener('click', btnNavigateMenuClick); - document.querySelector('#NavigateRefresh').addEventListener('click', btnNavigateRefreshClick); - document.querySelector('#NavigateNext').addEventListener('click', btnNavigateNextClick); - document.querySelector('#NavigatePrevious').addEventListener('click', btnNavigatePreviousClick); - document.querySelector('#NavigatePlay').addEventListener('click', btnNavigatePlayClick); - document.querySelector(TOGGLE_FULL_SCREEN_SELECTOR).addEventListener('click', btnFullScreenClick); - const btnGetGps = document.querySelector(BNT_GET_GPS_SELECTOR); - btnGetGps.addEventListener('click', btnGetGpsClick); - if (!navigator.geolocation) btnGetGps.style.display = 'none'; - - document.querySelector('#divTwc').addEventListener('mousemove', () => { - if (document.fullscreenElement) updateFullScreenNavigate(); - }); - // local change detection when exiting full screen via ESC key (or other non button click methods) - window.addEventListener('resize', fullScreenResizeCheck); - fullScreenResizeCheck.wasFull = false; - - document.querySelector(TXT_ADDRESS_SELECTOR).addEventListener('keydown', (key) => { if (key.code === 'Enter') formSubmit(); }); - document.querySelector('#btnGetLatLng').addEventListener('click', () => formSubmit()); - - document.addEventListener('keydown', documentKeydown); - document.addEventListener('touchmove', (e) => { if (document.fullscreenElement) e.preventDefault(); }); - - $(TXT_ADDRESS_SELECTOR).devbridgeAutocomplete({ - serviceUrl: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest', - deferRequestBy: 300, - paramName: 'text', - params: { - f: 'json', - category, - maxSuggestions: 10, - }, - dataType: 'json', - transformResult: (response) => ({ - suggestions: response.suggestions.map((i) => ({ - value: i.text, - data: i.magicKey, - })), - }), - minChars: 3, - showNoSuggestionNotice: true, - noSuggestionNotice: 'No results found. Please try a different search string.', - onSelect(suggestion) { autocompleteOnSelect(suggestion, this); }, - width: 490, - }); - - const formSubmit = () => { - const ac = $(TXT_ADDRESS_SELECTOR).devbridgeAutocomplete(); - if (ac.suggestions[0]) $(ac.suggestionsContainer.children[0]).trigger('click'); - return false; - }; - - // attempt to parse the url parameters - const parsedParameters = parseQueryString(); - - const loadFromParsed = parsedParameters.latLonQuery && parsedParameters.latLon; - - // Auto load the parsed parameters and fall back to the previous query - const query = parsedParameters.latLonQuery ?? localStorage.getItem('latLonQuery'); - const latLon = parsedParameters.latLon ?? localStorage.getItem('latLon'); - const fromGPS = localStorage.getItem('latLonFromGPS') && !loadFromParsed; - if (query && latLon && !fromGPS) { - const txtAddress = document.querySelector(TXT_ADDRESS_SELECTOR); - txtAddress.value = query; - loadData(JSON.parse(latLon)); - } - if (fromGPS) { - btnGetGpsClick(); - } - - // if kiosk mode was set via the query string, also play immediately - settings.kiosk.value = parsedParameters['settings-kiosk-checkbox'] === 'true'; - const play = parsedParameters['settings-kiosk-checkbox'] ?? localStorage.getItem('play'); - if (play === null || play === 'true') postMessage('navButton', 'play'); - - document.querySelector('#btnClearQuery').addEventListener('click', () => { - document.querySelector('#spanCity').innerHTML = ''; - document.querySelector('#spanState').innerHTML = ''; - document.querySelector('#spanStationId').innerHTML = ''; - document.querySelector('#spanRadarId').innerHTML = ''; - document.querySelector('#spanZoneId').innerHTML = ''; - - document.querySelector('#chkAutoRefresh').checked = true; - localStorage.removeItem('autoRefresh'); - - localStorage.removeItem('play'); - postMessage('navButton', 'play'); - - localStorage.removeItem('latLonQuery'); - localStorage.removeItem('latLon'); - localStorage.removeItem('latLonFromGPS'); - document.querySelector(BNT_GET_GPS_SELECTOR).classList.remove('active'); - }); - - // swipe functionality - document.querySelector('#container').addEventListener('swiped-left', () => swipeCallBack('left')); - document.querySelector('#container').addEventListener('swiped-right', () => swipeCallBack('right')); -}; - -const autocompleteOnSelect = async (suggestion, elem) => { - // Do not auto get the same city twice. - if (elem.previousSuggestionValue === suggestion.value) return; - - const data = await json('https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find', { - data: { - text: suggestion.value, - magicKey: suggestion.data, - f: 'json', - }, - }); - - const loc = data.locations[0]; - if (loc) { - localStorage.removeItem('latLonFromGPS'); - document.querySelector(BNT_GET_GPS_SELECTOR).classList.remove('active'); - doRedirectToGeometry(loc.feature.geometry); - } else { - console.error('An unexpected error occurred. Please try a different search string.'); - } -}; - -const doRedirectToGeometry = (geom, haveDataCallback) => { - const latLon = { lat: round2(geom.y, 4), lon: round2(geom.x, 4) }; - // Save the query - localStorage.setItem('latLonQuery', document.querySelector(TXT_ADDRESS_SELECTOR).value); - localStorage.setItem('latLon', JSON.stringify(latLon)); - - // get the data - loadData(latLon, haveDataCallback); -}; - -const btnFullScreenClick = () => { - if (document.fullscreenElement) { - exitFullscreen(); - } else { - enterFullScreen(); - } - - if (isPlaying()) { - noSleep(true); - } else { - noSleep(false); - } - - updateFullScreenNavigate(); - - return false; -}; - -const enterFullScreen = () => { - const element = document.querySelector('#divTwc'); - - // Supports most browsers and their versions. - const requestMethod = element.requestFullScreen || element.webkitRequestFullScreen - || element.mozRequestFullScreen || element.msRequestFullscreen; - - if (requestMethod) { - // Native full screen. - requestMethod.call(element, { navigationUI: 'hide' }); - } else { - // iOS doesn't support FullScreen API. - window.scrollTo(0, 0); - } - resize(); - updateFullScreenNavigate(); - - // change hover text and image - const img = document.querySelector(TOGGLE_FULL_SCREEN_SELECTOR); - img.src = 'images/nav/ic_fullscreen_exit_white_24dp_2x.png'; - img.title = 'Exit fullscreen'; -}; - -const exitFullscreen = () => { - // exit full-screen - - if (document.exitFullscreen) { - // Chrome 71 broke this if the user pressed F11 to enter full screen mode. - document.exitFullscreen(); - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen(); - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } else if (document.msExitFullscreen) { - document.msExitFullscreen(); - } - resize(); - exitFullScreenVisibilityChanges(); -}; - -const exitFullScreenVisibilityChanges = () => { - // change hover text and image - const img = document.querySelector(TOGGLE_FULL_SCREEN_SELECTOR); - img.src = 'images/nav/ic_fullscreen_white_24dp_2x.png'; - img.title = 'Enter fullscreen'; - document.querySelector('#divTwc').classList.remove('no-cursor'); - const divTwcBottom = document.querySelector('#divTwcBottom'); - divTwcBottom.classList.remove('hidden'); - divTwcBottom.classList.add('visible'); -}; - -const btnNavigateMenuClick = () => { - postMessage('navButton', 'menu'); - return false; -}; - -const loadData = (_latLon, haveDataCallback) => { - // if latlon is provided store it locally - if (_latLon) loadData.latLon = _latLon; - // get the data - const { latLon } = loadData; - // if there's no data stop - if (!latLon) return; - - document.querySelector(TXT_ADDRESS_SELECTOR).blur(); - stopAutoRefreshTimer(); - latLonReceived(latLon, haveDataCallback); -}; - -const swipeCallBack = (direction) => { - switch (direction) { - case 'left': - btnNavigateNextClick(); - break; - - case 'right': - default: - btnNavigatePreviousClick(); - break; - } -}; - -const btnNavigateRefreshClick = () => { - resetStatuses(); - loadData(); - - return false; -}; - -const btnNavigateNextClick = () => { - postMessage('navButton', 'next'); - - return false; -}; - -const btnNavigatePreviousClick = () => { - postMessage('navButton', 'previous'); - - return false; -}; - -let navigateFadeIntervalId = null; - -const updateFullScreenNavigate = () => { - document.activeElement.blur(); - const divTwcBottom = document.querySelector('#divTwcBottom'); - divTwcBottom.classList.remove('hidden'); - divTwcBottom.classList.add('visible'); - document.querySelector('#divTwc').classList.remove('no-cursor'); - - if (navigateFadeIntervalId) { - clearTimeout(navigateFadeIntervalId); - navigateFadeIntervalId = null; - } - - navigateFadeIntervalId = setTimeout(() => { - if (document.fullscreenElement) { - divTwcBottom.classList.remove('visible'); - divTwcBottom.classList.add('hidden'); - document.querySelector('#divTwc').classList.add('no-cursor'); - } - }, 2000); -}; - -const documentKeydown = (e) => { - const { key } = e; - - if (document.fullscreenElement || document.activeElement === document.body) { - switch (key) { - case ' ': // Space - // don't scroll - e.preventDefault(); - btnNavigatePlayClick(); - return false; - - case 'ArrowRight': - case 'PageDown': - // don't scroll - e.preventDefault(); - btnNavigateNextClick(); - return false; - - case 'ArrowLeft': - case 'PageUp': - // don't scroll - e.preventDefault(); - btnNavigatePreviousClick(); - return false; - - case 'ArrowUp': // Home - e.preventDefault(); - btnNavigateMenuClick(); - return false; - - case '0': // "O" Restart - btnNavigateRefreshClick(); - return false; - - case 'F': - case 'f': - btnFullScreenClick(); - return false; - - default: - } - } - return false; -}; - -const btnNavigatePlayClick = () => { - postMessage('navButton', 'playToggle'); - - return false; -}; - -// post a message to the iframe -const postMessage = (type, myMessage = {}) => { - navMessage({ type, message: myMessage }); -}; - -const getPosition = async () => new Promise((resolve) => { - navigator.geolocation.getCurrentPosition(resolve); -}); - -const btnGetGpsClick = async () => { - if (!navigator.geolocation) return; - const btn = document.querySelector(BNT_GET_GPS_SELECTOR); - - // toggle first - if (btn.classList.contains('active')) { - btn.classList.remove('active'); - localStorage.removeItem('latLonFromGPS'); - return; - } - - // set gps active - btn.classList.add('active'); - - // get position - const position = await getPosition(); - const { latitude, longitude } = position.coords; - - const txtAddress = document.querySelector(TXT_ADDRESS_SELECTOR); - txtAddress.value = `${round2(latitude, 4)}, ${round2(longitude, 4)}`; - - doRedirectToGeometry({ y: latitude, x: longitude }, (point) => { - const location = point.properties.relativeLocation.properties; - // Save the query - const query = `${location.city}, ${location.state}`; - localStorage.setItem('latLon', JSON.stringify({ lat: latitude, lon: longitude })); - localStorage.setItem('latLonQuery', query); - localStorage.setItem('latLonFromGPS', true); - txtAddress.value = `${location.city}, ${location.state}`; - }); -}; - -// check for change in full screen triggered by browser and run local functions -const fullScreenResizeCheck = () => { - if (fullScreenResizeCheck.wasFull && !document.fullscreenElement) { - // leaving full screen - exitFullScreenVisibilityChanges(); - } - if (!fullScreenResizeCheck.wasFull && document.fullscreenElement) { - // entering full screen - // can't do much here because a UI interaction is required to change the full screen div element - } - - // store state of fullscreen element for next change detection - fullScreenResizeCheck.wasFull = !!document.fullscreenElement; -}; diff --git a/dist/server/scripts/modules/almanac.mjs b/dist/server/scripts/modules/almanac.mjs deleted file mode 100644 index e2bf666..0000000 --- a/dist/server/scripts/modules/almanac.mjs +++ /dev/null @@ -1,179 +0,0 @@ -// display sun and moon data -import { loadImg, preloadImg } from './utils/image.mjs'; -import { DateTime } from '../vendor/auto/luxon.mjs'; -import STATUS from './status.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; - -class Almanac extends WeatherDisplay { - constructor(navId, elemId) { - super(navId, elemId, 'Almanac', true); - - // pre-load background images (returns promises) - this.backgroundImage0 = loadImg('images/BackGround3_1.png'); - - // preload the moon images - preloadImg('images/2/Full-Moon.gif'); - preloadImg('images/2/Last-Quarter.gif'); - preloadImg('images/2/New-Moon.gif'); - preloadImg('images/2/First-Quarter.gif'); - - this.timing.totalScreens = 1; - } - - async getData(_weatherParameters) { - const superResponse = super.getData(_weatherParameters); - const weatherParameters = _weatherParameters ?? this.weatherParameters; - - // get sun/moon data - const { sun, moon } = this.calcSunMoonData(weatherParameters); - - // store the data - this.data = { - sun, - moon, - }; - // share data - this.getDataCallback(); - - if (!superResponse) return; - - // update status - this.setStatus(STATUS.loaded); - } - - calcSunMoonData(weatherParameters) { - const sun = [ - SunCalc.getTimes(new Date(), weatherParameters.latitude, weatherParameters.longitude), - SunCalc.getTimes(DateTime.local().plus({ days: 1 }).toJSDate(), weatherParameters.latitude, weatherParameters.longitude), - ]; - - // brute force the moon phases by scanning the next 30 days - const moon = []; - // start with yesterday - let moonDate = DateTime.local().minus({ days: 1 }); - let { phase } = SunCalc.getMoonIllumination(moonDate.toJSDate()); - let iterations = 0; - do { - // get yesterday's moon info - const lastPhase = phase; - // calculate new values - moonDate = moonDate.plus({ days: 1 }); - phase = SunCalc.getMoonIllumination(moonDate.toJSDate()).phase; - // check for 4 cases - if (lastPhase < 0.25 && phase >= 0.25) moon.push(this.getMoonTransition(0.25, 'First', moonDate)); - if (lastPhase < 0.50 && phase >= 0.50) moon.push(this.getMoonTransition(0.50, 'Full', moonDate)); - if (lastPhase < 0.75 && phase >= 0.75) moon.push(this.getMoonTransition(0.75, 'Last', moonDate)); - if (lastPhase > phase) moon.push(this.getMoonTransition(0.00, 'New', moonDate)); - - // stop after 30 days or 4 moon phases - iterations += 1; - } while (iterations <= 30 && moon.length < 4); - - return { - sun, - moon, - }; - } - - // get moon transition from one phase to the next by drilling down by hours, minutes and seconds - getMoonTransition(threshold, phaseName, start, iteration = 0) { - let moonDate = start; - let { phase } = SunCalc.getMoonIllumination(moonDate.toJSDate()); - let iterations = 0; - const step = { - hours: iteration === 0 ? -1 : 0, - minutes: iteration === 1 ? 1 : 0, - seconds: iteration === 2 ? -1 : 0, - milliseconds: iteration === 3 ? 1 : 0, - }; - - // increasing test - let test = (lastPhase, testPhase) => lastPhase < threshold && testPhase >= threshold; - // decreasing test - if (iteration % 2 === 0) test = (lastPhase, testPhase) => lastPhase > threshold && testPhase <= threshold; - - do { - // store last phase - const lastPhase = phase; - // calculate new phase after step - moonDate = moonDate.plus(step); - phase = SunCalc.getMoonIllumination(moonDate.toJSDate()).phase; - // wrap phases > 0.9 to -0.1 for ease of detection - if (phase > 0.9) phase -= 1.0; - // compare - if (test(lastPhase, phase)) { - // last iteration is three, return value - if (iteration >= 3) break; - // iterate recursively - return this.getMoonTransition(threshold, phaseName, moonDate, iteration + 1); - } - iterations += 1; - } while (iterations < 1000); - - return { phase: phaseName, date: moonDate }; - } - - async drawCanvas() { - super.drawCanvas(); - const info = this.data; - const Today = DateTime.local(); - const Tomorrow = Today.plus({ days: 1 }); - - // sun and moon data - this.elem.querySelector('.day-1').innerHTML = Today.toLocaleString({ weekday: 'long' }); - this.elem.querySelector('.day-2').innerHTML = Tomorrow.toLocaleString({ weekday: 'long' }); - this.elem.querySelector('.rise-1').innerHTML = DateTime.fromJSDate(info.sun[0].sunrise).toLocaleString(DateTime.TIME_SIMPLE).toLowerCase(); - this.elem.querySelector('.rise-2').innerHTML = DateTime.fromJSDate(info.sun[1].sunrise).toLocaleString(DateTime.TIME_SIMPLE).toLowerCase(); - this.elem.querySelector('.set-1').innerHTML = DateTime.fromJSDate(info.sun[0].sunset).toLocaleString(DateTime.TIME_SIMPLE).toLowerCase(); - this.elem.querySelector('.set-2').innerHTML = DateTime.fromJSDate(info.sun[1].sunset).toLocaleString(DateTime.TIME_SIMPLE).toLowerCase(); - - const days = info.moon.map((MoonPhase) => { - const fill = {}; - - const date = MoonPhase.date.toLocaleString({ month: 'short', day: 'numeric' }); - - fill.date = date; - fill.type = MoonPhase.phase; - fill.icon = { type: 'img', src: imageName(MoonPhase.phase) }; - - return this.fillTemplate('day', fill); - }); - - const daysContainer = this.elem.querySelector('.moon .days'); - daysContainer.innerHTML = ''; - daysContainer.append(...days); - - this.finishDraw(); - } - - // make sun and moon data available outside this class - // promise allows for data to be requested before it is available - async getSun() { - return new Promise((resolve) => { - if (this.data) resolve(this.data); - // data not available, put it into the data callback queue - this.getDataCallbacks.push(resolve); - }); - } -} - -const imageName = (type) => { - switch (type) { - case 'Full': - return 'images/2/Full-Moon.gif'; - case 'Last': - return 'images/2/Last-Quarter.gif'; - case 'New': - return 'images/2/New-Moon.gif'; - case 'First': - default: - return 'images/2/First-Quarter.gif'; - } -}; - -// register display -const display = new Almanac(9, 'almanac'); -registerDisplay(display); - -export default display.getSun.bind(display); diff --git a/dist/server/scripts/modules/currentweather.mjs b/dist/server/scripts/modules/currentweather.mjs deleted file mode 100644 index f7512b6..0000000 --- a/dist/server/scripts/modules/currentweather.mjs +++ /dev/null @@ -1,140 +0,0 @@ -// current weather conditions display -import STATUS from './status.mjs'; -import { loadImg } from './utils/image.mjs'; -import { directionToNSEW } from './utils/calc.mjs'; -import { getWeatherIconFromIconLink } from './icons.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; -import { getConditionText } from './utils/weather.mjs'; - -class CurrentWeather extends WeatherDisplay { - constructor(navId, elemId) { - super(navId, elemId, 'Current Conditions', true); - // pre-load background image (returns promise) - this.backgroundImage = loadImg('images/BackGround1_1.png'); - } - - async getData(_weatherParameters) { - // always load the data for use in the lower scroll - const superResult = super.getData(_weatherParameters); - const weatherParameters = _weatherParameters ?? this.weatherParameters; - - // we only get here if there was no error above - this.data = parseData(weatherParameters); - this.getDataCallback(); - - // stop here if we're disabled - if (!superResult) return; - - this.setStatus(STATUS.loaded); - } - - async drawCanvas() { - super.drawCanvas(); - - let condition = getConditionText(this.data.TextConditions); - if (condition.length > 15) { - condition = shortConditions(condition); - } - - const iconImage = getWeatherIconFromIconLink(condition, this.data.timeZone); - - const fill = { - temp: this.data.Temperature + String.fromCharCode(176), - condition, - wind: this.data.WindDirection.padEnd(3, '') + this.data.WindSpeed.toString().padStart(3, ' '), - location: this.data.city, - humidity: `${this.data.Humidity}%`, - dewpoint: this.data.DewPoint + String.fromCharCode(176), - ceiling: (this.data.Ceiling === 0 ? 'Unlimited' : this.data.Ceiling + this.data.CeilingUnit), - visibility: this.data.Visibility + this.data.VisibilityUnit, - pressure: `${this.data.Pressure} ${this.data.PressureDirection}`, - icon: { type: 'img', src: iconImage }, - }; - - if (this.data.WindGust) fill['wind-gusts'] = `Gusts to ${this.data.WindGust}`; - - const area = this.elem.querySelector('.main'); - - area.innerHTML = ''; - area.append(this.fillTemplate('weather', fill)); - - this.finishDraw(); - } - - // make data available outside this class - // promise allows for data to be requested before it is available - async getCurrentWeather(stillWaiting) { - if (stillWaiting) this.stillWaitingCallbacks.push(stillWaiting); - return new Promise((resolve) => { - if (this.data) resolve(this.data); - // data not available, put it into the data callback queue - this.getDataCallbacks.push(() => resolve(this.data)); - }); - } -} - -const shortConditions = (_condition) => { - let condition = _condition; - condition = condition.replace(/Light/g, 'L'); - condition = condition.replace(/Heavy/g, 'H'); - condition = condition.replace(/Partly/g, 'P'); - condition = condition.replace(/Mostly/g, 'M'); - condition = condition.replace(/Few/g, 'F'); - condition = condition.replace(/Thunderstorm/g, 'T\'storm'); - condition = condition.replace(/ in /g, ''); - condition = condition.replace(/Vicinity/g, ''); - condition = condition.replace(/ and /g, ' '); - condition = condition.replace(/Freezing Rain/g, 'Frz Rn'); - condition = condition.replace(/Freezing/g, 'Frz'); - condition = condition.replace(/Unknown Precip/g, ''); - condition = condition.replace(/L Snow Fog/g, 'L Snw/Fog'); - condition = condition.replace(/ with /g, '/'); - return condition; -}; - -const getCurrentWeatherByHourFromTime = (data) => { - const currentTime = new Date(); - const onlyDate = currentTime.toISOString().split('T')[0]; // Extracts "YYYY-MM-DD" - - const availableTimes = data.forecast[onlyDate].hours; - - const closestTime = availableTimes.reduce((prev, curr) => { - const prevDiff = Math.abs(new Date(prev.time) - currentTime); - const currDiff = Math.abs(new Date(curr.time) - currentTime); - return currDiff < prevDiff ? curr : prev; - }); - - return closestTime; -}; - -// format the received data -const parseData = (data) => { - const currentForecast = getCurrentWeatherByHourFromTime(data); - - // values from api are provided in metric - data.Temperature = currentForecast.temperature_2m; - data.TemperatureUnit = 'C'; - data.DewPoint = currentForecast.dew_point_2m; - data.Ceiling = currentForecast.cloud_cover; - data.CeilingUnit = 'm.'; - data.Visibility = currentForecast.visibility; - data.VisibilityUnit = 'm.'; - data.WindSpeed = currentForecast.wind_speed_10m; - data.WindDirection = directionToNSEW(currentForecast.wind_direction_10m); - data.Pressure = currentForecast.pressure_msl; - // data.HeatIndex = Math.round(observations.heatIndex.value); - // data.WindChill = Math.round(observations.windChill.value); - data.WindGust = currentForecast.wind_gusts_10m; - data.WindUnit = 'km/h'; - data.Humidity = currentForecast.relative_humidity_2m; - data.PressureDirection = 'hPa'; - data.TextConditions = currentForecast.weather_code; - - return data; -}; - -const display = new CurrentWeather(1, 'current-weather'); -registerDisplay(display); - -export default display.getCurrentWeather.bind(display); diff --git a/dist/server/scripts/modules/currentweatherscroll.mjs b/dist/server/scripts/modules/currentweatherscroll.mjs deleted file mode 100644 index 7488809..0000000 --- a/dist/server/scripts/modules/currentweatherscroll.mjs +++ /dev/null @@ -1,98 +0,0 @@ -import { elemForEach } from './utils/elem.mjs'; -import getCurrentWeather from './currentweather.mjs'; -import { currentDisplay } from './navigation.mjs'; - -// constants -const degree = String.fromCharCode(176); - -// local variables -let interval; -let screenIndex = 0; - -// start drawing conditions -// reset starts from the first item in the text scroll list -const start = () => { - // store see if the context is new - - // set up the interval if needed - if (!interval) { - interval = setInterval(incrementInterval, 4000); - } - - // draw the data - drawScreen(); -}; - -const stop = (reset) => { - if (reset) screenIndex = 0; -}; - -// increment interval, roll over -const incrementInterval = () => { - // test current screen - const display = currentDisplay(); - if (!display?.okToDrawCurrentConditions) { - stop(display?.elemId === 'progress'); - return; - } - screenIndex = (screenIndex + 1) % (screens.length); - // draw new text - drawScreen(); -}; - -const drawScreen = async () => { - // get the conditions - const data = await getCurrentWeather(); - - // nothing to do if there's no data yet - if (!data) return; - - drawCondition(screens[screenIndex](data)); -}; - -// the "screens" are stored in an array for easy addition and removal -const screens = [ - // station name - (data) => `Conditions at ${data.city}`, - - // temperature - (data) => { - const text = `Temp: ${data.Temperature}${degree}${data.TemperatureUnit}`; - return text; - }, - - // humidity - (data) => `Humidity: ${data.Humidity}% Dewpoint: ${data.DewPoint}${degree}${data.TemperatureUnit}`, - - // barometric pressure - (data) => `Barometric Pressure: ${data.Pressure} ${data.PressureDirection}`, - - // wind - (data) => { - let text = data.WindSpeed > 0 - ? `Wind: ${data.WindDirection} ${data.WindSpeed} ${data.WindUnit}` - : 'Wind: Calm'; - - if (data.WindGust > 0) { - text += ` Gusts to ${data.WindGust}`; - } - return text; - }, - - // visibility - (data) => { - const distance = `${data.Ceiling} ${data.CeilingUnit}`; - return `Visib: ${data.Visibility} ${data.VisibilityUnit} Ceiling: ${data.Ceiling === 0 ? 'Unlimited' : distance}`; - }, -]; - -// internal draw function with preset parameters -const drawCondition = (text) => { - // update all html scroll elements - elemForEach('.weather-display .scroll .fixed', (elem) => { - elem.innerHTML = text; - }); -}; -document.addEventListener('DOMContentLoaded', () => { - start(); -}); diff --git a/dist/server/scripts/modules/extendedforecast.mjs b/dist/server/scripts/modules/extendedforecast.mjs deleted file mode 100644 index 5105022..0000000 --- a/dist/server/scripts/modules/extendedforecast.mjs +++ /dev/null @@ -1,84 +0,0 @@ -// display extended forecast graphically -// technically uses the same data as the local forecast, we'll let the browser do the caching of that - -import STATUS from './status.mjs'; -import { getWeatherIconFromIconLink } from './icons.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; -import { getConditionText } from './utils/weather.mjs'; - -class ExtendedForecast extends WeatherDisplay { - constructor(navId, elemId) { - super(navId, elemId, 'Extended Forecast', true); - - // set timings - this.timing.totalScreens = 2; - } - - async getData(_weatherParameters) { - if (!super.getData(_weatherParameters)) return; - - this.data = parse(_weatherParameters); - this.screenIndex = 0; - this.setStatus(STATUS.loaded); - } - - async drawCanvas() { - super.drawCanvas(); - - // determine bounds - // grab the first three or second set of three array elements - const forecast = this.data.slice(0 + 3 * this.screenIndex, 3 + this.screenIndex * 3); - - // create each day template - const days = forecast.map((Day) => { - const fill = { - icon: { type: 'img', src: Day.icon }, - condition: Day.text, - date: Day.dayName, - }; - - const { low } = Day; - if (low !== undefined) { - fill['value-lo'] = Math.round(low); - } - const { high } = Day; - fill['value-hi'] = Math.round(high); - - // return the filled template - return this.fillTemplate('day', fill); - }); - - // empty and update the container - const dayContainer = this.elem.querySelector('.day-container'); - dayContainer.innerHTML = ''; - dayContainer.append(...days); - this.finishDraw(); - } -} - -// the api provides the forecast in 12 hour increments, flatten to day increments with high and low temperatures -const parse = (fullForecast) => { - const forecast = []; - - Object.values(fullForecast.forecast).forEach((period) => { - const text = getConditionText(parseInt(period.weather_code, 10)); - const date = new Date(period.hours[0].time); - - const fDay = { - text, - icon: getWeatherIconFromIconLink(text, fullForecast.timeZone), - date: period.hours[0].time, - dayName: date.toLocaleDateString('en-US', { weekday: 'long' }), - high: period.temperature_2m_max, - low: period.temperature_2m_min, - }; - - forecast.push(fDay); - }); - - return forecast; -}; - -// register display -registerDisplay(new ExtendedForecast(8, 'extended-forecast')); diff --git a/dist/server/scripts/modules/hazards.mjs b/dist/server/scripts/modules/hazards.mjs deleted file mode 100644 index 8927c04..0000000 --- a/dist/server/scripts/modules/hazards.mjs +++ /dev/null @@ -1,166 +0,0 @@ -// hourly forecast list - -import STATUS from './status.mjs'; -import { json } from './utils/fetch.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; - -const hazardLevels = { - Extreme: 10, - Severe: 5, -}; - -const hazardModifiers = { - 'Hurricane Warning': 2, - 'Tornado Warning': 3, - 'Severe Thunderstorm Warning': 1, -}; - -class Hazards extends WeatherDisplay { - constructor(navId, elemId, defaultActive) { - // special height and width for scrolling - super(navId, elemId, 'Hazards', defaultActive); - this.showOnProgress = false; - - // 0 screens skips this during "play" - this.timing.totalScreens = 0; - } - - async getData(weatherParameters) { - // super checks for enabled - const superResult = super.getData(weatherParameters); - - const alert = this.checkbox.querySelector('.alert'); - alert.classList.remove('show'); - - // try { - // // get the forecast - // const url = new URL('https://api.weather.gov/alerts/active'); - // url.searchParams.append('point', `${this.weatherParameters.latitude},${this.weatherParameters.longitude}`); - // url.searchParams.append('limit', 5); - // const alerts = await json(url, { retryCount: 3, stillWaiting: () => this.stillWaiting() }); - // const unsortedAlerts = alerts.features ?? []; - // const hasImmediate = unsortedAlerts.reduce((acc, hazard) => acc || hazard.properties.urgency === 'Immediate', false); - // const sortedAlerts = unsortedAlerts.sort((a, b) => (calcSeverity(b.properties.severity, b.properties.event)) - (calcSeverity(a.properties.severity, a.properties.event))); - // const filteredAlerts = sortedAlerts.filter((hazard) => hazard.properties.severity !== 'Unknown' && (!hasImmediate || (hazard.properties.urgency === 'Immediate'))); - // this.data = filteredAlerts; - - // // show alert indicator - // if (this.data.length > 0) alert.classList.add('show'); - // } catch (error) { - // console.error('Get hourly forecast failed'); - // console.error(error.status, error.responseJSON); - // if (this.isEnabled) this.setStatus(STATUS.failed); - // // return undefined to other subscribers - // this.getDataCallback(undefined); - // return; - // } - - this.getDataCallback(); - - if (!superResult) { - this.setStatus(STATUS.loaded); - return; - } - this.drawLongCanvas(); - } - - async drawLongCanvas() { - // get the list element and populate - const list = this.elem.querySelector('.hazard-lines'); - list.innerHTML = ''; - - const lines = this.data.map((data) => { - const fillValues = {}; - // text - fillValues['hazard-text'] = `${data.properties.event}

${data.properties.description.replaceAll('\n\n', '

').replaceAll('\n', ' ')}`; - - return this.fillTemplate('hazard', fillValues); - }); - - list.append(...lines); - - // no alerts, skip this display by setting timing to zero - if (lines.length === 0) { - this.setStatus(STATUS.loaded); - this.timing.totalScreens = 0; - this.setStatus(STATUS.loaded); - return; - } - - // update timing - // set up the timing - this.timing.baseDelay = 20; - // 24 hours = 6 pages - const pages = Math.max(Math.ceil(list.scrollHeight / 400) - 3, 1); - const timingStep = 400; - this.timing.delay = [150 + timingStep]; - // add additional pages - for (let i = 0; i < pages; i += 1) this.timing.delay.push(timingStep); - // add the final 3 second delay - this.timing.delay.push(250); - this.calcNavTiming(); - this.setStatus(STATUS.loaded); - } - - drawCanvas() { - super.drawCanvas(); - this.finishDraw(); - } - - showCanvas() { - // special to hourly to draw the remainder of the canvas - this.drawCanvas(); - super.showCanvas(); - } - - // screen index change callback just runs the base count callback - screenIndexChange() { - this.baseCountChange(this.navBaseCount); - } - - // base count change callback - baseCountChange(count) { - // calculate scroll offset and don't go past end - let offsetY = Math.min(this.elem.querySelector('.hazard-lines').getBoundingClientRect().height - 390, (count - 150)); - - // don't let offset go negative - if (offsetY < 0) offsetY = 0; - - // copy the scrolled portion of the canvas - this.elem.querySelector('.main').scrollTo(0, offsetY); - } - - // make data available outside this class - // promise allows for data to be requested before it is available - async getCurrentData(stillWaiting) { - if (stillWaiting) this.stillWaitingCallbacks.push(stillWaiting); - return new Promise((resolve) => { - if (this.data) resolve(this.data); - // data not available, put it into the data callback queue - this.getDataCallbacks.push(() => resolve(this.data)); - }); - } - - // after we roll through the hazards once, don't display again until the next refresh (10 minutes) - screenIndexFromBaseCount() { - const superValue = super.screenIndexFromBaseCount(); - // false is returned when we reach the end of the scroll - if (superValue === false) { - // set total screens to zero to take this out of the rotation - this.timing.totalScreens = 0; - } - // return the value as expected - return superValue; - } -} - -const calcSeverity = (severity, event) => { - // base severity plus some modifiers for specific types of warnings - const baseSeverity = hazardLevels[severity] ?? 0; - const modifiedSeverity = hazardModifiers[event] ?? 0; - return baseSeverity + modifiedSeverity; -}; - -// register display -registerDisplay(new Hazards(0, 'hazards', true)); diff --git a/dist/server/scripts/modules/hourly-graph.mjs b/dist/server/scripts/modules/hourly-graph.mjs deleted file mode 100644 index eb7d9d7..0000000 --- a/dist/server/scripts/modules/hourly-graph.mjs +++ /dev/null @@ -1,148 +0,0 @@ -// hourly forecast list - -import STATUS from './status.mjs'; -import getHourlyData from './hourly.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; -import { DateTime } from '../vendor/auto/luxon.mjs'; - -class HourlyGraph extends WeatherDisplay { - constructor(navId, elemId, defaultActive) { - super(navId, elemId, 'Hourly Graph', defaultActive); - - // move the top right data into the correct location on load - document.addEventListener('DOMContentLoaded', () => { - this.moveHeader(); - }); - } - - moveHeader() { - // get the header - const header = this.fillTemplate('top-right', {}); - // place the header - this.elem.querySelector('.header .right').append(header); - } - - async getData() { - if (!super.getData()) return; - - const data = await getHourlyData(() => this.stillWaiting()); - if (data === undefined) { - this.setStatus(STATUS.failed); - return; - } - - // get interesting data - const temperature = data.map((d) => d.temperature); - const probabilityOfPrecipitation = data.map((d) => d.probabilityOfPrecipitation); - const skyCover = data.map((d) => d.skyCover); - - this.data = { - skyCover, temperature, probabilityOfPrecipitation, - }; - - this.setStatus(STATUS.loaded); - } - - drawCanvas() { - if (!this.image) this.image = this.elem.querySelector('.chart img'); - - // get available space - const availableWidth = 532; - const availableHeight = 285; - - this.image.width = availableWidth; - this.image.height = availableHeight; - - // get context - const canvas = document.createElement('canvas'); - canvas.width = availableWidth; - canvas.height = availableHeight; - const ctx = canvas.getContext('2d'); - ctx.imageSmoothingEnabled = false; - - // calculate time scale - const timeScale = calcScale(0, 5, this.data.temperature.length - 1, availableWidth); - const startTime = DateTime.now().startOf('hour'); - document.querySelector('.x-axis .l-1').innerHTML = formatTime(startTime); - document.querySelector('.x-axis .l-2').innerHTML = formatTime(startTime.plus({ hour: 6 })); - document.querySelector('.x-axis .l-3').innerHTML = formatTime(startTime.plus({ hour: 12 })); - document.querySelector('.x-axis .l-4').innerHTML = formatTime(startTime.plus({ hour: 18 })); - document.querySelector('.x-axis .l-5').innerHTML = formatTime(startTime.plus({ hour: 24 })); - - // order is important last line drawn is on top - // clouds - const percentScale = calcScale(0, availableHeight - 10, 100, 10); - const cloud = createPath(this.data.skyCover, timeScale, percentScale); - drawPath(cloud, ctx, { - strokeStyle: 'lightgrey', - lineWidth: 3, - }); - - // precip - const precip = createPath(this.data.probabilityOfPrecipitation, timeScale, percentScale); - drawPath(precip, ctx, { - strokeStyle: 'aqua', - lineWidth: 3, - }); - - // temperature - const minTemp = Math.min(...this.data.temperature); - const maxTemp = Math.max(...this.data.temperature); - const midTemp = Math.round((minTemp + maxTemp) / 2); - const tempScale = calcScale(minTemp, availableHeight - 10, maxTemp, 10); - const tempPath = createPath(this.data.temperature, timeScale, tempScale); - drawPath(tempPath, ctx, { - strokeStyle: 'red', - lineWidth: 3, - }); - - // temperature axis labels - // limited to 3 characters, sacraficing degree character - const degree = String.fromCharCode(176); - this.elem.querySelector('.y-axis .l-1').innerHTML = (maxTemp + degree).substring(0, 3); - this.elem.querySelector('.y-axis .l-2').innerHTML = (midTemp + degree).substring(0, 3); - this.elem.querySelector('.y-axis .l-3').innerHTML = (minTemp + degree).substring(0, 3); - - // set the image source - this.image.src = canvas.toDataURL(); - - super.drawCanvas(); - this.finishDraw(); - } -} - -// create a scaling function from two points -const calcScale = (x1, y1, x2, y2) => { - const m = (y2 - y1) / (x2 - x1); - const b = y1 - m * x1; - return (x) => m * x + b; -}; - -// create a path as an array of [x,y] -const createPath = (data, xScale, yScale) => data.map((d, i) => [xScale(i), yScale(d)]); - -// draw a path with shadow -const drawPath = (path, ctx, options) => { - // first shadow - ctx.beginPath(); - ctx.strokeStyle = 'black'; - ctx.lineWidth = (options?.lineWidth ?? 2) + 2; - ctx.moveTo(path[0][0], path[0][1]); - path.slice(1).forEach((point) => ctx.lineTo(point[0], point[1] + 2)); - ctx.stroke(); - - // then colored line - ctx.beginPath(); - ctx.strokeStyle = options?.strokeStyle ?? 'red'; - ctx.lineWidth = (options?.lineWidth ?? 2); - ctx.moveTo(path[0][0], path[0][1]); - path.slice(1).forEach((point) => ctx.lineTo(point[0], point[1])); - ctx.stroke(); -}; - -// format as 1p, 12a, etc. -const formatTime = (time) => time.toFormat('ha').slice(0, -1); - -// register display -registerDisplay(new HourlyGraph(4, 'hourly-graph')); diff --git a/dist/server/scripts/modules/hourly.mjs b/dist/server/scripts/modules/hourly.mjs deleted file mode 100644 index 342a735..0000000 --- a/dist/server/scripts/modules/hourly.mjs +++ /dev/null @@ -1,168 +0,0 @@ -// hourly forecast list - -import STATUS from './status.mjs'; -import { DateTime } from '../vendor/auto/luxon.mjs'; -import { getWeatherRegionalIconFromIconLink } from './icons.mjs'; -import { directionToNSEW } from './utils/calc.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; -import { getConditionText } from './utils/weather.mjs'; - -class Hourly extends WeatherDisplay { - constructor(navId, elemId, defaultActive) { - // special height and width for scrolling - super(navId, elemId, 'Hourly Forecast', defaultActive); - - // set up the timing - this.timing.baseDelay = 20; - // 24 hours = 6 pages - const pages = 4; // first page is already displayed, last page doesn't happen - const timingStep = 75 * 4; - this.timing.delay = [150 + timingStep]; - // add additional pages - for (let i = 0; i < pages; i += 1) this.timing.delay.push(timingStep); - // add the final 3 second delay - this.timing.delay.push(150); - } - - async getData(weatherParameters) { - this.data = await parseForecast(weatherParameters); - this.getDataCallback(); - - this.setStatus(STATUS.loaded); - this.drawLongCanvas(); - } - - async drawLongCanvas() { - // get the list element and populate - const list = this.elem.querySelector('.hourly-lines'); - list.innerHTML = ''; - - const startingHour = DateTime.local(); - - const lines = this.data.map((data, index) => { - const fillValues = {}; - - // hour - const hour = startingHour.plus({ hours: index }); - const formattedHour = hour.toLocaleString({ weekday: 'short', hour: 'numeric' }); - fillValues.hour = formattedHour; - - // temperatures, convert to strings with no decimal - const temperature = Math.round(data.temperature).toString().padStart(3); - const feelsLike = Math.round(data.apparentTemperature).toString().padStart(3); - fillValues.temp = temperature; - // only plot apparent temperature if there is a difference - // if (temperature !== feelsLike) line.querySelector('.like').innerHTML = feelsLike; - if (temperature !== feelsLike) fillValues.like = feelsLike; - - // wind - let wind = 'Calm'; - if (data.windSpeed > 0) { - const windSpeed = Math.round(data.windSpeed).toString(); - const windDirection = directionToNSEW(data.windDirection); - wind = windDirection + (Array(6 - windDirection.length - windSpeed.length).join(' ')) + windSpeed; - } - fillValues.wind = wind; - - // image - fillValues.icon = { type: 'img', src: data.icon }; - - return this.fillTemplate('hourly-row', fillValues); - }); - - list.append(...lines); - } - - drawCanvas() { - super.drawCanvas(); - this.finishDraw(); - } - - showCanvas() { - // special to hourly to draw the remainder of the canvas - this.drawCanvas(); - super.showCanvas(); - } - - // screen index change callback just runs the base count callback - screenIndexChange() { - this.baseCountChange(this.navBaseCount); - } - - // base count change callback - baseCountChange(count) { - // calculate scroll offset and don't go past end - let offsetY = Math.min(this.elem.querySelector('.hourly-lines').offsetHeight - 289, (count - 150)); - - // don't let offset go negative - if (offsetY < 0) offsetY = 0; - - // copy the scrolled portion of the canvas - this.elem.querySelector('.main').scrollTo(0, offsetY); - } - - // make data available outside this class - // promise allows for data to be requested before it is available - async getCurrentData(stillWaiting) { - if (stillWaiting) this.stillWaitingCallbacks.push(stillWaiting); - return new Promise((resolve) => { - if (this.data) resolve(this.data); - // data not available, put it into the data callback queue - this.getDataCallbacks.push(() => resolve(this.data)); - }); - } -} - -const getCurrentWeatherByHourFromTime = (data) => { - const currentTime = new Date(); - const onlyDate = currentTime.toISOString().split('T')[0]; // Extracts "YYYY-MM-DD" - - const availableTimes = data.forecast[onlyDate].hours; - const nextDate = DateTime.fromISO(onlyDate).plus({ days: 1 }).toISODate(); - - const availableTimesNextDay = data.forecast[nextDate]?.hours || []; - const allAvailableTimes = [...availableTimes, ...availableTimesNextDay]; - - let closestIndex = 0; - let closestTime = availableTimes[0]; - let minDiff = Math.abs(new Date(closestTime.time) - currentTime); - - availableTimes.forEach((entry, index) => { - const diff = Math.abs(new Date(entry.time) - currentTime); - if (diff < minDiff) { - minDiff = diff; - closestTime = entry; - closestIndex = index; - } - }); - - return { closestTime, index: closestIndex, todayAndTomorrow: allAvailableTimes }; -}; - -// extract specific values from forecast and format as an array -const parseForecast = async (data) => { - const currentForecast = getCurrentWeatherByHourFromTime(data); - - // Split today's date at the returned hourly index and iterate through 'todayAndTomorrow' from currentForecast to create hourly rows - const iterableHourlyData = currentForecast.todayAndTomorrow.slice(currentForecast.index).map((hour) => ({ - temperature: hour.temperature_2m, - apparentTemperature: hour.apparent_temperature, - windSpeed: hour.wind_speed_10m, - windDirection: hour.wind_direction_10m, - probabilityOfPrecipitation: hour.precipitation_probability, - skyCover: hour.cloud_cover, - icon: getWeatherRegionalIconFromIconLink(getConditionText(hour.weather_code), hour.is_day), - // is_day appears to be "buggy," in that it uses the calling application's IP/location to - // determine whether is_day is day or night relative to the calling machine's timezone.... - isDay: hour.is_day, - })); - - return iterableHourlyData; -}; - -// register display -const display = new Hourly(3, 'hourly', false); -registerDisplay(display); - -export default display.getCurrentData.bind(display); diff --git a/dist/server/scripts/modules/icons.mjs b/dist/server/scripts/modules/icons.mjs deleted file mode 100644 index 32d435a..0000000 --- a/dist/server/scripts/modules/icons.mjs +++ /dev/null @@ -1,334 +0,0 @@ -/* spell-checker: disable */ - -function isNightTime(timeZone) { - const now = new Date(); - const hour = new Intl.DateTimeFormat('en-US', { - hour: 'numeric', - hour12: false, - timeZone, - }).format(now); - - return hour >= 18 || hour < 6; -} - -const getWeatherRegionalIconFromIconLink = (text, isDay) => { - // internal function to add path to returned icon - const addPath = (icon) => `images/r/${icon}`; - - // const nightTime = isNightTime(timeZone); - let tidyText = text.toLowerCase(); - if (tidyText.includes(' ')) tidyText = tidyText.replaceAll(' ', '-'); - - if (isDay === 0) tidyText += '-night'; - - // find the icon - switch (tidyText) { - case 0: - case 'clear-sky': - return addPath('Sunny.gif'); - - case 'clear-sky-night': - return addPath('Clear-1992.gif'); - - case 1: - case 'mainly-clear': - return addPath('Sunny.gif'); - case 'mainly-clear-night': - return addPath('Mostly-Clear.gif'); - - case 2: - case 'partly-cloudy': - return addPath('Partly-Cloudy.gif'); - case 'partly-cloudy-night': - return addPath('Mostly-Clear.gif'); - - case 3: - case 'overcast': - return addPath('Partly-Cloudy.gif'); - case 'overcast-night': - return addPath('Mostly-Clear.gif'); - - case 45: - case 48: - case 'fog': - case 'fog-night': - case 'depositing-rime-fog': - case 'depositing-rime-fog-night': - return addPath('Fog.gif'); - - case 51: - case 'light-drizzle': - return addPath('Scattered-Showers-1994-2.gif'); - case 'light-drizzle-night': - return addPath('Scattered-Showers-Night.gif'); - - case 53: - case 55: - case 'moderate-drizzle': - case 'dense-drizzle': - case 'moderate-drizzle-night': - case 'dense-drizzle-night': - return addPath('Shower.gif'); - - case 56: - case 57: - case 'light-freezing-drizzle': - case 'dense-freezing-drizzle': - case 'light-freezing-drizzle-night': - case 'dense-freezing-drizzle-night': - return addPath('Freezing-Rain-1992.gif'); - - case 61: - case 'slight-rain': - case 'slight-rain-night': - return addPath('Shower.gif'); - - case 63: - case 65: - case 'moderate-rain': - case 'heavy-rain': - case 'moderate-rain-night': - case 'heavy-rain-night': - return addPath('Shower.gif'); - - case 66: - case 67: - case 'light-freezing-rain': - case 'heavy-freezing-rain': - case 'light-freezing-rain-night': - case 'heavy-freezing-rain-night': - return addPath('Freezing-Rain-1992.gif'); - - case 71: - case 'slight-snow-fall': - case 'slight-snow-fall-night': - return addPath('Light-Snow.gif'); - - case 73: - case 'moderate-snow-fall': - case 'moderate-snow-fall-night': - return addPath('Heavy-Snow.gif'); - - case 75: - case 'heavy-snow-fall': - case 'heavy-snow-fall-night': - return addPath('Heavy-Snow.gif'); - - case 77: - case 'snow-grains': - case 'snow-grains-night': - return addPath('Sleet.gif'); - - case 80: - case 'slight-rain-showers': - case 'slight-rain-showers-night': - return addPath('Shower.gif'); - - case 81: - case 82: - case 'moderate-rain-showers': - case 'voilent-rain-showers': - case 'moderate-rain-showers-night': - case 'voilent-rain-showers-night': - return addPath('Rain-1992.gif'); - - case 85: - case 86: - case 'slight-snow-showers': - case 'heavy-snow-showers': - case 'slight-snow-showers-night': - case 'heavy-snow-showers-night': - return addPath('Scattered-Snow-Showers-1994-2.gif'); - - case 95: - case 'thunderstorm': - case 'thunderstorm-night': - return addPath('Thunderstorm.gif'); - - case 99: - case 'thunderstorm-with-slight-hail': - case 'thunderstorm-with-heavy-hail': - case 'thunderstorm-with-slight-hail-night': - case 'thunderstorm-with-heavy-hail-night': - return addPath('ThunderSnow.gif'); - - default: - console.log(`Unable to locate icon for: ${text}`); - return addPath('Logo3.gif'); - } -}; - -const getWeatherIconFromIconLink = (text, timeZone) => { - if (!text) return false; - - const addPath = (icon) => `images/${icon}`; - - const nightTime = isNightTime(timeZone); - let tidyText = text.toLowerCase().replaceAll(' ', '-'); - - if (nightTime && tidyText.includes('clear')) tidyText += '-night'; - - // find the icon - switch (tidyText) { - case 0: - case 'clear-sky': - return addPath('CC_Clear1.gif'); - - case 'clear-sky-night': - return addPath('CC_Clear0.gif'); - - case 1: - case 'mainly-clear': - return addPath('CC_Clear1.gif'); - - case 'mainly-clear-night': - return addPath('CC_Clear0.gif'); - - case 2: - case 'partly-cloudy': - return addPath('CC_PartlyCloudy1.gif'); - - case 3: - case 'overcast': - return addPath('Cloudy.gif'); - - case 45: - case 48: - case 'fog': - case 'depositing-rime-fog': - return addPath('CC_Fog.gif'); - - case 51: - case 'light-drizzle': - return addPath('CC_Showers.gif'); - - case 53: - case 55: - case 'moderate-drizzle': - case 'dense-drizzle': - return addPath('CC_Rain.gif'); - - case 56: - case 57: - case 'light-freezing-drizzle': - case 'dense-freezing-drizzle': - return addPath('Freezing-Rain.gif'); - - case 61: - case 'slight-rain': - return addPath('CC_Showers.gif'); - - case 63: - case 65: - case 'moderate-rain': - case 'heavy-rain': - return addPath('CC_Rain.gif'); - - case 66: - case 67: - case 'light-freezing-rain': - case 'heavy-freezing-rain': - return addPath('CC_FreezingRain.gif'); - - case 71: - case 'slight-snow-fall': - return addPath('CC_SnowShowers.gif'); - - case 73: - case 'moderate-snow-fall': - return addPath('CC_Snow.gif'); - - case 75: - case 'heavy-snow-fall': - return addPath('Heavy-Snow.gif'); - - case 77: - case 'snow-grains': - return addPath('Sleet.gif'); - - case 80: - case 'slight-rain-showers': - return addPath('CC_Showers.gif'); - - case 81: - case 82: - case 'moderate-rain-showers': - case 'voilent-rain-showers': - return addPath('Rain.gif'); - - case 85: - case 86: - case 'slight-snow-showers': - case 'heavy-snow-showers': - return addPath('CC_Mix.gif'); - - case 95: - case 'thunderstorm': - return addPath('CC_TStorm.gif'); - - case 99: - case 'thunderstorm-with-slight-hail': - case 'thunderstorm-with-heavy-hail': - return addPath('ThunderSnow.gif'); - - default: - console.log(`Unable to locate icon for: ${text}`); - return addPath('Logo3.gif'); - } -}; - -// const getHourlyIcon = (skyCover, weather, iceAccumulation, probabilityOfPrecipitation, snowfallAmount, windSpeed, isNight = false) => { -// // internal function to add path to returned icon -// const addPath = (icon) => `images/r/${icon}`; - -// // possible phenomenon -// let thunder = false; -// let snow = false; -// let ice = false; -// let fog = false; -// let wind = false; - -// // test the phenomenon for various value if it is provided. -// weather.forEach((phenomenon) => { -// if (!phenomenon.weather) return; -// if (phenomenon.weather.toLowerCase().includes('thunder')) thunder = true; -// if (phenomenon.weather.toLowerCase().includes('snow')) snow = true; -// if (phenomenon.weather.toLowerCase().includes('ice')) ice = true; -// if (phenomenon.weather.toLowerCase().includes('fog')) fog = true; -// if (phenomenon.weather.toLowerCase().includes('wind')) wind = true; -// }); - -// // first item in list is highest priority, units are metric where applicable -// if (iceAccumulation > 0 || ice) return addPath('Freezing-Rain-1992.gif'); -// if (snowfallAmount > 10) { -// if (windSpeed > 30 || wind) return addPath('Blowing Snow.gif'); -// return addPath('Heavy-Snow-1994.gif'); -// } -// if ((snowfallAmount > 0 || snow) && thunder) return addPath('ThunderSnow.gif'); -// if (snowfallAmount > 0 || snow) return addPath('Light-Snow.gif'); -// if (thunder) return (addPath('Thunderstorm.gif')); -// if (probabilityOfPrecipitation > 70) return addPath('Rain-1992.gif'); -// if (probabilityOfPrecipitation > 50) return addPath('Shower.gif'); -// if (probabilityOfPrecipitation > 30) { -// if (!isNight) return addPath('Scattered-Showers-1994.gif'); -// return addPath('Scattered-Showers-Night.gif'); -// } -// if (fog) return addPath('Fog.gif'); -// if (skyCover > 70) return addPath('Cloudy.gif'); -// if (skyCover > 50) { -// if (!isNight) return addPath('Mostly-Cloudy-1994.gif'); -// return addPath('Partly-Clear-1994.gif'); -// } -// if (skyCover > 30) { -// if (!isNight) return addPath('Partly-Cloudy.gif'); -// return addPath('Mostly-Clear.gif'); -// } -// if (isNight) return addPath('Clear-1992.gif'); -// return addPath('Sunny.gif'); -// }; - -export { - getWeatherIconFromIconLink, - getWeatherRegionalIconFromIconLink, - // getHourlyIcon, -}; diff --git a/dist/server/scripts/modules/latestobservations.mjs b/dist/server/scripts/modules/latestobservations.mjs deleted file mode 100644 index 98cba31..0000000 --- a/dist/server/scripts/modules/latestobservations.mjs +++ /dev/null @@ -1,142 +0,0 @@ -// current weather conditions display -import { distance as calcDistance, directionToNSEW } from './utils/calc.mjs'; -import { json } from './utils/fetch.mjs'; -import STATUS from './status.mjs'; -import { locationCleanup } from './utils/string.mjs'; -import { celsiusToFahrenheit, kphToMph } from './utils/units.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; - -class LatestObservations extends WeatherDisplay { - constructor(navId, elemId) { - super(navId, elemId, 'Latest Observations', true); - - // constants - this.MaximumRegionalStations = 7; - } - - async getData(_weatherParameters) { - if (!super.getData(_weatherParameters)) return; - const weatherParameters = _weatherParameters ?? this.weatherParameters; - - // calculate distance to each station - const stationsByDistance = Object.keys(StationInfo).map((key) => { - const station = StationInfo[key]; - const distance = calcDistance(station.lat, station.lon, weatherParameters.latitude, weatherParameters.longitude); - return { ...station, distance }; - }); - - // sort the stations by distance - const sortedStations = stationsByDistance.sort((a, b) => a.distance - b.distance); - // try up to 30 regional stations - const regionalStations = sortedStations.slice(0, 30); - - // get data for regional stations - // get first 7 stations - const actualConditions = []; - let lastStation = Math.min(regionalStations.length, 7); - let firstStation = 0; - while (actualConditions.length < 7 && (lastStation) <= regionalStations.length) { - // eslint-disable-next-line no-await-in-loop - const someStations = await getStations(regionalStations.slice(firstStation, lastStation)); - - actualConditions.push(...someStations); - // update counters - firstStation += lastStation; - lastStation = Math.min(regionalStations.length + 1, firstStation + 7 - actualConditions.length); - } - - // cut down to the maximum of 7 - this.data = actualConditions.slice(0, this.MaximumRegionalStations); - - // test for at least one station - if (this.data.length === 0) { - this.setStatus(STATUS.noData); - return; - } - this.setStatus(STATUS.loaded); - } - - async drawCanvas() { - super.drawCanvas(); - const conditions = this.data; - - // sort array by station name - const sortedConditions = conditions.sort((a, b) => ((a.Name < b.Name) ? -1 : 1)); - - this.elem.querySelector('.column-headers .temp.english').classList.add('show'); - this.elem.querySelector('.column-headers .temp.metric').classList.remove('show'); - - const lines = sortedConditions.map((condition) => { - const windDirection = directionToNSEW(condition.windDirection.value); - - const Temperature = Math.round(celsiusToFahrenheit(condition.temperature.value)); - const WindSpeed = Math.round(kphToMph(condition.windSpeed.value)); - - const fill = { - location: locationCleanup(condition.city).substr(0, 14), - temp: Temperature, - weather: shortenCurrentConditions(condition.textDescription).substr(0, 9), - }; - - if (WindSpeed > 0) { - fill.wind = windDirection + (Array(6 - windDirection.length - WindSpeed.toString().length).join(' ')) + WindSpeed.toString(); - } else if (WindSpeed === 'NA') { - fill.wind = 'NA'; - } else { - fill.wind = 'Calm'; - } - - return this.fillTemplate('observation-row', fill); - }); - - const linesContainer = this.elem.querySelector('.observation-lines'); - linesContainer.innerHTML = ''; - linesContainer.append(...lines); - - this.finishDraw(); - } -} -const shortenCurrentConditions = (_condition) => { - let condition = _condition; - condition = condition.replace(/Light/, 'L'); - condition = condition.replace(/Heavy/, 'H'); - condition = condition.replace(/Partly/, 'P'); - condition = condition.replace(/Mostly/, 'M'); - condition = condition.replace(/Few/, 'F'); - condition = condition.replace(/Thunderstorm/, 'T\'storm'); - condition = condition.replace(/ in /, ''); - condition = condition.replace(/Vicinity/, ''); - condition = condition.replace(/ and /, ' '); - condition = condition.replace(/Freezing Rain/, 'Frz Rn'); - condition = condition.replace(/Freezing/, 'Frz'); - condition = condition.replace(/Unknown Precip/, ''); - condition = condition.replace(/L Snow Fog/, 'L Snw/Fog'); - condition = condition.replace(/ with /, '/'); - return condition; -}; - -const getStations = async (stations) => { - const stationData = await Promise.all(stations.map(async (station) => { - try { - const data = await json(`https://api.weather.gov/stations/${station.id}/observations/latest`, { retryCount: 1, stillWaiting: () => this.stillWaiting() }); - // test for temperature, weather and wind values present - if (data.properties.temperature.value === null - || data.properties.textDescription === '' - || data.properties.windSpeed.value === null) return false; - // format the return values - return { - ...data.properties, - StationId: station.id, - city: station.city, - }; - } catch (error) { - console.log(`Unable to get latest observations for ${station.id}`); - return false; - } - })); - // filter false (no data or other error) - return stationData.filter((d) => d); -}; -// register display -registerDisplay(new LatestObservations(2, 'latest-observations')); diff --git a/dist/server/scripts/modules/localforecast.mjs b/dist/server/scripts/modules/localforecast.mjs deleted file mode 100644 index 8861bf5..0000000 --- a/dist/server/scripts/modules/localforecast.mjs +++ /dev/null @@ -1,81 +0,0 @@ -// display text based local forecast - -import STATUS from './status.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; -import { generateLocalForecast } from './utils/localForecastTextGenerator.mjs'; - -// 3 days, morning night; including the current day's morning/night -class LocalForecast extends WeatherDisplay { - constructor(navId, elemId) { - super(navId, elemId, 'Local Forecast', true); - - // set timings - this.timing.baseDelay = 5000; - } - - async getData(_weatherParameters) { - if (!super.getData(_weatherParameters)) return; - - // get today + 2 more days hourly forecasts - const days = Object.keys(_weatherParameters.forecast).slice(0, 3); - const daysWeatherData = Object.values(_weatherParameters.forecast).slice(0, 3); - - const localForecastTextByDay = []; - - daysWeatherData.forEach((day, index) => { - const result = generateLocalForecast(days[index], day.hours); - localForecastTextByDay.push(JSON.parse(result)); - }); - - const conditions = []; - - localForecastTextByDay.forEach((forecast) => { - const page = Object.values(forecast.periods).map((forecastText) => ({ - DayName: forecast.date, - Text: forecastText.text, - })); - - conditions.push(...page); - }); - - // read each text - this.screenTexts = conditions.map((condition) => { - // process the text - let text = `${condition.DayName.toUpperCase()}...`; - const conditionText = condition.Text; - text += conditionText.toUpperCase().replace('...', ' '); - - return text; - }); - - // fill the forecast texts - const templates = this.screenTexts.map((text) => this.fillTemplate('forecast', { text })); - const forecastsElem = this.elem.querySelector('.forecasts'); - forecastsElem.innerHTML = ''; - forecastsElem.append(...templates); - - // increase each forecast height to a multiple of container height - this.pageHeight = forecastsElem.parentNode.scrollHeight; - templates.forEach((forecast) => { - const newHeight = Math.ceil(forecast.scrollHeight / this.pageHeight) * this.pageHeight; - forecast.style.height = `${newHeight}px`; - }); - - this.timing.totalScreens = forecastsElem.scrollHeight / this.pageHeight; - this.calcNavTiming(); - this.setStatus(STATUS.loaded); - } - - async drawCanvas() { - super.drawCanvas(); - - const top = -this.screenIndex * this.pageHeight; - this.elem.querySelector('.forecasts').style.top = `${top}px`; - - this.finishDraw(); - } -} - -// register display -registerDisplay(new LocalForecast(7, 'local-forecast')); diff --git a/dist/server/scripts/modules/navigation.mjs b/dist/server/scripts/modules/navigation.mjs deleted file mode 100644 index f64adf8..0000000 --- a/dist/server/scripts/modules/navigation.mjs +++ /dev/null @@ -1,429 +0,0 @@ -// navigation handles progress, next/previous and initial load messages from the parent frame -import noSleep from './utils/nosleep.mjs'; -import STATUS from './status.mjs'; -import { wrap } from './utils/calc.mjs'; -import { getPoint, getGeocoding, aggregateWeatherForecastData } from './utils/weather.mjs'; -import settings from './settings.mjs'; - -document.addEventListener('DOMContentLoaded', () => { - init(); -}); - -const displays = []; -let playing = false; -let progress; -const weatherParameters = {}; - -// auto refresh -const AUTO_REFRESH_INTERVAL_MS = 500; -const AUTO_REFRESH_TIME_MS = 600_000; // 10 min. -const CHK_AUTO_REFRESH_SELECTOR = '#chkAutoRefresh'; -let AutoRefreshIntervalId = null; -let AutoRefreshCountMs = 0; - -const init = async () => { - // set up resize handler - window.addEventListener('resize', resize); - resize(); - - // auto refresh - const autoRefresh = localStorage.getItem('autoRefresh'); - if (!autoRefresh || autoRefresh === 'true') { - document.querySelector(CHK_AUTO_REFRESH_SELECTOR).checked = true; - } else { - document.querySelector(CHK_AUTO_REFRESH_SELECTOR).checked = false; - } - document.querySelector(CHK_AUTO_REFRESH_SELECTOR).addEventListener('change', autoRefreshChange); - generateCheckboxes(); -}; - -const message = (data) => { - // dispatch event - if (!data.type) return false; - if (data.type === 'navButton') return handleNavButton(data.message); - return console.error(`Unknown event ${data.type}`); -}; - -const getWeather = async (latLon, haveDataCallback) => { - // get initial weather data - const point = await getPoint(latLon.lat, latLon.lon); - - const aggregatedForecastData = aggregateWeatherForecastData(point); - - if (typeof haveDataCallback === 'function') haveDataCallback(point); - - // Get locality data from open-meteo and local storage - const localityName = localStorage.getItem('latLonQuery'); - // 'latLonQuery' is set in server>scripts>index.mjs in the format of "Amsterdam, NLD" - // therefore we need to split on the "," to get the locality name for open-meteo - const locality = await getGeocoding(localityName.split(',')[0]); - - // @todo - this shouldn't be hardcoded - // when a user searches for a location that doesn't have a city - // this will error out. - - // set the city and state - let city = locality.results[0].name; - let country = locality.results[0].country; - let state = locality.results[0].admin1; // admin1 is usually the state / province - let timezone = locality.results[0].timezone; - - // populate the weather parameters - weatherParameters.latitude = latLon.lat; - weatherParameters.longitude = latLon.lon; - weatherParameters.city = city; - weatherParameters.state = state; - weatherParameters.country = country; - weatherParameters.timeZone = timezone; - - // WeatherParameters to modify... - weatherParameters.forecast = aggregatedForecastData; - // weatherParameters.forecastGridData = point.properties.forecastGridData; - // weatherParameters.stations = stations.features; - - // WeatherParameters that might be optional to modify - // or aren't obviously used anywhere for data retrieval... - weatherParameters.stationId = 'stationId-dont-matter-anymore'; - weatherParameters.zoneId = 'zoneId-dont-matter'; - weatherParameters.radarId = 'radarId-dont-matter'; - weatherParameters.weatherOffice = 'weatherOffice-dont-matter'; - - // update the main process for display purposes - populateWeatherParameters(weatherParameters); - - // draw the progress canvas and hide others - hideAllCanvases(); - document.querySelector('#loading').style.display = 'none'; - if (progress) { - await progress.drawCanvas(); - progress.showCanvas(); - } - - // call for new data on each display - displays.forEach((display) => display.getData(weatherParameters)); -}; - -// receive a status update from a module {id, value} -const updateStatus = (value) => { - if (value.id < 0) return; - if (!progress) return; - progress.drawCanvas(displays, countLoadedDisplays()); - - // first display is hazards and it must load before evaluating the first display - if (displays[0].status === STATUS.loading) return; - - // calculate first enabled display - const firstDisplayIndex = displays.findIndex((display) => display.enabled && display.timing.totalScreens > 0); - - // value.id = 0 is hazards, if they fail to load hot-wire a new value.id to the current display to see if it needs to be loaded - // typically this plays out as current conditions loads, then hazards fails. - if (value.id === 0 && (value.status === STATUS.failed || value.status === STATUS.retrying)) { - value.id = firstDisplayIndex; - value.status = displays[firstDisplayIndex].status; - } - - // if hazards data arrives after the firstDisplayIndex loads, then we need to hot wire this to the first display - if (value.id === 0 && value.status === STATUS.loaded && displays[0].timing.totalScreens === 0) { - value.id = firstDisplayIndex; - value.status = displays[firstDisplayIndex].status; - } - - // if this is the first display and we're playing, load it up so it starts playing - if (isPlaying() && value.id === firstDisplayIndex && value.status === STATUS.loaded) { - navTo(msg.command.firstFrame); - } - - // send loaded messaged to parent - if (countLoadedDisplays() < displays.length) return; - - // everything loaded, set timestamps - AssignLastUpdate(new Date()); -}; - -// note: a display that is "still waiting"/"retrying" is considered loaded intentionally -// the weather.gov api has long load times for some products when you are the first -// requester for the product after the cache expires -const countLoadedDisplays = () => displays.reduce((acc, display) => { - if (display.status !== STATUS.loading) return acc + 1; - return acc; -}, 0); - -const hideAllCanvases = () => { - displays.forEach((display) => display.hideCanvas()); -}; - -// is playing interface -const isPlaying = () => playing; - -// navigation message constants -const msg = { - response: { // display to navigation - previous: Symbol('previous'), // already at first frame, calling function should switch to previous canvas - inProgress: Symbol('inProgress'), // have data to display, calling function should do nothing - next: Symbol('next'), // end of frames reached, calling function should switch to next canvas - }, - command: { // navigation to display - firstFrame: Symbol('firstFrame'), - previousFrame: Symbol('previousFrame'), - nextFrame: Symbol('nextFrame'), - lastFrame: Symbol('lastFrame'), // used when navigating backwards from the begining of the next canvas - }, -}; - -// receive navigation messages from displays -const displayNavMessage = (myMessage) => { - if (myMessage.type === msg.response.previous) loadDisplay(-1); - if (myMessage.type === msg.response.next) loadDisplay(1); -}; - -// navigate to next or previous -const navTo = (direction) => { - // test for a current display - const current = currentDisplay(); - progress.hideCanvas(); - if (!current) { - // special case for no active displays (typically on progress screen) - // find the first ready display - let firstDisplay; - let displayCount = 0; - do { - if (displays[displayCount].status === STATUS.loaded && displays[displayCount].timing.totalScreens > 0) firstDisplay = displays[displayCount]; - displayCount += 1; - } while (!firstDisplay && displayCount < displays.length); - - if (!firstDisplay) return; - - firstDisplay.navNext(msg.command.firstFrame); - firstDisplay.showCanvas(); - return; - } - if (direction === msg.command.nextFrame) currentDisplay().navNext(); - if (direction === msg.command.previousFrame) currentDisplay().navPrev(); -}; - -// find the next or previous available display -const loadDisplay = (direction) => { - const totalDisplays = displays.length; - const curIdx = currentDisplayIndex(); - let idx; - for (let i = 0; i < totalDisplays; i += 1) { - // convert form simple 0-10 to start at current display index +/-1 and wrap - idx = wrap(curIdx + (i + 1) * direction, totalDisplays); - if (displays[idx].status === STATUS.loaded && displays[idx].timing.totalScreens > 0) break; - } - // if new display index is less than current display a wrap occurred, test for reload timeout - if (idx <= curIdx && refreshCheck()) return; - const newDisplay = displays[idx]; - // hide all displays - hideAllCanvases(); - // show the new display and navigate to an appropriate display - if (direction < 0) newDisplay.showCanvas(msg.command.lastFrame); - if (direction > 0) newDisplay.showCanvas(msg.command.firstFrame); -}; - -// get the current display index or value -const currentDisplayIndex = () => displays.findIndex((display) => display.active); -const currentDisplay = () => displays[currentDisplayIndex()]; - -const setPlaying = (newValue) => { - playing = newValue; - const playButton = document.querySelector('#NavigatePlay'); - localStorage.setItem('play', playing); - - if (playing) { - noSleep(true); - playButton.title = 'Pause'; - playButton.src = 'images/nav/ic_pause_white_24dp_2x.png'; - } else { - noSleep(false); - playButton.title = 'Play'; - playButton.src = 'images/nav/ic_play_arrow_white_24dp_2x.png'; - } - // if we're playing and on the progress screen jump to the next screen - if (!progress) return; - if (playing && !currentDisplay()) navTo(msg.command.firstFrame); -}; - -// handle all navigation buttons -const handleNavButton = (button) => { - switch (button) { - case 'play': - setPlaying(true); - break; - case 'playToggle': - setPlaying(!playing); - break; - case 'stop': - setPlaying(false); - break; - case 'next': - setPlaying(false); - navTo(msg.command.nextFrame); - break; - case 'previous': - setPlaying(false); - navTo(msg.command.previousFrame); - break; - case 'menu': - setPlaying(false); - progress.showCanvas(); - hideAllCanvases(); - break; - default: - console.error(`Unknown navButton ${button}`); - } -}; - -// return the specificed display -const getDisplay = (index) => displays[index]; - -// resize the container on a page resize -const resize = () => { - const targetWidth = settings.wide.value ? 640 + 107 + 107 : 640; - const widthZoomPercent = (document.querySelector('#divTwcBottom').getBoundingClientRect().width) / targetWidth; - const heightZoomPercent = (window.innerHeight) / 480; - - const scale = Math.min(widthZoomPercent, heightZoomPercent); - if (scale < 1.0 || document.fullscreenElement || settings.kiosk) { - document.querySelector('#container').style.transform = `scale(${scale})`; - } else { - document.querySelector('#container').style.transform = 'unset'; - } -}; - -// reset all statuses to loading on all displays, used to keep the progress bar accurate during refresh -const resetStatuses = () => { - displays.forEach((display) => { display.status = STATUS.loading; }); -}; - -// allow displays to register themselves -const registerDisplay = (display) => { - displays[display.navId] = display; - - // generate checkboxes - generateCheckboxes(); -}; - -const generateCheckboxes = () => { - const availableDisplays = document.querySelector('#enabledDisplays'); - - if (!availableDisplays) return; - // generate checkboxes - const checkboxes = displays.map((d) => d.generateCheckbox(d.defaultEnabled)).filter((d) => d); - - // write to page - availableDisplays.innerHTML = ''; - availableDisplays.append(...checkboxes); -}; - -// special registration method for progress display -const registerProgress = (_progress) => { - progress = _progress; -}; - -const populateWeatherParameters = (params) => { - document.querySelector('#spanCity').innerHTML = `${params.city}, `; - document.querySelector('#spanState').innerHTML = params.state; - document.querySelector('#spanStationId').innerHTML = params.stationId; - document.querySelector('#spanRadarId').innerHTML = params.radarId; - document.querySelector('#spanZoneId').innerHTML = params.zoneId; -}; - -const autoRefreshChange = (e) => { - const { checked } = e.target; - - if (checked) { - startAutoRefreshTimer(); - } else { - stopAutoRefreshTimer(); - } - - localStorage.setItem('autoRefresh', checked); -}; - -const AssignLastUpdate = (date) => { - if (date) { - document.querySelector('#spanLastRefresh').innerHTML = date.toLocaleString('en-US', { - weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'short', - }); - if (document.querySelector(CHK_AUTO_REFRESH_SELECTOR).checked) startAutoRefreshTimer(); - } else { - document.querySelector('#spanLastRefresh').innerHTML = '(none)'; - } -}; - -const latLonReceived = (data, haveDataCallback) => { - getWeather(data, haveDataCallback); - AssignLastUpdate(null); -}; - -const startAutoRefreshTimer = () => { - // Ensure that any previous timer has already stopped. - // check if timer is running - if (AutoRefreshIntervalId) return; - - // Reset the time elapsed. - AutoRefreshCountMs = 0; - - const AutoRefreshTimer = () => { - // Increment the total time elapsed. - AutoRefreshCountMs += AUTO_REFRESH_INTERVAL_MS; - - // Display the count down. - let RemainingMs = (AUTO_REFRESH_TIME_MS - AutoRefreshCountMs); - if (RemainingMs < 0) { - RemainingMs = 0; - } - const dt = new Date(RemainingMs); - document.querySelector('#spanRefreshCountDown').innerHTML = `${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}`; - - // Time has elapsed. - if (AutoRefreshCountMs >= AUTO_REFRESH_TIME_MS && !isPlaying()) loadTwcData(); - }; - AutoRefreshIntervalId = window.setInterval(AutoRefreshTimer, AUTO_REFRESH_INTERVAL_MS); - AutoRefreshTimer(); -}; -const stopAutoRefreshTimer = () => { - if (AutoRefreshIntervalId) { - window.clearInterval(AutoRefreshIntervalId); - document.querySelector('#spanRefreshCountDown').innerHTML = '--:--'; - AutoRefreshIntervalId = null; - } -}; - -const refreshCheck = () => { - // Time has elapsed. - if (AutoRefreshCountMs >= AUTO_REFRESH_TIME_MS && isPlaying()) { - loadTwcData(); - return true; - } - return false; -}; - -const loadTwcData = () => { - if (loadTwcData.callback) loadTwcData.callback(); -}; - -const registerRefreshData = (callback) => { - loadTwcData.callback = callback; -}; - -const timeZone = () => weatherParameters.timeZone; - -export { - updateStatus, - displayNavMessage, - resetStatuses, - isPlaying, - resize, - registerDisplay, - registerProgress, - currentDisplay, - getDisplay, - msg, - message, - latLonReceived, - stopAutoRefreshTimer, - registerRefreshData, - timeZone, -}; diff --git a/dist/server/scripts/modules/progress.mjs b/dist/server/scripts/modules/progress.mjs deleted file mode 100644 index 266922f..0000000 --- a/dist/server/scripts/modules/progress.mjs +++ /dev/null @@ -1,97 +0,0 @@ -// regional forecast and observations -import { loadImg } from './utils/image.mjs'; -import STATUS, { calcStatusClass, statusClasses } from './status.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { - registerProgress, message, getDisplay, msg, -} from './navigation.mjs'; - -class Progress extends WeatherDisplay { - constructor(navId, elemId) { - super(navId, elemId, '', false); - - // pre-load background image (returns promise) - this.backgroundImage = loadImg('images/BackGround1_1.png'); - - // disable any navigation timing - this.timing = false; - - // setup event listener for dom-required initialization - document.addEventListener('DOMContentLoaded', () => { - this.version = document.querySelector('#version').innerHTML; - this.elem.querySelector('.container').addEventListener('click', this.lineClick.bind(this)); - }); - - this.okToDrawCurrentConditions = false; - } - - async drawCanvas(displays, loadedCount) { - if (!this.elem) return; - super.drawCanvas(); - - // get the progress bar cover (makes percentage) - if (!this.progressCover) this.progressCover = this.elem.querySelector('.scroll .cover'); - - // if no displays provided just draw the backgrounds (above) - if (!displays) return; - const lines = displays.map((display, index) => { - if (display.showOnProgress === false) return false; - const fill = { - name: display.name, - }; - - const statusClass = calcStatusClass(display.status); - - // make the line - const line = this.fillTemplate('item', fill); - // because of timing, this might get called before the template is loaded - if (!line) return false; - - // update the status - const links = line.querySelector('.links'); - links.classList.remove(...statusClasses); - links.classList.add(statusClass); - links.dataset.index = index; - return line; - }).filter((d) => d); - - // get the container and update - const container = this.elem.querySelector('.container'); - container.innerHTML = ''; - container.append(...lines); - - this.finishDraw(); - - // calculate loaded percent - const loadedPercent = (loadedCount / displays.length); - - this.progressCover.style.width = `${(1.0 - loadedPercent) * 100}%`; - if (loadedPercent < 1.0) { - // show the progress bar and set width - this.progressCover.parentNode.classList.add('show'); - } else { - // hide the progressbar after 1 second (lines up with with width transition animation) - setTimeout(() => this.progressCover.parentNode.classList.remove('show'), 1000); - } - } - - lineClick(e) { - // get index - const indexRaw = e.target?.parentNode?.dataset?.index; - if (indexRaw === undefined) return; - const index = +indexRaw; - - // stop playing - message('navButton'); - // use the y value to determine an index - const display = getDisplay(index); - if (display && display.status === STATUS.loaded) { - display.showCanvas(msg.command.firstFrame); - this.elem.classList.remove('show'); - } - } -} - -// register our own display -const progress = new Progress(-1, 'progress'); -registerProgress(progress); diff --git a/dist/server/scripts/modules/radar-utils.mjs b/dist/server/scripts/modules/radar-utils.mjs deleted file mode 100644 index d2b46a7..0000000 --- a/dist/server/scripts/modules/radar-utils.mjs +++ /dev/null @@ -1,185 +0,0 @@ -const getXYFromLatitudeLongitudeMap = (pos, offsetX, offsetY) => { - let y = 0; - let x = 0; - const imgHeight = 3200; - const imgWidth = 5100; - - y = (51.75 - pos.latitude) * 55.2; - // center map - y -= offsetY; - - // Do not allow the map to exceed the max/min coordinates. - if (y > (imgHeight - (offsetY * 2))) { - y = imgHeight - (offsetY * 2); - } else if (y < 0) { - y = 0; - } - - x = ((-130.37 - pos.longitude) * 41.775) * -1; - // center map - x -= offsetX; - - // Do not allow the map to exceed the max/min coordinates. - if (x > (imgWidth - (offsetX * 2))) { - x = imgWidth - (offsetX * 2); - } else if (x < 0) { - x = 0; - } - - return { x: x * 2, y: y * 2 }; -}; - -const getXYFromLatitudeLongitudeDoppler = (pos, offsetX, offsetY) => { - let y = 0; - let x = 0; - const imgHeight = 6000; - const imgWidth = 2800; - - y = (51 - pos.latitude) * 61.4481; - // center map - y -= offsetY; - - // Do not allow the map to exceed the max/min coordinates. - if (y > (imgHeight - (offsetY * 2))) { - y = imgHeight - (offsetY * 2); - } else if (y < 0) { - y = 0; - } - - x = ((-129.138 - pos.longitude) * 42.1768) * -1; - // center map - x -= offsetX; - - // Do not allow the map to exceed the max/min coordinates. - if (x > (imgWidth - (offsetX * 2))) { - x = imgWidth - (offsetX * 2); - } else if (x < 0) { - x = 0; - } - - return { x: x * 2, y: y * 2 }; -}; - -const removeDopplerRadarImageNoise = (RadarContext) => { - const RadarImageData = RadarContext.getImageData(0, 0, RadarContext.canvas.width, RadarContext.canvas.height); - - // examine every pixel, - // change any old rgb to the new-rgb - for (let i = 0; i < RadarImageData.data.length; i += 4) { - // i + 0 = red - // i + 1 = green - // i + 2 = blue - // i + 3 = alpha (0 = transparent, 255 = opaque) - let R = RadarImageData.data[i]; - let G = RadarImageData.data[i + 1]; - let B = RadarImageData.data[i + 2]; - let A = RadarImageData.data[i + 3]; - - // is this pixel the old rgb? - if ((R === 0 && G === 0 && B === 0) - || (R === 0 && G === 236 && B === 236) - || (R === 1 && G === 160 && B === 246) - || (R === 0 && G === 0 && B === 246)) { - // change to your new rgb - - // Transparent - R = 0; - G = 0; - B = 0; - A = 0; - } else if ((R === 0 && G === 255 && B === 0)) { - // Light Green 1 - R = 49; - G = 210; - B = 22; - A = 255; - } else if ((R === 0 && G === 200 && B === 0)) { - // Light Green 2 - R = 0; - G = 142; - B = 0; - A = 255; - } else if ((R === 0 && G === 144 && B === 0)) { - // Dark Green 1 - R = 20; - G = 90; - B = 15; - A = 255; - } else if ((R === 255 && G === 255 && B === 0)) { - // Dark Green 2 - R = 10; - G = 40; - B = 10; - A = 255; - } else if ((R === 231 && G === 192 && B === 0)) { - // Yellow - R = 196; - G = 179; - B = 70; - A = 255; - } else if ((R === 255 && G === 144 && B === 0)) { - // Orange - R = 190; - G = 72; - B = 19; - A = 255; - } else if ((R === 214 && G === 0 && B === 0) - || (R === 255 && G === 0 && B === 0)) { - // Red - R = 171; - G = 14; - B = 14; - A = 255; - } else if ((R === 192 && G === 0 && B === 0) - || (R === 255 && G === 0 && B === 255)) { - // Brown - R = 115; - G = 31; - B = 4; - A = 255; - } - - RadarImageData.data[i] = R; - RadarImageData.data[i + 1] = G; - RadarImageData.data[i + 2] = B; - RadarImageData.data[i + 3] = A; - } - - RadarContext.putImageData(RadarImageData, 0, 0); -}; - -const mergeDopplerRadarImage = (mapContext, radarContext) => { - const mapImageData = mapContext.getImageData(0, 0, mapContext.canvas.width, mapContext.canvas.height); - const radarImageData = radarContext.getImageData(0, 0, radarContext.canvas.width, radarContext.canvas.height); - - // examine every pixel, - // change any old rgb to the new-rgb - for (let i = 0; i < radarImageData.data.length; i += 4) { - // i + 0 = red - // i + 1 = green - // i + 2 = blue - // i + 3 = alpha (0 = transparent, 255 = opaque) - - // is this pixel the old rgb? - if ((mapImageData.data[i] < 116 && mapImageData.data[i + 1] < 116 && mapImageData.data[i + 2] < 116)) { - // change to your new rgb - - // Transparent - radarImageData.data[i] = 0; - radarImageData.data[i + 1] = 0; - radarImageData.data[i + 2] = 0; - radarImageData.data[i + 3] = 0; - } - } - - radarContext.putImageData(radarImageData, 0, 0); - - mapContext.drawImage(radarContext.canvas, 0, 0); -}; - -export { - getXYFromLatitudeLongitudeDoppler, - getXYFromLatitudeLongitudeMap, - removeDopplerRadarImageNoise, - mergeDopplerRadarImage, -}; diff --git a/dist/server/scripts/modules/radar.mjs b/dist/server/scripts/modules/radar.mjs deleted file mode 100644 index 7beac32..0000000 --- a/dist/server/scripts/modules/radar.mjs +++ /dev/null @@ -1,229 +0,0 @@ -// current weather conditions display -import STATUS from './status.mjs'; -import { DateTime } from '../vendor/auto/luxon.mjs'; -import { loadImg } from './utils/image.mjs'; -import { text } from './utils/fetch.mjs'; -import { rewriteUrl } from './utils/cors.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay, timeZone } from './navigation.mjs'; -import * as utils from './radar-utils.mjs'; - -class Radar extends WeatherDisplay { - constructor(navId, elemId) { - super(navId, elemId, 'Local Radar', true); - - this.okToDrawCurrentConditions = false; - this.okToDrawCurrentDateTime = false; - - // set max images - this.dopplerRadarImageMax = 6; - // update timing - this.timing.baseDelay = 350; - this.timing.delay = [ - { time: 4, si: 5 }, - { time: 1, si: 0 }, - { time: 1, si: 1 }, - { time: 1, si: 2 }, - { time: 1, si: 3 }, - { time: 1, si: 4 }, - { time: 4, si: 5 }, - { time: 1, si: 0 }, - { time: 1, si: 1 }, - { time: 1, si: 2 }, - { time: 1, si: 3 }, - { time: 1, si: 4 }, - { time: 4, si: 5 }, - { time: 1, si: 0 }, - { time: 1, si: 1 }, - { time: 1, si: 2 }, - { time: 1, si: 3 }, - { time: 1, si: 4 }, - { time: 12, si: 5 }, - ]; - } - - async getData(_weatherParameters) { - if (!super.getData(_weatherParameters)) return; - const weatherParameters = _weatherParameters ?? this.weatherParameters; - - // ALASKA AND HAWAII AREN'T SUPPORTED! - if (weatherParameters.state === 'AK' || weatherParameters.state === 'HI') { - this.setStatus(STATUS.noData); - return; - } - - // get the base map - let src = 'images/4000RadarMap2.jpg'; - if (weatherParameters.State === 'HI') src = 'images/HawaiiRadarMap2.png'; - this.baseMap = await loadImg(src); - - const baseUrl = 'https://mesonet.agron.iastate.edu/archive/data/'; - const baseUrlEnd = '/GIS/uscomp/'; - const baseUrls = []; - let date = DateTime.utc().minus({ days: 1 }).startOf('day'); - - // make urls for yesterday and today - while (date <= DateTime.utc().startOf('day')) { - baseUrls.push(`${baseUrl}${date.toFormat('yyyy/LL/dd')}${baseUrlEnd}`); - date = date.plus({ days: 1 }); - } - - const lists = (await Promise.all(baseUrls.map(async (url) => { - try { - // get a list of available radars - return text(url, { cors: true }); - } catch (error) { - console.log('Unable to get list of radars'); - console.error(error); - this.setStatus(STATUS.failed); - return false; - } - }))).filter((d) => d); - - // convert to an array of gif urls - const pngs = lists.flatMap((html, htmlIdx) => { - const parser = new DOMParser(); - const xmlDoc = parser.parseFromString(html, 'text/html'); - // add the base url - const base = xmlDoc.createElement('base'); - base.href = baseUrls[htmlIdx]; - xmlDoc.head.append(base); - const anchors = xmlDoc.querySelectorAll('a'); - const urls = []; - Array.from(anchors).forEach((elem) => { - if (elem.innerHTML?.match(/n0r_\d{12}\.png/)) { - urls.push(elem.href); - } - }); - return urls; - }); - - // get the last few images - const timestampRegex = /_(\d{12})\.png/; - const sortedPngs = pngs.sort((a, b) => (a.match(timestampRegex)[1] < b.match(timestampRegex)[1] ? -1 : 1)); - const urls = sortedPngs.slice(-(this.dopplerRadarImageMax)); - - // calculate offsets and sizes - let offsetX = 120; - let offsetY = 69; - const width = 2550; - const height = 1600; - offsetX *= 2; - offsetY *= 2; - const sourceXY = utils.getXYFromLatitudeLongitudeMap(weatherParameters, offsetX, offsetY); - - // create working context for manipulation - const workingCanvas = document.createElement('canvas'); - workingCanvas.width = width; - workingCanvas.height = height; - const workingContext = workingCanvas.getContext('2d'); - workingContext.imageSmoothingEnabled = false; - - // calculate radar offsets - const radarOffsetX = 120; - const radarOffsetY = 70; - const radarSourceXY = utils.getXYFromLatitudeLongitudeDoppler(weatherParameters, offsetX, offsetY); - const radarSourceX = radarSourceXY.x / 2; - const radarSourceY = radarSourceXY.y / 2; - - // Load the most recent doppler radar images. - const radarInfo = await Promise.all(urls.map(async (url) => { - // create destination context - const canvas = document.createElement('canvas'); - canvas.width = 640; - canvas.height = 367; - const context = canvas.getContext('2d'); - context.imageSmoothingEnabled = false; - - // get the image - const response = await fetch(rewriteUrl(url)); - - // test response - if (!response.ok) throw new Error(`Unable to fetch radar error ${response.status} ${response.statusText} from ${response.url}`); - - // get the blob - const blob = await response.blob(); - - // store the time - const timeMatch = url.match(/_(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)\./); - let time; - if (timeMatch) { - const [, year, month, day, hour, minute] = timeMatch; - time = DateTime.fromObject({ - year, - month, - day, - hour, - minute, - }, { - zone: 'UTC', - }).setZone(timeZone()); - } else { - time = DateTime.fromHTTP(response.headers.get('last-modified')).setZone(timeZone()); - } - - // assign to an html image element - const imgBlob = await loadImg(blob); - - // draw the entire image - workingContext.clearRect(0, 0, width, 1600); - workingContext.drawImage(imgBlob, 0, 0, width, 1600); - - // get the base map - context.drawImage(await this.baseMap, sourceXY.x, sourceXY.y, offsetX * 2, offsetY * 2, 0, 0, 640, 367); - - // crop the radar image - const cropCanvas = document.createElement('canvas'); - cropCanvas.width = 640; - cropCanvas.height = 367; - const cropContext = cropCanvas.getContext('2d', { willReadFrequently: true }); - cropContext.imageSmoothingEnabled = false; - cropContext.drawImage(workingCanvas, radarSourceX, radarSourceY, (radarOffsetX * 2), (radarOffsetY * 2.33), 0, 0, 640, 367); - // clean the image - utils.removeDopplerRadarImageNoise(cropContext); - - // merge the radar and map - utils.mergeDopplerRadarImage(context, cropContext); - - const elem = this.fillTemplate('frame', { map: { type: 'img', src: canvas.toDataURL() } }); - - return { - canvas, - time, - elem, - }; - })); - - // put the elements in the container - const scrollArea = this.elem.querySelector('.scroll-area'); - scrollArea.innerHTML = ''; - scrollArea.append(...radarInfo.map((r) => r.elem)); - - // set max length - this.timing.totalScreens = radarInfo.length; - // store the images - this.data = radarInfo.map((radar) => radar.canvas); - - this.times = radarInfo.map((radar) => radar.time); - this.setStatus(STATUS.loaded); - } - - async drawCanvas() { - super.drawCanvas(); - const time = this.times[this.screenIndex].toLocaleString(DateTime.TIME_SIMPLE); - const timePadded = time.length >= 8 ? time : ` ${time}`; - this.elem.querySelector('.header .right .time').innerHTML = timePadded; - - // get image offset calculation - // is slides slightly because of scaling so we have to take a measurement from the rendered page - const actualFrameHeight = this.elem.querySelector('.frame').scrollHeight; - - // scroll to image - this.elem.querySelector('.scroll-area').style.top = `${-this.screenIndex * actualFrameHeight}px`; - - this.finishDraw(); - } -} - -// register display -registerDisplay(new Radar(10, 'radar')); diff --git a/dist/server/scripts/modules/regionalforecast-utils.mjs b/dist/server/scripts/modules/regionalforecast-utils.mjs deleted file mode 100644 index 02e434d..0000000 --- a/dist/server/scripts/modules/regionalforecast-utils.mjs +++ /dev/null @@ -1,207 +0,0 @@ -import { getWeatherRegionalIconFromIconLink } from './icons.mjs'; -import { preloadImg } from './utils/image.mjs'; -import { json } from './utils/fetch.mjs'; - -const buildForecast = (forecast, city, cityXY) => ({ - daytime: forecast.isDaytime, - temperature: forecast.temperature || 0, - name: formatCity(city.city), - icon: forecast.icon, - x: cityXY.x, - y: cityXY.y, - time: forecast.startTime, -}); - -const getRegionalObservation = async (point, city) => { - try { - // get stations - const stations = await json(`https://api.weather.gov/gridpoints/${point.wfo}/${point.x},${point.y}/stations`); - - // get the first station - const station = stations.features[0].id; - // get the observation data - const observation = await json(`${station}/observations/latest`); - // preload the image - if (!observation.properties.icon) return false; - const icon = getWeatherRegionalIconFromIconLink(observation.properties.icon, !observation.properties.daytime); - if (!icon) return false; - preloadImg(icon); - // return the observation - return observation.properties; - } catch (error) { - console.log(`Unable to get regional observations for ${city.Name ?? city.city}`); - console.error(error.status, error.responseJSON); - return false; - } -}; - -// utility latitude/pixel conversions -const getXYFromLatitudeLongitude = (Latitude, Longitude, OffsetX, OffsetY, state) => { - if (state === 'AK') return getXYFromLatitudeLongitudeAK(Latitude, Longitude, OffsetX, OffsetY); - if (state === 'HI') return getXYFromLatitudeLongitudeHI(Latitude, Longitude, OffsetX, OffsetY); - let y = 0; - let x = 0; - const ImgHeight = 1600; - const ImgWidth = 2550; - - y = (50.5 - Latitude) * 55.2; - y -= OffsetY; // Centers map. - // Do not allow the map to exceed the max/min coordinates. - if (y > (ImgHeight - (OffsetY * 2))) { - y = ImgHeight - (OffsetY * 2); - } else if (y < 0) { - y = 0; - } - - x = ((-127.5 - Longitude) * 41.775) * -1; - x -= OffsetX; // Centers map. - // Do not allow the map to exceed the max/min coordinates. - if (x > (ImgWidth - (OffsetX * 2))) { - x = ImgWidth - (OffsetX * 2); - } else if (x < 0) { - x = 0; - } - - return { x, y }; -}; - -const getXYFromLatitudeLongitudeAK = (Latitude, Longitude, OffsetX, OffsetY) => { - let y = 0; - let x = 0; - const ImgHeight = 1142; - const ImgWidth = 1200; - - y = (73.0 - Latitude) * 56; - y -= OffsetY; // Centers map. - // Do not allow the map to exceed the max/min coordinates. - if (y > (ImgHeight - (OffsetY * 2))) { - y = ImgHeight - (OffsetY * 2); - } else if (y < 0) { - y = 0; - } - - x = ((-175.0 - Longitude) * 25.0) * -1; - x -= OffsetX; // Centers map. - // Do not allow the map to exceed the max/min coordinates. - if (x > (ImgWidth - (OffsetX * 2))) { - x = ImgWidth - (OffsetX * 2); - } else if (x < 0) { - x = 0; - } - - return { x, y }; -}; - -const getXYFromLatitudeLongitudeHI = (Latitude, Longitude, OffsetX, OffsetY) => { - let y = 0; - let x = 0; - const ImgHeight = 571; - const ImgWidth = 600; - - y = (25 - Latitude) * 55.2; - y -= OffsetY; // Centers map. - // Do not allow the map to exceed the max/min coordinates. - if (y > (ImgHeight - (OffsetY * 2))) { - y = ImgHeight - (OffsetY * 2); - } else if (y < 0) { - y = 0; - } - - x = ((-164.5 - Longitude) * 41.775) * -1; - x -= OffsetX; // Centers map. - // Do not allow the map to exceed the max/min coordinates. - if (x > (ImgWidth - (OffsetX * 2))) { - x = ImgWidth - (OffsetX * 2); - } else if (x < 0) { - x = 0; - } - - return { x, y }; -}; - -const getMinMaxLatitudeLongitude = (X, Y, OffsetX, OffsetY, state) => { - if (state === 'AK') return getMinMaxLatitudeLongitudeAK(X, Y, OffsetX, OffsetY); - if (state === 'HI') return getMinMaxLatitudeLongitudeHI(X, Y, OffsetX, OffsetY); - const maxLat = ((Y / 55.2) - 50.5) * -1; - const minLat = (((Y + (OffsetY * 2)) / 55.2) - 50.5) * -1; - const minLon = (((X * -1) / 41.775) + 127.5) * -1; - const maxLon = ((((X + (OffsetX * 2)) * -1) / 41.775) + 127.5) * -1; - - return { - minLat, maxLat, minLon, maxLon, - }; -}; - -const getMinMaxLatitudeLongitudeAK = (X, Y, OffsetX, OffsetY) => { - const maxLat = ((Y / 56) - 73.0) * -1; - const minLat = (((Y + (OffsetY * 2)) / 56) - 73.0) * -1; - const minLon = (((X * -1) / 25) + 175.0) * -1; - const maxLon = ((((X + (OffsetX * 2)) * -1) / 25) + 175.0) * -1; - - return { - minLat, maxLat, minLon, maxLon, - }; -}; - -const getMinMaxLatitudeLongitudeHI = (X, Y, OffsetX, OffsetY) => { - const maxLat = ((Y / 55.2) - 25) * -1; - const minLat = (((Y + (OffsetY * 2)) / 55.2) - 25) * -1; - const minLon = (((X * -1) / 41.775) + 164.5) * -1; - const maxLon = ((((X + (OffsetX * 2)) * -1) / 41.775) + 164.5) * -1; - - return { - minLat, maxLat, minLon, maxLon, - }; -}; - -const getXYForCity = (City, MaxLatitude, MinLongitude, state) => { - if (state === 'AK') getXYForCityAK(City, MaxLatitude, MinLongitude); - if (state === 'HI') getXYForCityHI(City, MaxLatitude, MinLongitude); - let x = (City.lon - MinLongitude) * 57; - let y = (MaxLatitude - City.lat) * 70; - - if (y < 30) y = 30; - if (y > 282) y = 282; - - if (x < 40) x = 40; - if (x > 580) x = 580; - - return { x, y }; -}; - -const getXYForCityAK = (City, MaxLatitude, MinLongitude) => { - let x = (City.lon - MinLongitude) * 37; - let y = (MaxLatitude - City.lat) * 70; - - if (y < 30) y = 30; - if (y > 282) y = 282; - - if (x < 40) x = 40; - if (x > 580) x = 580; - return { x, y }; -}; - -const getXYForCityHI = (City, MaxLatitude, MinLongitude) => { - let x = (City.lon - MinLongitude) * 57; - let y = (MaxLatitude - City.lat) * 70; - - if (y < 30) y = 30; - if (y > 282) y = 282; - - if (x < 40) x = 40; - if (x > 580) x = 580; - - return { x, y }; -}; - -// to fit on the map, remove anything after punctuation and then limit to 15 characters -const formatCity = (city) => city.match(/[^,/;\\-]*/)[0].substr(0, 12); - -export { - buildForecast, - getRegionalObservation, - getXYFromLatitudeLongitude, - getMinMaxLatitudeLongitude, - getXYForCity, - formatCity, -}; diff --git a/dist/server/scripts/modules/regionalforecast.mjs b/dist/server/scripts/modules/regionalforecast.mjs deleted file mode 100644 index 15d89b1..0000000 --- a/dist/server/scripts/modules/regionalforecast.mjs +++ /dev/null @@ -1,208 +0,0 @@ -// regional forecast and observations -// type 0 = observations, 1 = first forecast, 2 = second forecast - -import STATUS from './status.mjs'; -import { distance as calcDistance } from './utils/calc.mjs'; -import { json } from './utils/fetch.mjs'; -import { celsiusToFahrenheit } from './utils/units.mjs'; -import { getWeatherRegionalIconFromIconLink } from './icons.mjs'; -import { preloadImg } from './utils/image.mjs'; -import { DateTime } from '../vendor/auto/luxon.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; -import * as utils from './regionalforecast-utils.mjs'; -import { getPoint } from './utils/weather.mjs'; - -class RegionalForecast extends WeatherDisplay { - constructor(navId, elemId) { - super(navId, elemId, 'Regional Forecast', true); - - // timings - this.timing.totalScreens = 3; - } - - async getData(_weatherParameters) { - if (!super.getData(_weatherParameters)) return; - const weatherParameters = _weatherParameters ?? this.weatherParameters; - - // pre-load the base map - let baseMap = 'images/Basemap2.png'; - if (weatherParameters.state === 'HI') { - baseMap = 'images/HawaiiRadarMap4.png'; - } else if (weatherParameters.state === 'AK') { - baseMap = 'images/AlaskaRadarMap6.png'; - } - this.elem.querySelector('.map img').src = baseMap; - - // map offset - const offsetXY = { - x: 240, - y: 117, - }; - // get user's location in x/y - const sourceXY = utils.getXYFromLatitudeLongitude(weatherParameters.latitude, weatherParameters.longitude, offsetXY.x, offsetXY.y, weatherParameters.state); - - // get latitude and longitude limits - const minMaxLatLon = utils.getMinMaxLatitudeLongitude(sourceXY.x, sourceXY.y, offsetXY.x, offsetXY.y, weatherParameters.state); - - // get a target distance - let targetDistance = 2.5; - if (weatherParameters.state === 'HI') targetDistance = 1; - - // make station info into an array - const stationInfoArray = Object.values(StationInfo).map((value) => ({ ...value, targetDistance })); - // combine regional cities with station info for additional stations - // stations are intentionally after cities to allow cities priority when drawing the map - const combinedCities = [...RegionalCities, ...stationInfoArray]; - - // Determine which cities are within the max/min latitude/longitude. - const regionalCities = []; - combinedCities.forEach((city) => { - if (city.lat > minMaxLatLon.minLat && city.lat < minMaxLatLon.maxLat - && city.lon > minMaxLatLon.minLon && city.lon < minMaxLatLon.maxLon - 1) { - // default to 1 for cities loaded from RegionalCities, use value calculate above for remaining stations - const targetDist = city.targetDistance || 1; - // Only add the city as long as it isn't within set distance degree of any other city already in the array. - const okToAddCity = regionalCities.reduce((acc, testCity) => { - const distance = calcDistance(city.lon, city.lat, testCity.lon, testCity.lat); - return acc && distance >= targetDist; - }, true); - if (okToAddCity) regionalCities.push(city); - } - }); - - // get regional forecasts and observations (the two are intertwined due to the design of api.weather.gov) - const regionalDataAll = await Promise.all(regionalCities.map(async (city) => { - try { - const point = city?.point ?? (await getAndFormatPoint(city.lat, city.lon)); - if (!point) throw new Error('No pre-loaded point'); - - // start off the observation task - const observationPromise = utils.getRegionalObservation(point, city); - - const forecast = await json(`https://api.weather.gov/gridpoints/${point.wfo}/${point.x},${point.y}/forecast`); - - // get XY on map for city - const cityXY = utils.getXYForCity(city, minMaxLatLon.maxLat, minMaxLatLon.minLon, weatherParameters.state); - - // wait for the regional observation if it's not done yet - const observation = await observationPromise; - - if (!observation) return false; - - // format the observation the same as the forecast - const regionalObservation = { - daytime: !!/\/day\//.test(observation.icon), - temperature: celsiusToFahrenheit(observation.temperature.value), - name: utils.formatCity(city.city), - icon: observation.icon, - x: cityXY.x, - y: cityXY.y, - }; - - // preload the icon - preloadImg(getWeatherRegionalIconFromIconLink(regionalObservation.icon, !regionalObservation.daytime)); - - // return a pared-down forecast - // 0th object is the current conditions - // first object is the next period i.e. if it's daytime then it's the "tonight" forecast - // second object is the following period - // always skip the first forecast index because it's what's going on right now - return [ - regionalObservation, - utils.buildForecast(forecast.properties.periods[1], city, cityXY), - utils.buildForecast(forecast.properties.periods[2], city, cityXY), - ]; - } catch (error) { - console.log(`No regional forecast data for '${city.name ?? city.city}'`); - console.log(error); - return false; - } - })); - - // filter out any false (unavailable data) - const regionalData = regionalDataAll.filter((data) => data); - - // test for data present - if (regionalData.length === 0) { - this.setStatus(STATUS.noData); - return; - } - - // return the weather data and offsets - this.data = { - regionalData, - offsetXY, - sourceXY, - }; - - this.setStatus(STATUS.loaded); - } - - drawCanvas() { - super.drawCanvas(); - // break up data into useful values - const { regionalData: data, sourceXY, offsetXY } = this.data; - - // draw the header graphics - - // draw the appropriate title - const titleTop = this.elem.querySelector('.title.dual .top'); - const titleBottom = this.elem.querySelector('.title.dual .bottom'); - if (this.screenIndex === 0) { - titleTop.innerHTML = 'Regional'; - titleBottom.innerHTML = 'Observations'; - } else { - const forecastDate = DateTime.fromISO(data[0][this.screenIndex].time); - - // get the name of the day - const dayName = forecastDate.toLocaleString({ weekday: 'long' }); - titleTop.innerHTML = 'Forecast for'; - // draw the title - titleBottom.innerHTML = data[0][this.screenIndex].daytime - ? dayName - : `${dayName} Night`; - } - - // draw the map - const scale = 640 / (offsetXY.x * 2); - const map = this.elem.querySelector('.map'); - map.style.transform = `scale(${scale}) translate(-${sourceXY.x}px, -${sourceXY.y}px)`; - - const cities = data.map((city) => { - const fill = {}; - const period = city[this.screenIndex]; - - fill.icon = { type: 'img', src: getWeatherRegionalIconFromIconLink(period.icon, !period.daytime) }; - fill.city = period.name; - const { temperature } = period; - fill.temp = temperature; - - const { x, y } = period; - - const elem = this.fillTemplate('location', fill); - elem.style.left = `${x}px`; - elem.style.top = `${y}px`; - - return elem; - }); - - const locationContainer = this.elem.querySelector('.location-container'); - locationContainer.innerHTML = ''; - locationContainer.append(...cities); - - this.finishDraw(); - } -} - -const getAndFormatPoint = async (lat, lon) => { - const point = await getPoint(lat, lon); - return { - x: point.properties.gridX, - y: point.properties.gridY, - wfo: point.properties.gridId, - }; -}; - -// register display -registerDisplay(new RegionalForecast(6, 'regional-forecast')); diff --git a/dist/server/scripts/modules/settings.mjs b/dist/server/scripts/modules/settings.mjs deleted file mode 100644 index d94ceb3..0000000 --- a/dist/server/scripts/modules/settings.mjs +++ /dev/null @@ -1,50 +0,0 @@ -import Setting from './utils/setting.mjs'; - -document.addEventListener('DOMContentLoaded', () => { - init(); -}); - -// default speed -const settings = { speed: { value: 1.0 } }; - -const init = () => { - // create settings - settings.wide = new Setting('wide', 'Widescreen', 'checkbox', false, wideScreenChange, true); - settings.kiosk = new Setting('kiosk', 'Kiosk', 'boolean', false, kioskChange, false); - settings.speed = new Setting('speed', 'Speed', 'select', 1.0, null, true, [ - [0.5, 'Very Fast'], - [0.75, 'Fast'], - [1.0, 'Normal'], - [1.25, 'Slow'], - [1.5, 'Very Slow'], - ]); - - // generate html objects - const settingHtml = Object.values(settings).map((d) => d.generate()); - - // write to page - const settingsSection = document.querySelector('#settings'); - settingsSection.innerHTML = ''; - settingsSection.append(...settingHtml); -}; - -const wideScreenChange = (value) => { - const container = document.querySelector('#divTwc'); - if (value) { - container.classList.add('wide'); - } else { - container.classList.remove('wide'); - } -}; - -const kioskChange = (value) => { - const body = document.querySelector('body'); - if (value) { - body.classList.add('kiosk'); - window.dispatchEvent(new Event('resize')); - } else { - body.classList.remove('kiosk'); - } -}; - -export default settings; diff --git a/dist/server/scripts/modules/share.mjs b/dist/server/scripts/modules/share.mjs deleted file mode 100644 index 485cac1..0000000 --- a/dist/server/scripts/modules/share.mjs +++ /dev/null @@ -1,112 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => init()); - -// shorthand mappings for frequently used values -const specialMappings = { - kiosk: 'settings-kiosk-checkbox', -}; - -const init = () => { - // add action to existing link - const shareLink = document.querySelector('#share-link'); - shareLink.addEventListener('click', createLink); - - // if navigator.clipboard does not exist, change text - if (!navigator?.clipboard) { - shareLink.textContent = 'Get Permalink'; - } -}; - -const createLink = async (e) => { - // cancel default event (click on hyperlink) - e.preventDefault(); - // get all checkboxes on page - const checkboxes = document.querySelectorAll('input[type=checkbox]'); - - // list to receive checkbox statuses - const queryStringElements = {}; - - [...checkboxes].forEach((elem) => { - if (elem?.id) { - queryStringElements[elem.id] = elem?.checked ?? false; - } - }); - - // get all select boxes - const selects = document.querySelectorAll('select'); - [...selects].forEach((elem) => { - if (elem?.id) { - queryStringElements[elem.id] = elem?.value ?? 0; - } - }); - - // add the location string - queryStringElements.latLonQuery = localStorage.getItem('latLonQuery'); - queryStringElements.latLon = localStorage.getItem('latLon'); - - const queryString = (new URLSearchParams(queryStringElements)).toString(); - - const url = new URL(`?${queryString}`, document.location.href); - - // send to proper function based on availability of clipboard - if (navigator?.clipboard) { - copyToClipboard(url); - } else { - writeLinkToPage(url); - } -}; - -const copyToClipboard = async (url) => { - try { - // write to clipboard - await navigator.clipboard.writeText(url.toString()); - // alert user - const confirmSpan = document.querySelector('#share-link-copied'); - confirmSpan.style.display = 'inline'; - - // hide confirm text after 5 seconds - setTimeout(() => { - confirmSpan.style.display = 'none'; - }, 5000); - } catch (error) { - console.error(error); - } -}; - -const writeLinkToPage = (url) => { - // get elements - const shareLinkInstructions = document.querySelector('#share-link-instructions'); - const shareLinkUrl = shareLinkInstructions.querySelector('#share-link-url'); - // populate url and display - shareLinkUrl.value = url; - shareLinkInstructions.style.display = 'inline'; - // highlight for convenience - shareLinkUrl.focus(); - shareLinkUrl.select(); -}; - -const parseQueryString = () => { - // return memoized result - if (parseQueryString.params) return parseQueryString.params; - const urlSearchParams = new URLSearchParams(window.location.search); - - // turn into an array of key-value pairs - const paramsArray = [...urlSearchParams]; - - // add additional expanded keys - paramsArray.forEach((paramPair) => { - const expandedKey = specialMappings[paramPair[0]]; - if (expandedKey) { - paramsArray.push([expandedKey, paramPair[1]]); - } - }); - - // memoize result - parseQueryString.params = Object.fromEntries(paramsArray); - - return parseQueryString.params; -}; - -export { - createLink, - parseQueryString, -}; diff --git a/dist/server/scripts/modules/status.mjs b/dist/server/scripts/modules/status.mjs deleted file mode 100644 index 43b2eb4..0000000 --- a/dist/server/scripts/modules/status.mjs +++ /dev/null @@ -1,35 +0,0 @@ -const STATUS = { - loading: Symbol('loading'), - loaded: Symbol('loaded'), - failed: Symbol('failed'), - noData: Symbol('noData'), - disabled: Symbol('disabled'), - retrying: Symbol('retrying'), -}; - -const calcStatusClass = (statusCode) => { - switch (statusCode) { - case STATUS.loading: - return 'loading'; - case STATUS.loaded: - return 'press-here'; - case STATUS.failed: - return 'failed'; - case STATUS.noData: - return 'no-data'; - case STATUS.disabled: - return 'disabled'; - case STATUS.retrying: - return 'retrying'; - default: - return ''; - } -}; - -const statusClasses = ['loading', 'press-here', 'failed', 'no-data', 'disabled', 'retrying']; - -export default STATUS; -export { - calcStatusClass, - statusClasses, -}; diff --git a/dist/server/scripts/modules/travelforecast.mjs b/dist/server/scripts/modules/travelforecast.mjs deleted file mode 100644 index 8eaabf7..0000000 --- a/dist/server/scripts/modules/travelforecast.mjs +++ /dev/null @@ -1,161 +0,0 @@ -// travel forecast display -import STATUS from './status.mjs'; -import { json } from './utils/fetch.mjs'; -import { getWeatherRegionalIconFromIconLink } from './icons.mjs'; -import { DateTime } from '../vendor/auto/luxon.mjs'; -import WeatherDisplay from './weatherdisplay.mjs'; -import { registerDisplay } from './navigation.mjs'; - -class TravelForecast extends WeatherDisplay { - constructor(navId, elemId, defaultActive) { - // special height and width for scrolling - super(navId, elemId, 'Travel Forecast', defaultActive); - - // set up the timing - this.timing.baseDelay = 20; - // page sizes are 4 cities, calculate the number of pages necessary plus overflow - const pagesFloat = TravelCities.length / 4; - const pages = Math.floor(pagesFloat) - 2; // first page is already displayed, last page doesn't happen - const extra = pages % 1; - const timingStep = 75 * 4; - this.timing.delay = [150 + timingStep]; - // add additional pages - for (let i = 0; i < pages; i += 1) this.timing.delay.push(timingStep); - // add the extra (not exactly 4 pages portion) - if (extra !== 0) this.timing.delay.push(Math.round(this.extra * this.cityHeight)); - // add the final 3 second delay - this.timing.delay.push(150); - } - - async getData() { - // super checks for enabled - if (!super.getData()) return; - const forecastPromises = TravelCities.map(async (city) => { - try { - // get point then forecast - if (!city.point) throw new Error('No pre-loaded point'); - const forecast = await json(`https://api.weather.gov/gridpoints/${city.point.wfo}/${city.point.x},${city.point.y}/forecast`); - // determine today or tomorrow (shift periods by 1 if tomorrow) - const todayShift = forecast.properties.periods[0].isDaytime ? 0 : 1; - // return a pared-down forecast - return { - today: todayShift === 0, - high: forecast.properties.periods[todayShift].temperature, - low: forecast.properties.periods[todayShift + 1].temperature, - name: city.Name, - icon: getWeatherRegionalIconFromIconLink(forecast.properties.periods[todayShift].icon), - }; - } catch (error) { - console.error(`GetTravelWeather for ${city.Name} failed`); - console.error(error.status, error.responseJSON); - return { name: city.Name, error: true }; - } - }); - - // wait for all forecasts - const forecasts = await Promise.all(forecastPromises); - this.data = forecasts; - - // test for some data available in at least one forecast - const hasData = this.data.some((forecast) => forecast.high); - if (!hasData) { - this.setStatus(STATUS.noData); - return; - } - - this.setStatus(STATUS.loaded); - this.drawLongCanvas(); - } - - async drawLongCanvas() { - // get the element and populate - const list = this.elem.querySelector('.travel-lines'); - list.innerHTML = ''; - - // set up variables - const cities = this.data; - - const lines = cities.map((city) => { - if (city.error) return false; - const fillValues = { - city, - }; - - // check for forecast data - if (city.icon) { - fillValues.city = city.name; - // get temperatures and convert if necessary - const { low, high } = city; - - // convert to strings with no decimal - const lowString = Math.round(low).toString(); - const highString = Math.round(high).toString(); - - fillValues.low = lowString; - fillValues.high = highString; - const { icon } = city; - - fillValues.icon = { type: 'img', src: icon }; - } else { - fillValues.error = 'NO TRAVEL DATA AVAILABLE'; - } - return this.fillTemplate('travel-row', fillValues); - }).filter((d) => d); - list.append(...lines); - } - - async drawCanvas() { - // there are technically 2 canvases: the standard canvas and the extra-long canvas that contains the complete - // list of cities. The second canvas is copied into the standard canvas to create the scroll - super.drawCanvas(); - - // set up variables - const cities = this.data; - - this.elem.querySelector('.header .title.dual .bottom').innerHTML = `For ${getTravelCitiesDayName(cities)}`; - - this.finishDraw(); - } - - async showCanvas() { - // special to travel forecast to draw the remainder of the canvas - await this.drawCanvas(); - super.showCanvas(); - } - - // screen index change callback just runs the base count callback - screenIndexChange() { - this.baseCountChange(this.navBaseCount); - } - - // base count change callback - baseCountChange(count) { - // calculate scroll offset and don't go past end - let offsetY = Math.min(this.elem.querySelector('.travel-lines').offsetHeight - 289, (count - 150)); - - // don't let offset go negative - if (offsetY < 0) offsetY = 0; - - // copy the scrolled portion of the canvas - this.elem.querySelector('.main').scrollTo(0, offsetY); - } - - // necessary to get the lastest long canvas when scrolling - getLongCanvas() { - return this.longCanvas; - } -} - -// effectively returns early on the first found date -const getTravelCitiesDayName = (cities) => cities.reduce((dayName, city) => { - if (city && dayName === '') { - // today or tomorrow - const day = DateTime.local().plus({ days: (city.today) ? 0 : 1 }); - // return the day - return day.toLocaleString({ weekday: 'long' }); - } - return dayName; -}, ''); - -// register display, not active by default -registerDisplay(new TravelForecast(5, 'travel', false)); diff --git a/dist/server/scripts/modules/utils/calc.mjs b/dist/server/scripts/modules/utils/calc.mjs deleted file mode 100644 index b4c7469..0000000 --- a/dist/server/scripts/modules/utils/calc.mjs +++ /dev/null @@ -1,17 +0,0 @@ -// wind direction -const directionToNSEW = (Direction) => { - const val = Math.floor((Direction / 22.5) + 0.5); - const arr = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']; - return arr[(val % 16)]; -}; - -const distance = (x1, y1, x2, y2) => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); - -// wrap a number to 0-m -const wrap = (x, m) => ((x % m) + m) % m; - -export { - directionToNSEW, - distance, - wrap, -}; diff --git a/dist/server/scripts/modules/utils/cors.mjs b/dist/server/scripts/modules/utils/cors.mjs deleted file mode 100644 index 038a4c7..0000000 --- a/dist/server/scripts/modules/utils/cors.mjs +++ /dev/null @@ -1,12 +0,0 @@ -// rewrite some urls for local server -const rewriteUrl = (_url) => { - let url = _url; - url = url.replace('https://api.weather.gov/', `${window.location.protocol}//${window.location.host}/`); - url = url.replace('https://www.cpc.ncep.noaa.gov/', `${window.location.protocol}//${window.location.host}/`); - return url; -}; - -export { - // eslint-disable-next-line import/prefer-default-export - rewriteUrl, -}; diff --git a/dist/server/scripts/modules/utils/elem.mjs b/dist/server/scripts/modules/utils/elem.mjs deleted file mode 100644 index e4039fa..0000000 --- a/dist/server/scripts/modules/utils/elem.mjs +++ /dev/null @@ -1,8 +0,0 @@ -const elemForEach = (selector, callback) => { - [...document.querySelectorAll(selector)].forEach(callback); -}; - -export { - // eslint-disable-next-line import/prefer-default-export - elemForEach, -}; diff --git a/dist/server/scripts/modules/utils/fetch.mjs b/dist/server/scripts/modules/utils/fetch.mjs deleted file mode 100644 index b30f6d2..0000000 --- a/dist/server/scripts/modules/utils/fetch.mjs +++ /dev/null @@ -1,99 +0,0 @@ -import { rewriteUrl } from './cors.mjs'; - -const json = (url, params) => fetchAsync(url, 'json', params); -const text = (url, params) => fetchAsync(url, 'text', params); -const blob = (url, params) => fetchAsync(url, 'blob', params); - -const fetchAsync = async (_url, responseType, _params = {}) => { - // combine default and provided parameters - const params = { - method: 'GET', - mode: 'cors', - type: 'GET', - retryCount: 0, - ..._params, - }; - // store original number of retries - params.originalRetries = params.retryCount; - - // build a url, including the rewrite for cors if necessary - let corsUrl = _url; - if (params.cors === true) corsUrl = rewriteUrl(_url); - const url = new URL(corsUrl, `${window.location.origin}/`); - // match the security protocol when not on localhost - // url.protocol = window.location.hostname === 'localhost' ? url.protocol : window.location.protocol; - // add parameters if necessary - if (params.data) { - Object.keys(params.data).forEach((key) => { - // get the value - const value = params.data[key]; - // add to the url - url.searchParams.append(key, value); - }); - } - - // make the request - const response = await doFetch(url, params); - - // check for ok response - if (!response.ok) throw new Error(`Fetch error ${response.status} ${response.statusText} while fetching ${response.url}`); - // return the requested response - switch (responseType) { - case 'json': - return response.json(); - case 'text': - return response.text(); - case 'blob': - return response.blob(); - default: - return response; - } -}; - -// fetch with retry and back-off -const doFetch = (url, params) => new Promise((resolve, reject) => { - fetch(url, params).then((response) => { - if (params.retryCount > 0) { - // 500 status codes should be retried after a short backoff - if (response.status >= 500 && response.status <= 599 && params.retryCount > 0) { - // call the "still waiting" function - if (typeof params.stillWaiting === 'function' && params.retryCount === params.originalRetries) { - params.stillWaiting(); - } - // decrement and retry - const newParams = { - ...params, - retryCount: params.retryCount - 1, - }; - return resolve(delay(retryDelay(params.originalRetries - newParams.retryCount), doFetch, url, newParams)); - } - // not 500 status - return resolve(response); - } - // out of retries - return resolve(response); - }) - .catch((error) => reject(error)); -}); - -const delay = (time, func, ...args) => new Promise((resolve) => { - setTimeout(() => { - resolve(func(...args)); - }, time); -}); - -const retryDelay = (retryNumber) => { - switch (retryNumber) { - case 1: return 1000; - case 2: return 2000; - case 3: return 5000; - case 4: return 10_000; - default: return 30_000; - } -}; - -export { - json, - text, - blob, -}; diff --git a/dist/server/scripts/modules/utils/image.mjs b/dist/server/scripts/modules/utils/image.mjs deleted file mode 100644 index 1a7cabe..0000000 --- a/dist/server/scripts/modules/utils/image.mjs +++ /dev/null @@ -1,34 +0,0 @@ -import { blob } from './fetch.mjs'; -import { rewriteUrl } from './cors.mjs'; - -// ****************************** load images ********************************* -// load an image from a blob or url -const loadImg = (imgData, cors = false) => new Promise((resolve) => { - const img = new Image(); - img.onload = (e) => { - resolve(e.target); - }; - if (imgData instanceof Blob) { - img.src = window.URL.createObjectURL(imgData); - } else { - let url = imgData; - if (cors) url = rewriteUrl(imgData); - img.src = url; - } -}); - -// preload an image -// the goal is to get it in the browser's cache so it is available more quickly when the browser needs it -// a list of cached icons is used to avoid hitting the cache multiple times -const cachedImages = []; -const preloadImg = (src) => { - if (cachedImages.includes(src)) return false; - blob(src); - cachedImages.push(src); - return true; -}; - -export { - loadImg, - preloadImg, -}; diff --git a/dist/server/scripts/modules/utils/localForecastTextGenerator.mjs b/dist/server/scripts/modules/utils/localForecastTextGenerator.mjs deleted file mode 100644 index 99d6144..0000000 --- a/dist/server/scripts/modules/utils/localForecastTextGenerator.mjs +++ /dev/null @@ -1,103 +0,0 @@ -import { directionToNSEW } from './calc.mjs'; - -function generateLocalForecast(dateStamp, hourlyData) { - const MORNING_HOURS = [...Array(12).keys()].map((h) => h + 6); // 6 AM - 6 PM - const NIGHT_HOURS = [...Array(6).keys()].map((h) => h + 18).concat([...Array(6).keys()]); // 6 PM - 6 AM - - const phraseVariations = { - 'CHANCE OF PRECIPITATION': ['PRECIPITATION PROBABILITY', 'RAIN/SNOW CHANCES', 'EXPECTED PRECIPITATION LIKELIHOOD'], - WIND: ['WINDS FROM THE', 'EXPECT WINDS COMING FROM', 'BREEZES BLOWING FROM'], - CLOUDY: ['CLOUD COVER', 'SKIES WILL BE MOSTLY CLOUDY', 'OVERCAST CONDITIONS EXPECTED'], - CLEAR: ['MOSTLY CLEAR SKIES', 'FEW CLOUDS EXPECTED', 'SKIES REMAINING CLEAR'], - 'SNOW SHOWERS': ['FLURRIES LIKELY', 'SNOWFALL EXPECTED', 'LIGHT SNOW POSSIBLE'], - }; - - const forecastTemplates = [ - '{period}... {weatherEvent}. {cloudCover}, WITH A {tempLabel} AROUND {temp}. {windInfo}. {precipChance}', - '{period}: {weatherEvent}. EXPECT {cloudCover}, {tempLabel} NEAR {temp}. {windInfo}. {precipChance}', - '{period}: {weatherEvent}. {cloudCover}, {tempLabel} CLOSE TO {temp}. {windInfo}. {precipChance}', - '{weatherEvent} THIS {period}. {cloudCover}, WITH {tempLabel} AROUND {temp}. {windInfo}. {precipChance}', - '{period} FORECAST: {weatherEvent}. {cloudCover}, {tempLabel} {temp}. {windInfo}. {precipChance}', - '{period} OUTLOOK: {weatherEvent}. {cloudCover}, EXPECT A {tempLabel} AROUND {temp}. {windInfo}. {precipChance}', - '{period} WEATHER: {weatherEvent}. {cloudCover}, {tempLabel} AT {temp}. {windInfo}. {precipChance}', - '{period}: {weatherEvent}. {cloudCover}, {tempLabel} CLOSE TO {temp}. {windInfo}. {precipChance}', - ]; - - function getMostFrequent(arr) { - return arr.sort((a, b) => arr.filter((v) => v === a).length - arr.filter((v) => v === b).length).pop(); - } - - // eslint-disable-next-line no-shadow - function processForecast(hourlyData, period) { - const periodData = hourlyData.filter((entry) => (period === 'MORNING' ? MORNING_HOURS : NIGHT_HOURS).includes(new Date(entry.time).getHours())); - - if (!periodData.length) return null; - - const temps = periodData.map((entry) => entry.temperature_2m); - const temp = period === 'MORNING' ? Math.max(...temps) : Math.min(...temps); - const tempLabel = period === 'MORNING' ? 'HIGH' : 'LOW'; - - const windSpeeds = periodData.map((entry) => entry.wind_speed_10m); - const windDirs = periodData.map((entry) => entry.wind_direction_10m); - const windInfo = `${directionToNSEW(getMostFrequent(windDirs))} WIND ${Math.min(...windSpeeds)} TO ${Math.max(...windSpeeds)} KPH`; - - const precipProbs = periodData.map((entry) => entry.precipitation_probability); - const maxPrecip = Math.max(...precipProbs); - let precipChance = 'PRECIPITATION NOT EXPECTED.'; - - if (maxPrecip >= 30) { - const peakHour = periodData.find((entry) => entry.precipitation_probability === maxPrecip)?.time; - const hour = new Date(peakHour).getHours(); - const precipTime = `AFTER ${hour % 12 || 12} ${hour < 12 ? 'AM' : 'PM'}`; - precipChance = `${phraseVariations['CHANCE OF PRECIPITATION'][Math.floor(Math.random() * 3)]} ${precipTime}. CHANCE IS ${maxPrecip}%.`; - } - - const cloudCover = phraseVariations.CLOUDY[Math.floor(Math.random() * 3)]; - - const weatherEvent = maxPrecip >= 30 ? 'A CHANCE OF SNOW SHOWERS' : 'CLEAR EXPECTED'; - - const forecastText = forecastTemplates[Math.floor(Math.random() * forecastTemplates.length)] - .replace('{period}', period) - .replace('{weatherEvent}', weatherEvent) - .replace('{cloudCover}', cloudCover) - .replace('{tempLabel}', tempLabel) - .replace('{temp}', temp) - .replace('{windInfo}', windInfo) - .replace('{precipChance}', precipChance) - .replace(/\n/g, '') - .replace(/\r/g, ''); - - return { - period, - temperature: { label: tempLabel, value: temp }, - wind: windInfo, - precipitation: precipChance, - skyCondition: cloudCover, - text: forecastText, - }; - } - - // Generate forecast for the provided date - const dayDate = new Date(dateStamp); - const dayStr = dayDate.toLocaleDateString('en-US', { weekday: 'long' }).toUpperCase(); - - const dailyData = hourlyData.filter((entry) => new Date(entry.time).toDateString() === dayDate.toDateString()); - - const morningForecast = processForecast(dailyData, 'MORNING'); - const nightForecast = processForecast(dailyData, 'NIGHT'); - - const forecast = { - date: dayStr, - periods: { - morning: morningForecast, - night: nightForecast, - }, - }; - - return JSON.stringify(forecast, null, 2); -} - -export { - // eslint-disable-next-line import/prefer-default-export - generateLocalForecast, -}; diff --git a/dist/server/scripts/modules/utils/nosleep.mjs b/dist/server/scripts/modules/utils/nosleep.mjs deleted file mode 100644 index 53fe5f9..0000000 --- a/dist/server/scripts/modules/utils/nosleep.mjs +++ /dev/null @@ -1,18 +0,0 @@ -// track state of nosleep locally to avoid a null case error -// when nosleep.disable is called without first calling .enable - -let wakeLock = false; - -const noSleep = (enable = false) => { - // get a nosleep controller - if (!noSleep.controller) noSleep.controller = new NoSleep(); - // don't call anything if the states match - if (wakeLock === enable) return false; - // store the value - wakeLock = enable; - // call the function - if (enable) return noSleep.controller.enable(); - return noSleep.controller.disable(); -}; - -export default noSleep; diff --git a/dist/server/scripts/modules/utils/setting.mjs b/dist/server/scripts/modules/utils/setting.mjs deleted file mode 100644 index 7a8da59..0000000 --- a/dist/server/scripts/modules/utils/setting.mjs +++ /dev/null @@ -1,186 +0,0 @@ -import { parseQueryString } from '../share.mjs'; - -const SETTINGS_KEY = 'Settings'; - -class Setting { - constructor(shortName, name, type, defaultValue, changeAction, sticky, values) { - // store values - this.shortName = shortName; - this.name = name; - this.defaultValue = defaultValue; - this.myValue = defaultValue; - this.type = type ?? 'checkbox'; - this.sticky = sticky; - this.values = values; - // a default blank change function is provided - this.changeAction = changeAction ?? (() => { }); - - // get value from url - const urlValue = parseQueryString()?.[`settings-${shortName}-${type}`]; - let urlState; - if (type === 'checkbox' && urlValue !== undefined) { - urlState = urlValue === 'true'; - } - if (type === 'select' && urlValue !== undefined) { - urlState = parseFloat(urlValue); - } - - // get existing value if present - const storedValue = urlState ?? this.getFromLocalStorage(); - if (sticky && storedValue !== null) { - this.myValue = storedValue; - } - - // call the change function on startup - switch (type) { - case 'select': - this.selectChange({ target: { value: this.myValue } }); - break; - case 'checkbox': - default: - this.checkboxChange({ target: { checked: this.myValue } }); - } - } - - generateSelect() { - // create a radio button set in the selected displays area - const label = document.createElement('label'); - label.for = `settings-${this.shortName}-select`; - label.id = `settings-${this.shortName}-label`; - - const span = document.createElement('span'); - span.innerHTML = `${this.name} `; - label.append(span); - - const select = document.createElement('select'); - select.id = `settings-${this.shortName}-select`; - select.name = `settings-${this.shortName}-select`; - select.addEventListener('change', (e) => this.selectChange(e)); - - this.values.forEach(([value, text]) => { - const option = document.createElement('option'); - option.value = value.toFixed(2); - - option.innerHTML = text; - select.append(option); - }); - label.append(select); - - this.element = label; - - // set the initial value - this.selectHighlight(this.myValue); - - return label; - } - - generateCheckbox() { - // create a checkbox in the selected displays area - const label = document.createElement('label'); - label.for = `settings-${this.shortName}-checkbox`; - label.id = `settings-${this.shortName}-label`; - const checkbox = document.createElement('input'); - checkbox.type = 'checkbox'; - checkbox.value = true; - checkbox.id = `settings-${this.shortName}-checkbox`; - checkbox.name = `settings-${this.shortName}-checkbox`; - checkbox.checked = this.myValue; - checkbox.addEventListener('change', (e) => this.checkboxChange(e)); - const span = document.createElement('span'); - span.innerHTML = this.name; - - label.append(checkbox, span); - - this.element = label; - - return label; - } - - checkboxChange(e) { - // update the state - this.myValue = e.target.checked; - this.storeToLocalStorage(this.myValue); - - // call change action - this.changeAction(this.myValue); - } - - selectChange(e) { - // update the value - this.myValue = parseFloat(e.target.value); - this.storeToLocalStorage(this.myValue); - - // call the change action - this.changeAction(this.myValue); - } - - storeToLocalStorage(value) { - if (!this.sticky) return; - const allSettingsString = localStorage?.getItem(SETTINGS_KEY) ?? '{}'; - const allSettings = JSON.parse(allSettingsString); - allSettings[this.shortName] = value; - localStorage?.setItem(SETTINGS_KEY, JSON.stringify(allSettings)); - } - - getFromLocalStorage() { - const allSettings = localStorage?.getItem(SETTINGS_KEY); - try { - if (allSettings) { - const storedValue = JSON.parse(allSettings)?.[this.shortName]; - if (storedValue !== undefined) { - switch (this.type) { - case 'boolean': - return storedValue; - case 'select': - return storedValue; - default: - return null; - } - } - } - } catch { - return null; - } - return null; - } - - get value() { - return this.myValue; - } - - set value(newValue) { - // update the state - this.myValue = newValue; - switch (this.type) { - case 'select': - this.selectHighlight(newValue); - break; - case 'checkbox': - default: - this.element.checked = newValue; - } - this.storeToLocalStorage(this.myValue); - - // call change action - this.changeAction(this.myValue); - } - - selectHighlight(newValue) { - // set the dropdown to the provided value - this.element.querySelectorAll('option').forEach((elem) => { - elem.selected = newValue.toFixed(2) === elem.value; - }); - } - - generate() { - switch (this.type) { - case 'select': - return this.generateSelect(); - case 'checkbox': - default: - return this.generateCheckbox(); - } - } -} - -export default Setting; diff --git a/dist/server/scripts/modules/utils/string.mjs b/dist/server/scripts/modules/utils/string.mjs deleted file mode 100644 index ca20650..0000000 --- a/dist/server/scripts/modules/utils/string.mjs +++ /dev/null @@ -1,19 +0,0 @@ -const locationCleanup = (input) => { - // regexes to run - const regexes = [ - // "Chicago / West Chicago", removes before slash - /^[ A-Za-z]+ \/ /, - // "Chicago/Waukegan" removes before slash - /^[ A-Za-z]+\//, - // "Chicago, Chicago O'hare" removes before comma - /^[ A-Za-z]+, /, - ]; - - // run all regexes - return regexes.reduce((value, regex) => value.replace(regex, ''), input); -}; - -export { - // eslint-disable-next-line import/prefer-default-export - locationCleanup, -}; diff --git a/dist/server/scripts/modules/utils/units.mjs b/dist/server/scripts/modules/utils/units.mjs deleted file mode 100644 index fea90b4..0000000 --- a/dist/server/scripts/modules/utils/units.mjs +++ /dev/null @@ -1,18 +0,0 @@ -// *********************************** unit conversions *********************** - -const round2 = (value, decimals) => Math.trunc(value * 10 ** decimals) / 10 ** decimals; - -const kphToMph = (Kph) => Math.round(Kph / 1.609_34); -const celsiusToFahrenheit = (Celsius) => Math.round((Celsius * 9) / 5 + 32); -const kilometersToMiles = (Kilometers) => Math.round(Kilometers / 1.609_34); -const metersToFeet = (Meters) => Math.round(Meters / 0.3048); -const pascalToInHg = (Pascal) => round2(Pascal * 0.000_295_3, 2); - -export { - kphToMph, - celsiusToFahrenheit, - kilometersToMiles, - metersToFeet, - pascalToInHg, - round2, -}; diff --git a/dist/server/scripts/modules/utils/weather.md b/dist/server/scripts/modules/utils/weather.md deleted file mode 100644 index d45f1b9..0000000 --- a/dist/server/scripts/modules/utils/weather.md +++ /dev/null @@ -1,4615 +0,0 @@ -## Readme for `weather.mjs` - -### `getGeocoding(name: string)` -Queries open meteo's geocoding api to get locality information. - -#### An example query url, as generated for Amsterdam, NL: -``` -https://geocoding-api.open-meteo.com/v1/search?name=Amsterdam&count=10&language=en&format=json -``` - -#### The response is as follows: - -``` -{ - "results": [ - { - "id": 2759794, - "name": "Amsterdam", - "latitude": 52.37403, - "longitude": 4.88969, - "elevation": 13.0, - "feature_code": "PPLC", - "country_code": "NL", - "admin1_id": 2749879, - "admin2_id": 2759793, - "timezone": "Europe/Amsterdam", - "population": 741636, - "postcodes": [ - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "1060", - "1061", - "1062", - "1063", - "1064", - "1065", - "1066", - "1067", - "1068", - "1069", - "1071", - "1072", - "1073", - "1074", - "1075", - "1076", - "1077", - "1078", - "1079", - "1081", - "1082", - "1083", - "1086", - "1087", - "1091", - "1092", - "1093", - "1094", - "1095", - "1096", - "1097", - "1098", - "1101", - "1102", - "1103", - "1104", - "1105", - "1106", - "1107", - "1108", - "1109" - ], - "country_id": 2750405, - "country": "Netherlands", - "admin1": "North Holland", - "admin2": "Gemeente Amsterdam" - }, - { - "id": 5107152, - "name": "Amsterdam", - "latitude": 42.93869, - "longitude": -74.18819, - "elevation": 110.0, - "feature_code": "PPL", - "country_code": "US", - "admin1_id": 5128638, - "admin2_id": 5127354, - "admin3_id": 5107155, - "timezone": "America/New_York", - "population": 18008, - "postcodes": [ - "12010" - ], - "country_id": 6252001, - "country": "United States", - "admin1": "New York", - "admin2": "Montgomery", - "admin3": "City of Amsterdam" - }, - { - "id": 4755173, - "name": "Daleville", - "latitude": 37.40986, - "longitude": -79.91254, - "elevation": 396.0, - "feature_code": "PPL", - "country_code": "US", - "admin1_id": 6254928, - "admin2_id": 4748452, - "timezone": "America/New_York", - "population": 2557, - "postcodes": [ - "24083" - ], - "country_id": 6252001, - "country": "United States", - "admin1": "Virginia", - "admin2": "Botetourt" - }, - { - "id": 5145733, - "name": "Amsterdam", - "latitude": 40.47368, - "longitude": -80.92287, - "elevation": 283.0, - "feature_code": "PPL", - "country_code": "US", - "admin1_id": 5165418, - "admin2_id": 5159079, - "admin3_id": 5172836, - "timezone": "America/New_York", - "population": 489, - "postcodes": [ - "43903" - ], - "country_id": 6252001, - "country": "United States", - "admin1": "Ohio", - "admin2": "Jefferson", - "admin3": "Springfield Township" - }, - { - "id": 4374800, - "name": "Amsterdam", - "latitude": 38.34974, - "longitude": -94.58912, - "elevation": 270.0, - "feature_code": "PPL", - "country_code": "US", - "admin1_id": 4398678, - "admin2_id": 4375954, - "admin3_id": 4414192, - "timezone": "America/Chicago", - "population": 235, - "postcodes": [ - "64723" - ], - "country_id": 6252001, - "country": "United States", - "admin1": "Missouri", - "admin2": "Bates", - "admin3": "West Point Township" - }, - { - "id": 4505240, - "name": "Amsterdam", - "latitude": 39.95757, - "longitude": -82.37821, - "elevation": 359.0, - "feature_code": "PPL", - "country_code": "US", - "admin1_id": 5165418, - "admin2_id": 5160740, - "admin3_id": 4506932, - "timezone": "America/New_York", - "population": 549, - "country_id": 6252001, - "country": "United States", - "admin1": "Ohio", - "admin2": "Licking", - "admin3": "Bowling Green Township" - }, - { - "id": 5637141, - "name": "Amsterdam", - "latitude": 45.75798, - "longitude": -111.31996, - "elevation": 1355.0, - "feature_code": "PPL", - "country_code": "US", - "admin1_id": 5667009, - "admin2_id": 5653656, - "timezone": "America/Denver", - "population": 180, - "country_id": 6252001, - "country": "United States", - "admin1": "Montana", - "admin2": "Gallatin" - }, - { - "id": 4262053, - "name": "New Amsterdam", - "latitude": 38.10229, - "longitude": -86.27497, - "elevation": 137.0, - "feature_code": "PPL", - "country_code": "US", - "admin1_id": 4921868, - "admin2_id": 4258587, - "admin3_id": 4266617, - "timezone": "America/Kentucky/Louisville", - "population": 27, - "country_id": 6252001, - "country": "United States", - "admin1": "Indiana", - "admin2": "Harrison", - "admin3": "Washington Township" - }, - { - "id": 1022856, - "name": "Amsterdam", - "latitude": -31.62809, - "longitude": 25.62113, - "elevation": 1162.0, - "feature_code": "PPL", - "country_code": "ZA", - "admin1_id": 1085593, - "admin2_id": 8347343, - "admin3_id": 8347526, - "timezone": "Africa/Johannesburg", - "country_id": 953987, - "country": "South Africa", - "admin1": "Eastern Cape", - "admin2": "Chris Hani District Municipality", - "admin3": "Tsolwana" - }, - { - "id": 1022857, - "name": "Amsterdam", - "latitude": -26.62784, - "longitude": 30.66632, - "elevation": 1236.0, - "feature_code": "PPL", - "country_code": "ZA", - "admin1_id": 1085595, - "admin2_id": 8347371, - "admin3_id": 8347585, - "timezone": "Africa/Johannesburg", - "country_id": 953987, - "country": "South Africa", - "admin1": "Mpumalanga", - "admin2": "Eastvaal District Municipality", - "admin3": "Mkhondo" - } - ], - "generationtime_ms": 0.688076 -} -``` - -### `aggregateWeatherForecastData(getPointData)` -Aggregates the hourly 7 day forecast data received from `getPoints()` and creates an object of mapped entities indexed by date. - -For example: - -``` -{ - "2025-02-20": { - "temperature_2m": 7.529166666666665, - "relative_humidity_2m": 87.54166666666667, - "dew_point_2m": 5.558333333333333, - "apparent_temperature": 5.158333333333334, - "precipitation_probability": 23.083333333333332, - "precipitation": 0.07916666666666668, - "rain": 0.07916666666666668, - "showers": 0, - "snowfall": 0, - "snow_depth": 0, - "weather_code": 12.916666666666666, - "pressure_msl": 1021.8333333333331, - "surface_pressure": 1016.7583333333333, - "cloud_cover": 90.58333333333333, - "visibility": 15504.166666666666, - "evapotranspiration": 0.0004166666666666667, - "et0_fao_evapotranspiration": 0.03125, - "vapour_pressure_deficit": 0.13166666666666668, - "uv_index": 0.28750000000000003, - "uv_index_clear_sky": 0.7270833333333333, - "is_day": 0.4166666666666667, - "sunshine_duration": 150, - "wet_bulb_temperature_2m": 6.2375 - }, - "2025-02-21": { - "temperature_2m": 6.9958333333333345, - "relative_humidity_2m": 92.33333333333333, - "dew_point_2m": 5.816666666666666, - "apparent_temperature": 4.395833333333333, - "precipitation_probability": 56.791666666666664, - "precipitation": 0.8416666666666668, - "rain": 0.8416666666666668, - "showers": 0, - "snowfall": 0, - "snow_depth": 0, - "weather_code": 40.833333333333336, - "pressure_msl": 1022.1500000000001, - "surface_pressure": 1017.0625, - "cloud_cover": 100, - "visibility": 9695.833333333334, - "evapotranspiration": 0, - "et0_fao_evapotranspiration": 0.016666666666666666, - "vapour_pressure_deficit": 0.0791666666666667, - "uv_index": 0.20833333333333337, - "uv_index_clear_sky": 0.74375, - "is_day": 0.4166666666666667, - "sunshine_duration": 31.36, - "wet_bulb_temperature_2m": 6.175000000000001 - }, - "2025-02-22": { - "temperature_2m": 7.374999999999999, - "relative_humidity_2m": 93.5, - "dew_point_2m": 6.400000000000002, - "apparent_temperature": 4.954166666666667, - "precipitation_probability": 93.125, - "precipitation": 1.054166666666667, - "rain": 1.0333333333333334, - "showers": 0.020833333333333332, - "snowfall": 0, - "snow_depth": 0, - "weather_code": 46.083333333333336, - "pressure_msl": 1014.9249999999998, - "surface_pressure": 1009.875, - "cloud_cover": 100, - "visibility": 15858.333333333334, - "evapotranspiration": 0, - "et0_fao_evapotranspiration": 0.01416666666666667, - "vapour_pressure_deficit": 0.06708333333333334, - "uv_index": 0.16666666666666666, - "uv_index_clear_sky": 0.7520833333333333, - "is_day": 0.4166666666666667, - "sunshine_duration": 102.48, - "wet_bulb_temperature_2m": 6.670833333333333 - }, - "2025-02-23": { - "temperature_2m": 7.350000000000001, - "relative_humidity_2m": 95.95833333333333, - "dew_point_2m": 6.7375, - "apparent_temperature": 5.2, - "precipitation_probability": 87.20833333333333, - "precipitation": 1.2208333333333334, - "rain": 1.2208333333333334, - "showers": 0, - "snowfall": 0, - "snow_depth": 0, - "weather_code": 41.416666666666664, - "pressure_msl": 1008.0916666666666, - "surface_pressure": 1003.0916666666666, - "cloud_cover": 100, - "visibility": 15209.166666666666, - "evapotranspiration": 0, - "et0_fao_evapotranspiration": 0.009999999999999998, - "vapour_pressure_deficit": 0.04041666666666668, - "uv_index": 0.09583333333333333, - "uv_index_clear_sky": 0.775, - "is_day": 0.4166666666666667, - "sunshine_duration": 40.28541666666667, - "wet_bulb_temperature_2m": 6.854166666666667 - }, - "2025-02-24": { - "temperature_2m": 7.8125, - "relative_humidity_2m": 87, - "dew_point_2m": 5.641666666666666, - "apparent_temperature": 5.4875, - "precipitation_probability": 78.875, - "precipitation": 0.21249999999999994, - "rain": 0.11249999999999999, - "showers": 0.10000000000000002, - "snowfall": 0, - "snow_depth": 0, - "weather_code": 26.291666666666668, - "pressure_msl": 1013.2833333333333, - "surface_pressure": 1008.2416666666664, - "cloud_cover": 93.70833333333333, - "visibility": 16741.666666666668, - "evapotranspiration": 0, - "et0_fao_evapotranspiration": 0.04041666666666667, - "vapour_pressure_deficit": 0.15041666666666667, - "uv_index": 0.575, - "uv_index_clear_sky": 0.8104166666666667, - "is_day": 0.4166666666666667, - "sunshine_duration": 1056.6125, - "wet_bulb_temperature_2m": 6.454166666666666 - }, - "2025-02-25": { - "temperature_2m": 6.7250000000000005, - "relative_humidity_2m": 90.41666666666667, - "dew_point_2m": 5.229166666666666, - "apparent_temperature": 3.808333333333334, - "precipitation_probability": 78.95833333333333, - "precipitation": 0.44583333333333314, - "rain": 0.4333333333333333, - "showers": 0.012500000000000002, - "snowfall": 0, - "snow_depth": 0, - "weather_code": 44.416666666666664, - "pressure_msl": 1010.7249999999999, - "surface_pressure": 1005.6833333333334, - "cloud_cover": 100, - "visibility": 12698.333333333334, - "evapotranspiration": 0, - "et0_fao_evapotranspiration": 0.01541666666666667, - "vapour_pressure_deficit": 0.09958333333333336, - "uv_index": 0.11874999999999998, - "uv_index_clear_sky": 0.6749999999999999, - "is_day": 0.4166666666666667, - "sunshine_duration": 127.35708333333332, - "wet_bulb_temperature_2m": 5.733333333333333 - }, - "2025-02-26": { - "temperature_2m": 7.079166666666667, - "relative_humidity_2m": 84.625, - "dew_point_2m": 4.587500000000001, - "apparent_temperature": 4.179166666666666, - "precipitation_probability": 27.583333333333332, - "precipitation": 0.0375, - "rain": 0.0375, - "showers": 0, - "snowfall": 0, - "snow_depth": 0, - "weather_code": 10.791666666666666, - "pressure_msl": 1028.0708333333332, - "surface_pressure": 1022.9416666666667, - "cloud_cover": 89.41666666666667, - "visibility": 20796.666666666668, - "evapotranspiration": 0, - "et0_fao_evapotranspiration": 0.047499999999999994, - "vapour_pressure_deficit": 0.16125, - "uv_index": 0.5854166666666666, - "uv_index_clear_sky": 0.8208333333333334, - "is_day": 0.4583333333333333, - "sunshine_duration": 1120.8379166666666, - "wet_bulb_temperature_2m": 5.529166666666668 - } -} -``` - -### `getPoint(lat: number, lon: number)` -Queries open meteo to get the _complete_ aggregated forecast information for a location. By default, this request gets an hourly forecast over 7 days. - -See reference for additional query parameters. -- Reference: https://open-meteo.com/en/docs - -#### An example query url, as generated for Amsterdam, NL: - -``` -https://api.open-meteo.com/v1/forecast?latitude=52.3615&longitude=4.8908&hourly=temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation_probability,precipitation,rain,showers,snowfall,snow_depth,weather_code,pressure_msl,surface_pressure,cloud_cover,visibility,evapotranspiration,et0_fao_evapotranspiration,vapour_pressure_deficit,uv_index,uv_index_clear_sky,is_day,sunshine_duration,wet_bulb_temperature_2m&models=best_match -``` - -#### The response is as follows: - -``` -{ - "latitude": 52.366, - "longitude": 4.901, - "generationtime_ms": 0.5203485488891602, - "utc_offset_seconds": 0, - "timezone": "GMT", - "timezone_abbreviation": "GMT", - "elevation": 6.0, - "hourly_units": { - "time": "iso8601", - "temperature_2m": "°C", - "relative_humidity_2m": "%", - "dew_point_2m": "°C", - "apparent_temperature": "°C", - "precipitation_probability": "%", - "precipitation": "mm", - "rain": "mm", - "showers": "mm", - "snowfall": "cm", - "snow_depth": "m", - "weather_code": "wmo code", - "pressure_msl": "hPa", - "surface_pressure": "hPa", - "cloud_cover": "%", - "visibility": "m", - "evapotranspiration": "mm", - "et0_fao_evapotranspiration": "mm", - "vapour_pressure_deficit": "kPa", - "uv_index": "", - "uv_index_clear_sky": "", - "is_day": "", - "sunshine_duration": "s", - "wet_bulb_temperature_2m": "°C" - }, - "hourly": { - "time": [ - "2025-02-20T00:00", - "2025-02-20T01:00", - "2025-02-20T02:00", - "2025-02-20T03:00", - "2025-02-20T04:00", - "2025-02-20T05:00", - "2025-02-20T06:00", - "2025-02-20T07:00", - "2025-02-20T08:00", - "2025-02-20T09:00", - "2025-02-20T10:00", - "2025-02-20T11:00", - "2025-02-20T12:00", - "2025-02-20T13:00", - "2025-02-20T14:00", - "2025-02-20T15:00", - "2025-02-20T16:00", - "2025-02-20T17:00", - "2025-02-20T18:00", - "2025-02-20T19:00", - "2025-02-20T20:00", - "2025-02-20T21:00", - "2025-02-20T22:00", - "2025-02-20T23:00", - "2025-02-21T00:00", - "2025-02-21T01:00", - "2025-02-21T02:00", - "2025-02-21T03:00", - "2025-02-21T04:00", - "2025-02-21T05:00", - "2025-02-21T06:00", - "2025-02-21T07:00", - "2025-02-21T08:00", - "2025-02-21T09:00", - "2025-02-21T10:00", - "2025-02-21T11:00", - "2025-02-21T12:00", - "2025-02-21T13:00", - "2025-02-21T14:00", - "2025-02-21T15:00", - "2025-02-21T16:00", - "2025-02-21T17:00", - "2025-02-21T18:00", - "2025-02-21T19:00", - "2025-02-21T20:00", - "2025-02-21T21:00", - "2025-02-21T22:00", - "2025-02-21T23:00", - "2025-02-22T00:00", - "2025-02-22T01:00", - "2025-02-22T02:00", - "2025-02-22T03:00", - "2025-02-22T04:00", - "2025-02-22T05:00", - "2025-02-22T06:00", - "2025-02-22T07:00", - "2025-02-22T08:00", - "2025-02-22T09:00", - "2025-02-22T10:00", - "2025-02-22T11:00", - "2025-02-22T12:00", - "2025-02-22T13:00", - "2025-02-22T14:00", - "2025-02-22T15:00", - "2025-02-22T16:00", - "2025-02-22T17:00", - "2025-02-22T18:00", - "2025-02-22T19:00", - "2025-02-22T20:00", - "2025-02-22T21:00", - "2025-02-22T22:00", - "2025-02-22T23:00", - "2025-02-23T00:00", - "2025-02-23T01:00", - "2025-02-23T02:00", - "2025-02-23T03:00", - "2025-02-23T04:00", - "2025-02-23T05:00", - "2025-02-23T06:00", - "2025-02-23T07:00", - "2025-02-23T08:00", - "2025-02-23T09:00", - "2025-02-23T10:00", - "2025-02-23T11:00", - "2025-02-23T12:00", - "2025-02-23T13:00", - "2025-02-23T14:00", - "2025-02-23T15:00", - "2025-02-23T16:00", - "2025-02-23T17:00", - "2025-02-23T18:00", - "2025-02-23T19:00", - "2025-02-23T20:00", - "2025-02-23T21:00", - "2025-02-23T22:00", - "2025-02-23T23:00", - "2025-02-24T00:00", - "2025-02-24T01:00", - "2025-02-24T02:00", - "2025-02-24T03:00", - "2025-02-24T04:00", - "2025-02-24T05:00", - "2025-02-24T06:00", - "2025-02-24T07:00", - "2025-02-24T08:00", - "2025-02-24T09:00", - "2025-02-24T10:00", - "2025-02-24T11:00", - "2025-02-24T12:00", - "2025-02-24T13:00", - "2025-02-24T14:00", - "2025-02-24T15:00", - "2025-02-24T16:00", - "2025-02-24T17:00", - "2025-02-24T18:00", - "2025-02-24T19:00", - "2025-02-24T20:00", - "2025-02-24T21:00", - "2025-02-24T22:00", - "2025-02-24T23:00", - "2025-02-25T00:00", - "2025-02-25T01:00", - "2025-02-25T02:00", - "2025-02-25T03:00", - "2025-02-25T04:00", - "2025-02-25T05:00", - "2025-02-25T06:00", - "2025-02-25T07:00", - "2025-02-25T08:00", - "2025-02-25T09:00", - "2025-02-25T10:00", - "2025-02-25T11:00", - "2025-02-25T12:00", - "2025-02-25T13:00", - "2025-02-25T14:00", - "2025-02-25T15:00", - "2025-02-25T16:00", - "2025-02-25T17:00", - "2025-02-25T18:00", - "2025-02-25T19:00", - "2025-02-25T20:00", - "2025-02-25T21:00", - "2025-02-25T22:00", - "2025-02-25T23:00", - "2025-02-26T00:00", - "2025-02-26T01:00", - "2025-02-26T02:00", - "2025-02-26T03:00", - "2025-02-26T04:00", - "2025-02-26T05:00", - "2025-02-26T06:00", - "2025-02-26T07:00", - "2025-02-26T08:00", - "2025-02-26T09:00", - "2025-02-26T10:00", - "2025-02-26T11:00", - "2025-02-26T12:00", - "2025-02-26T13:00", - "2025-02-26T14:00", - "2025-02-26T15:00", - "2025-02-26T16:00", - "2025-02-26T17:00", - "2025-02-26T18:00", - "2025-02-26T19:00", - "2025-02-26T20:00", - "2025-02-26T21:00", - "2025-02-26T22:00", - "2025-02-26T23:00" - ], - "temperature_2m": [ - 1.9, - 1.4, - 2.8, - 2.2, - 1.6, - 3.2, - 3.7, - 3.2, - 4.0, - 4.6, - 5.4, - 6.0, - 7.3, - 8.1, - 8.3, - 8.9, - 9.2, - 9.2, - 9.1, - 9.0, - 9.1, - 9.2, - 9.6, - 9.7, - 9.7, - 9.7, - 9.6, - 9.6, - 9.6, - 9.9, - 10.3, - 10.4, - 10.5, - 11.1, - 12.2, - 13.8, - 14.8, - 15.8, - 15.4, - 14.9, - 14.8, - 14.6, - 14.4, - 14.1, - 13.8, - 13.3, - 12.8, - 12.4, - 12.0, - 11.6, - 11.3, - 11.2, - 10.9, - 10.6, - 10.6, - 10.4, - 10.1, - 10.3, - 10.6, - 10.6, - 10.9, - 11.0, - 10.9, - 11.0, - 10.9, - 9.8, - 9.5, - 9.1, - 9.1, - 9.1, - 7.8, - 7.6, - 7.2, - 6.8, - 6.3, - 5.9, - 5.7, - 5.4, - 5.4, - 5.7, - 6.2, - 6.8, - 7.9, - 9.4, - 10.5, - 11.4, - 12.1, - 12.4, - 12.1, - 11.5, - 11.0, - 10.9, - 11.1, - 11.1, - 10.6, - 10.1, - 9.6, - 9.2, - 8.9, - 8.7, - 8.6, - 8.4, - 8.5, - 8.8, - 9.1, - 9.6, - 10.1, - 10.7, - 11.1, - 11.3, - 11.4, - 11.1, - 10.4, - 9.4, - 8.5, - 8.0, - 7.7, - 7.3, - 7.1, - 6.8, - 6.8, - 7.1, - 7.4, - 7.7, - 7.7, - 7.5, - 7.3, - 7.4, - 7.5, - 7.7, - 7.9, - 8.2, - 8.3, - 8.2, - 7.9, - 7.4, - 6.7, - 5.7, - 4.9, - 4.8, - 4.8, - 4.8, - 4.8, - 4.7, - 4.4, - 4.2, - 3.8, - 3.4, - 3.2, - 3.0, - 3.1, - 3.8, - 4.9, - 5.9, - 6.9, - 7.9, - 8.4, - 8.4, - 7.8, - 7.2, - 6.6, - 5.8, - 5.1, - 4.5, - 4.0, - 3.5, - 3.0, - 2.5 - ], - "relative_humidity_2m": [ - 69, - 76, - 70, - 72, - 77, - 80, - 89, - 96, - 98, - 99, - 97, - 96, - 97, - 96, - 96, - 96, - 96, - 95, - 95, - 95, - 94, - 94, - 93, - 94, - 95, - 97, - 96, - 96, - 96, - 97, - 95, - 94, - 94, - 93, - 90, - 86, - 80, - 77, - 76, - 76, - 72, - 71, - 73, - 74, - 75, - 76, - 80, - 83, - 84, - 84, - 85, - 85, - 88, - 90, - 90, - 89, - 89, - 89, - 89, - 89, - 88, - 88, - 88, - 88, - 89, - 88, - 84, - 93, - 95, - 94, - 98, - 97, - 97, - 98, - 98, - 99, - 99, - 99, - 99, - 99, - 100, - 98, - 93, - 86, - 80, - 76, - 74, - 72, - 71, - 70, - 69, - 68, - 66, - 67, - 71, - 78, - 83, - 86, - 89, - 91, - 92, - 93, - 93, - 93, - 93, - 93, - 92, - 90, - 88, - 85, - 81, - 79, - 82, - 86, - 90, - 91, - 92, - 92, - 93, - 94, - 94, - 94, - 93, - 93, - 93, - 94, - 94, - 93, - 92, - 90, - 86, - 81, - 77, - 75, - 75, - 76, - 79, - 84, - 87, - 88, - 88, - 88, - 89, - 89, - 90, - 91, - 93, - 94, - 95, - 95, - 94, - 90, - 84, - 79, - 74, - 69, - 67, - 68, - 72, - 76, - 80, - 85, - 88, - 90, - 91, - 91, - 91, - 91 - ], - "dew_point_2m": [ - -3.2, - -2.4, - -2.1, - -2.3, - -1.9, - 0.1, - 2.1, - 2.6, - 3.7, - 4.5, - 5.0, - 5.4, - 6.9, - 7.5, - 7.7, - 8.3, - 8.6, - 8.5, - 8.3, - 8.2, - 8.2, - 8.3, - 8.5, - 8.8, - 8.9, - 9.2, - 8.9, - 9.0, - 9.0, - 9.4, - 9.5, - 9.5, - 9.6, - 10.1, - 10.7, - 11.5, - 11.3, - 11.7, - 11.2, - 10.7, - 9.8, - 9.4, - 9.6, - 9.5, - 9.4, - 9.2, - 9.4, - 9.5, - 9.4, - 9.0, - 8.9, - 8.8, - 8.9, - 9.0, - 9.0, - 8.6, - 8.4, - 8.6, - 8.8, - 8.9, - 9.0, - 9.1, - 8.9, - 9.1, - 9.2, - 7.9, - 6.9, - 8.0, - 8.4, - 8.2, - 7.5, - 7.1, - 6.8, - 6.6, - 6.1, - 5.8, - 5.5, - 5.3, - 5.3, - 5.6, - 6.2, - 6.6, - 6.9, - 7.1, - 7.2, - 7.3, - 7.7, - 7.5, - 7.0, - 6.2, - 5.5, - 5.3, - 5.0, - 5.2, - 5.6, - 6.4, - 6.9, - 7.0, - 7.2, - 7.3, - 7.3, - 7.4, - 7.4, - 7.7, - 8.1, - 8.5, - 8.9, - 9.1, - 9.2, - 8.9, - 8.2, - 7.6, - 7.5, - 7.1, - 7.0, - 6.6, - 6.4, - 6.1, - 6.0, - 6.0, - 5.9, - 6.1, - 6.4, - 6.6, - 6.6, - 6.6, - 6.4, - 6.3, - 6.3, - 6.1, - 5.7, - 5.1, - 4.5, - 4.0, - 3.7, - 3.5, - 3.3, - 3.2, - 3.0, - 2.9, - 3.0, - 3.0, - 3.1, - 3.0, - 3.0, - 2.8, - 2.7, - 2.5, - 2.4, - 2.2, - 2.2, - 2.3, - 2.4, - 2.5, - 2.6, - 2.6, - 2.7, - 2.8, - 3.1, - 3.3, - 3.4, - 3.5, - 3.2, - 3.0, - 2.7, - 2.2, - 1.7, - 1.2 - ], - "apparent_temperature": [ - -2.9, - -3.3, - -1.8, - -2.4, - -2.8, - -1.1, - -0.7, - -0.5, - 0.6, - 1.8, - 2.0, - 2.8, - 4.3, - 4.9, - 5.1, - 5.9, - 6.2, - 6.0, - 5.6, - 6.0, - 6.1, - 6.2, - 6.9, - 7.2, - 7.2, - 7.1, - 6.8, - 6.9, - 7.2, - 7.3, - 7.8, - 8.0, - 8.1, - 8.5, - 9.7, - 11.4, - 12.0, - 13.0, - 12.6, - 11.9, - 11.7, - 11.2, - 11.0, - 10.6, - 10.1, - 10.1, - 10.0, - 9.9, - 9.5, - 9.0, - 8.7, - 8.8, - 8.5, - 8.0, - 7.9, - 7.5, - 7.1, - 7.4, - 7.8, - 7.8, - 8.2, - 8.1, - 7.9, - 8.1, - 7.8, - 5.4, - 5.9, - 6.0, - 6.2, - 7.1, - 5.4, - 5.1, - 4.7, - 4.2, - 3.5, - 3.0, - 2.7, - 2.5, - 2.5, - 2.7, - 3.0, - 3.6, - 4.4, - 5.6, - 6.6, - 7.6, - 8.6, - 8.9, - 8.5, - 7.7, - 6.9, - 6.6, - 6.4, - 6.1, - 5.8, - 5.4, - 5.0, - 4.7, - 4.5, - 4.3, - 4.2, - 4.1, - 4.1, - 4.5, - 5.0, - 5.6, - 6.3, - 6.8, - 7.1, - 7.2, - 7.0, - 6.8, - 6.5, - 6.0, - 5.5, - 5.1, - 4.6, - 4.3, - 4.0, - 3.8, - 3.8, - 4.1, - 4.6, - 5.0, - 4.9, - 4.7, - 4.6, - 4.7, - 4.8, - 4.6, - 4.7, - 4.8, - 4.7, - 4.2, - 3.6, - 3.2, - 2.8, - 2.4, - 2.0, - 1.7, - 1.7, - 1.5, - 1.5, - 1.5, - 1.4, - 1.1, - 0.7, - 0.3, - 0.0, - -0.3, - -0.2, - 0.2, - 1.0, - 1.7, - 2.4, - 3.1, - 3.5, - 3.6, - 3.2, - 2.9, - 2.5, - 2.0, - 1.5, - 1.1, - 0.7, - 0.3, - -0.2, - -0.6 - ], - "precipitation_probability": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7, - 17, - 22, - 18, - 10, - 6, - 11, - 21, - 27, - 26, - 22, - 18, - 15, - 11, - 8, - 6, - 4, - 2, - 1, - 0, - 0, - 0, - 0, - 0, - 1, - 3, - 4, - 4, - 4, - 4, - 3, - 1, - 0, - 0, - 1, - 2, - 5, - 8, - 10, - 8, - 5, - 4, - 8, - 15, - 25, - 39, - 55, - 69, - 80, - 89, - 94, - 95, - 92, - 90, - 89, - 89, - 88, - 87, - 86, - 82, - 73, - 61, - 49, - 37, - 24, - 14, - 9, - 6, - 4, - 2, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5, - 13, - 22, - 33, - 45, - 57, - 68, - 78, - 86, - 90, - 91, - 90, - 86, - 79, - 73, - 67, - 62, - 59, - 60, - 63, - 65, - 68, - 70, - 67, - 55, - 37, - 24, - 20, - 20, - 20, - 19, - 18, - 18, - 20, - 22, - 24, - 25, - 25, - 25, - 25, - 26, - 27, - 30, - 35, - 37, - 36, - 33, - 29, - 24, - 19, - 14, - 11, - 10, - 8, - 6, - 5, - 4, - 3, - 3, - 3, - 3, - 3, - 4, - 5, - 6, - 8, - 10, - 12, - 14, - 17, - 20, - 23, - 26, - 29, - 31, - 32, - 33, - 33, - 33, - 32 - ], - "precipitation": [ - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 1.10, - 0.00, - 0.00, - 0.00, - 0.00, - 0.10, - 0.00, - 0.00, - 0.10, - 0.20, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.20, - 0.30, - 0.30, - 0.10, - 0.10, - 0.10, - 0.10, - 0.10, - 0.10, - 0.20, - 0.10, - 0.00, - 0.30, - 0.70, - 0.20, - 0.30, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 0.30, - 0.30, - 0.40, - 0.40, - 0.40, - 0.80, - 0.80, - 0.80, - 0.60, - 0.60, - 0.60, - 0.20, - 0.20, - 0.20, - 0.10, - 0.10, - 0.10, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.50, - 0.50, - 0.50, - 0.10, - 0.10, - 0.10, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 0.30, - 0.30, - 0.30, - 0.30, - 0.30, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00 - ], - "rain": [ - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 1.10, - 0.00, - 0.00, - 0.00, - 0.00, - 0.10, - 0.00, - 0.00, - 0.10, - 0.20, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.20, - 0.30, - 0.30, - 0.10, - 0.10, - 0.10, - 0.10, - 0.10, - 0.10, - 0.20, - 0.10, - 0.00, - 0.30, - 0.70, - 0.20, - 0.30, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 0.30, - 0.30, - 0.40, - 0.40, - 0.40, - 0.80, - 0.80, - 0.80, - 0.60, - 0.60, - 0.60, - 0.20, - 0.20, - 0.20, - 0.10, - 0.10, - 0.10, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.50, - 0.50, - 0.50, - 0.10, - 0.10, - 0.10, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 0.30, - 0.30, - 0.30, - 0.30, - 0.30, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00 - ], - "showers": [ - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00 - ], - "snowfall": [ - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00 - ], - "snow_depth": [ - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00 - ], - "weather_code": [ - 3, - 1, - 3, - 3, - 3, - 3, - 3, - 3, - 51, - 55, - 3, - 3, - 3, - 3, - 51, - 3, - 3, - 51, - 51, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 51, - 51, - 51, - 51, - 51, - 51, - 51, - 51, - 51, - 51, - 51, - 3, - 51, - 53, - 51, - 51, - 3, - 3, - 3, - 2, - 2, - 2, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 1, - 1, - 1, - 2, - 3, - 3, - 3, - 3, - 51, - 51, - 51, - 51, - 51, - 51, - 53, - 53, - 53, - 53, - 53, - 53, - 51, - 51, - 51, - 51, - 51, - 51, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 2, - 3, - 3, - 53, - 53, - 53, - 51, - 51, - 51, - 2, - 1, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 51, - 51, - 51, - 51, - 51, - 51, - 0, - 0, - 0, - 0, - 0 - ], - "pressure_msl": [ - 1020.0, - 1020.2, - 1019.5, - 1019.2, - 1018.9, - 1018.7, - 1018.4, - 1019.1, - 1019.1, - 1018.7, - 1019.0, - 1018.8, - 1018.4, - 1018.2, - 1018.3, - 1018.5, - 1018.5, - 1018.3, - 1017.9, - 1018.6, - 1019.2, - 1019.3, - 1020.1, - 1020.4, - 1020.6, - 1020.3, - 1020.0, - 1019.7, - 1019.1, - 1018.8, - 1018.7, - 1018.9, - 1018.9, - 1018.6, - 1018.2, - 1017.5, - 1016.6, - 1015.8, - 1015.2, - 1014.7, - 1014.3, - 1013.8, - 1013.9, - 1013.9, - 1013.7, - 1013.7, - 1013.6, - 1013.3, - 1013.0, - 1012.6, - 1012.4, - 1012.0, - 1011.9, - 1012.0, - 1012.2, - 1012.5, - 1012.8, - 1013.0, - 1013.1, - 1013.3, - 1013.4, - 1013.3, - 1013.4, - 1013.6, - 1014.0, - 1015.1, - 1016.9, - 1018.4, - 1019.4, - 1020.5, - 1021.1, - 1022.0, - 1022.8, - 1023.3, - 1023.6, - 1024.0, - 1024.5, - 1025.0, - 1025.5, - 1025.9, - 1026.3, - 1026.5, - 1026.5, - 1026.4, - 1026.1, - 1025.4, - 1024.4, - 1023.6, - 1023.2, - 1023.0, - 1022.7, - 1022.3, - 1021.8, - 1021.2, - 1020.5, - 1019.8, - 1019.0, - 1018.1, - 1017.1, - 1016.3, - 1015.7, - 1015.2, - 1014.8, - 1014.7, - 1014.7, - 1014.7, - 1014.7, - 1014.7, - 1014.6, - 1014.4, - 1014.2, - 1014.1, - 1014.4, - 1014.8, - 1015.1, - 1015.2, - 1015.2, - 1015.1, - 1015.0, - 1014.7, - 1014.4, - 1013.8, - 1013.1, - 1012.5, - 1012.0, - 1011.6, - 1011.4, - 1011.6, - 1011.9, - 1012.3, - 1012.6, - 1012.8, - 1013.1, - 1013.4, - 1013.8, - 1014.3, - 1014.9, - 1015.5, - 1016.1, - 1016.6, - 1017.0, - 1017.4, - 1017.7, - 1017.9, - 1018.1, - 1018.3, - 1018.4, - 1018.5, - 1018.6, - 1018.6, - 1018.7, - 1018.8, - 1018.9, - 1019.0, - 1019.1, - 1019.2, - 1019.3, - 1019.4, - 1019.4, - 1019.5, - 1019.6, - 1019.7, - 1019.9, - 1020.2, - 1020.6, - 1021.0, - 1021.5, - 1022.0 - ], - "surface_pressure": [ - 1019.2, - 1019.4, - 1018.7, - 1018.4, - 1018.1, - 1017.9, - 1017.6, - 1018.3, - 1018.3, - 1017.9, - 1018.3, - 1018.1, - 1017.7, - 1017.5, - 1017.6, - 1017.8, - 1017.8, - 1017.6, - 1017.2, - 1017.9, - 1018.5, - 1018.6, - 1019.4, - 1019.7, - 1019.9, - 1019.6, - 1019.3, - 1019.0, - 1018.4, - 1018.1, - 1018.0, - 1018.2, - 1018.2, - 1017.9, - 1017.5, - 1016.8, - 1015.9, - 1015.1, - 1014.5, - 1014.0, - 1013.6, - 1013.1, - 1013.2, - 1013.2, - 1013.0, - 1013.0, - 1012.9, - 1012.6, - 1012.3, - 1011.9, - 1011.7, - 1011.3, - 1011.2, - 1011.3, - 1011.5, - 1011.8, - 1012.1, - 1012.3, - 1012.4, - 1012.6, - 1012.7, - 1012.6, - 1012.7, - 1012.9, - 1013.3, - 1014.4, - 1016.2, - 1017.7, - 1018.7, - 1019.8, - 1020.4, - 1021.3, - 1022.1, - 1022.6, - 1023.0, - 1023.4, - 1023.9, - 1024.4, - 1024.8, - 1025.2, - 1025.7, - 1025.9, - 1025.9, - 1025.8, - 1025.4, - 1024.7, - 1023.8, - 1023.0, - 1022.6, - 1022.3, - 1022.0, - 1021.6, - 1021.1, - 1020.6, - 1019.9, - 1019.1, - 1018.3, - 1017.4, - 1016.5, - 1015.7, - 1015.1, - 1014.6, - 1014.2, - 1014.0, - 1014.0, - 1014.0, - 1014.0, - 1014.0, - 1014.0, - 1013.8, - 1013.5, - 1013.4, - 1013.7, - 1014.1, - 1014.5, - 1014.6, - 1014.7, - 1014.6, - 1014.4, - 1014.1, - 1013.7, - 1013.2, - 1012.6, - 1012.0, - 1011.5, - 1011.0, - 1010.8, - 1010.9, - 1011.3, - 1011.6, - 1011.8, - 1012.1, - 1012.4, - 1012.8, - 1013.2, - 1013.7, - 1014.2, - 1014.8, - 1015.4, - 1015.9, - 1016.4, - 1016.8, - 1017.1, - 1017.2, - 1017.4, - 1017.6, - 1017.7, - 1017.8, - 1017.9, - 1018.0, - 1018.1, - 1018.2, - 1018.3, - 1018.4, - 1018.5, - 1018.5, - 1018.6, - 1018.7, - 1018.7, - 1018.8, - 1018.9, - 1019.0, - 1019.2, - 1019.5, - 1020.0, - 1020.4, - 1020.9, - 1021.4 - ], - "cloud_cover": [ - 81, - 21, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 95, - 99, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 99, - 82, - 72, - 63, - 54, - 47, - 45, - 53, - 67, - 77, - 79, - 76, - 73, - 70, - 66, - 60, - 48, - 34, - 30, - 46, - 71, - 90, - 93, - 90, - 88, - 91, - 96, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 100, - 72, - 33, - 5, - 0, - 0, - 2, - 4, - 8, - 12, - 16, - 21, - 25, - 28, - 30, - 38, - 58, - 83, - 100, - 100, - 100, - 94, - 89, - 81, - 70, - 50, - 25, - 8, - 4, - 7, - 13, - 23, - 37, - 44, - 39, - 29, - 20, - 17, - 17, - 16, - 14, - 13, - 12, - 13, - 14, - 16, - 18, - 19, - 20, - 19, - 16, - 14, - 12, - 9, - 7, - 5, - 4, - 3, - 2, - 1 - ], - "visibility": [ - 19880.00, - 16420.00, - 19420.00, - 18580.00, - 16060.00, - 14220.00, - 50000.00, - 3440.00, - 520.00, - 420.00, - 2880.00, - 3180.00, - 2700.00, - 3320.00, - 3380.00, - 3280.00, - 3800.00, - 3540.00, - 4100.00, - 5640.00, - 50000.00, - 6380.00, - 6460.00, - 6200.00, - 5740.00, - 2920.00, - 3040.00, - 3260.00, - 3220.00, - 2980.00, - 4900.00, - 6600.00, - 6260.00, - 6940.00, - 50000.00, - 11200.00, - 50000.00, - 50000.00, - 50000.00, - 16540.00, - 50000.00, - 19160.00, - 50000.00, - 50000.00, - 17200.00, - 16220.00, - 50000.00, - 12860.00, - 12320.00, - 50000.00, - 50000.00, - 50000.00, - 50000.00, - 22120.00, - 8960.00, - 50000.00, - 50000.00, - 50000.00, - 50000.00, - 50000.00, - 9740.00, - 50000.00, - 9600.00, - 50000.00, - 20500.00, - 19140.00, - 29080.00, - 50000.00, - 5180.00, - 50000.00, - 3680.00, - 1500.00, - 960.00, - 680.00, - 580.00, - 520.00, - 780.00, - 920.00, - 860.00, - 400.00, - 100.00, - 100.00, - 2420.00, - 37080.00, - 44420.00, - 52500.00, - 60600.00, - 68680.00, - 67800.00, - 66900.00, - 66020.00, - 60080.00, - 54120.00, - 48180.00, - 40940.00, - 33700.00, - 26460.00, - 27000.00, - 27520.00, - 28060.00, - 25880.00, - 23700.00, - 21520.00, - 19360.00, - 17200.00, - 15040.00, - 21540.00, - 28040.00, - 34540.00, - 34220.00, - 33880.00, - 33560.00, - 26440.00, - 19320.00, - 12200.00, - 9540.00, - 6880.00, - 4220.00, - 4160.00, - 4080.00, - 4020.00, - 3460.00, - 2880.00, - 2320.00, - 2860.00, - 3420.00, - 3960.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 22960.00, - 21780.00, - 20600.00, - 21780.00, - 22960.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00, - 24140.00 - ], - "evapotranspiration": [ - 0.01, - 0.01, - 0.01, - -0.00, - -0.00, - -0.00, - -0.00, - -0.00, - 0.01, - 0.01, - 0.01, - 0.02, - 0.03, - 0.02, - 0.01, - 0.01, - 0.01, - 0.01, - -0.00, - -0.00, - -0.00, - -0.00, - -0.00, - -0.00, - -0.00, - -0.00, - -0.00, - -0.00, - 0.00, - -0.00, - -0.00, - -0.00, - -0.00, - 0.01, - 0.02, - 0.03, - 0.04, - 0.04, - 0.05, - 0.05, - 0.04, - 0.03, - 0.02, - 0.02, - 0.02, - 0.02, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00 - ], - "et0_fao_evapotranspiration": [ - 0.02, - 0.02, - 0.02, - 0.02, - 0.01, - 0.01, - 0.00, - 0.01, - 0.01, - 0.01, - 0.02, - 0.03, - 0.03, - 0.03, - 0.02, - 0.02, - 0.02, - 0.02, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.02, - 0.02, - 0.04, - 0.08, - 0.15, - 0.18, - 0.18, - 0.11, - 0.08, - 0.08, - 0.08, - 0.05, - 0.05, - 0.05, - 0.04, - 0.03, - 0.02, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.00, - 0.00, - 0.03, - 0.03, - 0.04, - 0.05, - 0.05, - 0.06, - 0.06, - 0.04, - 0.04, - 0.03, - 0.04, - 0.02, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.01, - 0.01, - 0.03, - 0.05, - 0.09, - 0.17, - 0.19, - 0.20, - 0.18, - 0.13, - 0.08, - 0.06, - 0.05, - 0.05, - 0.04, - 0.04, - 0.03, - 0.03, - 0.03, - 0.03, - 0.03, - 0.02, - 0.02, - 0.02, - 0.03, - 0.03, - 0.04, - 0.06, - 0.09, - 0.11, - 0.12, - 0.12, - 0.10, - 0.07, - 0.03, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.01, - 0.02, - 0.04, - 0.06, - 0.08, - 0.10, - 0.10, - 0.09, - 0.08, - 0.06, - 0.03, - 0.01, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.02, - 0.05, - 0.09, - 0.13, - 0.15, - 0.16, - 0.15, - 0.12, - 0.07, - 0.02, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00 - ], - "vapour_pressure_deficit": [ - 0.22, - 0.16, - 0.22, - 0.20, - 0.16, - 0.15, - 0.09, - 0.03, - 0.02, - 0.01, - 0.03, - 0.04, - 0.03, - 0.04, - 0.04, - 0.05, - 0.05, - 0.06, - 0.06, - 0.06, - 0.07, - 0.07, - 0.08, - 0.07, - 0.06, - 0.04, - 0.05, - 0.05, - 0.05, - 0.04, - 0.06, - 0.08, - 0.08, - 0.09, - 0.14, - 0.22, - 0.34, - 0.41, - 0.42, - 0.41, - 0.47, - 0.48, - 0.44, - 0.42, - 0.39, - 0.37, - 0.30, - 0.24, - 0.22, - 0.22, - 0.20, - 0.20, - 0.16, - 0.13, - 0.13, - 0.14, - 0.14, - 0.14, - 0.14, - 0.14, - 0.16, - 0.16, - 0.16, - 0.16, - 0.14, - 0.15, - 0.19, - 0.08, - 0.06, - 0.07, - 0.02, - 0.03, - 0.03, - 0.02, - 0.02, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.00, - 0.02, - 0.07, - 0.16, - 0.25, - 0.32, - 0.37, - 0.41, - 0.41, - 0.41, - 0.41, - 0.42, - 0.45, - 0.44, - 0.37, - 0.27, - 0.20, - 0.16, - 0.13, - 0.10, - 0.09, - 0.08, - 0.08, - 0.08, - 0.08, - 0.08, - 0.10, - 0.13, - 0.16, - 0.20, - 0.26, - 0.28, - 0.23, - 0.16, - 0.11, - 0.10, - 0.08, - 0.08, - 0.07, - 0.06, - 0.06, - 0.06, - 0.07, - 0.07, - 0.07, - 0.06, - 0.06, - 0.07, - 0.08, - 0.10, - 0.15, - 0.21, - 0.25, - 0.27, - 0.27, - 0.25, - 0.21, - 0.15, - 0.11, - 0.10, - 0.10, - 0.10, - 0.09, - 0.09, - 0.08, - 0.07, - 0.06, - 0.05, - 0.04, - 0.04, - 0.05, - 0.08, - 0.14, - 0.20, - 0.26, - 0.33, - 0.37, - 0.35, - 0.30, - 0.25, - 0.20, - 0.14, - 0.11, - 0.08, - 0.07, - 0.07, - 0.07, - 0.07 - ], - "uv_index": [ - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.20, - 0.55, - 0.80, - 1.00, - 1.95, - 1.40, - 0.60, - 1.00, - 0.15, - 0.10, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.20, - 0.80, - 1.50, - 1.70, - 2.40, - 2.40, - 1.65, - 1.45, - 0.70, - 0.15, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.05, - 0.10, - 0.20, - 0.35, - 0.25, - 0.40, - 0.10, - 0.10, - 0.05, - 0.05, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 0.95, - 1.65, - 2.25, - 2.60, - 2.60, - 2.20, - 1.55, - 0.80, - 0.20, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.05, - 0.10, - 0.15, - 0.20, - 0.25, - 0.25, - 0.20, - 0.15, - 0.10, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.05, - 0.10, - 0.35, - 0.90, - 1.55, - 2.05, - 2.20, - 2.20, - 2.00, - 1.50, - 0.85, - 0.35, - 0.10, - 0.05, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.10, - 0.20, - 0.50, - 1.05, - 1.75, - 2.25, - 2.40, - 2.35, - 2.15, - 1.65, - 0.95, - 0.40, - 0.15, - 0.05, - 0.00, - 0.00, - 0.00 - ], - "uv_index_clear_sky": [ - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.25, - 0.85, - 1.50, - 2.10, - 2.40, - 2.35, - 2.00, - 1.40, - 0.70, - 0.15, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.25, - 0.90, - 1.60, - 2.20, - 2.50, - 2.50, - 2.10, - 1.50, - 0.75, - 0.20, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 0.90, - 1.55, - 2.10, - 2.40, - 2.35, - 2.00, - 1.40, - 0.75, - 0.20, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 0.95, - 1.65, - 2.25, - 2.60, - 2.60, - 2.20, - 1.55, - 0.80, - 0.20, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.30, - 0.95, - 1.65, - 2.20, - 2.50, - 2.45, - 2.10, - 1.50, - 0.80, - 0.20, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.05, - 0.20, - 0.45, - 1.00, - 1.70, - 2.20, - 2.40, - 2.35, - 2.15, - 1.65, - 0.90, - 0.35, - 0.10, - 0.05, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.10, - 0.20, - 0.50, - 1.05, - 1.80, - 2.30, - 2.45, - 2.45, - 2.20, - 1.65, - 0.95, - 0.40, - 0.15, - 0.05, - 0.00, - 0.00, - 0.00 - ], - "is_day": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "sunshine_duration": [ - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 352.96, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 445.21, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 2063.21, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 1037.95, - 2476.50, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 1710.03, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 669.47, - 2502.50, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 3531.24, - 936.66, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 65.58, - 3179.00, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 3600.00, - 2419.41, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00, - 0.00 - ], - "wet_bulb_temperature_2m": [ - -0.7, - -0.6, - 0.3, - -0.2, - -0.3, - 1.4, - 2.6, - 2.7, - 3.7, - 4.4, - 5.0, - 5.5, - 6.9, - 7.6, - 7.8, - 8.4, - 8.7, - 8.7, - 8.5, - 8.4, - 8.4, - 8.5, - 8.8, - 9.0, - 9.1, - 9.3, - 9.1, - 9.1, - 9.2, - 9.5, - 9.7, - 9.8, - 9.8, - 10.4, - 11.1, - 12.2, - 12.5, - 13.1, - 12.7, - 12.1, - 11.7, - 11.3, - 11.3, - 11.2, - 11.0, - 10.7, - 10.6, - 10.5, - 10.3, - 9.9, - 9.7, - 9.6, - 9.6, - 9.5, - 9.5, - 9.2, - 9.0, - 9.1, - 9.4, - 9.4, - 9.6, - 9.7, - 9.6, - 9.7, - 9.7, - 8.5, - 7.8, - 8.3, - 8.6, - 8.5, - 7.5, - 7.2, - 6.9, - 6.6, - 6.1, - 5.8, - 5.5, - 5.3, - 5.3, - 5.5, - 6.1, - 6.6, - 7.2, - 7.9, - 8.4, - 8.9, - 9.4, - 9.5, - 9.1, - 8.4, - 7.8, - 7.7, - 7.6, - 7.6, - 7.7, - 7.8, - 7.8, - 7.8, - 7.8, - 7.7, - 7.7, - 7.7, - 7.7, - 8.0, - 8.4, - 8.8, - 9.3, - 9.6, - 9.8, - 9.7, - 9.3, - 8.9, - 8.5, - 7.9, - 7.4, - 7.0, - 6.8, - 6.5, - 6.3, - 6.2, - 6.1, - 6.4, - 6.7, - 6.9, - 6.9, - 6.8, - 6.7, - 6.6, - 6.6, - 6.6, - 6.5, - 6.3, - 6.0, - 5.7, - 5.5, - 5.1, - 4.6, - 4.1, - 3.7, - 3.6, - 3.6, - 3.6, - 3.7, - 3.6, - 3.5, - 3.2, - 3.0, - 2.8, - 2.6, - 2.4, - 2.5, - 2.8, - 3.4, - 3.9, - 4.4, - 4.9, - 5.3, - 5.3, - 5.1, - 4.9, - 4.7, - 4.3, - 3.9, - 3.5, - 3.1, - 2.6, - 2.1, - 1.7 - ] - } -} -``` \ No newline at end of file diff --git a/dist/server/scripts/modules/utils/weather.mjs b/dist/server/scripts/modules/utils/weather.mjs deleted file mode 100644 index 72705c5..0000000 --- a/dist/server/scripts/modules/utils/weather.mjs +++ /dev/null @@ -1,177 +0,0 @@ -import { json } from './fetch.mjs'; - -const openMeteoAdditionalForecastParameters = '&daily=temperature_2m_max,temperature_2m_min&hourly=temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation_probability,precipitation,rain,showers,snowfall,snow_depth,weather_code,pressure_msl,surface_pressure,cloud_cover,visibility,evapotranspiration,et0_fao_evapotranspiration,vapour_pressure_deficit,uv_index,uv_index_clear_sky,is_day,sunshine_duration,wet_bulb_temperature_2m,wind_speed_10m,wind_direction_10m,wind_gusts_10m&models=best_match'; - -const getPoint = async (lat, lon) => { - try { - return await json(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}${openMeteoAdditionalForecastParameters}`); - } catch (error) { - console.log(`Unable to get point ${lat}, ${lon}`); - console.error(error); - return false; - } -}; - -const getGeocoding = async (name) => { - try { - return await json(`https://geocoding-api.open-meteo.com/v1/search?name=${name}&count=10&language=en&format=json`); - } catch (error) { - console.log(`Unable to get locality with value ${name}`); - console.error(error); - return false; - } -}; - -const weatherConditions = [ - { codes: [0], text: ['Clear sky'] }, - { codes: [1, 2, 3], text: ['Mainly clear', 'Partly cloudy', 'Overcast'] }, - { codes: [45, 48], text: ['Fog', 'Depositing rime fog'] }, - { codes: [51, 53, 55], text: ['Light Drizzle', 'Moderate Drizzle', 'Dense Drizzle'] }, - { codes: [56, 57], text: ['Light Freezing Drizzle', 'Dense Freezing Drizzle'] }, - { codes: [61, 63, 65], text: ['Slight Rain', 'Moderate Rain', 'Heavy Rain'] }, - { codes: [66, 67], text: ['Light Freezing Rain', 'Heavy Freezing Rain'] }, - { codes: [71, 73, 75], text: ['Slight Snow fall', 'Moderate Snow fall', 'Heavy Snow fall'] }, - { codes: [77], text: ['Snow grains'] }, - { codes: [80, 81, 82], text: ['Slight Rain showers', 'Moderate Rain showers', 'Violent Rain showers'] }, - { codes: [85, 86], text: ['Slight Snow showers', 'Heavy Snow Showers'] }, - { codes: [95], text: ['Thunderstorm'] }, - { codes: [96, 99], text: ['Thunderstorm with slight hail', 'Thunderstorm with heavy hail'] }, -]; - -const getConditionText = (code) => { - const conditionIndex = weatherConditions.findIndex((condition) => condition.codes.includes(code)); - const weatherConditionObject = weatherConditions[conditionIndex]; - - const weatherTextIndex = weatherConditionObject.codes.findIndex((conditionCode) => conditionCode === code); - const weatherText = weatherConditionObject.text[weatherTextIndex]; - - if (conditionIndex !== -1) return weatherText; - - console.log('unable to determine weather condition from code: ', code); - return `unknown weather condition with code: ${code}`; -}; - -/** - * - * @param {*} forecast expects the forecast object from open-meteo as the response from `getPoint` - * @returns A map indexed by date, with averaged values for each unit in "hourly_units" from the forecast object - */ -const aggregateWeatherForecastData = (getPointResponse) => { - // We expect the response obhect to be structured hourly like this: - // { - // "latitude": 52.366, - // "longitude": 4.901, - // "generationtime_ms": 0.5203485488891602, - // "utc_offset_seconds": 0, - // "timezone": "GMT", - // "timezone_abbreviation": "GMT", - // "elevation": 6.0, - // "hourly_units": { - // "time": "iso8601", - // "temperature_2m": "°C", - // "relative_humidity_2m": "%", - // "dew_point_2m": "°C", - // "apparent_temperature": "°C", - // "precipitation_probability": "%", - // "precipitation": "mm", - // "rain": "mm", - // "showers": "mm", - // "snowfall": "cm", - // "snow_depth": "m", - // "weather_code": "wmo code", - // "pressure_msl": "hPa", - // "surface_pressure": "hPa", - // "cloud_cover": "%", - // "visibility": "m", - // "evapotranspiration": "mm", - // "et0_fao_evapotranspiration": "mm", - // "vapour_pressure_deficit": "kPa", - // "uv_index": "", - // "uv_index_clear_sky": "", - // "is_day": "", - // "sunshine_duration": "s", - // "wet_bulb_temperature_2m": "°C" - // }, - // "hourly": { - // "time": [ - // "" - // ], - // "temperature_2m": [ - // "" - // ], - // "relative_humidity_2m": [ - // "" - // ], - // etc... - // }, - // } - - const { hourly, daily } = getPointResponse; - const keys = Object.keys(hourly).filter((key) => key !== 'time'); - - const dailyData = {}; - - hourly.time.forEach((timestamp, index) => { - const date = timestamp.split('T')[0]; - - if (!dailyData[date]) { - dailyData[date] = { hours: [], weather_code_counts: {} }; - keys.forEach((key) => { - dailyData[date][key] = { sum: 0, count: 0 }; - }); - } - - // Collect per-hour data - const hourData = { time: timestamp }; - keys.forEach((key) => { - hourData[key] = hourly[key][index]; - - // Aggregate sums for daily averages - dailyData[date][key].sum += hourly[key][index]; - dailyData[date][key].count += 1; - }); - - // Track weather code occurrences - if (hourly.weather_code) { - const weatherCode = hourly.weather_code[index]; - dailyData[date].weather_code_counts[weatherCode] = (dailyData[date].weather_code_counts[weatherCode] || 0) + 1; - } - - // Append the hourly entry to the "hours" array - dailyData[date].hours.push(hourData); - }); - - // Compute daily averages - const dailyAverages = {}; - Object.entries(dailyData).forEach(([date, data]) => { - dailyAverages[date] = { hours: data.hours }; - keys.forEach((key) => { - dailyAverages[date][key] = data[key].sum / data[key].count; - }); - - // Determine most common weather code - const weatherCodes = Object.entries(data.weather_code_counts); - if (weatherCodes.length > 0) { - [dailyAverages[date].weather_code] = weatherCodes.reduce((a, b) => (b[1] > a[1] ? b : a)); - } - }); - - // Add temperature_2m_max and temperature_2m_min from the daily section - daily.time.forEach((date, index) => { - if (!dailyData[date]) { - dailyData[date] = { hours: [] }; - } - dailyAverages[date].temperature_2m_max = daily.temperature_2m_max[index]; - dailyAverages[date].temperature_2m_min = daily.temperature_2m_min[index]; - }); - - return dailyAverages; -}; - -export { - // eslint-disable-next-line import/prefer-default-export - getPoint, - getGeocoding, - aggregateWeatherForecastData, - getConditionText, -}; diff --git a/dist/server/scripts/modules/weatherdisplay.mjs b/dist/server/scripts/modules/weatherdisplay.mjs deleted file mode 100644 index a1906d9..0000000 --- a/dist/server/scripts/modules/weatherdisplay.mjs +++ /dev/null @@ -1,431 +0,0 @@ -// base weather display class - -import STATUS, { calcStatusClass, statusClasses } from './status.mjs'; -import { DateTime } from '../vendor/auto/luxon.mjs'; -import { - msg, displayNavMessage, isPlaying, updateStatus, timeZone, -} from './navigation.mjs'; -import { parseQueryString } from './share.mjs'; -import settings from './settings.mjs'; - -class WeatherDisplay { - constructor(navId, elemId, name, defaultEnabled) { - // navId is used in messaging and sort order - this.navId = navId; - this.elemId = undefined; - this.data = undefined; - this.loadingStatus = STATUS.loading; - this.name = name ?? elemId; - this.getDataCallbacks = []; - this.stillWaitingCallbacks = []; - this.defaultEnabled = defaultEnabled; - this.okToDrawCurrentConditions = true; - this.okToDrawCurrentDateTime = true; - this.showOnProgress = true; - - // default navigation timing - this.timing = { - totalScreens: 1, - baseDelay: 9000, // 5 seconds - delay: 1, // 1*1second = 1 second total display time - }; - this.navBaseCount = 0; - this.screenIndex = -1; // special starting condition - - // store elemId once - this.storeElemId(elemId); - - if (this.isEnabled) { - this.setStatus(STATUS.loading); - } else { - this.setStatus(STATUS.disabled); - } - this.startNavCount(); - - // get any templates - document.addEventListener('DOMContentLoaded', () => { - this.loadTemplates(); - }); - } - - generateCheckbox(defaultEnabled = true) { - // no checkbox if progress - if (this.elemId === 'progress') return false; - - // get url provided state - const urlValue = parseQueryString()?.[`${this.elemId}-checkbox`]; - let urlState; - if (urlValue !== undefined) { - urlState = urlValue === 'true'; - } - - // get the saved status of the checkbox, but defer to a value set in the url - let savedStatus = urlState ?? window.localStorage.getItem(`display-enabled: ${this.elemId}`); - if (savedStatus === null) savedStatus = defaultEnabled; - this.isEnabled = !!((savedStatus === 'true' || savedStatus === true)); - - // refresh (or initially store the state of the checkbox) - window.localStorage.setItem(`display-enabled: ${this.elemId}`, this.isEnabled); - - // create a checkbox in the selected displays area - const label = document.createElement('label'); - label.for = `${this.elemId}-checkbox`; - label.id = `${this.elemId}-label`; - const checkbox = document.createElement('input'); - checkbox.type = 'checkbox'; - checkbox.value = true; - checkbox.id = `${this.elemId}-checkbox`; - checkbox.name = `${this.elemId}-checkbox`; - checkbox.checked = this.isEnabled; - checkbox.addEventListener('change', (e) => this.checkboxChange(e)); - const span = document.createElement('span'); - span.innerHTML = this.name; - const alert = document.createElement('span'); - alert.innerHTML = '!!!'; - alert.classList.add('alert'); - - label.append(checkbox, span, alert); - - this.checkbox = label; - - return label; - } - - checkboxChange(e) { - // update the state - this.isEnabled = e.target.checked; - // store the value for the next load - window.localStorage.setItem(`display-enabled: ${this.elemId}`, this.isEnabled); - // calling get data will update the status and actually get the data if we're set to enabled - this.getData(); - } - - // set data status and send update to navigation module - setStatus(value) { - this.status = value; - updateStatus({ - id: this.navId, - status: this.status, - }); - - // update coloring of checkbox at bottom of page - if (!this.checkbox) return; - this.checkbox.classList.remove(...statusClasses); - this.checkbox.classList.add(calcStatusClass(value)); - } - - get status() { - return this.loadingStatus; - } - - set status(state) { - this.loadingStatus = state; - } - - storeElemId(elemId) { - // only create it once - if (this.elemId) return; - this.elemId = elemId; - } - - // get necessary data for this display - getData(weatherParameters) { - // clear current data - this.data = undefined; - - // store weatherParameters locally in case we need them later - if (weatherParameters) this.weatherParameters = weatherParameters; - - // set status - if (this.isEnabled) { - this.setStatus(STATUS.loading); - } else { - this.setStatus(STATUS.disabled); - return false; - } - - // recalculate navigation timing (in case it was modified in the constructor) - this.calcNavTiming(); - return true; - } - - // return any data requested before it was available - getDataCallback() { - // call each callback - this.getDataCallbacks.forEach((fxn) => fxn(this.data)); - // clear the callbacks - this.getDataCallbacks = []; - } - - drawCanvas() { - // clean up the first-run flag in screen index - if (this.screenIndex < 0) this.screenIndex = 0; - if (this.okToDrawCurrentDateTime) this.drawCurrentDateTime(); - } - - finishDraw() { - // draw date and time - if (this.okToDrawCurrentDateTime) { - this.drawCurrentDateTime(); - // auto clock refresh - if (!this.dateTimeInterval) { - // only draw if canvas is active to conserve battery - this.dateTimeInterval = setInterval(() => this.active && this.drawCurrentDateTime(), 100); - } - } - } - - drawCurrentDateTime() { - // Get the current date and time. - const now = DateTime.local().setZone(timeZone()); - - // time = "11:35:08 PM"; - const time = now.toLocaleString(DateTime.TIME_WITH_SECONDS).padStart(11, ' '); - const date = now.toFormat(' ccc LLL ') + now.day.toString().padStart(2, ' '); - - const dateElem = this.elem.querySelector('.date-time.date'); - const timeElem = this.elem.querySelector('.date-time.time'); - - if (timeElem && this.lastTime !== time) { - timeElem.innerHTML = time.toUpperCase(); - } - this.lastTime = time; - - if (dateElem && this.lastDate !== date) { - dateElem.innerHTML = date.toUpperCase(); - } - this.lastDate = date; - } - - // show/hide the canvas and start/stop the navigation timer - showCanvas(navCmd) { - // reset timing if enabled - // if a nav command is present call it to set the screen index - if (navCmd === msg.command.firstFrame) this.navNext(navCmd); - if (navCmd === msg.command.lastFrame) this.navPrev(navCmd); - - this.startNavCount(); - - this.elem.classList.add('show'); - document.querySelector('#divTwc').classList.add(this.elemId); - } - - hideCanvas() { - this.resetNavBaseCount(); - this.elem.classList.remove('show'); - // used to change backgrounds for widescreen - document.querySelector('#divTwc').classList.remove(this.elemId); - } - - get active() { - return this.elem.offsetHeight !== 0; - } - - get enabled() { - return this.isEnabled; - } - - // navigation timings - // totalScreens = total number of screens that are available - // baseDelay = ms to delay before re-evaluating screenIndex - // delay: three options - // integer = each screen will display for this number of baseDelays - // [integer, integer, ...] = screenIndex 0 displays for integer[0]*baseDelay, etc. - // [{time, si}, ...] = time as above, si is specific screen index to display during this interval - // if the array forms are used totalScreens is overwritten by the size of the array - navBaseTime() { - // see if play is active and screen is active - if (!isPlaying() || !this.active) return; - // increment the base count - this.navBaseCount += 1; - - // call base count change if available for this function - if (this.baseCountChange) this.baseCountChange(this.navBaseCount); - - // handle base count/screen index changes - this.updateScreenFromBaseCount(); - } - - async updateScreenFromBaseCount() { - // get the next screen index - const nextScreenIndex = this.screenIndexFromBaseCount(); - - // special cases for first and last frame - // must compare with false as nextScreenIndex could be 0 which is valid - if (nextScreenIndex === false) { - this.sendNavDisplayMessage(msg.response.next); - return; - } - - // test for no change and exit early - if (nextScreenIndex === this.screenIndex) return; - - // test for -1 (no screen displayed yet) - this.screenIndex = nextScreenIndex === -1 ? 0 : nextScreenIndex; - - // call the appropriate screen index change method - if (this.screenIndexChange) { - this.screenIndexChange(this.screenIndex); - } else { - await this.drawCanvas(); - } - this.showCanvas(); - } - - // take the three timing formats shown above and break them into arrays for consistent usage in navigation functions - // this.timing.fullDelay = [end of screen index 0 in base counts, end of screen index 1...] - // this.timing.screenIndexes = [screen index to use during this.timing.fullDelay[0], screen index to use during this.timing.fullDelay[1], ...] - calcNavTiming() { - if (this.timing === false) return; - // update total screens - if (Array.isArray(this.timing.delay)) this.timing.totalScreens = this.timing.delay.length; - - // if the delay is provided as a single value, expand it to a series of the same value - let intermediateDelay = []; - if (typeof this.timing.delay === 'number') { - for (let i = 0; i < this.timing.totalScreens; i += 1) intermediateDelay.push(this.timing.delay); - } else { - // map just the delays to the intermediate block - intermediateDelay = this.timing.delay.map((delay) => { - if (typeof delay === 'object') return delay.time; - return delay; - }); - } - - // calculate the cumulative end point of each delay - let sum = 0; - this.timing.fullDelay = intermediateDelay.map((val) => { - const calc = sum + val; - sum += val; - return calc; - }); - - // generate a list of screen either sequentially if not provided in an object or from the object - if (Array.isArray(this.timing.delay) && typeof this.timing.delay[0] === 'object') { - // extract screen indexes from objects - this.timing.screenIndexes = this.timing.delay.map((delay) => delay.si); - } else { - // generate sequential screen indexes - this.timing.screenIndexes = []; - for (let i = 0; i < this.timing.totalScreens; i += 1) this.timing.screenIndexes.push(i); - } - } - - // navigate to next screen - navNext(command) { - // check for special 'first frame' command - if (command === msg.command.firstFrame) { - this.resetNavBaseCount(); - } else { - // set the base count to the next available frame - const newBaseCount = this.timing.fullDelay.find((delay) => delay > this.navBaseCount); - this.navBaseCount = newBaseCount; - } - this.updateScreenFromBaseCount(); - } - - // navigate to previous screen - navPrev(command) { - // check for special 'last frame' command - if (command === msg.command.lastFrame) { - this.navBaseCount = this.timing.fullDelay[this.timing.totalScreens - 1] - 1; - } else { - // find the highest fullDelay that is less than the current base count - const newBaseCount = this.timing.fullDelay.reduce((acc, delay) => { - if (delay < this.navBaseCount) return delay; - return acc; - }, 0); - // if the new base count is zero then we're already at the first screen - if (newBaseCount === 0 && this.navBaseCount === 0) { - this.sendNavDisplayMessage(msg.response.previous); - return; - } - this.navBaseCount = newBaseCount; - } - this.updateScreenFromBaseCount(); - } - - // get the screen index for the current base count, returns false if past end of timing array (go to next screen, stop timing) - screenIndexFromBaseCount() { - // test for timing enabled - if (!this.timing) return 0; - if (this.timing.totalScreens === 0) return false; - // find the first timing in the timing array that is greater than the base count - if (this.timing && !this.timing.fullDelay) this.calcNavTiming(); - const timingIndex = this.timing.fullDelay.findIndex((delay) => delay > this.navBaseCount); - if (timingIndex === -1) return false; - return this.timing.screenIndexes[timingIndex]; - } - - // start and stop base counter - startNavCount() { - if (!this.navInterval) this.navInterval = setInterval(() => this.navBaseTime(), this.timing.baseDelay * settings.speed.value); - } - - resetNavBaseCount() { - this.navBaseCount = 0; - this.screenIndex = -1; - // reset the timing so we don't short-change the first screen - if (this.navInterval) { - clearInterval(this.navInterval); - this.navInterval = undefined; - } - } - - sendNavDisplayMessage(message) { - displayNavMessage({ - id: this.navId, - type: message, - }); - } - - loadTemplates() { - this.templates = {}; - this.elem = document.querySelector(`#${this.elemId}-html`); - if (!this.elem) return; - const templates = this.elem.querySelectorAll('.template'); - templates.forEach((template) => { - const className = template.classList[0]; - const node = template.cloneNode(true); - node.classList.remove('template'); - this.templates[className] = node; - template.remove(); - }); - } - - fillTemplate(name, fillValues) { - // get the template - const templateNode = this.templates[name]; - if (!templateNode) return false; - - // clone it - const template = templateNode.cloneNode(true); - - Object.entries(fillValues).forEach(([key, value]) => { - // get the specified element - const elem = template.querySelector(`.${key}`); - if (!elem) return; - - // fill based on type provided - if (typeof value === 'string' || typeof value === 'number') { - // string and number fill the first found selector - elem.innerHTML = value; - } else if (value?.type === 'img') { - // fill the image source - elem.querySelector('img').src = value.src; - } - }); - - return template; - } - - // still waiting for data (retries triggered) - stillWaiting() { - if (this.isEnabled) this.setStatus(STATUS.retrying); - // handle still waiting callbacks - this.stillWaitingCallbacks.forEach((callback) => callback()); - this.stillWaitingCallbacks = []; - } -} - -export default WeatherDisplay; diff --git a/dist/server/scripts/vendor/auto/jquery.js b/dist/server/scripts/vendor/auto/jquery.js deleted file mode 100644 index 1a86433..0000000 --- a/dist/server/scripts/vendor/auto/jquery.js +++ /dev/null @@ -1,10716 +0,0 @@ -/*! - * jQuery JavaScript Library v3.7.1 - * https://jquery.com/ - * - * Copyright OpenJS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2023-08-28T13:37Z - */ -( function( global, factory ) { - - "use strict"; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket trac-14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. -"use strict"; - -var arr = []; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var flat = arr.flat ? function( array ) { - return arr.flat.call( array ); -} : function( array ) { - return arr.concat.apply( [], array ); -}; - - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call( Object ); - -var support = {}; - -var isFunction = function isFunction( obj ) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 - // Plus for old WebKit, typeof returns "function" for HTML collections - // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) - return typeof obj === "function" && typeof obj.nodeType !== "number" && - typeof obj.item !== "function"; - }; - - -var isWindow = function isWindow( obj ) { - return obj != null && obj === obj.window; - }; - - -var document = window.document; - - - - var preservedScriptAttributes = { - type: true, - src: true, - nonce: true, - noModule: true - }; - - function DOMEval( code, node, doc ) { - doc = doc || document; - - var i, val, - script = doc.createElement( "script" ); - - script.text = code; - if ( node ) { - for ( i in preservedScriptAttributes ) { - - // Support: Firefox 64+, Edge 18+ - // Some browsers don't support the "nonce" property on scripts. - // On the other hand, just using `getAttribute` is not enough as - // the `nonce` attribute is reset to an empty string whenever it - // becomes browsing-context connected. - // See https://github.com/whatwg/html/issues/2369 - // See https://html.spec.whatwg.org/#nonce-attributes - // The `node.getAttribute` check was added for the sake of - // `jQuery.globalEval` so that it can fake a nonce-containing node - // via an object. - val = node[ i ] || node.getAttribute && node.getAttribute( i ); - if ( val ) { - script.setAttribute( i, val ); - } - } - } - doc.head.appendChild( script ).parentNode.removeChild( script ); - } - - -function toType( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; -} -/* global Symbol */ -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - - -var version = "3.7.1", - - rhtmlSuffix = /HTML$/i, - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - - // Return all the elements in a clean array - if ( num == null ) { - return slice.call( this ); - } - - // Return just the one element from the set - return num < 0 ? this[ num + this.length ] : this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - even: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return ( i + 1 ) % 2; - } ) ); - }, - - odd: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return i % 2; - } ) ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - copy = options[ name ]; - - // Prevent Object.prototype pollution - // Prevent never-ending loop - if ( name === "__proto__" || target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = Array.isArray( copy ) ) ) ) { - src = target[ name ]; - - // Ensure proper type for the source value - if ( copyIsArray && !Array.isArray( src ) ) { - clone = []; - } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { - clone = {}; - } else { - clone = src; - } - copyIsArray = false; - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isPlainObject: function( obj ) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } - - proto = getProto( obj ); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, - - isEmptyObject: function( obj ) { - var name; - - for ( name in obj ) { - return false; - } - return true; - }, - - // Evaluates a script in a provided context; falls back to the global one - // if not specified. - globalEval: function( code, options, doc ) { - DOMEval( code, { nonce: options && options.nonce }, doc ); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - - // Retrieve the text value of an array of DOM nodes - text: function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - - // If no nodeType, this is expected to be an array - while ( ( node = elem[ i++ ] ) ) { - - // Do not traverse comment nodes - ret += jQuery.text( node ); - } - } - if ( nodeType === 1 || nodeType === 11 ) { - return elem.textContent; - } - if ( nodeType === 9 ) { - return elem.documentElement.textContent; - } - if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - - // Do not include comment or processing instruction nodes - - return ret; - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - isXMLDoc: function( elem ) { - var namespace = elem && elem.namespaceURI, - docElem = elem && ( elem.ownerDocument || elem ).documentElement; - - // Assume HTML when documentElement doesn't yet exist, such as inside - // document fragments. - return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" ); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return flat( ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), - function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); - } ); - -function isArrayLike( obj ) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType( obj ); - - if ( isFunction( obj ) || isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} - - -function nodeName( elem, name ) { - - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - -} -var pop = arr.pop; - - -var sort = arr.sort; - - -var splice = arr.splice; - - -var whitespace = "[\\x20\\t\\r\\n\\f]"; - - -var rtrimCSS = new RegExp( - "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", - "g" -); - - - - -// Note: an element does not contain itself -jQuery.contains = function( a, b ) { - var bup = b && b.parentNode; - - return a === bup || !!( bup && bup.nodeType === 1 && ( - - // Support: IE 9 - 11+ - // IE doesn't have `contains` on SVG. - a.contains ? - a.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - ) ); -}; - - - - -// CSS string/identifier serialization -// https://drafts.csswg.org/cssom/#common-serializing-idioms -var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; - -function fcssescape( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; -} - -jQuery.escapeSelector = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); -}; - - - - -var preferredDoc = document, - pushNative = push; - -( function() { - -var i, - Expr, - outermostContext, - sortInput, - hasDuplicate, - push = pushNative, - - // Local document vars - document, - documentElement, - documentIsHTML, - rbuggyQSA, - matches, - - // Instance-specific data - expando = jQuery.expando, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - nonnativeSelectorCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" + - "loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram - identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + - "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", - - // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + - whitespace + "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + - whitespace + "*" ), - rdescend = new RegExp( whitespace + "|>" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - ID: new RegExp( "^#(" + identifier + ")" ), - CLASS: new RegExp( "^\\.(" + identifier + ")" ), - TAG: new RegExp( "^(" + identifier + "|[*])" ), - ATTR: new RegExp( "^" + attributes ), - PSEUDO: new RegExp( "^" + pseudos ), - CHILD: new RegExp( - "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + - whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + - whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - bool: new RegExp( "^(?:" + booleans + ")$", "i" ), - - // For use in libraries implementing .is() - // We use this for POS matching in `select` - needsContext: new RegExp( "^" + whitespace + - "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + - "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + - "?|\\\\([^\\r\\n\\f])", "g" ), - funescape = function( escape, nonHex ) { - var high = "0x" + escape.slice( 1 ) - 0x10000; - - if ( nonHex ) { - - // Strip the backslash prefix from a non-hex escape sequence - return nonHex; - } - - // Replace a hexadecimal escape sequence with the encoded Unicode code point - // Support: IE <=11+ - // For values outside the Basic Multilingual Plane (BMP), manually construct a - // surrogate pair - return high < 0 ? - String.fromCharCode( high + 0x10000 ) : - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // Used for iframes; see `setDocument`. - // Support: IE 9 - 11+, Edge 12 - 18+ - // Removing the function wrapper causes a "Permission Denied" - // error in IE/Edge. - unloadHandler = function() { - setDocument(); - }, - - inDisabledFieldset = addCombinator( - function( elem ) { - return elem.disabled === true && nodeName( elem, "fieldset" ); - }, - { dir: "parentNode", next: "legend" } - ); - -// Support: IE <=9 only -// Accessing document.activeElement can throw unexpectedly -// https://bugs.jquery.com/ticket/13393 -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - ( arr = slice.call( preferredDoc.childNodes ) ), - preferredDoc.childNodes - ); - - // Support: Android <=4.0 - // Detect silently failing push.apply - // eslint-disable-next-line no-unused-expressions - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { - apply: function( target, els ) { - pushNative.apply( target, slice.call( els ) ); - }, - call: function( target ) { - pushNative.apply( target, slice.call( arguments, 1 ) ); - } - }; -} - -function find( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - setDocument( context ); - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { - - // ID selector - if ( ( m = match[ 1 ] ) ) { - - // Document context - if ( nodeType === 9 ) { - if ( ( elem = context.getElementById( m ) ) ) { - - // Support: IE 9 only - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - push.call( results, elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE 9 only - // getElementById can match elements by name instead of ID - if ( newContext && ( elem = newContext.getElementById( m ) ) && - find.contains( context, elem ) && - elem.id === m ) { - - push.call( results, elem ); - return results; - } - } - - // Type selector - } else if ( match[ 2 ] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( !nonnativeSelectorCache[ selector + " " ] && - ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) { - - newSelector = selector; - newContext = context; - - // qSA considers elements outside a scoping root when evaluating child or - // descendant combinators, which is not what we want. - // In such cases, we work around the behavior by prefixing every selector in the - // list with an ID selector referencing the scope context. - // The technique has to be used as well when a leading combinator is used - // as such selectors are not recognized by querySelectorAll. - // Thanks to Andrew Dupont for this technique. - if ( nodeType === 1 && - ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - - // We can use :scope instead of the ID hack if the browser - // supports it & if we're not changing the context. - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when - // strict-comparing two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( newContext != context || !support.scope ) { - - // Capture the context ID, setting it first if necessary - if ( ( nid = context.getAttribute( "id" ) ) ) { - nid = jQuery.escapeSelector( nid ); - } else { - context.setAttribute( "id", ( nid = expando ) ); - } - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + - toSelector( groups[ i ] ); - } - newSelector = groups.join( "," ); - } - - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - nonnativeSelectorCache( selector, true ); - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - - // All others - return select( selector.replace( rtrimCSS, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - - // Use (key + " ") to avoid collision with native prototype properties - // (see https://github.com/jquery/sizzle/issues/157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return ( cache[ key + " " ] = value ); - } - return cache; -} - -/** - * Mark a function for special use by jQuery selector module - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement( "fieldset" ); - - try { - return !!fn( el ); - } catch ( e ) { - return false; - } finally { - - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } - - // release memory in IE - el = null; - } -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - return nodeName( elem, "input" ) && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) && - elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ( "form" in elem ) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if ( elem.parentNode && elem.disabled === false ) { - - // Option elements defer to a parent optgroup if present - if ( "label" in elem ) { - if ( "label" in elem.parentNode ) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11+ - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - elem.isDisabled !== !disabled && - inDisabledFieldset( elem ) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ( "label" in elem ) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction( function( argument ) { - argument = +argument; - return markFunction( function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ ( j = matchIndexes[ i ] ) ] ) { - seed[ j ] = !( matches[ j ] = seed[ j ] ); - } - } - } ); - } ); -} - -/** - * Checks a node for validity as a jQuery selector context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [node] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -function setDocument( node ) { - var subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - documentElement = document.documentElement; - documentIsHTML = !jQuery.isXMLDoc( document ); - - // Support: iOS 7 only, IE 9 - 11+ - // Older browsers didn't support unprefixed `matches`. - matches = documentElement.matches || - documentElement.webkitMatchesSelector || - documentElement.msMatchesSelector; - - // Support: IE 9 - 11+, Edge 12 - 18+ - // Accessing iframe documents after unload throws "permission denied" errors - // (see trac-13936). - // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`, - // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well. - if ( documentElement.msMatchesSelector && - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - preferredDoc != document && - ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { - - // Support: IE 9 - 11+, Edge 12 - 18+ - subWindow.addEventListener( "unload", unloadHandler ); - } - - // Support: IE <10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert( function( el ) { - documentElement.appendChild( el ).id = jQuery.expando; - return !document.getElementsByName || - !document.getElementsByName( jQuery.expando ).length; - } ); - - // Support: IE 9 only - // Check to see if it's possible to do matchesSelector - // on a disconnected node. - support.disconnectedMatch = assert( function( el ) { - return matches.call( el, "*" ); - } ); - - // Support: IE 9 - 11+, Edge 12 - 18+ - // IE/Edge don't support the :scope pseudo-class. - support.scope = assert( function() { - return document.querySelectorAll( ":scope" ); - } ); - - // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only - // Make sure the `:has()` argument is parsed unforgivingly. - // We include `*` in the test to detect buggy implementations that are - // _selectively_ forgiving (specifically when the list includes at least - // one valid selector). - // Note that we treat complete lack of support for `:has()` as if it were - // spec-compliant support, which is fine because use of `:has()` in such - // environments will fail in the qSA path and fall back to jQuery traversal - // anyway. - support.cssHas = assert( function() { - try { - document.querySelector( ":has(*,:jqfake)" ); - return false; - } catch ( e ) { - return true; - } - } ); - - // ID filter and find - if ( support.getById ) { - Expr.filter.ID = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute( "id" ) === attrId; - }; - }; - Expr.find.ID = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var elem = context.getElementById( id ); - return elem ? [ elem ] : []; - } - }; - } else { - Expr.filter.ID = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode( "id" ); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find.ID = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var node, i, elems, - elem = context.getElementById( id ); - - if ( elem ) { - - // Verify the id attribute - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName( id ); - i = 0; - while ( ( elem = elems[ i++ ] ) ) { - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find.TAG = function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else { - return context.querySelectorAll( tag ); - } - }; - - // Class - Expr.find.CLASS = function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - rbuggyQSA = []; - - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert( function( el ) { - - var input; - - documentElement.appendChild( el ).innerHTML = - "" + - ""; - - // Support: iOS <=7 - 8 only - // Boolean attributes and "value" are not treated correctly in some XML documents - if ( !el.querySelectorAll( "[selected]" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: iOS <=7 - 8 only - if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push( "~=" ); - } - - // Support: iOS 8 only - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push( ".#.+[+~]" ); - } - - // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ - // In some of the document kinds, these selectors wouldn't work natively. - // This is probably OK but for backwards compatibility we want to maintain - // handling them through jQuery traversal in jQuery 3.x. - if ( !el.querySelectorAll( ":checked" ).length ) { - rbuggyQSA.push( ":checked" ); - } - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - input = document.createElement( "input" ); - input.setAttribute( "type", "hidden" ); - el.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE 9 - 11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ - // In some of the document kinds, these selectors wouldn't work natively. - // This is probably OK but for backwards compatibility we want to maintain - // handling them through jQuery traversal in jQuery 3.x. - documentElement.appendChild( el ).disabled = true; - if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: IE 11+, Edge 15 - 18+ - // IE 11/Edge don't find elements on a `[name='']` query in some cases. - // Adding a temporary attribute to the document before the selection works - // around the issue. - // Interestingly, IE 10 & older don't seem to have the issue. - input = document.createElement( "input" ); - input.setAttribute( "name", "" ); - el.appendChild( input ); - if ( !el.querySelectorAll( "[name='']" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + - whitespace + "*(?:''|\"\")" ); - } - } ); - - if ( !support.cssHas ) { - - // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ - // Our regular `try-catch` mechanism fails to detect natively-unsupported - // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) - // in browsers that parse the `:has()` argument as a forgiving selector list. - // https://drafts.csswg.org/selectors/#relational now requires the argument - // to be parsed unforgivingly, but browsers have not yet fully adjusted. - rbuggyQSA.push( ":has" ); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { - - // Choose the first element that is related to our preferred document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( a === document || a.ownerDocument == preferredDoc && - find.contains( preferredDoc, a ) ) { - return -1; - } - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( b === document || b.ownerDocument == preferredDoc && - find.contains( preferredDoc, b ) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - }; - - return document; -} - -find.matches = function( expr, elements ) { - return find( expr, null, null, elements ); -}; - -find.matchesSelector = function( elem, expr ) { - setDocument( elem ); - - if ( documentIsHTML && - !nonnativeSelectorCache[ expr + " " ] && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch ( e ) { - nonnativeSelectorCache( expr, true ); - } - } - - return find( expr, document, null, [ elem ] ).length > 0; -}; - -find.contains = function( context, elem ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( context.ownerDocument || context ) != document ) { - setDocument( context ); - } - return jQuery.contains( context, elem ); -}; - - -find.attr = function( elem, name ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( elem.ownerDocument || elem ) != document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - - // Don't get fooled by Object.prototype properties (see trac-13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - if ( val !== undefined ) { - return val; - } - - return elem.getAttribute( name ); -}; - -find.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -jQuery.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - // - // Support: Android <=4.0+ - // Testing for detecting duplicates is unpredictable so instead assume we can't - // depend on duplicate detection in all browsers without a stable sort. - hasDuplicate = !support.sortStable; - sortInput = !support.sortStable && slice.call( results, 0 ); - sort.call( results, sortOrder ); - - if ( hasDuplicate ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - splice.call( results, duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -jQuery.fn.uniqueSort = function() { - return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) ); -}; - -Expr = jQuery.expr = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - ATTR: function( match ) { - match[ 1 ] = match[ 1 ].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ) - .replace( runescape, funescape ); - - if ( match[ 2 ] === "~=" ) { - match[ 3 ] = " " + match[ 3 ] + " "; - } - - return match.slice( 0, 4 ); - }, - - CHILD: function( match ) { - - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[ 1 ] = match[ 1 ].toLowerCase(); - - if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { - - // nth-* requires argument - if ( !match[ 3 ] ) { - find.error( match[ 0 ] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[ 4 ] = +( match[ 4 ] ? - match[ 5 ] + ( match[ 6 ] || 1 ) : - 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) - ); - match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); - - // other types prohibit arguments - } else if ( match[ 3 ] ) { - find.error( match[ 0 ] ); - } - - return match; - }, - - PSEUDO: function( match ) { - var excess, - unquoted = !match[ 6 ] && match[ 2 ]; - - if ( matchExpr.CHILD.test( match[ 0 ] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[ 3 ] ) { - match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - - // Get excess from tokenize (recursively) - ( excess = tokenize( unquoted, true ) ) && - - // advance to the next closing parenthesis - ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { - - // excess is a negative index - match[ 0 ] = match[ 0 ].slice( 0, excess ); - match[ 2 ] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - TAG: function( nodeNameSelector ) { - var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { - return true; - } : - function( elem ) { - return nodeName( elem, expectedNodeName ); - }; - }, - - CLASS: function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - ( pattern = new RegExp( "(^|" + whitespace + ")" + className + - "(" + whitespace + "|$)" ) ) && - classCache( className, function( elem ) { - return pattern.test( - typeof elem.className === "string" && elem.className || - typeof elem.getAttribute !== "undefined" && - elem.getAttribute( "class" ) || - "" - ); - } ); - }, - - ATTR: function( name, operator, check ) { - return function( elem ) { - var result = find.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - if ( operator === "=" ) { - return result === check; - } - if ( operator === "!=" ) { - return result !== check; - } - if ( operator === "^=" ) { - return check && result.indexOf( check ) === 0; - } - if ( operator === "*=" ) { - return check && result.indexOf( check ) > -1; - } - if ( operator === "$=" ) { - return check && result.slice( -check.length ) === check; - } - if ( operator === "~=" ) { - return ( " " + result.replace( rwhitespace, " " ) + " " ) - .indexOf( check ) > -1; - } - if ( operator === "|=" ) { - return result === check || result.slice( 0, check.length + 1 ) === check + "-"; - } - - return false; - }; - }, - - CHILD: function( type, what, _argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, _context, xml ) { - var cache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( ( node = node[ dir ] ) ) { - if ( ofType ? - nodeName( node, name ) : - node.nodeType === 1 ) { - - return false; - } - } - - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - - // Seek `elem` from a previously-cached index - outerCache = parent[ expando ] || ( parent[ expando ] = {} ); - cache = outerCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( ( node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else { - - // Use previously-cached element index if available - if ( useCache ) { - outerCache = elem[ expando ] || ( elem[ expando ] = {} ); - cache = outerCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { - - // Use the same loop as above to seek `elem` from the start - while ( ( node = ++nodeIndex && node && node[ dir ] || - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - if ( ( ofType ? - nodeName( node, name ) : - node.nodeType === 1 ) && - ++diff ) { - - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || - ( node[ expando ] = {} ); - outerCache[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - PSEUDO: function( pseudo, argument ) { - - // pseudo-class names are case-insensitive - // https://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - find.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as jQuery does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction( function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf.call( seed, matched[ i ] ); - seed[ idx ] = !( matches[ idx ] = matched[ i ] ); - } - } ) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - - // Potentially complex pseudos - not: markFunction( function( selector ) { - - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrimCSS, "$1" ) ); - - return matcher[ expando ] ? - markFunction( function( seed, matches, _context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( ( elem = unmatched[ i ] ) ) { - seed[ i ] = !( matches[ i ] = elem ); - } - } - } ) : - function( elem, _context, xml ) { - input[ 0 ] = elem; - matcher( input, null, xml, results ); - - // Don't keep the element - // (see https://github.com/jquery/sizzle/issues/299) - input[ 0 ] = null; - return !results.pop(); - }; - } ), - - has: markFunction( function( selector ) { - return function( elem ) { - return find( selector, elem ).length > 0; - }; - } ), - - contains: markFunction( function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1; - }; - } ), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // https://www.w3.org/TR/selectors/#lang-pseudo - lang: markFunction( function( lang ) { - - // lang value must be a valid identifier - if ( !ridentifier.test( lang || "" ) ) { - find.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( ( elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); - return false; - }; - } ), - - // Miscellaneous - target: function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - root: function( elem ) { - return elem === documentElement; - }, - - focus: function( elem ) { - return elem === safeActiveElement() && - document.hasFocus() && - !!( elem.type || elem.href || ~elem.tabIndex ); - }, - - // Boolean properties - enabled: createDisabledPseudo( false ), - disabled: createDisabledPseudo( true ), - - checked: function( elem ) { - - // In CSS3, :checked should return both checked and selected elements - // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - return ( nodeName( elem, "input" ) && !!elem.checked ) || - ( nodeName( elem, "option" ) && !!elem.selected ); - }, - - selected: function( elem ) { - - // Support: IE <=11+ - // Accessing the selectedIndex property - // forces the browser to treat the default option as - // selected when in an optgroup. - if ( elem.parentNode ) { - // eslint-disable-next-line no-unused-expressions - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - empty: function( elem ) { - - // https://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - parent: function( elem ) { - return !Expr.pseudos.empty( elem ); - }, - - // Element/input types - header: function( elem ) { - return rheader.test( elem.nodeName ); - }, - - input: function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - button: function( elem ) { - return nodeName( elem, "input" ) && elem.type === "button" || - nodeName( elem, "button" ); - }, - - text: function( elem ) { - var attr; - return nodeName( elem, "input" ) && elem.type === "text" && - - // Support: IE <10 only - // New HTML5 attribute values (e.g., "search") appear - // with elem.type === "text" - ( ( attr = elem.getAttribute( "type" ) ) == null || - attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - first: createPositionalPseudo( function() { - return [ 0 ]; - } ), - - last: createPositionalPseudo( function( _matchIndexes, length ) { - return [ length - 1 ]; - } ), - - eq: createPositionalPseudo( function( _matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - } ), - - even: createPositionalPseudo( function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - odd: createPositionalPseudo( function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - lt: createPositionalPseudo( function( matchIndexes, length, argument ) { - var i; - - if ( argument < 0 ) { - i = argument + length; - } else if ( argument > length ) { - i = length; - } else { - i = argument; - } - - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - gt: createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ) - } -}; - -Expr.pseudos.nth = Expr.pseudos.eq; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -function tokenize( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || ( match = rcomma.exec( soFar ) ) ) { - if ( match ) { - - // Don't consume trailing commas as valid - soFar = soFar.slice( match[ 0 ].length ) || soFar; - } - groups.push( ( tokens = [] ) ); - } - - matched = false; - - // Combinators - if ( ( match = rleadingCombinator.exec( soFar ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - - // Cast descendant combinators to space - type: match[ 0 ].replace( rtrimCSS, " " ) - } ); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || - ( match = preFilters[ type ]( match ) ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - type: type, - matches: match - } ); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - if ( parseOnly ) { - return soFar.length; - } - - return soFar ? - find.error( selector ) : - - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -} - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[ i ].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; - - return combinator.first ? - - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - return false; - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || ( elem[ expando ] = {} ); - - if ( skip && nodeName( elem, skip ) ) { - elem = elem[ dir ] || elem; - } else if ( ( oldCache = outerCache[ key ] ) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return ( newCache[ 2 ] = oldCache[ 2 ] ); - } else { - - // Reuse newcache so results back-propagate to previous elements - outerCache[ key ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { - return true; - } - } - } - } - } - return false; - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[ i ]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[ 0 ]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - find( selector, contexts[ i ], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( ( elem = unmatched[ i ] ) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction( function( seed, results, context, xml ) { - var temp, i, elem, matcherOut, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || - multipleContexts( selector || "*", - context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems; - - if ( matcher ) { - - // If we have a postFinder, or filtered seed, or non-seed postFilter - // or preexisting results, - matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results; - - // Find primary matches - matcher( matcherIn, matcherOut, context, xml ); - } else { - matcherOut = matcherIn; - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( ( elem = temp[ i ] ) ) { - matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) ) { - - // Restore matcherIn since elem is not yet a final match - temp.push( ( matcherIn[ i ] = elem ) ); - } - } - postFinder( null, ( matcherOut = [] ), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) && - ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) { - - seed[ temp ] = !( results[ temp ] = elem ); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - } ); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[ 0 ].type ], - implicitRelative = leadingRelative || Expr.relative[ " " ], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf.call( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || ( - ( checkContext = context ).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - - // Avoid hanging onto element - // (see https://github.com/jquery/sizzle/issues/299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { - matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; - } else { - matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[ j ].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ) - .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) - ).replace( rtrimCSS, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find.TAG( "*", outermost ), - - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), - len = elems.length; - - if ( outermost ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - outermostContext = context == document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: iOS <=7 - 9 only - // Tolerate NodeList properties (IE: "length"; Safari: ) matching - // elements by id. (see trac-14142) - for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( !context && elem.ownerDocument != document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( ( matcher = elementMatchers[ j++ ] ) ) { - if ( matcher( elem, context || document, xml ) ) { - push.call( results, elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - - // They will have gone through all possible matchers - if ( ( elem = !matcher && elem ) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( ( matcher = setMatchers[ j++ ] ) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !( unmatched[ i ] || setMatched[ i ] ) ) { - setMatched[ i ] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - jQuery.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -function compile( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[ i ] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, - matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -} - -/** - * A low-level selection function that works with jQuery's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with jQuery selector compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -function select( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( ( selector = compiled.selector || selector ) ); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { - - // Reduce context if the leading compound selector is an ID - tokens = match[ 0 ] = match[ 0 ].slice( 0 ); - if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { - - context = ( Expr.find.ID( - token.matches[ 0 ].replace( runescape, funescape ), - context - ) || [] )[ 0 ]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[ i ]; - - // Abort if we hit a combinator - if ( Expr.relative[ ( type = token.type ) ] ) { - break; - } - if ( ( find = Expr.find[ type ] ) ) { - - // Search, expanding context for leading sibling combinators - if ( ( seed = find( - token.matches[ 0 ].replace( runescape, funescape ), - rsibling.test( tokens[ 0 ].type ) && - testContext( context.parentNode ) || context - ) ) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -} - -// One-time assignments - -// Support: Android <=4.0 - 4.1+ -// Sort stability -support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; - -// Initialize against the default document -setDocument(); - -// Support: Android <=4.0 - 4.1+ -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert( function( el ) { - - // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; -} ); - -jQuery.find = find; - -// Deprecated -jQuery.expr[ ":" ] = jQuery.expr.pseudos; -jQuery.unique = jQuery.uniqueSort; - -// These have always been private, but they used to be documented as part of -// Sizzle so let's maintain them for now for backwards compatibility purposes. -find.compile = compile; -find.select = select; -find.setDocument = setDocument; -find.tokenize = tokenize; - -find.escape = jQuery.escapeSelector; -find.getText = jQuery.text; -find.isXML = jQuery.isXMLDoc; -find.selectors = jQuery.expr; -find.support = jQuery.support; -find.uniqueSort = jQuery.uniqueSort; - - /* eslint-enable */ - -} )(); - - -var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; -}; - - -var siblings = function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; -}; - - -var rneedsContext = jQuery.expr.match.needsContext; - -var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); - - - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) !== not; - } ); - } - - // Single element - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); - } - - // Arraylike of elements (jQuery, arguments, Array) - if ( typeof qualifier !== "string" ) { - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not; - } ); - } - - // Filtered directly for both simple and complex selectors - return jQuery.filter( qualifier, elements, not ); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - if ( elems.length === 1 && elem.nodeType === 1 ) { - return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; - } - - return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); -}; - -jQuery.fn.extend( { - find: function( selector ) { - var i, ret, - len = this.length, - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } - - ret = this.pushStack( [] ); - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - return len > 1 ? jQuery.uniqueSort( ret ) : ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -} ); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (trac-9521) - // Strict HTML recognition (trac-11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { - - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - - // Properties of context are called as methods if possible - if ( isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); - - if ( elem ) { - - // Inject the element directly into the jQuery object - this[ 0 ] = elem; - this.length = 1; - } - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( isFunction( selector ) ) { - return root.ready !== undefined ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend( { - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter( function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; - } - } - } ); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery( selectors ); - - // Positional selectors never match, since there's no _selection_ context - if ( !rneedsContext.test( selectors ) ) { - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - - // Always skip document fragments - if ( cur.nodeType < 11 && ( targets ? - targets.index( cur ) > -1 : - - // Don't pass non-elements to jQuery#find - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { - - matched.push( cur ); - break; - } - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, - - // Determine the position of an element within the set - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // Index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - } -} ); - -function sibling( cur, dir ) { - while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} - return cur; -} - -jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, _i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, _i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, _i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - if ( elem.contentDocument != null && - - // Support: IE 11+ - // elements with no `data` attribute has an object - // `contentDocument` with a `null` prototype. - getProto( elem.contentDocument ) ) { - - return elem.contentDocument; - } - - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if ( nodeName( elem, "template" ) ) { - elem = elem.content || elem; - } - - return jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } - - if ( this.length > 1 ) { - - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.uniqueSort( matched ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } - - return this.pushStack( matched ); - }; -} ); -var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); - - - -// Convert String-formatted options into Object-formatted ones -function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { - object[ flag ] = true; - } ); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function() { - - // Enforce single-firing - locked = locked || options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { - - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { - - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } - - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && toType( arg ) !== "string" ) { - - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); - - if ( memory && !firing ) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = queue = []; - if ( !memory && !firing ) { - list = memory = ""; - } - return this; - }, - locked: function() { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -function Identity( v ) { - return v; -} -function Thrower( ex ) { - throw ex; -} - -function adoptValue( value, resolve, reject, noValue ) { - var method; - - try { - - // Check for promise aspect first to privilege synchronous behavior - if ( value && isFunction( ( method = value.promise ) ) ) { - method.call( value ).done( resolve ).fail( reject ); - - // Other thenables - } else if ( value && isFunction( ( method = value.then ) ) ) { - method.call( value, resolve, reject ); - - // Other non-thenables - } else { - - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply( undefined, [ value ].slice( noValue ) ); - } - - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch ( value ) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply( undefined, [ value ] ); - } -} - -jQuery.extend( { - - Deferred: function( func ) { - var tuples = [ - - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - [ "notify", "progress", jQuery.Callbacks( "memory" ), - jQuery.Callbacks( "memory" ), 2 ], - [ "resolve", "done", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 0, "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 1, "rejected" ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - "catch": function( fn ) { - return promise.then( null, fn ); - }, - - // Keep pipe for back-compat - pipe: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( _i, tuple ) { - - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; - - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - then: function( onFulfilled, onRejected, onProgress ) { - var maxDepth = 0; - function resolve( depth, deferred, handler, special ) { - return function() { - var that = this, - args = arguments, - mightThrow = function() { - var returned, then; - - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if ( depth < maxDepth ) { - return; - } - - returned = handler.apply( that, args ); - - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if ( returned === deferred.promise() ) { - throw new TypeError( "Thenable self-resolution" ); - } - - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - ( typeof returned === "object" || - typeof returned === "function" ) && - returned.then; - - // Handle a returned thenable - if ( isFunction( then ) ) { - - // Special processors (notify) just wait for resolution - if ( special ) { - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ) - ); - - // Normal processors (resolve) also hook into progress - } else { - - // ...and disregard older resolution values - maxDepth++; - - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ), - resolve( maxDepth, deferred, Identity, - deferred.notifyWith ) - ); - } - - // Handle all other returned values - } else { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Identity ) { - that = undefined; - args = [ returned ]; - } - - // Process the value(s) - // Default process is resolve - ( special || deferred.resolveWith )( that, args ); - } - }, - - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function() { - try { - mightThrow(); - } catch ( e ) { - - if ( jQuery.Deferred.exceptionHook ) { - jQuery.Deferred.exceptionHook( e, - process.error ); - } - - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if ( depth + 1 >= maxDepth ) { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Thrower ) { - that = undefined; - args = [ e ]; - } - - deferred.rejectWith( that, args ); - } - } - }; - - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if ( depth ) { - process(); - } else { - - // Call an optional hook to record the error, in case of exception - // since it's otherwise lost when execution goes async - if ( jQuery.Deferred.getErrorHook ) { - process.error = jQuery.Deferred.getErrorHook(); - - // The deprecated alias of the above. While the name suggests - // returning the stack, not an error instance, jQuery just passes - // it directly to `console.warn` so both will work; an instance - // just better cooperates with source maps. - } else if ( jQuery.Deferred.getStackHook ) { - process.error = jQuery.Deferred.getStackHook(); - } - window.setTimeout( process ); - } - }; - } - - return jQuery.Deferred( function( newDefer ) { - - // progress_handlers.add( ... ) - tuples[ 0 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onProgress ) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); - - // fulfilled_handlers.add( ... ) - tuples[ 1 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onFulfilled ) ? - onFulfilled : - Identity - ) - ); - - // rejected_handlers.add( ... ) - tuples[ 2 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onRejected ) ? - onRejected : - Thrower - ) - ); - } ).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 5 ]; - - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[ tuple[ 1 ] ] = list.add; - - // Handle state - if ( stateString ) { - list.add( - function() { - - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, - - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[ 3 - i ][ 2 ].disable, - - // rejected_handlers.disable - // fulfilled_handlers.disable - tuples[ 3 - i ][ 3 ].disable, - - // progress_callbacks.lock - tuples[ 0 ][ 2 ].lock, - - // progress_handlers.lock - tuples[ 0 ][ 3 ].lock - ); - } - - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add( tuple[ 3 ].fire ); - - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); - return this; - }; - - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( singleValue ) { - var - - // count of uncompleted subordinates - remaining = arguments.length, - - // count of unprocessed arguments - i = remaining, - - // subordinate fulfillment data - resolveContexts = Array( i ), - resolveValues = slice.call( arguments ), - - // the primary Deferred - primary = jQuery.Deferred(), - - // subordinate callback factory - updateFunc = function( i ) { - return function( value ) { - resolveContexts[ i ] = this; - resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( !( --remaining ) ) { - primary.resolveWith( resolveContexts, resolveValues ); - } - }; - }; - - // Single- and empty arguments are adopted like Promise.resolve - if ( remaining <= 1 ) { - adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, - !remaining ); - - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if ( primary.state() === "pending" || - isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { - - return primary.then(); - } - } - - // Multiple arguments are aggregated like Promise.all array elements - while ( i-- ) { - adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); - } - - return primary.promise(); - } -} ); - - -// These usually indicate a programmer mistake during development, -// warn about them ASAP rather than swallowing them by default. -var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - -// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error -// captured before the async barrier to get the original error cause -// which may otherwise be hidden. -jQuery.Deferred.exceptionHook = function( error, asyncError ) { - - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { - window.console.warn( "jQuery.Deferred exception: " + error.message, - error.stack, asyncError ); - } -}; - - - - -jQuery.readyException = function( error ) { - window.setTimeout( function() { - throw error; - } ); -}; - - - - -// The deferred used on DOM ready -var readyList = jQuery.Deferred(); - -jQuery.fn.ready = function( fn ) { - - readyList - .then( fn ) - - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch( function( error ) { - jQuery.readyException( error ); - } ); - - return this; -}; - -jQuery.extend( { - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See trac-6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - } -} ); - -jQuery.ready.then = readyList.then; - -// The ready event handler and self cleanup method -function completed() { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - jQuery.ready(); -} - -// Catch cases where $(document).ready() is called -// after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); - -} else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); -} - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( toType( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, _key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( - elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } - - if ( chainable ) { - return elems; - } - - // Gets - if ( bulk ) { - return fn.call( elems ); - } - - return len ? fn( elems[ 0 ], key ) : emptyGet; -}; - - -// Matches dashed string for camelizing -var rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g; - -// Used by camelCase as callback to replace() -function fcamelCase( _all, letter ) { - return letter.toUpperCase(); -} - -// Convert dashed to camelCase; used by the css and data modules -// Support: IE <=9 - 11, Edge 12 - 15 -// Microsoft forgot to hump their vendor prefix (trac-9572) -function camelCase( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); -} -var acceptData = function( owner ) { - - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - - - -function Data() { - this.expando = jQuery.expando + Data.uid++; -} - -Data.uid = 1; - -Data.prototype = { - - cache: function( owner ) { - - // Check if the owner object already has a cache - var value = owner[ this.expando ]; - - // If not, create one - if ( !value ) { - value = {}; - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see trac-8335. - // Always return an empty object. - if ( acceptData( owner ) ) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty( owner, this.expando, { - value: value, - configurable: true - } ); - } - } - } - - return value; - }, - set: function( owner, data, value ) { - var prop, - cache = this.cache( owner ); - - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if ( typeof data === "string" ) { - cache[ camelCase( data ) ] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for ( prop in data ) { - cache[ camelCase( prop ) ] = data[ prop ]; - } - } - return cache; - }, - get: function( owner, key ) { - return key === undefined ? - this.cache( owner ) : - - // Always use camelCase key (gh-2257) - owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; - }, - access: function( owner, key, value ) { - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ( ( key && typeof key === "string" ) && value === undefined ) ) { - - return this.get( owner, key ); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, - cache = owner[ this.expando ]; - - if ( cache === undefined ) { - return; - } - - if ( key !== undefined ) { - - // Support array or space separated string of keys - if ( Array.isArray( key ) ) { - - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map( camelCase ); - } else { - key = camelCase( key ); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [ key ] : - ( key.match( rnothtmlwhite ) || [] ); - } - - i = key.length; - - while ( i-- ) { - delete cache[ key[ i ] ]; - } - } - - // Remove the expando if there's no more data - if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if ( owner.nodeType ) { - owner[ this.expando ] = undefined; - } else { - delete owner[ this.expando ]; - } - } - }, - hasData: function( owner ) { - var cache = owner[ this.expando ]; - return cache !== undefined && !jQuery.isEmptyObject( cache ); - } -}; -var dataPriv = new Data(); - -var dataUser = new Data(); - - - -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; - -function getData( data ) { - if ( data === "true" ) { - return true; - } - - if ( data === "false" ) { - return false; - } - - if ( data === "null" ) { - return null; - } - - // Only convert to a number if it doesn't change the string - if ( data === +data + "" ) { - return +data; - } - - if ( rbrace.test( data ) ) { - return JSON.parse( data ); - } - - return data; -} - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = getData( data ); - } catch ( e ) {} - - // Make sure we set the data so it isn't changed later - dataUser.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend( { - hasData: function( elem ) { - return dataUser.hasData( elem ) || dataPriv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return dataUser.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - dataUser.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function( elem, name, data ) { - return dataPriv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - dataPriv.remove( elem, name ); - } -} ); - -jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = dataUser.get( elem ); - - if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE 11 only - // The attrs elements can be null (trac-14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - dataPriv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - dataUser.set( this, key ); - } ); - } - - return access( this, function( value ) { - var data; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, key ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each( function() { - - // We always store the camelCased key - dataUser.set( this, key, value ); - } ); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each( function() { - dataUser.remove( this, key ); - } ); - } -} ); - - -jQuery.extend( { - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = dataPriv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || Array.isArray( data ) ) { - queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - dataPriv.remove( elem, [ type + "queue", key ] ); - } ) - } ); - } -} ); - -jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); - } - - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); - - // Ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -} ); -var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; - -var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); - - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var documentElement = document.documentElement; - - - - var isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ); - }, - composed = { composed: true }; - - // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only - // Check attachment across shadow DOM boundaries when possible (gh-3504) - // Support: iOS 10.0-10.2 only - // Early iOS 10 versions support `attachShadow` but not `getRootNode`, - // leading to errors. We need to check for `getRootNode`. - if ( documentElement.getRootNode ) { - isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ) || - elem.getRootNode( composed ) === elem.ownerDocument; - }; - } -var isHiddenWithinTree = function( elem, el ) { - - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && - - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - isAttached( elem ) && - - jQuery.css( elem, "display" ) === "none"; - }; - - - -function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, scale, - maxIterations = 20, - currentValue = tween ? - function() { - return tween.cur(); - } : - function() { - return jQuery.css( elem, prop, "" ); - }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - initialInUnit = elem.nodeType && - ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); - - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - - // Support: Firefox <=54 - // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) - initial = initial / 2; - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - while ( maxIterations-- ) { - - // Evaluate and update our best guess (doubling guesses that zero out). - // Finish if the scale equals or crosses 1 (making the old*new product non-positive). - jQuery.style( elem, prop, initialInUnit + unit ); - if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { - maxIterations = 0; - } - initialInUnit = initialInUnit / scale; - - } - - initialInUnit = initialInUnit * 2; - jQuery.style( elem, prop, initialInUnit + unit ); - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - } - - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; -} - - -var defaultDisplayMap = {}; - -function getDefaultDisplay( elem ) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[ nodeName ]; - - if ( display ) { - return display; - } - - temp = doc.body.appendChild( doc.createElement( nodeName ) ); - display = jQuery.css( temp, "display" ); - - temp.parentNode.removeChild( temp ); - - if ( display === "none" ) { - display = "block"; - } - defaultDisplayMap[ nodeName ] = display; - - return display; -} - -function showHide( elements, show ) { - var display, elem, - values = [], - index = 0, - length = elements.length; - - // Determine new display value for elements that need to change - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - - display = elem.style.display; - if ( show ) { - - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if ( display === "none" ) { - values[ index ] = dataPriv.get( elem, "display" ) || null; - if ( !values[ index ] ) { - elem.style.display = ""; - } - } - if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { - values[ index ] = getDefaultDisplay( elem ); - } - } else { - if ( display !== "none" ) { - values[ index ] = "none"; - - // Remember what we're overwriting - dataPriv.set( elem, "display", display ); - } - } - } - - // Set the display of the elements in a second loop to avoid constant reflow - for ( index = 0; index < length; index++ ) { - if ( values[ index ] != null ) { - elements[ index ].style.display = values[ index ]; - } - } - - return elements; -} - -jQuery.fn.extend( { - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each( function() { - if ( isHiddenWithinTree( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - } ); - } -} ); -var rcheckableType = ( /^(?:checkbox|radio)$/i ); - -var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); - -var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); - - - -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (trac-11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (trac-14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // Support: IE <=9 only - // IE <=9 replaces "; - support.option = !!div.lastChild; -} )(); - - -// We have to close these tags to support XHTML (trac-13200) -var wrapMap = { - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
" ], - col: [ 2, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - _default: [ 0, "", "" ] -}; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: IE <=9 only -if ( !support.option ) { - wrapMap.optgroup = wrapMap.option = [ 1, "" ]; -} - - -function getAll( context, tag ) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) - var ret; - - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); - - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); - - } else { - ret = []; - } - - if ( tag === undefined || tag && nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, attached, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( toType( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (trac-12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - attached = isAttached( elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( attached ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; -} - - -var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Only attach events to objects that accept data - if ( !acceptData( elem ) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = Object.create( null ); - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( nativeEvent ) { - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( nativeEvent ), - - handlers = ( - dataPriv.get( this, "events" ) || Object.create( null ) - )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // If the event is namespaced, then each handler is only invoked if it is - // specially universal or its namespaces are a superset of the event's. - if ( !event.rnamespace || handleObj.namespace === false || - event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if ( delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (trac-13208) - // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (trac-13203) - sel = handleObj.selector + " "; - - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; - } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - click: { - - // Utilize native event to ensure correct state for checkable inputs - setup: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Claim the first handler - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - // dataPriv.set( el, "click", ... ) - leverageNative( el, "click", true ); - } - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Force setup before triggering a click - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - leverageNative( el, "click" ); - } - - // Return non-false to allow normal event-path propagation - return true; - }, - - // For cross-browser consistency, suppress native .click() on links - // Also prevent it if we're currently inside a leveraged native-event stack - _default: function( event ) { - var target = event.target; - return rcheckableType.test( target.type ) && - target.click && nodeName( target, "input" ) && - dataPriv.get( target, "click" ) || - nodeName( target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -// Ensure the presence of an event listener that handles manually-triggered -// synthetic events by interrupting progress until reinvoked in response to -// *native* events that it fires directly, ensuring that state changes have -// already occurred before other listeners are invoked. -function leverageNative( el, type, isSetup ) { - - // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add - if ( !isSetup ) { - if ( dataPriv.get( el, type ) === undefined ) { - jQuery.event.add( el, type, returnTrue ); - } - return; - } - - // Register the controller as a special universal handler for all event namespaces - dataPriv.set( el, type, false ); - jQuery.event.add( el, type, { - namespace: false, - handler: function( event ) { - var result, - saved = dataPriv.get( this, type ); - - if ( ( event.isTrigger & 1 ) && this[ type ] ) { - - // Interrupt processing of the outer synthetic .trigger()ed event - if ( !saved ) { - - // Store arguments for use when handling the inner native event - // There will always be at least one argument (an event object), so this array - // will not be confused with a leftover capture object. - saved = slice.call( arguments ); - dataPriv.set( this, type, saved ); - - // Trigger the native event and capture its result - this[ type ](); - result = dataPriv.get( this, type ); - dataPriv.set( this, type, false ); - - if ( saved !== result ) { - - // Cancel the outer synthetic event - event.stopImmediatePropagation(); - event.preventDefault(); - - return result; - } - - // If this is an inner synthetic event for an event with a bubbling surrogate - // (focus or blur), assume that the surrogate already propagated from triggering - // the native event and prevent that from happening again here. - // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the - // bubbling surrogate propagates *after* the non-bubbling base), but that seems - // less bad than duplication. - } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { - event.stopPropagation(); - } - - // If this is a native event triggered above, everything is now in order - // Fire an inner synthetic event with the original arguments - } else if ( saved ) { - - // ...and capture the result - dataPriv.set( this, type, jQuery.event.trigger( - saved[ 0 ], - saved.slice( 1 ), - this - ) ); - - // Abort handling of the native event by all jQuery handlers while allowing - // native handlers on the same element to run. On target, this is achieved - // by stopping immediate propagation just on the jQuery event. However, - // the native event is re-wrapped by a jQuery one on each level of the - // propagation so the only way to stop it for jQuery is to stop it for - // everyone via native `stopPropagation()`. This is not a problem for - // focus/blur which don't bubble, but it does also stop click on checkboxes - // and radios. We accept this limitation. - event.stopPropagation(); - event.isImmediatePropagationStopped = returnTrue; - } - } - } ); -} - -jQuery.removeEvent = function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (trac-504, trac-13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - code: true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - which: true -}, jQuery.event.addProp ); - -jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { - - function focusMappedHandler( nativeEvent ) { - if ( document.documentMode ) { - - // Support: IE 11+ - // Attach a single focusin/focusout handler on the document while someone wants - // focus/blur. This is because the former are synchronous in IE while the latter - // are async. In other browsers, all those handlers are invoked synchronously. - - // `handle` from private data would already wrap the event, but we need - // to change the `type` here. - var handle = dataPriv.get( this, "handle" ), - event = jQuery.event.fix( nativeEvent ); - event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; - event.isSimulated = true; - - // First, handle focusin/focusout - handle( nativeEvent ); - - // ...then, handle focus/blur - // - // focus/blur don't bubble while focusin/focusout do; simulate the former by only - // invoking the handler at the lower level. - if ( event.target === event.currentTarget ) { - - // The setup part calls `leverageNative`, which, in turn, calls - // `jQuery.event.add`, so event handle will already have been set - // by this point. - handle( event ); - } - } else { - - // For non-IE browsers, attach a single capturing handler on the document - // while someone wants focusin/focusout. - jQuery.event.simulate( delegateType, nativeEvent.target, - jQuery.event.fix( nativeEvent ) ); - } - } - - jQuery.event.special[ type ] = { - - // Utilize native event if possible so blur/focus sequence is correct - setup: function() { - - var attaches; - - // Claim the first handler - // dataPriv.set( this, "focus", ... ) - // dataPriv.set( this, "blur", ... ) - leverageNative( this, type, true ); - - if ( document.documentMode ) { - - // Support: IE 9 - 11+ - // We use the same native handler for focusin & focus (and focusout & blur) - // so we need to coordinate setup & teardown parts between those events. - // Use `delegateType` as the key as `type` is already used by `leverageNative`. - attaches = dataPriv.get( this, delegateType ); - if ( !attaches ) { - this.addEventListener( delegateType, focusMappedHandler ); - } - dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 ); - } else { - - // Return false to allow normal processing in the caller - return false; - } - }, - trigger: function() { - - // Force setup before trigger - leverageNative( this, type ); - - // Return non-false to allow normal event-path propagation - return true; - }, - - teardown: function() { - var attaches; - - if ( document.documentMode ) { - attaches = dataPriv.get( this, delegateType ) - 1; - if ( !attaches ) { - this.removeEventListener( delegateType, focusMappedHandler ); - dataPriv.remove( this, delegateType ); - } else { - dataPriv.set( this, delegateType, attaches ); - } - } else { - - // Return false to indicate standard teardown should be applied - return false; - } - }, - - // Suppress native focus or blur if we're currently inside - // a leveraged native-event stack - _default: function( event ) { - return dataPriv.get( event.target, type ); - }, - - delegateType: delegateType - }; - - // Support: Firefox <=44 - // Firefox doesn't have focus(in | out) events - // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 - // - // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 - // focus(in | out) events fire after focus & blur events, - // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order - // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 - // - // Support: IE 9 - 11+ - // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch, - // attach a single handler for both events in IE. - jQuery.event.special[ delegateType ] = { - setup: function() { - - // Handle: regular nodes (via `this.ownerDocument`), window - // (via `this.document`) & document (via `this`). - var doc = this.ownerDocument || this.document || this, - dataHolder = document.documentMode ? this : doc, - attaches = dataPriv.get( dataHolder, delegateType ); - - // Support: IE 9 - 11+ - // We use the same native handler for focusin & focus (and focusout & blur) - // so we need to coordinate setup & teardown parts between those events. - // Use `delegateType` as the key as `type` is already used by `leverageNative`. - if ( !attaches ) { - if ( document.documentMode ) { - this.addEventListener( delegateType, focusMappedHandler ); - } else { - doc.addEventListener( type, focusMappedHandler, true ); - } - } - dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this.document || this, - dataHolder = document.documentMode ? this : doc, - attaches = dataPriv.get( dataHolder, delegateType ) - 1; - - if ( !attaches ) { - if ( document.documentMode ) { - this.removeEventListener( delegateType, focusMappedHandler ); - } else { - doc.removeEventListener( type, focusMappedHandler, true ); - } - dataPriv.remove( dataHolder, delegateType ); - } else { - dataPriv.set( dataHolder, delegateType, attaches ); - } - } - }; -} ); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } -} ); - - -var - - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget( elem, content ) { - if ( nodeName( elem, "table" ) && - nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - - return jQuery( elem ).children( "tbody" )[ 0 ] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { - elem.type = elem.type.slice( 5 ); - } else { - elem.removeAttribute( "type" ); - } - - return elem; -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.get( src ); - events = pdataOld.events; - - if ( events ) { - dataPriv.remove( dest, "handle events" ); - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } -} - -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = flat( args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - valueIsFunction = isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( valueIsFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( valueIsFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (trac-8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Re-enable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl && !node.noModule ) { - jQuery._evalUrl( node.src, { - nonce: node.nonce || node.getAttribute( "nonce" ) - }, doc ); - } - } else { - - // Unwrap a CDATA section containing script contents. This shouldn't be - // needed as in XML documents they're already not visible when - // inspecting element contents and in HTML documents they have no - // meaning but we're preserving that logic for backwards compatibility. - // This will be removed completely in 4.0. See gh-4904. - DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); - } - } - } - } - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && isAttached( node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html; - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = isAttached( elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew jQuery#find here for performance reasons: - // https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } -} ); - -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); - -var rcustomProp = /^--/; - - -var getStyles = function( elem ) { - - // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if ( !view || !view.opener ) { - view = window; - } - - return view.getComputedStyle( elem ); - }; - -var swap = function( elem, options, callback ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.call( elem ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - -var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); - - - -( function() { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if ( !div ) { - return; - } - - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild( container ).appendChild( div ); - - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; - - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - // Support: Chrome <=64 - // Don't get tricked when zoom affects offsetWidth (gh-4029) - div.style.position = "absolute"; - scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; - - documentElement.removeChild( container ); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - function roundPixelMeasures( measure ) { - return Math.round( parseFloat( measure ) ); - } - - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableTrDimensionsVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (trac-8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - jQuery.extend( support, { - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function() { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function() { - computeStyleTests(); - return scrollboxSizeVal; - }, - - // Support: IE 9 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Behavior in IE 9 is more subtle than in newer versions & it passes - // some versions of this test; make sure not to make it pass there! - // - // Support: Firefox 70+ - // Only Firefox includes border widths - // in computed dimensions. (gh-4529) - reliableTrDimensions: function() { - var table, tr, trChild, trStyle; - if ( reliableTrDimensionsVal == null ) { - table = document.createElement( "table" ); - tr = document.createElement( "tr" ); - trChild = document.createElement( "div" ); - - table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; - tr.style.cssText = "box-sizing:content-box;border:1px solid"; - - // Support: Chrome 86+ - // Height set through cssText does not get applied. - // Computed height then comes back as 0. - tr.style.height = "1px"; - trChild.style.height = "9px"; - - // Support: Android 8 Chrome 86+ - // In our bodyBackground.html iframe, - // display for all div elements is set to "inline", - // which causes a problem only in Android 8 Chrome 86. - // Ensuring the div is `display: block` - // gets around this issue. - trChild.style.display = "block"; - - documentElement - .appendChild( table ) - .appendChild( tr ) - .appendChild( trChild ); - - trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + - parseInt( trStyle.borderTopWidth, 10 ) + - parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; - - documentElement.removeChild( table ); - } - return reliableTrDimensionsVal; - } - } ); -} )(); - - -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, - isCustomProp = rcustomProp.test( name ), - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles( elem ); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, trac-12537) - // .css('--customProperty) (gh-3144) - if ( computed ) { - - // Support: IE <=9 - 11+ - // IE only supports `"float"` in `getPropertyValue`; in computed styles - // it's only available as `"cssFloat"`. We no longer modify properties - // sent to `.css()` apart from camelCasing, so we need to check both. - // Normally, this would create difference in behavior: if - // `getPropertyValue` returns an empty string, the value returned - // by `.css()` would be `undefined`. This is usually the case for - // disconnected elements. However, in IE even disconnected elements - // with no styles return `"none"` for `getPropertyValue( "float" )` - ret = computed.getPropertyValue( name ) || computed[ name ]; - - if ( isCustomProp && ret ) { - - // Support: Firefox 105+, Chrome <=105+ - // Spec requires trimming whitespace for custom properties (gh-4926). - // Firefox only trims leading whitespace. Chrome just collapses - // both leading & trailing whitespace to a single space. - // - // Fall back to `undefined` if empty string returned. - // This collapses a missing definition with property defined - // and set to an empty string but there's no standard API - // allowing us to differentiate them without a performance penalty - // and returning `undefined` aligns with older jQuery. - // - // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED - // as whitespace while CSS does not, but this is not a problem - // because CSS preprocessing replaces them with U+000A LINE FEED - // (which *is* CSS whitespace) - // https://www.w3.org/TR/css-syntax-3/#input-preprocessing - ret = ret.replace( rtrimCSS, "$1" ) || undefined; - } - - if ( ret === "" && !isAttached( elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf( conditionFn, hookFn ) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - - -var cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style, - vendorProps = {}; - -// Return a vendor-prefixed property or undefined -function vendorPropName( name ) { - - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} - -// Return a potentially-mapped jQuery.cssProps or vendor prefixed property -function finalPropName( name ) { - var final = jQuery.cssProps[ name ] || vendorProps[ name ]; - - if ( final ) { - return final; - } - if ( name in emptyStyle ) { - return name; - } - return vendorProps[ name ] = vendorPropName( name ) || name; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }; - -function setPositiveNumber( _elem, value, subtract ) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} - -function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0, - marginDelta = 0; - - // Adjustment may not be necessary - if ( box === ( isBorderBox ? "border" : "content" ) ) { - return 0; - } - - for ( ; i < 4; i += 2 ) { - - // Both box models exclude margin - // Count margin delta separately to only add it after scroll gutter adjustment. - // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). - if ( box === "margin" ) { - marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); - } - - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if ( !isBorderBox ) { - - // Add padding - delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // For "border" or "margin", add border - if ( box !== "padding" ) { - delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - - // But still keep track of it otherwise - } else { - extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { - - // For "content", subtract padding - if ( box === "content" ) { - delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // For "content" or "padding", subtract border - if ( box !== "margin" ) { - delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - // Account for positive content-box scroll gutter when requested by providing computedVal - if ( !isBorderBox && computedVal >= 0 ) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max( 0, Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - computedVal - - delta - - extra - - 0.5 - - // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter - // Use an explicit zero to avoid NaN (gh-3964) - ) ) || 0; - } - - return delta + marginDelta; -} - -function getWidthOrHeight( elem, dimension, extra ) { - - // Start with computed style - var styles = getStyles( elem ), - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). - // Fake content-box until we know it's needed to know the true value. - boxSizingNeeded = !support.boxSizingReliable() || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - valueIsBorderBox = isBorderBox, - - val = curCSS( elem, dimension, styles ), - offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); - - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if ( rnumnonpx.test( val ) ) { - if ( !extra ) { - return val; - } - val = "auto"; - } - - - // Support: IE 9 - 11 only - // Use offsetWidth/offsetHeight for when box sizing is unreliable. - // In those cases, the computed value can be trusted to be border-box. - if ( ( !support.boxSizingReliable() && isBorderBox || - - // Support: IE 10 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Interestingly, in some cases IE 9 doesn't suffer from this issue. - !support.reliableTrDimensions() && nodeName( elem, "tr" ) || - - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - val === "auto" || - - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && - - // Make sure the element is visible & connected - elem.getClientRects().length ) { - - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // Where available, offsetWidth/offsetHeight approximate border box dimensions. - // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the - // retrieved value as a content box dimension. - valueIsBorderBox = offsetProp in elem; - if ( valueIsBorderBox ) { - val = elem[ offsetProp ]; - } - } - - // Normalize "" and auto - val = parseFloat( val ) || 0; - - // Adjust for the element's box model - return ( val + - boxModelAdjustment( - elem, - dimension, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles, - - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; -} - -jQuery.extend( { - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - animationIterationCount: true, - aspectRatio: true, - borderImageSlice: true, - columnCount: true, - flexGrow: true, - flexShrink: true, - fontWeight: true, - gridArea: true, - gridColumn: true, - gridColumnEnd: true, - gridColumnStart: true, - gridRow: true, - gridRowEnd: true, - gridRowStart: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - scale: true, - widows: true, - zIndex: true, - zoom: true, - - // SVG-related - fillOpacity: true, - floodOpacity: true, - stopOpacity: true, - strokeMiterlimit: true, - strokeOpacity: true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (trac-7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); - - // Fixes bug trac-9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (trac-7116) - if ( value == null || value !== value ) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append - // "px" to a few hardcoded values. - if ( type === "number" && !isCustomProp ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } - - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - - if ( isCustomProp ) { - style.setProperty( name, value ); - } else { - style[ name ] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[ name ]; - } - }, - - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - - return val; - } -} ); - -jQuery.each( [ "height", "width" ], function( _i, dimension ) { - jQuery.cssHooks[ dimension ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, dimension, extra ); - } ) : - getWidthOrHeight( elem, dimension, extra ); - } - }, - - set: function( elem, value, extra ) { - var matches, - styles = getStyles( elem ), - - // Only read styles.position if the test has a chance to fail - // to avoid forcing a reflow. - scrollboxSizeBuggy = !support.scrollboxSize() && - styles.position === "absolute", - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) - boxSizingNeeded = scrollboxSizeBuggy || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - subtract = extra ? - boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ) : - 0; - - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if ( isBorderBox && scrollboxSizeBuggy ) { - subtract -= Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - parseFloat( styles[ dimension ] ) - - boxModelAdjustment( elem, dimension, "border", false, styles ) - - 0.5 - ); - } - - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { - - elem.style[ dimension ] = value; - value = jQuery.css( elem, dimension ); - } - - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); - -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( prefix !== "margin" ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -} ); - -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; - - if ( Array.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - } -} ); - - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } - - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); - - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && ( - jQuery.cssHooks[ tween.prop ] || - tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; - -jQuery.fx = Tween.prototype.init; - -// Back compat <1.8 extension point -jQuery.fx.step = {}; - - - - -var - fxNow, inProgress, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; - -function schedule() { - if ( inProgress ) { - if ( document.hidden === false && window.requestAnimationFrame ) { - window.requestAnimationFrame( schedule ); - } else { - window.setTimeout( schedule, jQuery.fx.interval ); - } - - jQuery.fx.tick(); - } -} - -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = Date.now() ); -} - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; - - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - - // We're done with this property - return tween; - } - } -} - -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); - - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always( function() { - - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); - } - - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; - - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } - - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { - - // Support: IE <=9 - 11, Edge 12 - 15 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY and Edge just mirrors - // the overflowX value there. - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); - } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } - } - - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { - - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } - - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { - - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } - - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; - } - - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } - - /* eslint-disable no-loop-func */ - - anim.done( function() { - - /* eslint-enable no-loop-func */ - - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - } ); - } - - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; - } - } - } -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( Array.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { - - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ] ); - - // If there's more to do, yield - if ( percent < 1 && length ) { - return remaining; - } - - // If this was an empty animation, synthesize a final progress notification - if ( !length ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - } - - // Resolve the animation and report its conclusion - deferred.resolveWith( elem, [ animation ] ); - return false; - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - result.stop.bind( result ); - } - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - // Attach callbacks from options - animation - .progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); - - return animation; -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, - - tweener: function( props, callback ) { - if ( isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, - - prefilters: [ defaultPrefilter ], - - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); - -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !isFunction( easing ) && easing - }; - - // Go to the end state if fx are off - if ( jQuery.fx.off ) { - opt.duration = 0; - - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; - - } else { - opt.duration = jQuery.fx.speeds._default; - } - } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { - - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue ) { - this.queue( type || "fx", [] ); - } - - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { - - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - } ); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // Enable finishing flag on private data - data.finish = true; - - // Empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // Turn off finishing flag - delete data.finish; - } ); - } -} ); - -jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); - -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); - -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; - - fxNow = Date.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - - // Run the timer and safely remove it when done (allowing for external removal) - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - jQuery.fx.start(); -}; - -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( inProgress ) { - return; - } - - inProgress = true; - schedule(); -}; - -jQuery.fx.stop = function() { - inProgress = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - - // Default speed - _default: 400 -}; - - -// Based off of the plugin by Clint Helfers, with permission. -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; - - -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); - } -} ); - -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } - - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } - - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - elem.setAttribute( name, value + "" ); - return value; - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } - } - } -} ); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); - } - return name; - } -}; - -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; - - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if ( !isXML ) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); - - - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); - -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - return ( elem[ name ] = value ); - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - return elem[ name ]; - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // Use proper attribute retrieval (trac-12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - if ( tabindex ) { - return parseInt( tabindex, 10 ); - } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -} ); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -} ); - - - - - // Strip and collapse whitespace according to HTML spec - // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace - function stripAndCollapse( value ) { - var tokens = value.match( rnothtmlwhite ) || []; - return tokens.join( " " ); - } - - -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} - -function classesToArray( value ) { - if ( Array.isArray( value ) ) { - return value; - } - if ( typeof value === "string" ) { - return value.match( rnothtmlwhite ) || []; - } - return []; -} - -jQuery.fn.extend( { - addClass: function( value ) { - var classNames, cur, curValue, className, i, finalValue; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - classNames = classesToArray( value ); - - if ( classNames.length ) { - return this.each( function() { - curValue = getClass( this ); - cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - for ( i = 0; i < classNames.length; i++ ) { - className = classNames[ i ]; - if ( cur.indexOf( " " + className + " " ) < 0 ) { - cur += className + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - this.setAttribute( "class", finalValue ); - } - } - } ); - } - - return this; - }, - - removeClass: function( value ) { - var classNames, cur, curValue, className, i, finalValue; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( !arguments.length ) { - return this.attr( "class", "" ); - } - - classNames = classesToArray( value ); - - if ( classNames.length ) { - return this.each( function() { - curValue = getClass( this ); - - // This expression is here for better compressibility (see addClass) - cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - for ( i = 0; i < classNames.length; i++ ) { - className = classNames[ i ]; - - // Remove *all* instances - while ( cur.indexOf( " " + className + " " ) > -1 ) { - cur = cur.replace( " " + className + " ", " " ); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - this.setAttribute( "class", finalValue ); - } - } - } ); - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var classNames, className, i, self, - type = typeof value, - isValidValue = type === "string" || Array.isArray( value ); - - if ( isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } - - if ( typeof stateVal === "boolean" && isValidValue ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - classNames = classesToArray( value ); - - return this.each( function() { - if ( isValidValue ) { - - // Toggle individual class names - self = jQuery( this ); - - for ( i = 0; i < classNames.length; i++ ) { - className = classNames[ i ]; - - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { - - // Store className if set - dataPriv.set( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); - } - } - } ); - }, - - hasClass: function( selector ) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } - } - - return false; - } -} ); - - - - -var rreturn = /\r/g; - -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, valueIsFunction, - elem = this[ 0 ]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - valueIsFunction = isFunction( value ); - - return this.each( function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( valueIsFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - - } else if ( typeof val === "number" ) { - val += ""; - - } else if ( Array.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; - } ); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - } ); - } -} ); - -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { - - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (trac-14686, trac-14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); - } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if ( index < 0 ) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (trac-2551) - if ( ( option.selected || i === index ) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - - /* eslint-disable no-cond-assign */ - - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - } -} ); - -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( Array.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } - } - }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } -} ); - - - - -// Return jQuery for attributes-only inclusion -var location = window.location; - -var nonce = { guid: Date.now() }; - -var rquery = ( /\?/ ); - - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml, parserErrorElem; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) {} - - parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; - if ( !xml || parserErrorElem ) { - jQuery.error( "Invalid XML: " + ( - parserErrorElem ? - jQuery.map( parserErrorElem.childNodes, function( el ) { - return el.textContent; - } ).join( "\n" ) : - data - ) ); - } - return xml; -}; - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function( e ) { - e.stopPropagation(); - }; - -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = lastElement = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (trac-9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) - if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (trac-6170) - if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - - if ( event.isPropagationStopped() ) { - lastElement.addEventListener( type, stopPropagationCallback ); - } - - elem[ type ](); - - if ( event.isPropagationStopped() ) { - lastElement.removeEventListener( type, stopPropagationCallback ); - } - - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger( e, null, elem ); - } - -} ); - -jQuery.fn.extend( { - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( Array.isArray( obj ) ) { - - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); - - } else if ( !traditional && toType( obj ) === "object" ) { - - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - - // If value is a function, invoke it and use its return value - var value = isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; - - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; - - if ( a == null ) { - return ""; - } - - // If an array was passed in, assume that it is an array of form elements. - if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ); -}; - -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ).filter( function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ).map( function( _i, elem ) { - var val = jQuery( this ).val(); - - if ( val == null ) { - return null; - } - - if ( Array.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); - } - - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); - } -} ); - - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - - // trac-7653, trac-8125, trac-8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), - - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - -originAnchor.href = location.href; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - - if ( isFunction( func ) ) { - - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { - - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); - - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes trac-9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend( { - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": JSON.parse, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, - - // timeout handle - timeoutTimer, - - // Url cleanup var - urlAnchor, - - // Request state (becomes false upon send and true upon completion) - completed, - - // To know if global events are to be dispatched - fireGlobals, - - // Loop variable - i, - - // uncached part of the url - uncached, - - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - - // Callbacks context - callbackContext = s.context || s, - - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), - - // Status-dependent callbacks - statusCode = s.statusCode || {}, - - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - - // Default abort message - strAbort = "canceled", - - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() + " " ] = - ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) - .concat( match[ 2 ] ); - } - } - match = responseHeaders[ key.toLowerCase() + " " ]; - } - return match == null ? null : match.join( ", " ); - }, - - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { - - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { - - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ); - - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (trac-10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - - // Alias method option to type as per ticket trac-12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; - - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); - - // Support: IE <=8 - 11, Edge 12 - 15 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; - - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { - - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118) - fireGlobals = jQuery.event && s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); - - // If data is available and should be processed, append data to url - if ( s.data && ( s.processData || typeof s.data === "string" ) ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; - - // trac-9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + - uncached; - } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } - - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); - } - - // Aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; - } - - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { - - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } - - // Propagate others as results - done( -1, e ); - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Ignore repeat invocations - if ( completed ) { - return; - } - - completed = true; - - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Use a noop converter for missing script but not if jsonp - if ( !isSuccess && - jQuery.inArray( "script", s.dataTypes ) > -1 && - jQuery.inArray( "json", s.dataTypes ) < 0 ) { - s.converters[ "text script" ] = function() {}; - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -} ); - -jQuery.each( [ "get", "post" ], function( _i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - - // Shift arguments if data argument was omitted - if ( isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); - -jQuery.ajaxPrefilter( function( s ) { - var i; - for ( i in s.headers ) { - if ( i.toLowerCase() === "content-type" ) { - s.contentType = s.headers[ i ] || ""; - } - } -} ); - - -jQuery._evalUrl = function( url, options, doc ) { - return jQuery.ajax( { - url: url, - - // Make this explicit, since user can override this through ajaxSetup (trac-11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, - - // Only evaluate the response if it is successful (gh-4126) - // dataFilter is not invoked for failure responses, so using it instead - // of the default converter is kludgy but it works. - converters: { - "text script": function() {} - }, - dataFilter: function( response ) { - jQuery.globalEval( response, options, doc ); - } - } ); -}; - - -jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } - - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); - - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } - - wrap.map( function() { - var elem = this; - - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; - } - - return elem; - } ).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); - } - - return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - } ); - }, - - wrap: function( html ) { - var htmlIsFunction = isFunction( html ); - - return this.each( function( i ) { - jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); - } ); - }, - - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); - } ); - return this; - } -} ); - - -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; - - - - -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} -}; - -var xhrSuccessStatus = { - - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // trac-1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } - - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.ontimeout = - xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see trac-8605, trac-14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); - - try { - - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - - // trac-14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -} ); - - - - -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); - -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /\b(?:java|ecma)script\b/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -} ); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -} ); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - - // This transport only deals with cross domain or forced-by-attrs requests - if ( s.crossDomain || s.scriptAttrs ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( " - - - - <% } else { %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <% } %> - - - - - - -
- -
- - - -
-
- - -
-
-
-
-
WeatherStar 4000+
-
v<%- version %>
-
Enter your location above to continue
-
-
-
- <%- include('partials/progress.ejs') %> -
-
- <%- include('partials/hourly.ejs') %> -
-
- <%- include('partials/hourly-graph.ejs') %> -
-
- <%- include('partials/travel.ejs') %> -
-
- <%- include('partials/current-weather.ejs') %> -
-
- <%- include('partials/local-forecast.ejs') %> -
-
- <%- include('partials/latest-observations.ejs') %> -
-
- <%- include('partials/regional-forecast.ejs') %> -
-
- <%- include('partials/almanac.ejs') %> -
-
- <%- include('partials/extended-forecast.ejs') %> -
-
- <%- include('partials/radar.ejs') %> -
-
- <%- include('partials/hazards.ejs') %> -
-
-
-
- - - - -
-
- -
-
- -
-
-
- -
- - - -
Selected displays
-
- -
- -
Settings
-
-
- -
Sharing
-
- Copy Permalink Link copied to clipboard! - -
- - -
Forecast Information
-
- Location:
- Station Id:
- Radar Id:
- Zone Id:
-
- -
- Last Update: (None)
- -
- - - - \ No newline at end of file diff --git a/dist/views/partials/almanac.ejs b/dist/views/partials/almanac.ejs deleted file mode 100644 index fa8f81a..0000000 --- a/dist/views/partials/almanac.ejs +++ /dev/null @@ -1,31 +0,0 @@ -<%- include('header.ejs', {title:'Almanac', hasTime: true}) %> -
-
-
-
-
Monday
-
Tuesday
-
-
-
Sunrise:
-
6:24 am
-
6:25 am
-
-
-
Sunset:
-
6:24 am
-
6:25 am
-
-
-
-
Moon Data:
-
-
-
-
-
-
-
-
-
-<%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/current-weather.ejs b/dist/views/partials/current-weather.ejs deleted file mode 100644 index f5224f7..0000000 --- a/dist/views/partials/current-weather.ejs +++ /dev/null @@ -1,43 +0,0 @@ -<%- include('header.ejs', {titleDual:{ top: 'Current' , bottom: 'Conditions' }, noaaLogo: true, hasTime: true}) %> -
-
-
-
-
-
-
-
Wind:
-
-
-
-
-
-
-
-
Humidity:
-
-
-
-
Dewpoint:
-
-
-
-
Ceiling:
-
-
-
-
Visibility:
-
-
-
-
Pressure:
-
-
-
-
-
-
-
-
-
- <%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/extended-forecast.ejs b/dist/views/partials/extended-forecast.ejs deleted file mode 100644 index ba6aa52..0000000 --- a/dist/views/partials/extended-forecast.ejs +++ /dev/null @@ -1,23 +0,0 @@ -<%- include('header.ejs', {titleDual:{ top: 'Extended' , bottom: 'Forecast' }, hasTime: true }) %> -
-
-
-
-
- -
-
-
-
-
Lo
-
-
-
-
Hi
-
-
-
-
-
-
-<%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/hazards.ejs b/dist/views/partials/hazards.ejs deleted file mode 100644 index c6e59d3..0000000 --- a/dist/views/partials/hazards.ejs +++ /dev/null @@ -1,8 +0,0 @@ -
-
-
-
-
-
-
- <%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/header.ejs b/dist/views/partials/header.ejs deleted file mode 100644 index 6df3a93..0000000 --- a/dist/views/partials/header.ejs +++ /dev/null @@ -1,28 +0,0 @@ -
- - <% if (locals?.titleDual) { %> -
-
- <%-titleDual.top %> -
-
- <%-titleDual.bottom %> -
-
- <% } else { %> -
- <%-title %> -
- <% } %> - <% if (locals?.hasTime) { %> -
-
- <% } else if (!locals?.noaaLogo) { %> -
- <% } %> - <% if (locals?.noaaLogo) { %> - - <%}%> -
\ No newline at end of file diff --git a/dist/views/partials/hourly-graph.ejs b/dist/views/partials/hourly-graph.ejs deleted file mode 100644 index 2124782..0000000 --- a/dist/views/partials/hourly-graph.ejs +++ /dev/null @@ -1,24 +0,0 @@ -<%- include('header.ejs', {title: 'Hourly Graph' , hasTime: false }) %> -
-
-
Temperature
-
Cloud %
-
Precip %
-
-
-
75
-
65
-
55
-
-
- -
-
-
12a
-
6a
-
12p
-
6p
-
12a
-
-
- <%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/hourly.ejs b/dist/views/partials/hourly.ejs deleted file mode 100644 index b1859b9..0000000 --- a/dist/views/partials/hourly.ejs +++ /dev/null @@ -1,18 +0,0 @@ -<%- include('header.ejs', {title: 'Hourly Forecast' , hasTime: true }) %> -
-
-
TEMP
- -
WIND
-
-
-
-
-
-
- -
-
-
-
- <%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/latest-observations.ejs b/dist/views/partials/latest-observations.ejs deleted file mode 100644 index 7adf27d..0000000 --- a/dist/views/partials/latest-observations.ejs +++ /dev/null @@ -1,20 +0,0 @@ -<%- include('header.ejs', {titleDual:{ top: 'Latest' , bottom: 'Observations' }, noaaLogo: true, hasTime: true }) %> -
-
-
-
°F
-
°C
-
Weather
-
Wind
-
-
-
-
-
-
-
-
-
-
-
- <%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/local-forecast.ejs b/dist/views/partials/local-forecast.ejs deleted file mode 100644 index a773d7f..0000000 --- a/dist/views/partials/local-forecast.ejs +++ /dev/null @@ -1,12 +0,0 @@ -<%- include('header.ejs', {titleDual:{ top: 'Local' , bottom: 'Forecast' }, hasTime: true, noaaLogo: true}) %> -
-
-
-
-
-
-
-
-
-
- <%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/progress.ejs b/dist/views/partials/progress.ejs deleted file mode 100644 index db93b42..0000000 --- a/dist/views/partials/progress.ejs +++ /dev/null @@ -1,22 +0,0 @@ -<%- include('header.ejs', {titleDual:{ top: 'WeatherStar' , bottom: '4000+ v' + version }, hasTime: true}) %> -
-
-
-
Current Conditions
- -
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/dist/views/partials/radar.ejs b/dist/views/partials/radar.ejs deleted file mode 100644 index dbeeefb..0000000 --- a/dist/views/partials/radar.ejs +++ /dev/null @@ -1,43 +0,0 @@ -
- -
-
- Local -
-
- Radar -
-
-
-
-
PRECIP
-
-
Light
-
-
-
-
-
-
-
-
-
-
-
Heavy
-
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
\ No newline at end of file diff --git a/dist/views/partials/regional-forecast.ejs b/dist/views/partials/regional-forecast.ejs deleted file mode 100644 index ac27df0..0000000 --- a/dist/views/partials/regional-forecast.ejs +++ /dev/null @@ -1,14 +0,0 @@ -<%- include('header.ejs', {titleDual:{ top: 'Regional' , bottom: 'Observations' }, hasTime: true }) %> -
-
-
-
-
- -
-
-
-
-
-
- <%- include('scroll.ejs') %> \ No newline at end of file diff --git a/dist/views/partials/scroll.ejs b/dist/views/partials/scroll.ejs deleted file mode 100644 index 0fb3cac..0000000 --- a/dist/views/partials/scroll.ejs +++ /dev/null @@ -1,4 +0,0 @@ -
-
-
-
\ No newline at end of file diff --git a/dist/views/partials/travel.ejs b/dist/views/partials/travel.ejs deleted file mode 100644 index fd5a126..0000000 --- a/dist/views/partials/travel.ejs +++ /dev/null @@ -1,16 +0,0 @@ -<%- include('header.ejs', {titleDual: {top: 'Travel Forecast', bottom: 'For '} , hasTime: true }) %> -
-
-
LOW
-
HIGH
-
-
-
-
-
-
-
-
-
-
-<%- include('scroll.ejs') %> \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..aee1c5f --- /dev/null +++ b/docs/index.html @@ -0,0 +1 @@ +WeatherStar 4000+ International
WeatherStar 4000+
v6.0.0
Enter your location above to continue
WeatherStar
4000+ v6.0.0
Current Conditions
Hourly Forecast
TEMP
WIND
Hourly Graph
Temperature
Cloud %
Precip %
75
65
55
12a
6a
12p
6p
12a
Travel Forecast
For
LOW
HIGH
Current
Conditions
Wind:
Humidity:
Dewpoint:
Ceiling:
Visibility:
Pressure:
Local
Forecast
Latest
Observations
°F
°C
Weather
Wind
Regional
Observations
Almanac
Monday
Tuesday
Sunrise:
6:24 am
6:25 am
Sunset:
6:24 am
6:25 am
Moon Data:
Extended
Forecast
Lo
Hi
Local
Radar
PRECIP
Light
Heavy

Selected displays
Settings
Sharing
Copy Permalink Link copied to clipboard!
Forecast Information
Location:
Station Id:
Radar Id:
Zone Id:
Last Update: (None)
\ No newline at end of file diff --git a/dist/server/manifest.json b/docs/manifest.json similarity index 100% rename from dist/server/manifest.json rename to docs/manifest.json diff --git a/dist/server/styles/main.css b/docs/resources/ws.min.css similarity index 100% rename from dist/server/styles/main.css rename to docs/resources/ws.min.css diff --git a/docs/resources/ws.min.js b/docs/resources/ws.min.js new file mode 100644 index 0000000..fd29cdf --- /dev/null +++ b/docs/resources/ws.min.js @@ -0,0 +1 @@ +(()=>{"use strict";const e=(e,o)=>t(e,"json",o),t=async(e,t,n={})=>{const r={method:"GET",mode:"cors",type:"GET",retryCount:0,...n};r.originalRetries=r.retryCount;let a=e;!0===r.cors&&(a=(e=>{let t=e;return t=t.replace("https://api.weather.gov/",`${window.location.protocol}//${window.location.host}/`),t=t.replace("https://www.cpc.ncep.noaa.gov/",`${window.location.protocol}//${window.location.host}/`),t})(e));const s=new URL(a,`${window.location.origin}/`);r.data&&Object.keys(r.data).forEach((e=>{const t=r.data[e];s.searchParams.append(e,t)}));const c=await o(s,r);if(!c.ok)throw new Error(`Fetch error ${c.status} ${c.statusText} while fetching ${c.url}`);switch(t){case"json":return c.json();case"text":return c.text();case"blob":return c.blob();default:return c}},o=(e,t)=>new Promise(((a,s)=>{fetch(e,t).then((s=>{if(t.retryCount>0){if(s.status>=500&&s.status<=599&&t.retryCount>0){"function"==typeof t.stillWaiting&&t.retryCount===t.originalRetries&&t.stillWaiting();const s={...t,retryCount:t.retryCount-1};return a(n(r(t.originalRetries-s.retryCount),o,e,s))}return a(s)}return a(s)})).catch((e=>s(e)))})),n=(e,t,...o)=>new Promise((n=>{setTimeout((()=>{n(t(...o))}),e)})),r=e=>{switch(e){case 1:return 1e3;case 2:return 2e3;case 3:return 5e3;case 4:return 1e4;default:return 3e4}};let a=!1;const s=(e=!1)=>(s.controller||(s.controller=new NoSleep),a!==e&&(a=e,e?s.controller.enable():s.controller.disable())),c=s,l={loading:Symbol("loading"),loaded:Symbol("loaded"),failed:Symbol("failed"),noData:Symbol("noData"),disabled:Symbol("disabled"),retrying:Symbol("retrying")},i=l;document.addEventListener("DOMContentLoaded",(()=>d()));const u={kiosk:"settings-kiosk-checkbox"},d=()=>{const e=document.querySelector("#share-link");e.addEventListener("click",m),navigator?.clipboard||(e.textContent="Get Permalink")},m=async e=>{e.preventDefault();const t=document.querySelectorAll("input[type=checkbox]"),o={};[...t].forEach((e=>{e?.id&&(o[e.id]=e?.checked??!1)}));[...document.querySelectorAll("select")].forEach((e=>{e?.id&&(o[e.id]=e?.value??0)})),o.latLonQuery=localStorage.getItem("latLonQuery"),o.latLon=localStorage.getItem("latLon");const n=new URLSearchParams(o).toString(),r=new URL(`?${n}`,document.location.href);navigator?.clipboard?h(r):g(r)},h=async e=>{try{await navigator.clipboard.writeText(e.toString());const t=document.querySelector("#share-link-copied");t.style.display="inline",setTimeout((()=>{t.style.display="none"}),5e3)}catch(e){console.error(e)}},g=e=>{const t=document.querySelector("#share-link-instructions"),o=t.querySelector("#share-link-url");o.value=e,t.style.display="inline",o.focus(),o.select()},y=()=>{if(y.params)return y.params;const e=[...new URLSearchParams(window.location.search)];return e.forEach((t=>{const o=u[t[0]];o&&e.push([o,t[1]])})),y.params=Object.fromEntries(e),y.params},p="Settings";const v=class{constructor(e,t,o,n,r,a,s){this.shortName=e,this.name=t,this.defaultValue=n,this.myValue=n,this.type=o??"checkbox",this.sticky=a,this.values=s,this.changeAction=r??(()=>{});const c=y()?.[`settings-${e}-${o}`];let l;"checkbox"===o&&void 0!==c&&(l="true"===c),"select"===o&&void 0!==c&&(l=parseFloat(c));const i=l??this.getFromLocalStorage();if(a&&null!==i&&(this.myValue=i),"select"===o)this.selectChange({target:{value:this.myValue}});else this.checkboxChange({target:{checked:this.myValue}})}generateSelect(){const e=document.createElement("label");e.for=`settings-${this.shortName}-select`,e.id=`settings-${this.shortName}-label`;const t=document.createElement("span");t.innerHTML=`${this.name} `,e.append(t);const o=document.createElement("select");return o.id=`settings-${this.shortName}-select`,o.name=`settings-${this.shortName}-select`,o.addEventListener("change",(e=>this.selectChange(e))),this.values.forEach((([e,t])=>{const n=document.createElement("option");n.value=e.toFixed(2),n.innerHTML=t,o.append(n)})),e.append(o),this.element=e,this.selectHighlight(this.myValue),e}generateCheckbox(){const e=document.createElement("label");e.for=`settings-${this.shortName}-checkbox`,e.id=`settings-${this.shortName}-label`;const t=document.createElement("input");t.type="checkbox",t.value=!0,t.id=`settings-${this.shortName}-checkbox`,t.name=`settings-${this.shortName}-checkbox`,t.checked=this.myValue,t.addEventListener("change",(e=>this.checkboxChange(e)));const o=document.createElement("span");return o.innerHTML=this.name,e.append(t,o),this.element=e,e}checkboxChange(e){this.myValue=e.target.checked,this.storeToLocalStorage(this.myValue),this.changeAction(this.myValue)}selectChange(e){this.myValue=parseFloat(e.target.value),this.storeToLocalStorage(this.myValue),this.changeAction(this.myValue)}storeToLocalStorage(e){if(!this.sticky)return;const t=localStorage?.getItem(p)??"{}",o=JSON.parse(t);o[this.shortName]=e,localStorage?.setItem(p,JSON.stringify(o))}getFromLocalStorage(){const e=localStorage?.getItem(p);try{if(e){const t=JSON.parse(e)?.[this.shortName];if(void 0!==t)switch(this.type){case"boolean":case"select":return t;default:return null}}}catch{return null}return null}get value(){return this.myValue}set value(e){if(this.myValue=e,"select"===this.type)this.selectHighlight(e);else this.element.checked=e;this.storeToLocalStorage(this.myValue),this.changeAction(this.myValue)}selectHighlight(e){this.element.querySelectorAll("option").forEach((t=>{t.selected=e.toFixed(2)===t.value}))}generate(){return"select"===this.type?this.generateSelect():this.generateCheckbox()}};document.addEventListener("DOMContentLoaded",(()=>{f()}));const S={speed:{value:1}},f=()=>{S.wide=new v("wide","Widescreen","checkbox",!1,w,!0),S.kiosk=new v("kiosk","Kiosk","boolean",!1,L,!1),S.speed=new v("speed","Speed","select",1,null,!0,[[.5,"Very Fast"],[.75,"Fast"],[1,"Normal"],[1.25,"Slow"],[1.5,"Very Slow"]]);const e=Object.values(S).map((e=>e.generate())),t=document.querySelector("#settings");t.innerHTML="",t.append(...e)},w=e=>{const t=document.querySelector("#divTwc");e?t.classList.add("wide"):t.classList.remove("wide")},L=e=>{const t=document.querySelector("body");e?(t.classList.add("kiosk"),window.dispatchEvent(new Event("resize"))):t.classList.remove("kiosk")},k=S;document.addEventListener("DOMContentLoaded",(()=>{I()}));const b=[];let E,_=!1;const q={},x=6e5,F="#chkAutoRefresh";let T=null,C=0;const I=async()=>{window.addEventListener("resize",B),B();const e=localStorage.getItem("autoRefresh");document.querySelector(F).checked=!e||"true"===e,document.querySelector(F).addEventListener("change",U),G()},N=async(t,o)=>{const n=await(async(t,o)=>{try{return await e(`https://api.open-meteo.com/v1/forecast?latitude=${t}&longitude=${o}&daily=temperature_2m_max,temperature_2m_min&hourly=temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation_probability,precipitation,rain,showers,snowfall,snow_depth,weather_code,pressure_msl,surface_pressure,cloud_cover,visibility,evapotranspiration,et0_fao_evapotranspiration,vapour_pressure_deficit,uv_index,uv_index_clear_sky,is_day,sunshine_duration,wet_bulb_temperature_2m,wind_speed_10m,wind_direction_10m,wind_gusts_10m&models=best_match`)}catch(e){return console.log(`Unable to get point ${t}, ${o}`),console.error(e),!1}})(t.lat,t.lon),r=(e=>{const{hourly:t,daily:o}=e,n=Object.keys(t).filter((e=>"time"!==e)),r={};t.time.forEach(((e,o)=>{const a=e.split("T")[0];r[a]||(r[a]={hours:[],weather_code_counts:{}},n.forEach((e=>{r[a][e]={sum:0,count:0}})));const s={time:e};if(n.forEach((e=>{s[e]=t[e][o],r[a][e].sum+=t[e][o],r[a][e].count+=1})),t.weather_code){const e=t.weather_code[o];r[a].weather_code_counts[e]=(r[a].weather_code_counts[e]||0)+1}r[a].hours.push(s)}));const a={};return Object.entries(r).forEach((([e,t])=>{a[e]={hours:t.hours},n.forEach((o=>{a[e][o]=t[o].sum/t[o].count}));const o=Object.entries(t.weather_code_counts);o.length>0&&([a[e].weather_code]=o.reduce(((e,t)=>t[1]>e[1]?t:e)))})),o.time.forEach(((e,t)=>{r[e]||(r[e]={hours:[]}),a[e].temperature_2m_max=o.temperature_2m_max[t],a[e].temperature_2m_min=o.temperature_2m_min[t]})),a})(n);"function"==typeof o&&o(n);const a=localStorage.getItem("latLonQuery"),s=await(async t=>{try{return await e(`https://geocoding-api.open-meteo.com/v1/search?name=${t}&count=10&language=en&format=json`)}catch(e){return console.log(`Unable to get locality with value ${t}`),console.error(e),!1}})(a.split(",")[0]);let c=s.results[0].name,l=s.results[0].country,i=s.results[0].admin1,u=s.results[0].timezone;q.latitude=t.lat,q.longitude=t.lon,q.city=c,q.state=i,q.country=l,q.timeZone=u,q.forecast=r,q.stationId="stationId-dont-matter-anymore",q.zoneId="zoneId-dont-matter",q.radarId="radarId-dont-matter",q.weatherOffice="weatherOffice-dont-matter",j(q),P(),document.querySelector("#loading").style.display="none",E&&(await E.drawCanvas(),E.showCanvas()),b.forEach((e=>e.getData(q)))},P=()=>{b.forEach((e=>e.hideCanvas()))},R=()=>_,M={response:{previous:Symbol("previous"),inProgress:Symbol("inProgress"),next:Symbol("next")},command:{firstFrame:Symbol("firstFrame"),previousFrame:Symbol("previousFrame"),nextFrame:Symbol("nextFrame"),lastFrame:Symbol("lastFrame")}},H=e=>{const t=D();if(E.hideCanvas(),!t){let e,t=0;do{b[t].status===i.loaded&&b[t].timing.totalScreens>0&&(e=b[t]),t+=1}while(!e&&tb.findIndex((e=>e.active)),D=()=>b[O()],V=e=>{_=e;const t=document.querySelector("#NavigatePlay");localStorage.setItem("play",_),_?(c(!0),t.title="Pause",t.src="images/nav/ic_pause_white_24dp_2x.png"):(c(!1),t.title="Play",t.src="images/nav/ic_play_arrow_white_24dp_2x.png"),E&&_&&!D()&&H(M.command.firstFrame)},A=e=>{switch(e){case"play":V(!0);break;case"playToggle":V(!_);break;case"stop":V(!1);break;case"next":V(!1),H(M.command.nextFrame);break;case"previous":V(!1),H(M.command.previousFrame);break;case"menu":V(!1),E.showCanvas(),P();break;default:console.error(`Unknown navButton ${e}`)}},B=()=>{const e=k.wide.value?854:640,t=document.querySelector("#divTwcBottom").getBoundingClientRect().width/e,o=window.innerHeight/480,n=Math.min(t,o);n<1||document.fullscreenElement||k.kiosk?document.querySelector("#container").style.transform=`scale(${n})`:document.querySelector("#container").style.transform="unset"},G=()=>{const e=document.querySelector("#enabledDisplays");if(!e)return;const t=b.map((e=>e.generateCheckbox(e.defaultEnabled))).filter((e=>e));e.innerHTML="",e.append(...t)},j=e=>{document.querySelector("#spanCity").innerHTML=`${e.city}, `,document.querySelector("#spanState").innerHTML=e.state,document.querySelector("#spanStationId").innerHTML=e.stationId,document.querySelector("#spanRadarId").innerHTML=e.radarId,document.querySelector("#spanZoneId").innerHTML=e.zoneId},U=e=>{const{checked:t}=e.target;t?Q():W(),localStorage.setItem("autoRefresh",t)},z=e=>{e?(document.querySelector("#spanLastRefresh").innerHTML=e.toLocaleString("en-US",{weekday:"short",month:"short",day:"numeric",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric",timeZoneName:"short"}),document.querySelector(F).checked&&Q()):document.querySelector("#spanLastRefresh").innerHTML="(none)"},Q=()=>{if(T)return;C=0;const e=()=>{C+=500;let e=x-C;e<0&&(e=0);const t=new Date(e);document.querySelector("#spanRefreshCountDown").innerHTML=`${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}`,C>=x&&!R()&&J()};T=window.setInterval(e,500),e()},W=()=>{T&&(window.clearInterval(T),document.querySelector("#spanRefreshCountDown").innerHTML="--:--",T=null)},J=()=>{J.callback&&J.callback()},Z=(e,t)=>Math.trunc(e*10**t)/10**t;document.addEventListener("DOMContentLoaded",(()=>{te()}));const K=["Land Features","Bay","Channel","Cove","Dam","Delta","Gulf","Lagoon","Lake","Ocean","Reef","Reservoir","Sea","Sound","Strait","Waterfall","Wharf","Amusement Park","Historical Monument","Landmark","Tourist Attraction","Zoo","College","Beach","Campground","Golf Course","Harbor","Nature Reserve","Other Parks and Outdoors","Park","Racetrack","Scenic Overlook","Ski Resort","Sports Center","Sports Field","Wildlife Reserve","Airport","Ferry","Marina","Pier","Port","Resort","Postal","Populated Place"].join(","),X="#txtAddress",Y="#ToggleFullScreen",ee="#btnGetGps",te=()=>{var e;document.querySelector(X).addEventListener("focus",(e=>{e.target.select()})),e=ie,J.callback=e,document.querySelector("#NavigateMenu").addEventListener("click",le),document.querySelector("#NavigateRefresh").addEventListener("click",de),document.querySelector("#NavigateNext").addEventListener("click",me),document.querySelector("#NavigatePrevious").addEventListener("click",he),document.querySelector("#NavigatePlay").addEventListener("click",ve),document.querySelector(Y).addEventListener("click",re);const t=document.querySelector(ee);t.addEventListener("click",fe),navigator.geolocation||(t.style.display="none"),document.querySelector("#divTwc").addEventListener("mousemove",(()=>{document.fullscreenElement&&ye()})),window.addEventListener("resize",we),we.wasFull=!1,document.querySelector(X).addEventListener("keydown",(e=>{"Enter"===e.code&&o()})),document.querySelector("#btnGetLatLng").addEventListener("click",(()=>o())),document.addEventListener("keydown",pe),document.addEventListener("touchmove",(e=>{document.fullscreenElement&&e.preventDefault()})),$(X).devbridgeAutocomplete({serviceUrl:"https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest",deferRequestBy:300,paramName:"text",params:{f:"json",category:K,maxSuggestions:10},dataType:"json",transformResult:e=>({suggestions:e.suggestions.map((e=>({value:e.text,data:e.magicKey})))}),minChars:3,showNoSuggestionNotice:!0,noSuggestionNotice:"No results found. Please try a different search string.",onSelect(e){oe(e,this)},width:490});const o=()=>{const e=$(X).devbridgeAutocomplete();return e.suggestions[0]&&$(e.suggestionsContainer.children[0]).trigger("click"),!1},n=y(),r=n.latLonQuery&&n.latLon,a=n.latLonQuery??localStorage.getItem("latLonQuery"),s=n.latLon??localStorage.getItem("latLon"),c=localStorage.getItem("latLonFromGPS")&&!r;if(a&&s&&!c){document.querySelector(X).value=a,ie(JSON.parse(s))}c&&fe(),k.kiosk.value="true"===n["settings-kiosk-checkbox"];const l=n["settings-kiosk-checkbox"]??localStorage.getItem("play");null!==l&&"true"!==l||Se("navButton","play"),document.querySelector("#btnClearQuery").addEventListener("click",(()=>{document.querySelector("#spanCity").innerHTML="",document.querySelector("#spanState").innerHTML="",document.querySelector("#spanStationId").innerHTML="",document.querySelector("#spanRadarId").innerHTML="",document.querySelector("#spanZoneId").innerHTML="",document.querySelector("#chkAutoRefresh").checked=!0,localStorage.removeItem("autoRefresh"),localStorage.removeItem("play"),Se("navButton","play"),localStorage.removeItem("latLonQuery"),localStorage.removeItem("latLon"),localStorage.removeItem("latLonFromGPS"),document.querySelector(ee).classList.remove("active")})),document.querySelector("#container").addEventListener("swiped-left",(()=>ue("left"))),document.querySelector("#container").addEventListener("swiped-right",(()=>ue("right")))},oe=async(t,o)=>{if(o.previousSuggestionValue===t.value)return;const n=(await e("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find",{data:{text:t.value,magicKey:t.data,f:"json"}})).locations[0];n?(localStorage.removeItem("latLonFromGPS"),document.querySelector(ee).classList.remove("active"),ne(n.feature.geometry)):console.error("An unexpected error occurred. Please try a different search string.")},ne=(e,t)=>{const o={lat:Z(e.y,4),lon:Z(e.x,4)};localStorage.setItem("latLonQuery",document.querySelector(X).value),localStorage.setItem("latLon",JSON.stringify(o)),ie(o,t)},re=()=>(document.fullscreenElement?se():ae(),R()?c(!0):c(!1),ye(),!1),ae=()=>{const e=document.querySelector("#divTwc"),t=e.requestFullScreen||e.webkitRequestFullScreen||e.mozRequestFullScreen||e.msRequestFullscreen;t?t.call(e,{navigationUI:"hide"}):window.scrollTo(0,0),B(),ye();const o=document.querySelector(Y);o.src="images/nav/ic_fullscreen_exit_white_24dp_2x.png",o.title="Exit fullscreen"},se=()=>{document.exitFullscreen?document.exitFullscreen():document.webkitExitFullscreen?document.webkitExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.msExitFullscreen&&document.msExitFullscreen(),B(),ce()},ce=()=>{const e=document.querySelector(Y);e.src="images/nav/ic_fullscreen_white_24dp_2x.png",e.title="Enter fullscreen",document.querySelector("#divTwc").classList.remove("no-cursor");const t=document.querySelector("#divTwcBottom");t.classList.remove("hidden"),t.classList.add("visible")},le=()=>(Se("navButton","menu"),!1),ie=(e,t)=>{e&&(ie.latLon=e);const{latLon:o}=ie;o&&(document.querySelector(X).blur(),W(),((e,t)=>{N(e,t),z(null)})(o,t))},ue=e=>{if("left"===e)me();else he()},de=()=>(b.forEach((e=>{e.status=i.loading})),ie(),!1),me=()=>(Se("navButton","next"),!1),he=()=>(Se("navButton","previous"),!1);let ge=null;const ye=()=>{document.activeElement.blur();const e=document.querySelector("#divTwcBottom");e.classList.remove("hidden"),e.classList.add("visible"),document.querySelector("#divTwc").classList.remove("no-cursor"),ge&&(clearTimeout(ge),ge=null),ge=setTimeout((()=>{document.fullscreenElement&&(e.classList.remove("visible"),e.classList.add("hidden"),document.querySelector("#divTwc").classList.add("no-cursor"))}),2e3)},pe=e=>{const{key:t}=e;if(document.fullscreenElement||document.activeElement===document.body)switch(t){case" ":return e.preventDefault(),ve(),!1;case"ArrowRight":case"PageDown":return e.preventDefault(),me(),!1;case"ArrowLeft":case"PageUp":return e.preventDefault(),he(),!1;case"ArrowUp":return e.preventDefault(),le(),!1;case"0":return de(),!1;case"F":case"f":return re(),!1}return!1},ve=()=>(Se("navButton","playToggle"),!1),Se=(e,t={})=>{var o;(o={type:e,message:t}).type&&("navButton"===o.type?A(o.message):console.error(`Unknown event ${o.type}`))},fe=async()=>{if(!navigator.geolocation)return;const e=document.querySelector(ee);if(e.classList.contains("active"))return e.classList.remove("active"),void localStorage.removeItem("latLonFromGPS");e.classList.add("active");const t=await(async()=>new Promise((e=>{navigator.geolocation.getCurrentPosition(e)})))(),{latitude:o,longitude:n}=t.coords,r=document.querySelector(X);r.value=`${Z(o,4)}, ${Z(n,4)}`,ne({y:o,x:n},(e=>{const t=e.properties.relativeLocation.properties,a=`${t.city}, ${t.state}`;localStorage.setItem("latLon",JSON.stringify({lat:o,lon:n})),localStorage.setItem("latLonQuery",a),localStorage.setItem("latLonFromGPS",!0),r.value=`${t.city}, ${t.state}`}))},we=()=>{we.wasFull&&!document.fullscreenElement&&ce(),!we.wasFull&&document.fullscreenElement,we.wasFull=!!document.fullscreenElement}})(); \ No newline at end of file diff --git a/dist/server/robots.txt b/docs/robots.txt similarity index 100% rename from dist/server/robots.txt rename to docs/robots.txt diff --git a/gulp/build-gh-pages.mjs b/gulp/build-gh-pages.mjs new file mode 100644 index 0000000..6c090cd --- /dev/null +++ b/gulp/build-gh-pages.mjs @@ -0,0 +1,54 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { + src, dest, series, parallel, +} from 'gulp'; +import concat from 'gulp-concat'; +import ejs from 'gulp-ejs'; +import rename from 'gulp-rename'; +import htmlmin from 'gulp-htmlmin'; +import { deleteAsync } from 'del'; +import webpack from 'webpack-stream'; +import TerserPlugin from 'terser-webpack-plugin'; +import { readFile } from 'fs/promises'; + +const clean = () => deleteAsync(['./docs']); + +const BUILD_PATH = './docs/resources'; + +const webpackOptions = { + mode: 'production', + output: { filename: 'ws.min.js' }, + optimization: { + minimize: true, + minimizer: [new TerserPlugin({ extractComments: false })], + }, +}; + +const buildJs = () => src(['server/scripts/index.mjs']) + .pipe(webpack(webpackOptions)) + .pipe(dest(BUILD_PATH)); + +const copyCss = () => src(['server/styles/main.css']) + .pipe(concat('ws.min.css')) + .pipe(dest(BUILD_PATH)); + +const compressHtml = async () => { + const packageJson = await readFile('package.json'); + const { version } = JSON.parse(packageJson); + + return src('views/*.ejs') + .pipe(ejs({ + production: true, + version, + }, {}, { ext: '.html' })) // Prevents EJS from escaping values + .pipe(rename({ extname: '.html' })) + .pipe(htmlmin({ collapseWhitespace: true })) + .pipe(dest('./docs')); +}; + +const copyOtherFiles = () => src(['server/robots.txt', 'server/manifest.json'], { base: 'server/' }) + .pipe(dest('./docs')); + +const build = series(clean, parallel(buildJs, copyCss, compressHtml, copyOtherFiles)); + +export default build; diff --git a/gulp/publish-frontend.mjs b/gulp/publish-frontend.mjs deleted file mode 100644 index faca59a..0000000 --- a/gulp/publish-frontend.mjs +++ /dev/null @@ -1,178 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { - src, dest, series, parallel, -} from 'gulp'; -import concat from 'gulp-concat'; -import terser from 'gulp-terser'; -import ejs from 'gulp-ejs'; -import rename from 'gulp-rename'; -import htmlmin from 'gulp-htmlmin'; -import { deleteAsync } from 'del'; -import s3Upload from 'gulp-s3-upload'; -import webpack from 'webpack-stream'; -import TerserPlugin from 'terser-webpack-plugin'; -import { readFile } from 'fs/promises'; - -// get cloudfront -import { CloudFrontClient, CreateInvalidationCommand } from '@aws-sdk/client-cloudfront'; - -const clean = () => deleteAsync(['./dist**']); - -const cloudfront = new CloudFrontClient({ region: 'us-east-1' }); - -const RESOURCES_PATH = './dist/resources'; - -const jsSourcesData = [ - 'server/scripts/data/travelcities.js', - 'server/scripts/data/regionalcities.js', - 'server/scripts/data/stations.js', -]; - -const webpackOptions = { - mode: 'production', - // mode: 'development', - // devtool: 'source-map', - output: { - filename: 'ws.min.js', - }, - resolve: { - roots: ['./'], - }, - optimization: { - minimize: true, - minimizer: [ - new TerserPlugin({ - extractComments: false, - terserOptions: { - // sourceMap: true, - format: { - comments: false, - }, - }, - }), - ], - }, -}; - -const compressJsData = () => src(jsSourcesData) - .pipe(concat('data.min.js')) - .pipe(terser()) - .pipe(dest(RESOURCES_PATH)); - -const jsVendorSources = [ - 'server/scripts/vendor/auto/jquery.js', - 'server/scripts/vendor/jquery.autocomplete.min.js', - 'server/scripts/vendor/auto/nosleep.js', - 'server/scripts/vendor/auto/swiped-events.js', - 'server/scripts/vendor/auto/suncalc.js', -]; - -const compressJsVendor = () => src(jsVendorSources) - .pipe(concat('vendor.min.js')) - .pipe(terser()) - .pipe(dest(RESOURCES_PATH)); - -const mjsSources = [ - 'server/scripts/modules/currentweatherscroll.mjs', - 'server/scripts/modules/hazards.mjs', - 'server/scripts/modules/currentweather.mjs', - 'server/scripts/modules/almanac.mjs', - 'server/scripts/modules/icons.mjs', - 'server/scripts/modules/extendedforecast.mjs', - 'server/scripts/modules/hourly.mjs', - 'server/scripts/modules/hourly-graph.mjs', - 'server/scripts/modules/latestobservations.mjs', - 'server/scripts/modules/localforecast.mjs', - 'server/scripts/modules/radar.mjs', - 'server/scripts/modules/regionalforecast.mjs', - 'server/scripts/modules/travelforecast.mjs', - 'server/scripts/modules/progress.mjs', - 'server/scripts/index.mjs', -]; - -const buildJs = () => src(mjsSources) - .pipe(webpack(webpackOptions)) - .pipe(dest(RESOURCES_PATH)); - -const cssSources = [ - 'server/styles/main.css', -]; -const copyCss = () => src(cssSources) - .pipe(concat('ws.min.css')) - .pipe(dest(RESOURCES_PATH)); - -const htmlSources = [ - 'views/*.ejs', -]; -const compressHtml = async () => { - const packageJson = await readFile('package.json'); - const { version } = JSON.parse(packageJson); - - return src(htmlSources) - .pipe(ejs({ - production: version, - version, - })) - .pipe(rename({ extname: '.html' })) - .pipe(htmlmin({ collapseWhitespace: true })) - .pipe(dest('./dist')); -}; - -const otherFiles = [ - 'server/robots.txt', - 'server/manifest.json', -]; -const copyOtherFiles = () => src(otherFiles, { base: 'server/' }) - .pipe(dest('./dist')); - -const s3 = s3Upload({ - useIAM: true, -}, { - region: 'us-east-1', -}); -const uploadSources = [ - 'dist/**', - '!dist/**/*.map', -]; -const upload = () => src(uploadSources, { base: './dist' }) - .pipe(s3({ - Bucket: 'weatherstar', - StorageClass: 'STANDARD', - maps: { - CacheControl: (keyname) => { - if (keyname.indexOf('index.html') > -1) return 'max-age=300'; // 10 minutes - return 'max-age=2592000'; // 1 month - }, - }, - })); - -const imageSources = [ - 'server/fonts/**', - 'server/images/**', -]; -const uploadImages = () => src(imageSources, { base: './server', encoding: false }) - .pipe( - s3({ - Bucket: 'weatherstar', - StorageClass: 'STANDARD', - }), - ); - -const invalidate = () => cloudfront.send(new CreateInvalidationCommand({ - DistributionId: 'E9171A4KV8KCW', - InvalidationBatch: { - CallerReference: (new Date()).toLocaleString(), - Paths: { - Quantity: 1, - Items: ['/*'], - }, - }, -})); - -const buildDist = series(clean, parallel(buildJs, compressJsData, compressJsVendor, copyCss, compressHtml, copyOtherFiles)); - -// upload_images could be in parallel with upload, but _images logs a lot and has little changes -// by running upload last the majority of the changes will be at the bottom of the log for easy viewing -const publishFrontend = series(buildDist, uploadImages, upload, invalidate); - -export default publishFrontend; diff --git a/gulpfile.mjs b/gulpfile.mjs index 09fb16a..0ad85e9 100644 --- a/gulpfile.mjs +++ b/gulpfile.mjs @@ -1,7 +1,9 @@ import updateVendor from './gulp/update-vendor.mjs'; -import publishFrontend from './gulp/publish-frontend.mjs'; +import publishFrontend from './gulp/build-gh-pages.mjs'; export { updateVendor, publishFrontend, }; + +export default publishFrontend; diff --git a/package.json b/package.json index fe11275..e619fbb 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,7 @@ "lint": "eslint ./server/scripts/**/*.mjs", "lint:fix": "eslint --fix ./server/scripts/**/*.mjs", "start": "nodemon index.js", - "pages": "node dist/index.js", - "build": "rm -rf /dist && node build.mjs" + "build": "gulp" }, "repository": { "type": "git",