mirix commited on
Commit
b2c7cca
·
verified ·
1 Parent(s): 1da05bf

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +97 -62
  2. requirements.txt +23 -16
  3. weather_icons_custom.json +1002 -0
app.py CHANGED
@@ -2,6 +2,7 @@ import os
2
  import json
3
  import pathlib
4
  import gpxpy
 
5
  import pandas as pd
6
  import gradio as gr
7
  from datetime import datetime
@@ -10,15 +11,15 @@ import pytz
10
  from sunrisesunset import SunriseSunset
11
  from timezonefinder import TimezoneFinder
12
  tf = TimezoneFinder()
13
- from beaufort_scale.beaufort_scale import beaufort_scale_ms
14
-
15
- from wordsegment import load, segment
16
- load()
17
 
18
  import srtm
19
  elevation_data = srtm.get_data()
20
 
21
- import requests
 
 
 
22
 
23
  from geopy.geocoders import Nominatim
24
  geolocator = Nominatim(user_agent='FreeLetzWeather')
@@ -27,12 +28,20 @@ from apscheduler.schedulers.background import BackgroundScheduler
27
 
28
  ### Default variables ###
29
 
30
- # Met No weather forecast API
31
- url = 'https://api.met.no/weatherapi/locationforecast/2.0/complete'
32
- headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'}
 
 
 
 
 
 
 
 
33
 
34
  # Weather icons URL
35
- icon_url = 'https://raw.githubusercontent.com/metno/weathericons/89e3173756248b4696b9b10677b66c4ef435db53/weather/svg/'
36
 
37
  # Custom CSS
38
  css = '''
@@ -55,6 +64,25 @@ gpx_path = pathlib.Path(gpx_file)
55
 
56
  ### Functions ###
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  # Pluviometry to natural language
59
  def rain_intensity(precipt):
60
  if precipt >= 50:
@@ -86,19 +114,7 @@ def gen_dates_list():
86
  day_read = today.strftime('%A %-d %B')
87
  day_print = '<h2>' + day_read + '</h2>'
88
 
89
- resp = requests.get(url=url, headers=headers, params=params)
90
- data = resp.json()
91
-
92
- dates_aval = []
93
- for d in data['properties']['timeseries']:
94
- if 'next_1_hours' in d['data']:
95
- date = datetime.strptime(d['time'], '%Y-%m-%dT%H:%M:%SZ')
96
- dates_aval.append(date.date())
97
-
98
- dates_aval = sorted(set(dates_aval))
99
-
100
- if len(dates_aval) > 3:
101
- dates_aval = dates_aval[:3]
102
 
103
  dates_read = [x.strftime('%A %-d %B %Y') for x in dates_aval]
104
  dates_filt = [x.strftime('%Y-%m-%d') for x in dates_aval]
@@ -122,8 +138,8 @@ def sunrise_sunset(lat, lon, day):
122
  sunrise = rise_time.strftime('%H:%M')
123
  sunset = set_time.strftime('%H:%M')
124
 
125
- sunrise_icon = '<img style="float: left;" width="24px" src=' + icon_url + 'clearsky_day.svg>'
126
- sunset_icon = '<img style="float: left;" width="24px" src=' + icon_url + 'clearsky_night.svg>'
127
 
128
  sunrise = '<h6>' + sunrise_icon + ' Sunrise ' + sunrise + '</h6>'
129
  sunset = '<h6>' + sunset_icon + ' Sunset ' + sunset + '</h6>'
@@ -135,39 +151,55 @@ def json_parser(date):
135
 
136
  global dfs
137
 
138
- resp = requests.get(url=url, headers=headers, params=params)
139
- data = resp.json()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
- day = date
 
 
142
 
143
- dict_weather = {'Time': [], 'Weather': [], 'Weather outline': [], 'Temp (°C)': [], 'Rain (mm/h)': [], 'Rain level': [], 'Wind (m/s)': [], 'Wind level': [] }
 
144
 
145
- for d in data['properties']['timeseries']:
146
- date = datetime.strptime(d['time'], '%Y-%m-%dT%H:%M:%SZ')
147
- date_read = date.strftime('%Y-%m-%d')
148
 
149
- if date_read == day:
150
- dict_weather['Time'].append(date.strftime('%H'))
151
- weather = d['data']['next_1_hours']['summary']['symbol_code']
152
- icon_path = '<img style="float: left; padding: 0; margin: -6px; display: block;" width=32px; src=' + icon_url + weather + '.svg>'
153
- dict_weather['Weather'].append(icon_path)
154
- weather_read = ' '.join(segment(weather.replace('_', '')))
155
- dict_weather['Weather outline'].append(weather_read)
156
- temp = d['data']['instant']['details']['air_temperature']
157
- dict_weather['Temp (°C)'].append(str(int(round(temp, 0))) + '°')
158
- rain = d['data']['next_1_hours']['details']['precipitation_amount']
159
- dict_weather['Rain (mm/h)'].append(rain)
160
- dict_weather['Rain level'].append(rain_intensity(rain))
161
- wind = d['data']['instant']['details']['wind_speed']
162
- dict_weather['Wind (m/s)'].append(wind)
163
- dict_weather['Wind level'].append(beaufort_scale_ms(wind, language='en'))
164
 
165
- df = pd.DataFrame(dict_weather)
 
166
 
167
- df['Weather outline'] = df['Weather outline'].str.capitalize().str.replace(' night','').str.replace(' day','')
168
- df[['Rain (mm/h)', 'Wind (m/s)']] = df[['Rain (mm/h)', 'Wind (m/s)']].round(1).replace({0:''}).astype(str)
169
 
170
- dfs = df.style.set_properties(**{'border': '0px'})
 
 
 
 
 
 
 
 
 
 
 
171
 
172
  return dfs
173
 
@@ -197,21 +229,24 @@ def coor_gpx(gpx):
197
  for segment in track.segments:
198
  for p in segment.points:
199
  points.append({
200
- 'lat': p.latitude,
201
- 'lon': p.longitude,
202
- 'altitude': p.elevation,
203
  })
204
  df_gpx = pd.DataFrame.from_records(points)
205
- params = df_gpx.iloc[-1].to_dict()
206
- lat = params['lat']
207
- lon = params['lon']
208
-
209
- if params['altitude'] == None:
210
- params['altitude'] = int(round(elevation_data.get_elevation(lat, lon), 0))
 
 
 
211
  else:
212
- params['altitude'] = int(round(params['altitude'], 0))
213
 
214
- altitude = params['altitude']
215
 
216
  location = geolocator.reverse('{}, {}'.format(lat, lon), zoom=14)
217
 
@@ -292,7 +327,7 @@ with gr.Blocks(theme='ParityError/Interstellar', css=css, fill_height=True) as d
292
  datatype=['str', 'html', 'str', 'str', 'str', 'str', 'str', 'str'],
293
  )
294
  gr.HTML('<center>Freedom Luxembourg<br><a style="color: DarkGoldenrod; font-style: italic; text-decoration: none" href="https://www.freeletz.lu/freeletz/" target="_blank">freeletz.lu</a></center>')
295
- gr.HTML('<center>Powered by the <a style="color: #004170; text-decoration: none" href="https://api.met.no/weatherapi/locationforecast/2.0/documentation" target="_blank">Norwegian Meteorological Institute</a> API</center>')
296
  upload_gpx.upload(fn=coor_gpx, inputs=upload_gpx, outputs=[file_name, loc, dates, choosen_date, sunrise, sunset, table])
297
  dates.input(fn=date_chooser, inputs=dates, outputs=[choosen_date, sunrise, sunset, table, dates])
298
 
 
2
  import json
3
  import pathlib
4
  import gpxpy
5
+ import numpy as np
6
  import pandas as pd
7
  import gradio as gr
8
  from datetime import datetime
 
11
  from sunrisesunset import SunriseSunset
12
  from timezonefinder import TimezoneFinder
13
  tf = TimezoneFinder()
14
+ from beaufort_scale.beaufort_scale import beaufort_scale_kmh
 
 
 
15
 
16
  import srtm
17
  elevation_data = srtm.get_data()
18
 
19
+ import openmeteo_requests
20
+
21
+ import requests_cache
22
+ from retry_requests import retry
23
 
24
  from geopy.geocoders import Nominatim
25
  geolocator = Nominatim(user_agent='FreeLetzWeather')
 
28
 
29
  ### Default variables ###
30
 
31
+ # Setup the Open-Meteo API client with cache and retry on error
32
+ cache_session = requests_cache.CachedSession('.cache', expire_after = 3600)
33
+ retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2)
34
+ openmeteo = openmeteo_requests.Client(session = retry_session)
35
+
36
+ # Open Meteo weather forecast API
37
+ url = 'https://api.open-meteo.com/v1/forecast'
38
+ params = {
39
+ 'timezone': 'auto',
40
+ 'hourly': ['temperature_2m', 'rain', 'wind_speed_10m', 'weather_code', 'is_day']
41
+ }
42
 
43
  # Weather icons URL
44
+ icon_url = 'https://raw.githubusercontent.com/basmilius/weather-icons/refs/heads/dev/production/fill/svg/'
45
 
46
  # Custom CSS
47
  css = '''
 
64
 
65
  ### Functions ###
66
 
67
+ with open('weather_icons_custom.json', 'r') as file:
68
+ icons = json.load(file)
69
+
70
+ def map_icons(df):
71
+
72
+ code = df['weather_code']
73
+
74
+ if df['is_day'] == 1:
75
+ icon = icons[str(code)]['day']['icon']
76
+ description = icons[str(code)]['day']['description']
77
+ elif df['is_day'] == 0:
78
+ icon = icons[str(code)]['night']['icon']
79
+ description = icons[str(code)]['night']['description']
80
+
81
+ df['Weather'] = '<img style="float: left; padding: 0; margin: -6px; display: block;" width=32px; src=' + icon_url + icon + '>'
82
+ df['Weather outline'] = description
83
+
84
+ return df
85
+
86
  # Pluviometry to natural language
87
  def rain_intensity(precipt):
88
  if precipt >= 50:
 
114
  day_read = today.strftime('%A %-d %B')
115
  day_print = '<h2>' + day_read + '</h2>'
116
 
117
+ dates_aval = pd.date_range(datetime.today(), periods=7).to_pydatetime().tolist()
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  dates_read = [x.strftime('%A %-d %B %Y') for x in dates_aval]
120
  dates_filt = [x.strftime('%Y-%m-%d') for x in dates_aval]
 
138
  sunrise = rise_time.strftime('%H:%M')
139
  sunset = set_time.strftime('%H:%M')
140
 
141
+ sunrise_icon = '<img style="float: left;" width="32px" src=' + icon_url + 'sunrise.svg>'
142
+ sunset_icon = '<img style="float: left;" width="32px" src=' + icon_url + 'sunset.svg>'
143
 
144
  sunrise = '<h6>' + sunrise_icon + ' Sunrise ' + sunrise + '</h6>'
145
  sunset = '<h6>' + sunset_icon + ' Sunset ' + sunset + '</h6>'
 
151
 
152
  global dfs
153
 
154
+ responses = openmeteo.weather_api(url, params=params)
155
+
156
+ # Process first location. Add a for-loop for multiple locations or weather models
157
+ response = responses[0]
158
+
159
+ # Process hourly data. The order of variables needs to be the same as requested.
160
+ hourly = response.Hourly()
161
+
162
+ hourly_temperature_2m = hourly.Variables(0).ValuesAsNumpy()
163
+ rain = hourly.Variables(1).ValuesAsNumpy()
164
+ hourly_wind_speed_10m = hourly.Variables(2).ValuesAsNumpy()
165
+ weather_code = hourly.Variables(3).ValuesAsNumpy()
166
+ is_day = hourly.Variables(4).ValuesAsNumpy()
167
+
168
+ hourly_data = {'date': pd.date_range(
169
+ start = pd.to_datetime(hourly.Time(), unit = 's', utc = True),
170
+ end = pd.to_datetime(hourly.TimeEnd(), unit = 's', utc = True),
171
+ freq = pd.Timedelta(seconds = hourly.Interval()),
172
+ inclusive = 'left'
173
+ )}
174
 
175
+ hourly_data['Temp (°C)'] = hourly_temperature_2m.round(0).astype(int)
176
+ hourly_data['weather_code'] = weather_code.astype(int)
177
+ hourly_data['is_day'] = is_day.astype(int)
178
 
179
+ v_rain_intensity = np.vectorize(rain_intensity)
180
+ hourly_data['Rain level'] = v_rain_intensity(rain)
181
 
182
+ v_beaufort_scale_kmh = np.vectorize(beaufort_scale_kmh)
 
 
183
 
184
+ hourly_data['Wind level'] = v_beaufort_scale_kmh(hourly_wind_speed_10m, language='en')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
+ hourly_data['Rain (mm/h)'] = rain.round(1)
187
+ hourly_data['Wind (km/h)'] = hourly_wind_speed_10m.round(1)
188
 
189
+ hourly_dataframe = pd.DataFrame(data = hourly_data)
 
190
 
191
+ hourly_dataframe['Temp (°C)'] = hourly_dataframe['Temp (°C)'].astype(str) + '°'
192
+ hourly_dataframe['Wind (km/h)'] = hourly_dataframe['Wind (km/h)'].astype(str).replace('0.0', '')
193
+ hourly_dataframe['Rain (mm/h)'] = hourly_dataframe['Rain (mm/h)'].astype(str).replace('0.0', '')
194
+ hourly_dataframe['Time'] = hourly_dataframe['date'].dt.hour.astype(str).str.zfill(2)
195
+
196
+ hourly_dataframe = hourly_dataframe.apply(map_icons, axis=1)
197
+
198
+ dfs = hourly_dataframe[hourly_dataframe['date'].dt.strftime('%Y-%m-%d') == date]
199
+
200
+ dfs = dfs[['Time', 'Weather', 'Weather outline', 'Temp (°C)', 'Rain (mm/h)', 'Rain level', 'Wind (km/h)', 'Wind level']]
201
+
202
+ dfs = dfs.style.set_properties(**{'border': '0px'})
203
 
204
  return dfs
205
 
 
229
  for segment in track.segments:
230
  for p in segment.points:
231
  points.append({
232
+ 'latitude': p.latitude,
233
+ 'longitude': p.longitude,
234
+ 'elevation': p.elevation,
235
  })
236
  df_gpx = pd.DataFrame.from_records(points)
237
+ gpx_dict = df_gpx.iloc[-1].to_dict()
238
+ params['latitude'] = gpx_dict['latitude']
239
+ params['longitude'] = gpx_dict['longitude']
240
+ params['elevation'] = gpx_dict['elevation']
241
+ lat = params['latitude']
242
+ lon = params['longitude']
243
+
244
+ if params['elevation'] == None:
245
+ params['elevation'] = int(round(elevation_data.get_elevation(lat, lon), 0))
246
  else:
247
+ params['elevation'] = int(round(params['elevation'], 0))
248
 
249
+ altitude = params['elevation']
250
 
251
  location = geolocator.reverse('{}, {}'.format(lat, lon), zoom=14)
252
 
 
327
  datatype=['str', 'html', 'str', 'str', 'str', 'str', 'str', 'str'],
328
  )
329
  gr.HTML('<center>Freedom Luxembourg<br><a style="color: DarkGoldenrod; font-style: italic; text-decoration: none" href="https://www.freeletz.lu/freeletz/" target="_blank">freeletz.lu</a></center>')
330
+ gr.HTML('<center>Powered by <a style="color: #004170; text-decoration: none" href="https://open-meteo.com/" target="_blank">Open Meteo</a></center>')
331
  upload_gpx.upload(fn=coor_gpx, inputs=upload_gpx, outputs=[file_name, loc, dates, choosen_date, sunrise, sunset, table])
332
  dates.input(fn=date_chooser, inputs=dates, outputs=[choosen_date, sunrise, sunset, table, dates])
333
 
requirements.txt CHANGED
@@ -1,65 +1,72 @@
1
  aiofiles==23.2.1
2
  annotated-types==0.7.0
3
- anyio==4.6.2.post1
4
  APScheduler==3.11.0
 
5
  beaufort-scale==1.0.2
 
6
  certifi==2024.8.30
7
  cffi==1.17.1
8
  charset-normalizer==3.4.0
9
  click==8.1.7
10
- fastapi==0.115.5
11
  ffmpy==0.4.0
12
  filelock==3.16.1
 
13
  fsspec==2024.10.0
14
  geographiclib==2.0
15
  geopy==2.4.1
16
  gpxpy==1.6.2
17
- gradio==5.7.1
18
- gradio_client==1.5.0
19
  h11==0.14.0
20
  h3==4.1.2
21
  httpcore==1.0.7
22
- httpx==0.28.0
23
- huggingface-hub==0.26.3
24
  idna==3.10
25
  Jinja2==3.1.4
26
- lxml==5.3.0
27
  markdown-it-py==3.0.0
28
  MarkupSafe==2.1.5
29
  mdurl==0.1.2
30
- numpy==2.1.3
 
 
31
  orjson==3.10.12
32
  packaging==24.2
33
  pandas==2.2.3
34
  pillow==11.0.0
 
35
  pycparser==2.22
36
- pydantic==2.10.2
37
  pydantic_core==2.27.1
38
  pydub==0.25.1
39
  Pygments==2.18.0
40
  python-dateutil==2.9.0.post0
41
- python-multipart==0.0.12
42
  pytz==2024.2
43
  PyYAML==6.0.2
44
  requests==2.32.3
 
 
45
  rich==13.9.4
46
- ruff==0.8.1
47
  safehttpx==0.1.6
48
  semantic-version==2.10.0
49
  shellingham==1.5.4
50
- six==1.16.0
51
  sniffio==1.3.1
52
  SRTM.py==0.3.7
53
  starlette==0.41.3
54
  sunrisesunset==1.0.2
55
  timezonefinder==6.5.7
56
- tomlkit==0.12.0
57
  tqdm==4.67.1
58
- typer==0.14.0
59
  typing_extensions==4.12.2
60
  tzdata==2024.2
61
  tzlocal==5.2
 
62
  urllib3==2.2.3
63
  uvicorn==0.32.1
64
- websockets==12.0
65
- wordsegment==1.3.1
 
1
  aiofiles==23.2.1
2
  annotated-types==0.7.0
3
+ anyio==4.7.0
4
  APScheduler==3.11.0
5
+ attrs==24.2.0
6
  beaufort-scale==1.0.2
7
+ cattrs==24.1.2
8
  certifi==2024.8.30
9
  cffi==1.17.1
10
  charset-normalizer==3.4.0
11
  click==8.1.7
12
+ fastapi==0.115.6
13
  ffmpy==0.4.0
14
  filelock==3.16.1
15
+ flatbuffers==24.3.25
16
  fsspec==2024.10.0
17
  geographiclib==2.0
18
  geopy==2.4.1
19
  gpxpy==1.6.2
20
+ gradio==5.8.0
21
+ gradio_client==1.5.1
22
  h11==0.14.0
23
  h3==4.1.2
24
  httpcore==1.0.7
25
+ httpx==0.28.1
26
+ huggingface-hub==0.26.5
27
  idna==3.10
28
  Jinja2==3.1.4
 
29
  markdown-it-py==3.0.0
30
  MarkupSafe==2.1.5
31
  mdurl==0.1.2
32
+ numpy==2.2.0
33
+ openmeteo_requests==1.3.0
34
+ openmeteo_sdk==1.18.0
35
  orjson==3.10.12
36
  packaging==24.2
37
  pandas==2.2.3
38
  pillow==11.0.0
39
+ platformdirs==4.3.6
40
  pycparser==2.22
41
+ pydantic==2.10.3
42
  pydantic_core==2.27.1
43
  pydub==0.25.1
44
  Pygments==2.18.0
45
  python-dateutil==2.9.0.post0
46
+ python-multipart==0.0.19
47
  pytz==2024.2
48
  PyYAML==6.0.2
49
  requests==2.32.3
50
+ requests-cache==1.2.1
51
+ retry-requests==2.0.0
52
  rich==13.9.4
53
+ ruff==0.8.3
54
  safehttpx==0.1.6
55
  semantic-version==2.10.0
56
  shellingham==1.5.4
57
+ six==1.17.0
58
  sniffio==1.3.1
59
  SRTM.py==0.3.7
60
  starlette==0.41.3
61
  sunrisesunset==1.0.2
62
  timezonefinder==6.5.7
63
+ tomlkit==0.13.2
64
  tqdm==4.67.1
65
+ typer==0.15.1
66
  typing_extensions==4.12.2
67
  tzdata==2024.2
68
  tzlocal==5.2
69
+ url-normalize==1.4.3
70
  urllib3==2.2.3
71
  uvicorn==0.32.1
72
+ websockets==14.1
 
weather_icons_custom.json ADDED
@@ -0,0 +1,1002 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "0": {
3
+ "day": {
4
+ "description": "Sunny",
5
+ "icon": "clear-day.svg"
6
+ },
7
+ "night": {
8
+ "description": "Clear",
9
+ "icon": "clear-night.svg"
10
+ }
11
+ },
12
+ "1": {
13
+ "day": {
14
+ "description": "Mostly Sunny",
15
+ "icon": "partly-cloudy-day.svg"
16
+ },
17
+ "night": {
18
+ "description": "Mostly Clear",
19
+ "icon": "partly-cloudy-night.svg"
20
+ }
21
+ },
22
+ "2": {
23
+ "day": {
24
+ "description": "Partly Cloudy",
25
+ "icon": "overcast-day.svg"
26
+ },
27
+ "night": {
28
+ "description": "Partly Cloudy",
29
+ "icon": "overcast-night.svg"
30
+ }
31
+ },
32
+ "3": {
33
+ "day": {
34
+ "description": "Cloudy",
35
+ "icon": "cloudy.svg"
36
+ },
37
+ "night": {
38
+ "description": "Cloudy",
39
+ "icon": "cloudy.svg"
40
+ }
41
+ },
42
+ "4": {
43
+ "day": {
44
+ "description": "Smoke",
45
+ "icon": "smoke.svg"
46
+ },
47
+ "night": {
48
+ "description": "Smoke",
49
+ "icon": "smoke.svg"
50
+ }
51
+ },
52
+ "5": {
53
+ "day": {
54
+ "description": "Haze",
55
+ "icon": "haze-day.svg"
56
+ },
57
+ "night": {
58
+ "description": "Haze",
59
+ "icon": "haze-night.svg"
60
+ }
61
+ },
62
+ "6": {
63
+ "day": {
64
+ "description": "Some Dust",
65
+ "icon": "dust-day.svg"
66
+ },
67
+ "night": {
68
+ "description": "Some Dust",
69
+ "icon": "dust-night.svg"
70
+ }
71
+ },
72
+ "7": {
73
+ "day": {
74
+ "description": "Dust",
75
+ "icon": "dust.svg"
76
+ },
77
+ "night": {
78
+ "description": "Dust",
79
+ "icon": "dust.svg"
80
+ }
81
+ },
82
+ "8": {
83
+ "day": {
84
+ "description": "Dust / Sand Whirls",
85
+ "icon": "dust-wind.svg"
86
+ },
87
+ "night": {
88
+ "description": "Dust / Sand Whirls",
89
+ "icon": "dust-wind.svg"
90
+ }
91
+ },
92
+ "9": {
93
+ "day": {
94
+ "description": "Duststorms / Sandstorms",
95
+ "icon": "dust-wind.svg"
96
+ },
97
+ "night": {
98
+ "description": "Duststorms / Sandstorms",
99
+ "icon": "dust-wind.svg"
100
+ }
101
+ },
102
+ "10": {
103
+ "day": {
104
+ "description": "Mist",
105
+ "icon": "mist.svg"
106
+ },
107
+ "night": {
108
+ "description": "Mist",
109
+ "icon": "mist.svg"
110
+ }
111
+ },
112
+ "11": {
113
+ "day": {
114
+ "description": "Foggy Patches",
115
+ "icon": "fog-day.svg"
116
+ },
117
+ "night": {
118
+ "description": "Foggy Patches",
119
+ "icon": "fog-night.svg"
120
+ }
121
+ },
122
+ "12": {
123
+ "day": {
124
+ "description": "Foggy",
125
+ "icon": "fog.svg"
126
+ },
127
+ "night": {
128
+ "description": "Foggy",
129
+ "icon": "fog.svg"
130
+ }
131
+ },
132
+ "13": {
133
+ "day": {
134
+ "description": "Distant lightning",
135
+ "icon": "thunderstorms-day.svg"
136
+ },
137
+ "night": {
138
+ "description": "Distant lightning",
139
+ "icon": "thunderstorms-night.svg"
140
+ }
141
+ },
142
+ "14": {
143
+ "day": {
144
+ "description": "Distant drizzle",
145
+ "icon": "partly-cloudy-day-drizzle.svg"
146
+ },
147
+ "night": {
148
+ "description": "Distant drizzle",
149
+ "icon": "partly-cloudy-night-drizzle.svg"
150
+ }
151
+ },
152
+ "15": {
153
+ "day": {
154
+ "description": "Distant rain",
155
+ "icon": "partly-cloudy-day-drizzle.svg"
156
+ },
157
+ "night": {
158
+ "description": "Distant rain",
159
+ "icon": "partly-cloudy-night-drizzle.svg"
160
+ }
161
+ },
162
+ "16": {
163
+ "day": {
164
+ "description": "Rain within sight",
165
+ "icon": "partly-cloudy-day-drizzle.svg"
166
+ },
167
+ "night": {
168
+ "description": "Rain within sight",
169
+ "icon": "partly-cloudy-night-drizzle.svg"
170
+ }
171
+ },
172
+ "17": {
173
+ "day": {
174
+ "description": "Thunder",
175
+ "icon": "thunderstorms-day.svg"
176
+ },
177
+ "night": {
178
+ "description": "Thunder",
179
+ "icon": "thunderstorms-night.svg"
180
+ }
181
+ },
182
+ "18": {
183
+ "day": {
184
+ "description": "Squalls",
185
+ "icon": "wind.svg"
186
+ },
187
+ "night": {
188
+ "description": "Squalls",
189
+ "icon": "wind.svg"
190
+ }
191
+ },
192
+ "19": {
193
+ "day": {
194
+ "description": "Funnel clouds",
195
+ "icon": "tornado.svg"
196
+ },
197
+ "night": {
198
+ "description": "Funnel clouds",
199
+ "icon": "tornado.svg"
200
+ }
201
+ },
202
+ "20": {
203
+ "day": {
204
+ "description": "Drizzle (previous hour)",
205
+ "icon": "partly-cloudy-day-drizzle.svg"
206
+ },
207
+ "night": {
208
+ "description": "Drizzle (previous hour)",
209
+ "icon": "partly-cloudy-night-drizzle.svg"
210
+ }
211
+ },
212
+ "21": {
213
+ "day": {
214
+ "description": "Light rain (previous hour)",
215
+ "icon": "partly-cloudy-day-drizzle.svg"
216
+ },
217
+ "night": {
218
+ "description": "Light rain (previous hour)",
219
+ "icon": "partly-cloudy-night-drizzle.svg"
220
+ }
221
+ },
222
+ "22": {
223
+ "day": {
224
+ "description": "Light snow (previous hour)",
225
+ "icon": "partly-cloudy-day-snow.svg"
226
+ },
227
+ "night": {
228
+ "description": "Light snow (previous hour)",
229
+ "icon": "partly-cloudy-night-snow.svg"
230
+ }
231
+ },
232
+ "23": {
233
+ "day": {
234
+ "description": "Sleet / Snow / Hail (previous hour)",
235
+ "icon": "partly-cloudy-day-sleet.svg"
236
+ },
237
+ "night": {
238
+ "description": "Sleet / Snow / Hail (previous hour)",
239
+ "icon": "partly-cloudy-night-sleet.svg"
240
+ }
241
+ },
242
+ "24": {
243
+ "day": {
244
+ "description": "Freezing drizzle / rain (previous hour)",
245
+ "icon": "partly-cloudy-day-sleet.svg"
246
+ },
247
+ "night": {
248
+ "description": "Freezing drizzle / rain (previous hour)",
249
+ "icon": "partly-cloudy-night-sleet.svg"
250
+ }
251
+ },
252
+ "25": {
253
+ "day": {
254
+ "description": "Rain (previous hour)",
255
+ "icon": "partly-cloudy-day-drizzle.svg"
256
+ },
257
+ "night": {
258
+ "description": "Rain (previous hour)",
259
+ "icon": "partly-cloudy-night-drizzle.svg"
260
+ }
261
+ },
262
+ "26": {
263
+ "day": {
264
+ "description": "Snow (previous hour)",
265
+ "icon": "partly-cloudy-day-snow.svg"
266
+ },
267
+ "night": {
268
+ "description": "Snow (previous hour)",
269
+ "icon": "partly-cloudy-night-snow.svg"
270
+ }
271
+ },
272
+ "27": {
273
+ "day": {
274
+ "description": "Hail (previous hour)",
275
+ "icon": "partly-cloudy-day-hail.svg"
276
+ },
277
+ "night": {
278
+ "description": "Hail (previous hour)",
279
+ "icon": "partly-cloudy-night-hail.svg"
280
+ }
281
+ },
282
+ "28": {
283
+ "day": {
284
+ "description": "Fog (previous hour)",
285
+ "icon": "fog-day.svg"
286
+ },
287
+ "night": {
288
+ "description": "Fog (previous hour)",
289
+ "icon": "fog-night.svg"
290
+ }
291
+ },
292
+ "29": {
293
+ "day": {
294
+ "description": "Thunderstorm (previous hour)",
295
+ "icon": "thunderstorms-day.svg"
296
+ },
297
+ "night": {
298
+ "description": "Thunderstorm (previous hour)",
299
+ "icon": "thunderstorms-night.svg"
300
+ }
301
+ },
302
+ "30": {
303
+ "day": {
304
+ "description": "Slight duststorm (receding)",
305
+ "icon": "dust-day.svg"
306
+ },
307
+ "night": {
308
+ "description": "Slight duststorm (receding)",
309
+ "icon": "dust-night.svg"
310
+ }
311
+ },
312
+ "31": {
313
+ "day": {
314
+ "description": "Slight duststorm (ongoing)",
315
+ "icon": "dust-day.svg"
316
+ },
317
+ "night": {
318
+ "description": "Slight duststorm (ongoing)",
319
+ "icon": "dust-night.svg"
320
+ }
321
+ },
322
+ "32": {
323
+ "day": {
324
+ "description": "Duststorm (building up)",
325
+ "icon": "dust-wind.svg"
326
+ },
327
+ "night": {
328
+ "description": "Duststorm (building up)",
329
+ "icon": "dust-wind.svg"
330
+ }
331
+ },
332
+ "33": {
333
+ "day": {
334
+ "description": "Duststorm (receding)",
335
+ "icon": "dust-day.svg"
336
+ },
337
+ "night": {
338
+ "description": "Duststorm (receding)",
339
+ "icon": "dust-night.svg"
340
+ }
341
+ },
342
+ "34": {
343
+ "day": {
344
+ "description": "Duststorm (ongoing)",
345
+ "icon": "dust-wind.svg"
346
+ },
347
+ "night": {
348
+ "description": "Duststorm (ongoing)",
349
+ "icon": "dust-wind.svg"
350
+ }
351
+ },
352
+ "35": {
353
+ "day": {
354
+ "description": "Severe duststorm (building up)",
355
+ "icon": "dust-wind.svg"
356
+ },
357
+ "night": {
358
+ "description": "Severe duststorm (building up)",
359
+ "icon": "dust-wind.svg"
360
+ }
361
+ },
362
+ "36": {
363
+ "day": {
364
+ "description": "Slight Drifting Snow",
365
+ "icon": "wind.svg"
366
+ },
367
+ "night": {
368
+ "description": "Slight Drifting Snow",
369
+ "icon": "wind.svg"
370
+ }
371
+ },
372
+ "37": {
373
+ "day": {
374
+ "description": "Heavy Drifting Snow",
375
+ "icon": "wind.svg"
376
+ },
377
+ "night": {
378
+ "description": "Heavy Drifting Snow",
379
+ "icon": "wind.svg"
380
+ }
381
+ },
382
+ "38": {
383
+ "day": {
384
+ "description": "Slight Blowing Snow",
385
+ "icon": "wind.svg"
386
+ },
387
+ "night": {
388
+ "description": "Slight Blowing Snow",
389
+ "icon": "wind.svg"
390
+ }
391
+ },
392
+ "39": {
393
+ "day": {
394
+ "description": "Heavy Blowing Snow",
395
+ "icon": "wind.svg"
396
+ },
397
+ "night": {
398
+ "description": "Heavy Blowing Snow",
399
+ "icon": "wind.svg"
400
+ }
401
+ },
402
+ "40": {
403
+ "day": {
404
+ "description": "Distant fog",
405
+ "icon": "partly-cloudy-day-fog.svg"
406
+ },
407
+ "night": {
408
+ "description": "Distant fog",
409
+ "icon": "partly-cloudy-night-fog.svg"
410
+ }
411
+ },
412
+ "41": {
413
+ "day": {
414
+ "description": "Fog Patches",
415
+ "icon": "fog-day.svg"
416
+ },
417
+ "night": {
418
+ "description": "Fog Patches",
419
+ "icon": "fog-night.svg"
420
+ }
421
+ },
422
+ "42": {
423
+ "day": {
424
+ "description": "Low fog (receding)",
425
+ "icon": "fog-day.svg"
426
+ },
427
+ "night": {
428
+ "description": "Low fog (receding)",
429
+ "icon": "fog-night.svg"
430
+ }
431
+ },
432
+ "43": {
433
+ "day": {
434
+ "description": "Fog (receding)",
435
+ "icon": "partly-cloudy-day-fog.svg"
436
+ },
437
+ "night": {
438
+ "description": "Fog (receding)",
439
+ "icon": "partly-cloudy-night-fog.svg"
440
+ }
441
+ },
442
+ "44": {
443
+ "day": {
444
+ "description": "Low fog (ongoing)",
445
+ "icon": "partly-cloudy-day-fog.svg"
446
+ },
447
+ "night": {
448
+ "description": "Low fog (ongoing)",
449
+ "icon": "partly-cloudy-night-fog.svg"
450
+ }
451
+ },
452
+ "45": {
453
+ "day": {
454
+ "description": "Fog (ongoing)",
455
+ "icon": "fog.svg"
456
+ },
457
+ "night": {
458
+ "description": "Fog (ongoing)",
459
+ "icon": "fog.svg"
460
+ }
461
+ },
462
+ "46": {
463
+ "day": {
464
+ "description": "Low fog (building up)",
465
+ "icon": "partly-cloudy-day-fog.svg"
466
+ },
467
+ "night": {
468
+ "description": "Low fog (building up)",
469
+ "icon": "partly-cloudy-night-fog.svg"
470
+ }
471
+ },
472
+ "47": {
473
+ "day": {
474
+ "description": "Fog (building up)",
475
+ "icon": "fog.svg"
476
+ },
477
+ "night": {
478
+ "description": "Fog (building up)",
479
+ "icon": "fog.svg"
480
+ }
481
+ },
482
+ "48": {
483
+ "day": {
484
+ "description": "Low Freezing Fog",
485
+ "icon": "partly-cloudy-day-fog.svg"
486
+ },
487
+ "night": {
488
+ "description": "Low Freezing Fog",
489
+ "icon": "partly-cloudy-night-fog.svg"
490
+ }
491
+ },
492
+ "49": {
493
+ "day": {
494
+ "description": "Freezing Fog",
495
+ "icon": "fog.svg"
496
+ },
497
+ "night": {
498
+ "description": "Freezing Fog",
499
+ "icon": "fog.svg"
500
+ }
501
+ },
502
+ "50": {
503
+ "day": {
504
+ "description": "Light Intermittent Drizzle",
505
+ "icon": "partly-cloudy-day-drizzle.svg"
506
+ },
507
+ "night": {
508
+ "description": "Light Intermittent Drizzle",
509
+ "icon": "partly-cloudy-night-drizzle.svg"
510
+ }
511
+ },
512
+ "51": {
513
+ "day": {
514
+ "description": "Light Drizzle",
515
+ "icon": "drizzle.svg"
516
+ },
517
+ "night": {
518
+ "description": "Light Drizzle",
519
+ "icon": "drizzle.svg"
520
+ }
521
+ },
522
+ "52": {
523
+ "day": {
524
+ "description": "Intermittent Drizzle",
525
+ "icon": "drizzle.svg"
526
+ },
527
+ "night": {
528
+ "description": "Intermittent Drizzle",
529
+ "icon": "drizzle.svg"
530
+ }
531
+ },
532
+ "53": {
533
+ "day": {
534
+ "description": "Drizzle",
535
+ "icon": "drizzle.svg"
536
+ },
537
+ "night": {
538
+ "description": "Drizzle",
539
+ "icon": "drizzle.svg"
540
+ }
541
+ },
542
+ "54": {
543
+ "day": {
544
+ "description": "Dense Intermittent Drizzle",
545
+ "icon": "drizzle.svg"
546
+ },
547
+ "night": {
548
+ "description": "Dense Intermittent Drizzle",
549
+ "icon": "drizzle.svg"
550
+ }
551
+ },
552
+ "55": {
553
+ "day": {
554
+ "description": "Dense Drizzle",
555
+ "icon": "drizzle.svg"
556
+ },
557
+ "night": {
558
+ "description": "Dense Drizzle",
559
+ "icon": "drizzle.svg"
560
+ }
561
+ },
562
+ "56": {
563
+ "day": {
564
+ "description": "Slight Freezing Drizzle",
565
+ "icon": "sleet.svg"
566
+ },
567
+ "night": {
568
+ "description": "Slight Freezing Drizzle",
569
+ "icon": "sleet.svg"
570
+ }
571
+ },
572
+ "57": {
573
+ "day": {
574
+ "description": "Freezing Drizzle",
575
+ "icon": "sleet.svg"
576
+ },
577
+ "night": {
578
+ "description": "Freezing Drizzle",
579
+ "icon": "sleet.svg"
580
+ }
581
+ },
582
+ "58": {
583
+ "day": {
584
+ "description": "Light Rain / Drizzle",
585
+ "icon": "drizzle.svg"
586
+ },
587
+ "night": {
588
+ "description": "Light Rain / Drizzle",
589
+ "icon": "drizzle.svg"
590
+ }
591
+ },
592
+ "59": {
593
+ "day": {
594
+ "description": "Rain / Drizzle",
595
+ "icon": "drizzle.svg"
596
+ },
597
+ "night": {
598
+ "description": "Rain / Drizzle",
599
+ "icon": "drizzle.svg"
600
+ }
601
+ },
602
+ "60": {
603
+ "day": {
604
+ "description": "Light Intermittent Rain",
605
+ "icon": "partly-cloudy-day-rain.svg"
606
+ },
607
+ "night": {
608
+ "description": "Light Intermittent Rain",
609
+ "icon": "partly-cloudy-night-rain.svg"
610
+ }
611
+ },
612
+ "61": {
613
+ "day": {
614
+ "description": "Light Rain",
615
+ "icon": "drizzle.svg"
616
+ },
617
+ "night": {
618
+ "description": "Light Rain",
619
+ "icon": "drizzle.svg"
620
+ }
621
+ },
622
+ "62": {
623
+ "day": {
624
+ "description": "Intermittent Rain",
625
+ "icon": "drizzle.svg"
626
+ },
627
+ "night": {
628
+ "description": "Intermittent Rain",
629
+ "icon": "drizzle.svg"
630
+ }
631
+ },
632
+ "63": {
633
+ "day": {
634
+ "description": "Rain",
635
+ "icon": "rain.svg"
636
+ },
637
+ "night": {
638
+ "description": "Rain",
639
+ "icon": "rain.svg"
640
+ }
641
+ },
642
+ "64": {
643
+ "day": {
644
+ "description": "Heavy Intermittent Rain",
645
+ "icon": "rain.svg"
646
+ },
647
+ "night": {
648
+ "description": "Heavy Intermittent Rain",
649
+ "icon": "rain.svg"
650
+ }
651
+ },
652
+ "65": {
653
+ "day": {
654
+ "description": "Heavy Rain",
655
+ "icon": "rain.svg"
656
+ },
657
+ "night": {
658
+ "description": "Heavy Rain",
659
+ "icon": "rain.svg"
660
+ }
661
+ },
662
+ "66": {
663
+ "day": {
664
+ "description": "Slight Freezing Rain",
665
+ "icon": "sleet.svg"
666
+ },
667
+ "night": {
668
+ "description": "Slight Freezing Rain",
669
+ "icon": "sleet.svg"
670
+ }
671
+ },
672
+ "67": {
673
+ "day": {
674
+ "description": "Freezing Rain",
675
+ "icon": "sleet.svg"
676
+ },
677
+ "night": {
678
+ "description": "Freezing Rain",
679
+ "icon": "sleet.svg"
680
+ }
681
+ },
682
+ "68": {
683
+ "day": {
684
+ "description": "Light Sleet",
685
+ "icon": "sleet.svg"
686
+ },
687
+ "night": {
688
+ "description": "Light Sleet",
689
+ "icon": "sleet.svg"
690
+ }
691
+ },
692
+ "69": {
693
+ "day": {
694
+ "description": "Sleet",
695
+ "icon": "sleet.svg"
696
+ },
697
+ "night": {
698
+ "description": "Sleet",
699
+ "icon": "sleet.svg"
700
+ }
701
+ },
702
+ "70": {
703
+ "day": {
704
+ "description": "Light Intermittent Snowfalls",
705
+ "icon": "partly-cloudy-day-snow.svg"
706
+ },
707
+ "night": {
708
+ "description": "Light Intermittent Snowfalls",
709
+ "icon": "partly-cloudy-night-snow.svg"
710
+ }
711
+ },
712
+ "71": {
713
+ "day": {
714
+ "description": "Light Snowfall",
715
+ "icon": "snow.svg"
716
+ },
717
+ "night": {
718
+ "description": "Light Snowfall",
719
+ "icon": "snow.svg"
720
+ }
721
+ },
722
+ "72": {
723
+ "day": {
724
+ "description": "Intermittent Snowfalls",
725
+ "icon": "snow.svg"
726
+ },
727
+ "night": {
728
+ "description": "Intermittent Snowfalls",
729
+ "icon": "snow.svg"
730
+ }
731
+ },
732
+ "73": {
733
+ "day": {
734
+ "description": "Snowfall",
735
+ "icon": "snow.svg"
736
+ },
737
+ "night": {
738
+ "description": "Snowfall",
739
+ "icon": "snow.svg"
740
+ }
741
+ },
742
+ "74": {
743
+ "day": {
744
+ "description": "Heavy Intermittent Snowfalls",
745
+ "icon": "snow.svg"
746
+ },
747
+ "night": {
748
+ "description": "Heavy Intermittent Snowfalls",
749
+ "icon": "snow.svg"
750
+ }
751
+ },
752
+ "75": {
753
+ "day": {
754
+ "description": "Heavy Snowfall",
755
+ "icon": "snow.svg"
756
+ },
757
+ "night": {
758
+ "description": "Heavy Snowfall",
759
+ "icon": "snow.svg"
760
+ }
761
+ },
762
+ "76": {
763
+ "day": {
764
+ "description": "Diamond dust",
765
+ "icon": "snow.svg"
766
+ },
767
+ "night": {
768
+ "description": "Diamond dust",
769
+ "icon": "snow.svg"
770
+ }
771
+ },
772
+ "77": {
773
+ "day": {
774
+ "description": "Snow grains",
775
+ "icon": "hail.svg"
776
+ },
777
+ "night": {
778
+ "description": "Snow grains",
779
+ "icon": "hail.svg"
780
+ }
781
+ },
782
+ "78": {
783
+ "day": {
784
+ "description": "Sparse snow crystals",
785
+ "icon": "snow.svg"
786
+ },
787
+ "night": {
788
+ "description": "Sparse snow crystals",
789
+ "icon": "snow.svg"
790
+ }
791
+ },
792
+ "79": {
793
+ "day": {
794
+ "description": "Ice pellets",
795
+ "icon": "hail.svg"
796
+ },
797
+ "night": {
798
+ "description": "Ice pellets",
799
+ "icon": "hail.svg"
800
+ }
801
+ },
802
+ "80": {
803
+ "day": {
804
+ "description": "Light Rain Showers",
805
+ "icon": "drizzle.svg"
806
+ },
807
+ "night": {
808
+ "description": "Light Rain Showers",
809
+ "icon": "drizzle.svg"
810
+ }
811
+ },
812
+ "81": {
813
+ "day": {
814
+ "description": "Rain Showers",
815
+ "icon": "rain.svg"
816
+ },
817
+ "night": {
818
+ "description": "Rain Showers",
819
+ "icon": "rain.svg"
820
+ }
821
+ },
822
+ "82": {
823
+ "day": {
824
+ "description": "Very Heavy Rain Showers",
825
+ "icon": "rain.svg"
826
+ },
827
+ "night": {
828
+ "description": "Very Heavy Rain Showers",
829
+ "icon": "rain.svg"
830
+ }
831
+ },
832
+ "83": {
833
+ "day": {
834
+ "description": "Light Sleet Showers",
835
+ "icon": "sleet.svg"
836
+ },
837
+ "night": {
838
+ "description": "Light Sleet Showers",
839
+ "icon": "sleet.svg"
840
+ }
841
+ },
842
+ "84": {
843
+ "day": {
844
+ "description": "Sleet Showers",
845
+ "icon": "sleet.svg"
846
+ },
847
+ "night": {
848
+ "description": "Sleet Showers",
849
+ "icon": "sleet.svg"
850
+ }
851
+ },
852
+ "85": {
853
+ "day": {
854
+ "description": "Light Snow Showers",
855
+ "icon": "snow.svg"
856
+ },
857
+ "night": {
858
+ "description": "Light Snow Showers",
859
+ "icon": "snow.svg"
860
+ }
861
+ },
862
+ "86": {
863
+ "day": {
864
+ "description": "Snow Showers",
865
+ "icon": "snow.svg"
866
+ },
867
+ "night": {
868
+ "description": "Snow Showers",
869
+ "icon": "snow.svg"
870
+ }
871
+ },
872
+ "87": {
873
+ "day": {
874
+ "description": "Light Snow Pellets / Small Hail",
875
+ "icon": "hail.svg"
876
+ },
877
+ "night": {
878
+ "description": "Light Snow Pellets / Small Hail",
879
+ "icon": "hail.svg"
880
+ }
881
+ },
882
+ "88": {
883
+ "day": {
884
+ "description": "Snow Pellets / Small Hail",
885
+ "icon": "hail.svg"
886
+ },
887
+ "night": {
888
+ "description": "Snow Pellets / Small Hail",
889
+ "icon": "hail.svg"
890
+ }
891
+ },
892
+ "89": {
893
+ "day": {
894
+ "description": "Slight Hail Showers",
895
+ "icon": "hail.svg"
896
+ },
897
+ "night": {
898
+ "description": "Slight Hail Showers",
899
+ "icon": "hail.svg"
900
+ }
901
+ },
902
+ "90": {
903
+ "day": {
904
+ "description": "Hail Showers",
905
+ "icon": "hail.svg"
906
+ },
907
+ "night": {
908
+ "description": "Hail Showers",
909
+ "icon": "hail.svg"
910
+ }
911
+ },
912
+ "91": {
913
+ "day": {
914
+ "description": "Light rain (post-thunderstorm)",
915
+ "icon": "drizzle.svg"
916
+ },
917
+ "night": {
918
+ "description": "Light rain (post-thunderstorm)",
919
+ "icon": "drizzle.svg"
920
+ }
921
+ },
922
+ "92": {
923
+ "day": {
924
+ "description": "Rain (post-thunderstorm)",
925
+ "icon": "rain.svg"
926
+ },
927
+ "night": {
928
+ "description": "Rain (post-thunderstorm)",
929
+ "icon": "rain.svg"
930
+ }
931
+ },
932
+ "93": {
933
+ "day": {
934
+ "description": "Light snow (post-thunderstorm)",
935
+ "icon": "snow.svg"
936
+ },
937
+ "night": {
938
+ "description": "Light snow (post-thunderstorm)",
939
+ "icon": "snow.svg"
940
+ }
941
+ },
942
+ "94": {
943
+ "day": {
944
+ "description": "Snow (post-thunderstorm)",
945
+ "icon": "snow.svg"
946
+ },
947
+ "night": {
948
+ "description": "Snow (post-thunderstorm)",
949
+ "icon": "snow.svg"
950
+ }
951
+ },
952
+ "95": {
953
+ "day": {
954
+ "description": "Thunderstorm with Showers",
955
+ "icon": "thunderstorms-rain.svg"
956
+ },
957
+ "night": {
958
+ "description": "Thunderstorm with Showers",
959
+ "icon": "thunderstorms-rain.svg"
960
+ }
961
+ },
962
+ "96": {
963
+ "day": {
964
+ "description": "Thunderstorm with Hail",
965
+ "icon": "thunderstorms-rain.svg"
966
+ },
967
+ "night": {
968
+ "description": "Thunderstorm with Hail",
969
+ "icon": "thunderstorms-rain.svg"
970
+ }
971
+ },
972
+ "97": {
973
+ "day": {
974
+ "description": "Heavy Thunderstorm with Showers",
975
+ "icon": "thunderstorms-rain.svg"
976
+ },
977
+ "night": {
978
+ "description": "Heavy Thunderstorm with Showers",
979
+ "icon": "thunderstorms-rain.svg"
980
+ }
981
+ },
982
+ "98": {
983
+ "day": {
984
+ "description": "Thunderstorm with dust/sandstorm",
985
+ "icon": "thunderstorms.svg"
986
+ },
987
+ "night": {
988
+ "description": "Thunderstorm with dust/sandstorm",
989
+ "icon": "thunderstorms.svg"
990
+ }
991
+ },
992
+ "99": {
993
+ "day": {
994
+ "description": "Heavy Thunderstorm with Hail",
995
+ "icon": "thunderstorms-rain.svg"
996
+ },
997
+ "night": {
998
+ "description": "Heavy Thunderstorm with Hail",
999
+ "icon": "thunderstorms-rain.svg"
1000
+ }
1001
+ }
1002
+ }