geo-activity-playground 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,6 +32,17 @@ logger = logging.getLogger(__name__)
32
32
  DEFAULT_UNKNOWN_NAME = "Unknown"
33
33
 
34
34
 
35
+ def format_timedelta(v: datetime.timedelta):
36
+ if pd.isna(v):
37
+ return "—"
38
+ else:
39
+ seconds = v.total_seconds()
40
+ h = int(seconds // 3600)
41
+ m = int(seconds // 60 % 60)
42
+ s = int(seconds // 1 % 60)
43
+ return f"{h}:{m:02d}:{s:02d}"
44
+
45
+
35
46
  class ActivityMeta(TypedDict):
36
47
  average_speed_elapsed_kmh: float
37
48
  average_speed_moving_kmh: float
@@ -165,6 +176,23 @@ class Activity(DB.Model):
165
176
  else:
166
177
  return self.raw_time_series
167
178
 
179
+ @property
180
+ def emoji_string(self) -> str:
181
+ bits = []
182
+ if self.kind:
183
+ bits.append(f"{self.kind.name} with")
184
+ if self.distance_km:
185
+ bits.append(f"📏 {round(self.distance_km, 1)} km")
186
+ if self.elapsed_time:
187
+ bits.append(f"⏱️ {format_timedelta(self.elapsed_time)} h")
188
+ if self.elevation_gain:
189
+ bits.append(f"⛰️ {round(self.elevation_gain, 1)} m")
190
+ if self.calories:
191
+ bits.append(f"🍭 {self.calories} kcal")
192
+ if self.steps:
193
+ bits.append(f"👣 {self.steps}")
194
+ return " ".join(bits)
195
+
168
196
  def delete_data(self) -> None:
169
197
  for path in [
170
198
  TIME_SERIES_DIR() / f"{self.id}.parquet",
@@ -229,14 +257,15 @@ def query_activity_meta(clauses: list = []) -> pd.DataFrame:
229
257
  .order_by(Activity.start)
230
258
  ).all()
231
259
  df = pd.DataFrame(rows)
232
- # If the search yields only activities without time information, the dtype isn't derived correctly.
233
- df["start"] = pd.to_datetime(df["start"])
234
- # start = df["start"].to_list()
235
- # random.shuffle(start)
236
- # df["start"] = pd.Series(start)
237
- df["elapsed_time"] = pd.to_timedelta(df["elapsed_time"])
238
260
 
239
261
  if len(df):
262
+ # If the search yields only activities without time information, the dtype isn't derived correctly.
263
+ df["start"] = pd.to_datetime(df["start"])
264
+ # start = df["start"].to_list()
265
+ # random.shuffle(start)
266
+ # df["start"] = pd.Series(start)
267
+ df["elapsed_time"] = pd.to_timedelta(df["elapsed_time"])
268
+
240
269
  for old, new in [
241
270
  ("elapsed_time", "average_speed_elapsed_kmh"),
242
271
  ("moving_time", "average_speed_moving_kmh"),
@@ -12,6 +12,7 @@ from flask import render_template
12
12
  from flask import request
13
13
  from flask import Response
14
14
  from flask import url_for
15
+ from flask.typing import ResponseReturnValue
15
16
  from PIL import Image
16
17
  from PIL import ImageOps
17
18
 
@@ -123,7 +124,7 @@ def make_photo_blueprint(
123
124
 
124
125
  @blueprint.route("/new", methods=["GET", "POST"])
125
126
  @needs_authentication(authenticator)
126
- def new() -> Response:
127
+ def new() -> ResponseReturnValue:
127
128
  if request.method == "POST":
128
129
  # check if the post request has the file part
129
130
  if "file" not in request.files:
@@ -132,66 +133,74 @@ def make_photo_blueprint(
132
133
  )
133
134
  return redirect(url_for(".new"))
134
135
 
135
- file = request.files["file"]
136
- # If the user does not select a file, the browser submits an
137
- # empty file without a filename.
138
- if file.filename == "":
139
- flasher.flash_message("No selected file.", FlashTypes.WARNING)
140
- return redirect(url_for(".new"))
141
- if not file:
142
- flasher.flash_message("Empty file uploaded.", FlashTypes.WARNING)
143
- return redirect(url_for(".new"))
136
+ new_photos: list[Photo] = []
137
+ for file in request.files.getlist("file"):
138
+ # If the user does not select a file, the browser submits an
139
+ # empty file without a filename.
140
+ if file.filename == "":
141
+ flasher.flash_message("No selected file.", FlashTypes.WARNING)
142
+ return redirect(url_for(".new"))
143
+ if not file:
144
+ flasher.flash_message("Empty file uploaded.", FlashTypes.WARNING)
145
+ return redirect(url_for(".new"))
146
+
147
+ filename = str(uuid.uuid4()) + pathlib.Path(file.filename).suffix
148
+ path = PHOTOS_DIR() / "original" / filename
149
+ path.parent.mkdir(exist_ok=True)
150
+ file.save(path)
151
+ metadata = get_metadata_from_image(path)
152
+
153
+ if "time" not in metadata:
154
+ flasher.flash_message(
155
+ f"Your image '{file.filename}' doesn't have the EXIF attribute 'EXIF DateTimeOriginal' and hence cannot be dated.",
156
+ FlashTypes.DANGER,
157
+ )
158
+ continue
159
+ time: datetime.datetime = metadata["time"]
160
+
161
+ activity = DB.session.scalar(
162
+ sqlalchemy.select(Activity)
163
+ .where(
164
+ Activity.start.is_not(None),
165
+ Activity.elapsed_time.is_not(None),
166
+ Activity.start <= time,
167
+ )
168
+ .order_by(Activity.start.desc())
169
+ .limit(1)
170
+ )
171
+ if activity is None or activity.start + activity.elapsed_time < time:
172
+ flasher.flash_message(
173
+ f"Your image '{file.filename}' is from {time} but no activity could be found. Please first upload an activity or fix the time in the photo.",
174
+ FlashTypes.DANGER,
175
+ )
176
+ continue
177
+
178
+ if "latitude" not in metadata:
179
+ time_series = activity.time_series
180
+ print(time_series)
181
+ row = time_series.loc[time_series["time"] >= time].iloc[0]
182
+ metadata["latitude"] = row["latitude"]
183
+ metadata["longitude"] = row["longitude"]
184
+
185
+ photo = Photo(
186
+ filename=filename,
187
+ time=time,
188
+ latitude=metadata["latitude"],
189
+ longitude=metadata["longitude"],
190
+ activity=activity,
191
+ )
144
192
 
145
- filename = str(uuid.uuid4()) + pathlib.Path(file.filename).suffix
146
- path = PHOTOS_DIR() / "original" / filename
147
- path.parent.mkdir(exist_ok=True)
148
- file.save(path)
149
- metadata = get_metadata_from_image(path)
193
+ DB.session.add(photo)
194
+ DB.session.commit()
195
+ new_photos.append(photo)
150
196
 
151
- if "time" not in metadata:
197
+ if new_photos:
152
198
  flasher.flash_message(
153
- "Your image doesn't have the EXIF attribute 'EXIF DateTimeOriginal' and hence cannot be dated.",
154
- FlashTypes.DANGER,
199
+ f"Added {len(new_photos)} new photos.", FlashTypes.SUCCESS
155
200
  )
201
+ return redirect(f"/activity/{new_photos[-1].activity.id}")
202
+ else:
156
203
  return redirect(url_for(".new"))
157
- time: datetime.datetime = metadata["time"]
158
-
159
- activity = DB.session.scalar(
160
- sqlalchemy.select(Activity)
161
- .where(
162
- Activity.start.is_not(None),
163
- Activity.elapsed_time.is_not(None),
164
- Activity.start <= time,
165
- )
166
- .order_by(Activity.start.desc())
167
- .limit(1)
168
- )
169
- if activity is None or activity.start + activity.elapsed_time < time:
170
- flasher.flash_message(
171
- f"Your image is from {time} but no activity could be found. Please first upload an activity or fix the time in the photo",
172
- FlashTypes.DANGER,
173
- )
174
- print(activity)
175
-
176
- if "latitude" not in metadata:
177
- time_series = activity.time_series
178
- print(time_series)
179
- row = time_series.loc[time_series["time"] >= time].iloc[0]
180
- metadata["latitude"] = row["latitude"]
181
- metadata["longitude"] = row["longitude"]
182
-
183
- photo = Photo(
184
- filename=filename,
185
- time=time,
186
- latitude=metadata["latitude"],
187
- longitude=metadata["longitude"],
188
- activity=activity,
189
- )
190
-
191
- DB.session.add(photo)
192
- DB.session.commit()
193
-
194
- return redirect(f"/activity/{activity.id}")
195
204
  else:
196
205
  return render_template("photo/new.html.j2")
197
206
 
@@ -447,6 +447,23 @@ def make_settings_blueprint(
447
447
  else:
448
448
  return render_template("settings/tags-edit.html.j2", tag=tag)
449
449
 
450
+ @blueprint.route("/tile-source", methods=["GET", "POST"])
451
+ @needs_authentication(authenticator)
452
+ def tile_source() -> str:
453
+ if request.method == "POST":
454
+ config_accessor().map_tile_url = request.form["map_tile_url"]
455
+ config_accessor().map_tile_attribution = request.form[
456
+ "map_tile_attribution"
457
+ ]
458
+ config_accessor.save()
459
+ flasher.flash_message("Tile source updated.", FlashTypes.SUCCESS)
460
+ return render_template(
461
+ "settings/tile-source.html.j2",
462
+ map_tile_url=config_accessor().map_tile_url,
463
+ map_tile_attribution=config_accessor().map_tile_attribution,
464
+ test_url=config_accessor().map_tile_url.format(zoom=14, x=8514, y=5504),
465
+ )
466
+
450
467
  return blueprint
451
468
 
452
469
 
@@ -49,13 +49,13 @@
49
49
  <h3>{{ equipment }}</h3>
50
50
  <div class="row mb-3">
51
51
  <div class="col-md-4">
52
- {{ vega_direct(data.total_distances_plot_id, data.total_distances_plot) }}
52
+ {{ vega_direct(data.total_distances_plot) }}
53
53
  </div>
54
54
  <div class="col-md-4">
55
- {{ vega_direct(data.yearly_distance_plot_id, data.yearly_distance_plot) }}
55
+ {{ vega_direct(data.yearly_distance_plot) }}
56
56
  </div>
57
57
  <div class="col-md-4">
58
- {{ vega_direct(data.usages_plot_id, data.usages_plot) }}
58
+ {{ vega_direct(data.usages_plot) }}
59
59
  </div>
60
60
  </div>
61
61
  {% endfor %}
@@ -44,9 +44,8 @@
44
44
  {% endfor %}
45
45
  </ul>
46
46
  </p>
47
- <p class="card-text"><small class="text-body-secondary"></small>{{ activity.kind }} with {{
48
- (activity.distance_km)|round(1) }} km / {{activity.elevation_gain|round|int}} m in {{
49
- activity.elapsed_time|td }} on {{ activity.start|dt }}</small></p>
47
+ <p class="card-text"><small class="text-body-secondary"></small>{{ activity.emoji_string }} on {{
48
+ activity.start|dt }}</small></p>
50
49
  </div>
51
50
  </div>
52
51
  </div>
@@ -46,14 +46,7 @@
46
46
  <h5 class="card-title">{{ elem.activity.name }}</h5>
47
47
  </a>
48
48
  <p class="card-text">
49
- {{ elem.activity.kind.name }} with
50
- 📏 {{ (elem.activity.distance_km)|round(1) }} km
51
- {% if elem.activity.elapsed_time %}
52
- ⏱️ {{ elem.activity.elapsed_time|td }}
53
- {% endif %}
54
- {% if elem.activity.elevation_gain %}
55
- ⛰️ {{ (elem.activity.elevation_gain)|round|int }} m
56
- {% endif %}
49
+ {{ elem.activity.emoji_string }}
57
50
  </p>
58
51
  {% if elem.activity.start %}
59
52
  <p class="card-text"><small class="text-body-secondary">{{ elem.activity.start|dt }}</small></p>
@@ -6,7 +6,7 @@
6
6
  <form method="POST" enctype="multipart/form-data">
7
7
  <div class="mb-3">
8
8
  <label for="file" class="form-label">Photo file</label>
9
- <input type="file" name="file" id="file" class="form-control">
9
+ <input type="file" name="file" id="file" class="form-control" multiple>
10
10
  </div>
11
11
  <button type="submit" class="btn btn-primary">Upload</button>
12
12
  </form>
@@ -56,6 +56,15 @@
56
56
  </div>
57
57
  </div>
58
58
  </div>
59
+ <div class="col">
60
+ <div class="card">
61
+ <div class="card-body">
62
+ <h5 class="card-title">Map tile source</h5>
63
+ <p class="card-text">Change the source of the map tiles.</p>
64
+ <a href="{{ url_for('.tile_source') }}" class="btn btn-primary">Change tile source</a>
65
+ </div>
66
+ </div>
67
+ </div>
59
68
  <div class="col">
60
69
  <div class="card">
61
70
  <div class="card-body">
@@ -0,0 +1,33 @@
1
+ {% extends "page.html.j2" %}
2
+
3
+ {% block container %}
4
+
5
+ <h1 class="mb-3">Tile Source</h1>
6
+
7
+ <p>You can change the tile source to be whatever you like. Be aware that different sources have different licensing
8
+ constraints. It is on you to make sure that you are allowed to use the tiles from the source that you enter. See <a
9
+ href="https://wiki.openstreetmap.org/wiki/Raster_tile_providers" target="_blank">this list of raster tile
10
+ providers</a> for inspiration.</p>
11
+
12
+
13
+ <form action="" method="POST" class="mb-3">
14
+ <div class="mb-3">
15
+ <label for="map_tile_url" class="form-label">Map tile URL</label>
16
+ <input type="text" class="form-control" id="map_tile_url" name="map_tile_url" value="{{ map_tile_url }}" />
17
+ </div>
18
+ <div class="mb-3">
19
+ <label for="map_tile_attribution" class="form-label">Map tile attribution</label>
20
+ <input type="text" class="form-control" id="map_tile_attribution" name="map_tile_attribution"
21
+ value="{{ map_tile_attribution|e }}" />
22
+ </div>
23
+
24
+ <button type="submit" class="btn btn-primary">Save</button>
25
+ </form>
26
+
27
+ <h2>Test image</h2>
28
+
29
+ <p>This is a tile using your current tile source:</p>
30
+
31
+ <p><img src="{{ test_url }}"></p>
32
+
33
+ {% endblock %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geo-activity-playground
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: Analysis of geo data activities like rides, runs or hikes.
5
5
  License: MIT
6
6
  Author: Martin Ueding
@@ -18,7 +18,7 @@ geo_activity_playground/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
18
18
  geo_activity_playground/core/activities.py,sha256=apP_-Rg1ub3lh7RARMGXf2BOmJTiahxqpX_soEnYF3E,4681
19
19
  geo_activity_playground/core/config.py,sha256=mmdMQ5iCLNGnAlriT1ETEVS-gM6Aq_9sg22QECHj4n8,5358
20
20
  geo_activity_playground/core/coordinates.py,sha256=tDfr9mlXhK6E_MMIJ0vYWVCoH0Lq8uyuaqUgaa8i0jg,966
21
- geo_activity_playground/core/datamodel.py,sha256=FDeoejm2OOzh2ZYjIXV24fI29V6m91LGxvBoGUFLY6g,13901
21
+ geo_activity_playground/core/datamodel.py,sha256=yzHdALuA9MShuBXtyEUoE0PS_7C8SNw9Weqa21_ALg4,14820
22
22
  geo_activity_playground/core/enrichment.py,sha256=Tju9sKI-V40CmsS9RiNeGz-Zhp_hx1xjlaWzJMrasXI,7640
23
23
  geo_activity_playground/core/export.py,sha256=ayOmhWL72263oP9NLIZRYCg_Db0GLUFhgNIL_MCrV-E,4435
24
24
  geo_activity_playground/core/heart_rate.py,sha256=-S3WAhS7AOywrw_Lk5jfuo_fu6zvZQ1VtjwEKSycWpU,1542
@@ -68,10 +68,10 @@ geo_activity_playground/webui/blueprints/explorer_blueprint.py,sha256=vOzDI2lq-e
68
68
  geo_activity_playground/webui/blueprints/export_blueprint.py,sha256=C9yFH5gEJs2YtWE-EhcGDEyGwwaLgC1umybgIRi6duE,1036
69
69
  geo_activity_playground/webui/blueprints/hall_of_fame_blueprint.py,sha256=zNYKw7ps9Yx9995Zsj4psAlOLnt4tFi2Hwp74-kjmzw,2806
70
70
  geo_activity_playground/webui/blueprints/heatmap_blueprint.py,sha256=iHI5YJYhX7ZOlzTgzl2efIRDzt3UMYCx7X4-LVd0MWk,8702
71
- geo_activity_playground/webui/blueprints/photo_blueprint.py,sha256=sYGp2XVGodkAifGHbEqpIY-7bBH5R7G7Dwg4HqgxMSY,7269
71
+ geo_activity_playground/webui/blueprints/photo_blueprint.py,sha256=ZBh7Gt5vEzeW8JDK3t-3RcLTT40mbOqRkttkicgcIRM,7885
72
72
  geo_activity_playground/webui/blueprints/plot_builder_blueprint.py,sha256=nGtYblRTJ0rasJvl_L35cs1Iry4LONPy_9TY4ytXB-Q,3838
73
73
  geo_activity_playground/webui/blueprints/search_blueprint.py,sha256=Sv_KL1Cdai26y51qVfI-5jZLhtElREsEar1dbR_VAC4,2275
74
- geo_activity_playground/webui/blueprints/settings_blueprint.py,sha256=FLKQ0JTThUlsCBR2TqRvdDGIJpPDycy47iiQof9gbHA,20077
74
+ geo_activity_playground/webui/blueprints/settings_blueprint.py,sha256=uPN4ORhWyLVo23YKhRFjGB-VxJFOoJIHR5NLmHi11k4,20856
75
75
  geo_activity_playground/webui/blueprints/square_planner_blueprint.py,sha256=xVaxJxmt8Dysl3UL9f2y__LVLtTH2Np1Ust4OSXKRAk,4746
76
76
  geo_activity_playground/webui/blueprints/summary_blueprint.py,sha256=AlRnsPUamoqsQ5JD5PpmSsJdhxDgrJOq5O11MQM3gME,6680
77
77
  geo_activity_playground/webui/blueprints/tile_blueprint.py,sha256=YzZf9OrNdjhc1_j4MtO1DMcw1uCv29ueNsYd-mWqgbg,837
@@ -128,15 +128,15 @@ geo_activity_playground/webui/templates/calendar/month.html.j2,sha256=IEhGqknL69
128
128
  geo_activity_playground/webui/templates/eddington/distance.html.j2,sha256=9cLlIrImgMYYE9AKjhqHMpjpTem8sMEnVHt78krWf7w,3508
129
129
  geo_activity_playground/webui/templates/eddington/elevation_gain.html.j2,sha256=h2mI1Uc1-P7rN_SeCVP_uadpQqX09ZpBG3Z6N8QWNLw,4723
130
130
  geo_activity_playground/webui/templates/elevation_eddington/index.html.j2,sha256=WjquRFWaMzIZrvByhRIuhJbSCUW2HTfMck6THQHZI-I,4743
131
- geo_activity_playground/webui/templates/equipment/index.html.j2,sha256=eI17zEHn4uliJ-JlxWZQEYgpgwAbSy0Ke2IC1zxYBDU,1823
131
+ geo_activity_playground/webui/templates/equipment/index.html.j2,sha256=6pzSCJACMXA1fKgsO_KrCTvpumAKlelzj5f9dReey14,1742
132
132
  geo_activity_playground/webui/templates/explorer/server-side.html.j2,sha256=ynejXeUjb-ZwkvPtbD20R8R1KLUIFsyM5VJgwW7vzM8,3133
133
133
  geo_activity_playground/webui/templates/export/index.html.j2,sha256=vxqpAm9KnT405Qz7q0_td-HZ4mCjcPR4Lp6EnIEWisg,1652
134
- geo_activity_playground/webui/templates/hall_of_fame/index.html.j2,sha256=H81vfgtqvQw-8cxCkixlQwb8gDUx-Y5gpzuyKiN3hew,1900
134
+ geo_activity_playground/webui/templates/hall_of_fame/index.html.j2,sha256=t02N1VtTyj_pBBSd3mzO1xNyDLwGa1XdH0RFvKAmdIg,1766
135
135
  geo_activity_playground/webui/templates/heatmap/index.html.j2,sha256=uM-l4gmDKw6307ZH_zb8zroMTKBuOkrR0Bu4fTEJE0s,1231
136
- geo_activity_playground/webui/templates/home.html.j2,sha256=RDTcBi3KEniHB54MW3k5zkjrt1Hh0DkQREMBYBHunQM,2572
136
+ geo_activity_playground/webui/templates/home.html.j2,sha256=R0T4z9aEUD0dAnCrdXcu9O3GafXruaZjKKDmks3ST64,2182
137
137
  geo_activity_playground/webui/templates/page.html.j2,sha256=sN1OmuN4c4g6M4h_hZ8UMX4wsWZq7_r0M8fgzpxyKss,12016
138
138
  geo_activity_playground/webui/templates/photo/map.html.j2,sha256=MWhqt5Q8ExiRhgxndcEnwngOj1qw0E0u4hKuiuY24Gg,1437
139
- geo_activity_playground/webui/templates/photo/new.html.j2,sha256=GGLejO4ap6ZMe54jZP39ktSLkdw5j67bf5PTlHEK7qc,383
139
+ geo_activity_playground/webui/templates/photo/new.html.j2,sha256=0BO4ZJgJQM1Hlp9SHylEOfthpQlywDc-xFs8K_Spptc,392
140
140
  geo_activity_playground/webui/templates/plot-macros.html.j2,sha256=lzsu8c8fcsVjgpdcmpwCa1e6EPALZtCS9RbvQ-DAtAs,2861
141
141
  geo_activity_playground/webui/templates/plot_builder/edit.html.j2,sha256=S_ReKqpSmtf4wPvkRjdNz8WXUBfSIXQ3aJnLMIkLJaY,2519
142
142
  geo_activity_playground/webui/templates/plot_builder/import-spec.html.j2,sha256=jCumhh-xdxKhVEZtkWHFMWPMiE5wdBZVpQVcrbnXr2c,668
@@ -146,7 +146,7 @@ geo_activity_playground/webui/templates/search_form.html.j2,sha256=BBxT2aAUlOZ41
146
146
  geo_activity_playground/webui/templates/settings/admin-password.html.j2,sha256=VYwddpObD1RpeTH5Dm4y7VtmT7kwURDCIjxyzJeq08c,495
147
147
  geo_activity_playground/webui/templates/settings/color-schemes.html.j2,sha256=iR91Wxd2_TMuIo9dBDZBrWSUGHNwTwzC6O8oNH-XBt4,1653
148
148
  geo_activity_playground/webui/templates/settings/heart-rate.html.j2,sha256=UPT3MegRgSeff36lhCo0l3ZwhqNSIg5gM6h2s32GkCY,4255
149
- geo_activity_playground/webui/templates/settings/index.html.j2,sha256=sphzznODrgb9I3SdYoV8zsmnh2FHxzt5NhhrVPPO9wY,5062
149
+ geo_activity_playground/webui/templates/settings/index.html.j2,sha256=mapSC1TTS_cFg7K0eNuTbENTMg2EFb1atPdIj14xU_c,5468
150
150
  geo_activity_playground/webui/templates/settings/manage-equipments.html.j2,sha256=vPGGlwyG_xMZc4a6JdajwWMJBfN1lBNBtDSt6QPJBiY,1585
151
151
  geo_activity_playground/webui/templates/settings/manage-kinds.html.j2,sha256=382VW-cEe0iPJ8TNL2jrcRtVYb_RFdzDyeC1ncpWZ9M,1616
152
152
  geo_activity_playground/webui/templates/settings/metadata-extraction.html.j2,sha256=0g9RlHFKipN45RaH_FANWnY1lfXUkKjtc_9B-vJ19LQ,2298
@@ -157,13 +157,14 @@ geo_activity_playground/webui/templates/settings/strava.html.j2,sha256=GCE5gskQ6
157
157
  geo_activity_playground/webui/templates/settings/tags-edit.html.j2,sha256=Lna2QBacuMwaFODGCVulOpHSHHjqCdhNJg2c6i-ogY0,586
158
158
  geo_activity_playground/webui/templates/settings/tags-list.html.j2,sha256=6giFWtVCTLXLC_Ojh56XhB_1Rouit9YzIs_YHIiayLg,369
159
159
  geo_activity_playground/webui/templates/settings/tags-new.html.j2,sha256=xi6KbwydDVrUJM4_ty4KbMa74k3QaoyZhZAn2paERnM,358
160
+ geo_activity_playground/webui/templates/settings/tile-source.html.j2,sha256=C9kRBBuorjZ8Ctx8_0Hft7EHLBQHbypFFLq4eQX6GVI,1228
160
161
  geo_activity_playground/webui/templates/square_planner/index.html.j2,sha256=-OnY2nQCgZCslOzf28ogZwFykwF8tZm7PgFwOE3eBDk,8176
161
162
  geo_activity_playground/webui/templates/summary/index.html.j2,sha256=VuSed6GU-FzjPC1aCYuEuK5B8Rw2D8NcseNLTFIGxkA,1441
162
163
  geo_activity_playground/webui/templates/summary/vega-chart.html.j2,sha256=mw8HtigeSnShTFZNG56UGUqHLJe70kvFR3o0TT71dBI,94
163
164
  geo_activity_playground/webui/templates/upload/index.html.j2,sha256=I1Ix8tDS3YBdi-HdaNfjkzYXVVCjfUTe5PFTnap1ydc,775
164
165
  geo_activity_playground/webui/templates/upload/reload.html.j2,sha256=YZWX5eDeNyqKJdQAywDBcU8DZBm22rRBbZqFjrFrCvQ,556
165
- geo_activity_playground-1.1.0.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
166
- geo_activity_playground-1.1.0.dist-info/METADATA,sha256=YVWhoJ4nIcQUL1CoSAWqIb8P4UGmVMWSIX0E1_Q99Xs,1890
167
- geo_activity_playground-1.1.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
168
- geo_activity_playground-1.1.0.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
169
- geo_activity_playground-1.1.0.dist-info/RECORD,,
166
+ geo_activity_playground-1.2.0.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
167
+ geo_activity_playground-1.2.0.dist-info/METADATA,sha256=THvhUmP_4CRz5cGUzxQg_LsLVQJaFEgEHoPPwVGzI1o,1890
168
+ geo_activity_playground-1.2.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
169
+ geo_activity_playground-1.2.0.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
170
+ geo_activity_playground-1.2.0.dist-info/RECORD,,