diff --git a/index.html b/index.html
index 89dae19..c5470c1 100644
--- a/index.html
+++ b/index.html
@@ -21,8 +21,9 @@
-
+
+
@@ -156,7 +157,35 @@
downloadAnchorNode.click();
downloadAnchorNode.remove();
},
- async restore() {
+ async restore(event) {
+ this.launched = true;
+
+ // Sure would be nice if the API were just designed this way!
+ const read_file = async (file) => new Promise((resolve) => {
+ const fileReader = new FileReader();
+ fileReader.onload = (e) => resolve(fileReader.result);
+ fileReader.readAsText(file);
+ });
+
+ const save_data = await read_file(event.target.files[0]);
+ const save = JSON.parse(save_data, (k, v) => k == 'time' ? new Date(v) : v);
+ this.state_cities = save.cities;
+ this.simplified_cities = this.state_cities.map(city => simplify(city.name));
+ this.state_name = save.state;
+ this.message = `Restored game from ${save.time.toLocaleString()} with ${save.cities.filter(c => c.guessed).length }/${ save.cities.length} cities guessed`;
+
+ // The rest of this function is duplicated from launch(), above
+ const shapes_response = await this.shapes_request;
+ const shapes_data = await shapes_response.json();
+ const shape = shapes_data.features.find(f => f.properties.NAME.toLowerCase() == this.state_name.toLowerCase());
+ if (shape.geometry.type == "MultiPolygon") {
+ this.state_shape = shape.geometry.coordinates.map(a => a.flat());
+ } else { // Polygon
+ this.state_shape = shape.geometry.coordinates;
+ }
+ this.state_mercator_adjusted_bounds = find_bounds(this.state_shape.flat().map(mercator));
+
+ this.draw();
},
guess() {
const rank = this.simplified_cities.indexOf(simplify(this.city_guess))