mirix commited on
Commit
d679073
·
verified ·
1 Parent(s): 43ba732

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +18 -0
  2. app.py +333 -0
  3. requirements.txt +66 -0
  4. weather_icons_custom.json +1002 -0
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.12
5
+
6
+ RUN useradd -m -u 1000 mirix
7
+ USER mirix
8
+ ENV PATH="/home/mirix/.local/bin:$PATH"
9
+
10
+ WORKDIR /app
11
+
12
+ COPY --chown=mirix ./requirements.txt requirements.txt
13
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
+ RUN pip install gunicorn
15
+
16
+ COPY --chown=mirix . /app
17
+
18
+ CMD ["gunicorn", "app:server", "-b", "0.0.0.0:7860"]
app.py ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timedelta
2
+ import pandas as pd
3
+ import numpy as np
4
+ import os
5
+
6
+ import srtm
7
+ elevation_data = srtm.get_data()
8
+
9
+ import json
10
+ import geopy
11
+ from geopy import distance
12
+ from beaufort_scale.beaufort_scale import beaufort_scale_kmh
13
+
14
+ import requests
15
+ import requests_cache
16
+ import openmeteo_requests
17
+ from retry_requests import retry
18
+
19
+ from dash import Dash, dcc, html, Input, Output, callback, no_update
20
+ from dash_extensions import Purify
21
+ import plotly.graph_objects as go
22
+
23
+ ### UPDATE PEAK LIST ###
24
+
25
+ lat = 49.610755
26
+ lon = 6.13268
27
+ ele = 310
28
+ dist = 100
29
+
30
+ overpass_url = 'https://overpass.private.coffee/api/interpreter'
31
+
32
+ def add_ele(row):
33
+ if str(int(round(row['altitude'], 0))).isnumeric():
34
+ row['altitude'] = row['altitude']
35
+ else:
36
+ row['altitude'] = elevation_data.get_elevation(row['latitude'], row['longitude'], 0)
37
+ return row
38
+
39
+ def eukarney(lat1, lon1):
40
+ p1 = (lat1, lon1)
41
+ p2 = (lat, lon)
42
+ karney = distance.distance(p1, p2).m
43
+ return karney
44
+
45
+ def compute_bbox(lat, lon, dist):
46
+ bearings = [225, 45]
47
+ origin = geopy.Point(lat, lon)
48
+ l = []
49
+
50
+ for bearing in bearings:
51
+ destination = distance.distance(dist).destination(origin, bearing)
52
+ coords = destination.latitude, destination.longitude
53
+ l.extend(coords)
54
+ return l
55
+
56
+ bbox = compute_bbox(lat, lon, dist)
57
+ bbox = ','.join(str(x) for x in compute_bbox(lat, lon, dist))
58
+
59
+ peak_list = 'peak_list.csv'
60
+
61
+ def update_peaks():
62
+
63
+ overpass_query = '[out:json];(nwr[natural=peak](' + bbox + ');nwr[natural=hill](' + bbox + '););out body;'
64
+
65
+ response = requests.get(overpass_url, params={'data': overpass_query})
66
+
67
+ response = response.json()
68
+
69
+ peak_dict = {'name': [], 'latitude': [], 'longitude': [], 'altitude': []}
70
+ for e in response['elements']:
71
+ peak_dict['latitude'].append(float(e['lat']))
72
+ peak_dict['longitude'].append(float(e['lon']))
73
+ if 'name' in e['tags'].keys():
74
+ peak_dict['name'].append(e['tags']['name'])
75
+ else:
76
+ peak_dict['name'].append('Unnamed hill')
77
+ if 'ele' in e['tags'].keys():
78
+ peak_dict['altitude'].append(float(e['tags']['ele']))
79
+ else:
80
+ peak_dict['altitude'].append(elevation_data.get_elevation(e['lat'], e['lon'], 0))
81
+
82
+
83
+ df = pd.DataFrame.from_dict(peak_dict)
84
+
85
+ df = df.apply(lambda x: add_ele(x), axis=1)
86
+
87
+ df['distances'] = df.apply(lambda x: eukarney(x['latitude'], x['longitude']), axis=1).fillna(0)
88
+
89
+ df['altitude'] = df['altitude'].round(0).astype(int)
90
+
91
+ df.to_csv(peak_list, index=False)
92
+
93
+ return df
94
+
95
+ ### WEATHER FORECAST ###
96
+
97
+ cache_session = requests_cache.CachedSession('.cache', expire_after = 3600)
98
+ retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2)
99
+ openmeteo = openmeteo_requests.Client(session = retry_session)
100
+
101
+ # Open Meteo weather forecast API
102
+ url = 'https://api.open-meteo.com/v1/forecast'
103
+ params = {
104
+ 'timezone': 'auto',
105
+ 'hourly': ['temperature_2m', 'is_day', 'rain', 'weather_code', 'wind_speed_10m', 'snow_depth']
106
+ }
107
+
108
+ # Load the JSON files mapping weather codes to descriptions and icons
109
+ with open('weather_icons_custom.json', 'r') as file:
110
+ icons = json.load(file)
111
+
112
+ # Weather icons URL
113
+ icon_url = 'https://raw.githubusercontent.com/basmilius/weather-icons/refs/heads/dev/production/fill/svg/'
114
+
115
+ def map_icons(df):
116
+ code = df['weather_code']
117
+
118
+ if df['is_day'] == 1:
119
+ icon = icons[str(code)]['day']['icon']
120
+ description = icons[str(code)]['day']['description']
121
+ elif df['is_day'] == 0:
122
+ icon = icons[str(code)]['night']['icon']
123
+ description = icons[str(code)]['night']['description']
124
+
125
+ df['Weather'] = icon_url + icon
126
+ df['Weather outline'] = description
127
+
128
+ return df
129
+
130
+ # Quantitative pluviometry to natural language
131
+ def rain_intensity(precipt):
132
+ if precipt >= 50:
133
+ rain = 'Extreme rain'
134
+ elif 50 < precipt <= 16:
135
+ rain = 'Very heavy rain'
136
+ elif 4 <= precipt < 16:
137
+ rain = 'Heavy rain'
138
+ elif 1 <= precipt < 4:
139
+ rain = 'Moderate rain'
140
+ elif 0.25 <= precipt < 1:
141
+ rain = 'Light rain'
142
+ elif 0 < precipt < 0.25:
143
+ rain = 'Light drizzle'
144
+ else:
145
+ rain = 'No rain / No info'
146
+ return rain
147
+
148
+ # Obtain the weather forecast for each waypoint at each specific time
149
+ def get_weather(df):
150
+
151
+ params['latitude'] = df['latitude']
152
+ params['longitude'] = df['longitude']
153
+ params['elevation'] = df['altitude']
154
+
155
+ now = datetime.now()
156
+
157
+ start_period = (now - timedelta(seconds=3600)).strftime('%Y-%m-%dT%H:%M')
158
+ end_period = now.strftime('%Y-%m-%dT%H:%M')
159
+
160
+ params['start_hour'] = start_period
161
+ params['end_hour'] = end_period
162
+
163
+ responses = openmeteo.weather_api(url, params=params)
164
+
165
+ # Process first location. Add a for-loop for multiple locations or weather models
166
+ response = responses[0]
167
+
168
+ # Process hourly data. The order of variables needs to be the same as requested.
169
+ # currently = response.Current()
170
+ hourly = response.Hourly()
171
+
172
+ minutely_temperature_2m = hourly.Variables(0).ValuesAsNumpy()[0]
173
+ is_day = hourly.Variables(1).ValuesAsNumpy()[0]
174
+ rain = hourly.Variables(2).ValuesAsNumpy()[0]
175
+ weather_code = hourly.Variables(3).ValuesAsNumpy()[0]
176
+ minutely_wind_speed_10m = hourly.Variables(4).ValuesAsNumpy()[0]
177
+ snow_depth = hourly.Variables(5).ValuesAsNumpy()[0]
178
+
179
+ df['Temp (°C)'] = minutely_temperature_2m
180
+ df['weather_code'] = weather_code
181
+ df['is_day'] = is_day
182
+
183
+ v_rain_intensity = np.vectorize(rain_intensity)
184
+ df['Rain level'] = v_rain_intensity(rain)
185
+
186
+ v_beaufort_scale_kmh = np.vectorize(beaufort_scale_kmh)
187
+
188
+ df['Wind level'] = v_beaufort_scale_kmh(minutely_wind_speed_10m, language='en')
189
+
190
+ df['Rain (mm/h)'] = rain
191
+ df['Wind (km/h)'] = minutely_wind_speed_10m
192
+
193
+ df['Snow depth (cm)'] = (snow_depth * 100).round(1)
194
+
195
+ return df
196
+
197
+
198
+ def format_peaks():
199
+
200
+ if not os.path.isfile(peak_list):
201
+ update_peaks()
202
+
203
+ today = datetime.today()
204
+ modified_date = datetime.fromtimestamp(os.path.getmtime(peak_list))
205
+ peak_age = today - modified_date
206
+
207
+ if peak_age.days > 30:
208
+ update_peaks()
209
+
210
+ df = pd.read_csv(peak_list)
211
+ df = df[df['altitude']>=df['altitude'].quantile(3/4)].copy()
212
+ df = df.sort_values(by='distances',ascending=True).reset_index(drop=True)
213
+ df = df.head(600).copy()
214
+
215
+ df = df.apply(lambda x: get_weather(x), axis=1)
216
+
217
+ df['Temp (°C)'] = df['Temp (°C)'].round(0).astype(int).astype(str) + '°C'
218
+ df['Wind (km/h)'] = df['Wind (km/h)'].round(1).astype(str).replace('0.0', '')
219
+ df['Rain (mm/h)'] = df['Rain (mm/h)'].round(1).astype(str).replace('0.0', '')
220
+ df['distances'] = (df['distances'] / 1000).round(1).astype(str) + ' km'
221
+ df['Snow depth (cm)'] = df['Snow depth (cm)'].astype(str) + ' cm'
222
+ df['altitude'] = df['altitude'].astype(str) + ' m'
223
+ df['is_day'] = df['is_day'].astype(int)
224
+
225
+ df['weather_code'] = df['weather_code'].astype(int)
226
+ df = df.apply(map_icons, axis=1)
227
+
228
+ df['Rain level'] = df['Rain level'].astype(str)
229
+ df['Wind level'] = df['Wind level'].astype(str)
230
+
231
+ df = df.rename(columns={'distances': 'Distance (km)'})
232
+
233
+ df['dist_read'] = ('<p style="font-family:sans; font-size:12px;">' +
234
+ df['name'] + '<br>' +
235
+ df['altitude'] + ' | ' + df['Distance (km)'] + '<br><br>' +
236
+ 'Snow: ' + df['Snow depth (cm)'] + '<br><br>' +
237
+ '<b>' + df['Weather outline'] + '</b><br><br>' +
238
+ df['Temp (°C)'] + '<br><br>' +
239
+ df['Rain level'] + '<br>' +
240
+ df['Wind level'])
241
+
242
+ return df
243
+
244
+ def snow_color(row):
245
+ if row['Snow depth (cm)'] == '0.0 cm':
246
+ row['snow_colour'] = 'goldenrod'
247
+ else:
248
+ row['snow_colour'] = 'aqua'
249
+ return row
250
+
251
+ def plot_fig():
252
+
253
+ global df
254
+
255
+ lat_centre = 49.8464
256
+ lon_centre = 6.0992
257
+
258
+ df = format_peaks()
259
+
260
+ df['snow_colour'] = ''
261
+
262
+ df = df.apply(lambda row: snow_color(row), axis=1)
263
+
264
+ fig = go.Figure()
265
+
266
+ fig.add_trace(go.Scattermap(lon=df['longitude'],
267
+ lat=df['latitude'],
268
+ mode='markers', marker=dict(size=24, color=df['snow_colour'], opacity=0.8, symbol='circle'),
269
+ name='circles'))
270
+
271
+ fig.add_trace(go.Scattermap(lon=df['longitude'],
272
+ lat=df['latitude'],
273
+ mode='markers', marker=dict(size=8, opacity=1, symbol='mountain'),
274
+ name='peaks'))
275
+
276
+ fig.update_layout(map_style='open-street-map',
277
+ map=dict(center=dict(lat=lat_centre, lon=lon_centre), zoom=8))
278
+
279
+ fig.update_traces(showlegend=False, hoverinfo='none', hovertemplate=None, selector=({'name': 'circles'}))
280
+ fig.update_traces(showlegend=False, hoverinfo='none', hovertemplate=None, selector=({'name': 'peaks'}))
281
+
282
+ return fig
283
+
284
+ app = Dash(__name__)
285
+ server = app.server
286
+
287
+ def serve_layout():
288
+
289
+ layout = html.Div([
290
+ html.Div([dcc.Graph(id='base-figure', clear_on_unhover=True, style={'height': '99vh'})], id='base-figure-div'),
291
+ dcc.Tooltip(id='figure-tooltip'),
292
+ dcc.Interval(
293
+ id='interval-component',
294
+ interval=60 * 60 * 1000,
295
+ n_intervals=0),
296
+ ], id='layout-content')
297
+
298
+ return layout
299
+
300
+ app.layout = serve_layout
301
+
302
+ @callback(Output('figure-tooltip', 'show'),
303
+ Output('figure-tooltip', 'bbox'),
304
+ Output('figure-tooltip', 'children'),
305
+ Input('base-figure', 'hoverData'))
306
+ def display_hover(hoverData):
307
+
308
+ if hoverData is None:
309
+ return False, no_update, no_update
310
+
311
+ pt = hoverData['points'][0]
312
+ bbox = pt['bbox']
313
+ num = pt['pointNumber']
314
+
315
+ df_row = df.iloc[num].copy()
316
+ img_src = df_row['Weather']
317
+ txt_src = df_row['dist_read']
318
+
319
+ children = [html.Div([html.Img(src=img_src, style={'width': '100%'}), Purify(txt_src),],
320
+ style={'width': '96px', 'white-space': 'normal'})]
321
+
322
+ return True, bbox, children
323
+
324
+ @callback(Output('base-figure', 'figure'),
325
+ [Input('interval-component', 'n_intervals')])
326
+ def refresh_layout(n):
327
+ global fig
328
+ fig = plot_fig()
329
+ return fig
330
+
331
+ if __name__ == '__main__':
332
+ app.run(debug=True, host='0.0.0.0', port=7860)
333
+
requirements.txt ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ annotated-types==0.7.0
2
+ attrs==24.3.0
3
+ beaufort-scale==1.0.2
4
+ blinker==1.9.0
5
+ cachelib==0.9.0
6
+ cattrs==24.1.2
7
+ certifi==2024.12.14
8
+ cffi==1.17.1
9
+ charset-normalizer==3.4.0
10
+ click==8.1.7
11
+ dash==2.18.2
12
+ dash-bootstrap-components==1.6.0
13
+ dash-core-components==2.0.0
14
+ dash-extensions==1.0.19
15
+ dash-html-components==2.0.0
16
+ dash-table==5.0.0
17
+ dash_mantine_components==0.15.1
18
+ dataclass-wizard==0.30.1
19
+ DateTime==5.5
20
+ EditorConfig==0.17.0
21
+ Flask==3.0.3
22
+ Flask-Caching==2.3.0
23
+ flatbuffers==24.3.25
24
+ geographiclib==2.0
25
+ geopy==2.4.1
26
+ gpx-converter==2.1.0
27
+ gpxpy==1.6.2
28
+ h3==4.1.2
29
+ idna==3.10
30
+ importlib_metadata==8.5.0
31
+ itsdangerous==2.2.0
32
+ Jinja2==3.1.4
33
+ jsbeautifier==1.15.1
34
+ MarkupSafe==3.0.2
35
+ more-itertools==10.5.0
36
+ nest-asyncio==1.6.0
37
+ numpy==2.2.0
38
+ openmeteo_requests==1.3.0
39
+ openmeteo_sdk==1.18.0
40
+ packaging==24.2
41
+ pandas==2.2.3
42
+ platformdirs==4.3.6
43
+ plotly==5.24.1
44
+ pycparser==2.22
45
+ pydantic==2.10.4
46
+ pydantic_core==2.27.2
47
+ python-dateutil==2.9.0.post0
48
+ pytz==2024.2
49
+ requests==2.32.3
50
+ requests-cache==1.2.1
51
+ retry-requests==2.0.0
52
+ retrying==1.3.4
53
+ setuptools==75.6.0
54
+ six==1.17.0
55
+ SRTM.py==0.3.7
56
+ sunrisesunset==1.0.2
57
+ tenacity==9.0.0
58
+ timezonefinder==6.5.7
59
+ typing_extensions==4.12.2
60
+ tzdata==2024.2
61
+ tzlocal==5.2
62
+ url-normalize==1.4.3
63
+ urllib3==2.2.3
64
+ Werkzeug==3.0.6
65
+ zipp==3.21.0
66
+ zope.interface==7.2
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
+ }