Compare commits

...

132 commits

Author SHA1 Message Date
Yohan Boniface
a3a520dec4 3.0.5
Some checks failed
Release Charts / release (push) Has been cancelled
Test & Docs / tests (postgresql, 3.10) (push) Has been cancelled
Test & Docs / tests (postgresql, 3.12) (push) Has been cancelled
Test & Docs / lint (push) Has been cancelled
2025-04-25 17:45:37 +02:00
Yohan Boniface
4b4f9bbc5c i18n 2025-04-25 17:40:47 +02:00
Yohan Boniface
279717e630 chore: fix badge visibility in filter tab in browser panel
Co-authored-by: David Larlet <david@larlet.fr>
2025-04-25 17:29:18 +02:00
Yohan Boniface
39e4e2a33c
fix: make sure DataLayer rank is always set (#2682) 2025-04-25 17:20:10 +02:00
Yohan Boniface
e5dbca21b0 fix: make sure DataLayer rank is always set
Co-authored-by: David Larlet <david@larlet.fr>
2025-04-25 17:12:17 +02:00
Yohan Boniface
1ecddc1c02
chore: use details/summary for datalayers boxes in browser (#2680)
![image](https://github.com/user-attachments/assets/978e2f05-b7f3-4648-afec-92a24a88226a)
2025-04-25 16:29:06 +02:00
Yohan Boniface
8658e7eba7 chore: use details/summary for datalayers boxes in browser 2025-04-25 16:20:37 +02:00
Yohan Boniface
6ac3685172
fix: fix error when saving and deleting heatmap layer (#2681) 2025-04-25 15:57:17 +02:00
Yohan Boniface
1085861d42 chore: add --maxfail to py.test in make test command
Co-authored-by: David Larlet <david@larlet.fr>
2025-04-25 15:56:20 +02:00
Yohan Boniface
fab0c8f9ea fix: fix error when saving and deleting heatmap layer
Co-authored-by: David Larlet <david@larlet.fr>
2025-04-25 15:47:33 +02:00
Yohan Boniface
858768896e
fix: loading remote data should not make the map dirty (#2679)
See the second commit for the logic change.
2025-04-25 15:35:38 +02:00
Yohan Boniface
bffbeb5230
fix: allow to save/undo/sync drag'n'drop of datalayers (#2677)
This also:
- introduces a new DataLayerManager
- removes the _umap_options coming from the geojson form the server
- removes all backup related functions (now we have undo/redo)

fix #2674
2025-04-25 15:35:23 +02:00
Yohan Boniface
f01a74f19f i18n 2025-04-25 11:29:43 +02:00
Yohan Boniface
00228ccf92 fix: loading remote data should not make the map dirty 2025-04-25 11:25:54 +02:00
Yohan Boniface
6c8046456a chore: remove unused isDirty flags 2025-04-25 09:44:49 +02:00
Yohan Boniface
626b669d89 fixup: fix tests 2025-04-25 07:09:31 +02:00
Yohan Boniface
5af41b4528 fix: allow to save/undo/sync drag'n'drop of datalayers
This also:
- introduces a new DataLayerManager
- removes the _umap_options coming from the geojson form the server
- removes all backup related functions (now we have undo/redo)

Co-authored-by: David Larlet <david@larlet.fr>
2025-04-24 18:38:02 +02:00
Yohan Boniface
1a9c325f16
fix: setting center and zoom manually should set dirty status (#2676)
Some checks failed
Release Charts / release (push) Has been cancelled
Test & Docs / tests (postgresql, 3.10) (push) Has been cancelled
Test & Docs / tests (postgresql, 3.12) (push) Has been cancelled
Test & Docs / lint (push) Has been cancelled
2025-04-23 18:51:36 +02:00
Yohan Boniface
19d16ac01b fix: setting center and zoom manually should set dirty status
Co-authored-by: David Larlet <david@larlet.fr>
2025-04-23 18:00:48 +02:00
Yohan Boniface
efaa765b82
chore: cleaning core utils and removing DomUtil/DomEvent from modules (#2671) 2025-04-23 17:51:45 +02:00
Yohan Boniface
92ca581fb6
fix: allow to save a remote data with unloaded data (#2657)
When loading remote data fails, the layer is in state "unloaded", and
thus it was not possible to save it.
This "isLoaded" check is made for non remote layer so that we don't save
it by mistake with no data.

Also, let's allow to edit non loaded layers, this check was there when
settings was not on db, so not all loaded at map init, again not to
override with incomplete metadata.
2025-04-23 17:49:12 +02:00
Yohan Boniface
6687cd53ba
feat: add a back button in rules form (#2673)
To go back in rules list.

fix #2631


![image](https://github.com/user-attachments/assets/d0ad67fe-90c1-45c5-8bca-5ac30ef8366a)
2025-04-23 17:43:22 +02:00
Yohan Boniface
4997ee8860
feat: naive support for GeometryCollection as Feature geometry (#2658)
Currently, we just skip those, but sometimes togeojson produces this
output from a KML.
This will create one feature per geometry, while in an ideal world this
should be a multi, but we lack reliable geometry tools to merge the
geometries without risking to create mistakes.
So let's say it's a first improvement.
2025-04-23 17:43:05 +02:00
Yohan Boniface
a708316604
fix: make rules reordering syncable, savable and undoable (#2672) 2025-04-23 17:42:47 +02:00
Yohan Boniface
71d92aa610
fix: show an error message if saving layer failed (#2670)
This could occur when server is down or there is no network.
2025-04-23 17:40:19 +02:00
Yohan Boniface
41752bd0c6
fix: do not display "saved" message if some request failed (#2669) 2025-04-23 17:39:59 +02:00
Yohan Boniface
5b6138a210
chore: move pure Leaflet controls to modules (#2668)
pure == inheriting from Leaflet itself, not from some plugin (which
aren't ESM ready…)
2025-04-23 17:39:33 +02:00
Yohan Boniface
07363fa5fe chore: remove unused DomEvent.once 2025-04-23 16:52:55 +02:00
Yohan Boniface
7991d6cdbe chore: remove DomUtil.after/before 2025-04-23 16:50:13 +02:00
Yohan Boniface
60ac4b35f2 chore: remove most of DomUtil/DomEvent from browser.js 2025-04-23 16:24:15 +02:00
Yohan Boniface
bf2e9dc175 chore: remove call to DomUtil.createIcon in umap.js 2025-04-23 11:33:12 +02:00
Yohan Boniface
67ed6d5b44 feat: add a back button in rules form
To go back in rules list.

fix #2631
2025-04-23 10:55:39 +02:00
Yohan Boniface
fad182c5f3 fix: make rules reordering syncable, savable and undoable 2025-04-23 10:19:19 +02:00
Yohan Boniface
3f5d282477 chore: remove DomUtil and DomEvent dependency from rules.js 2025-04-23 10:14:22 +02:00
Yohan Boniface
49496348d2 chore: remove unused L.DomUtil.createLink method 2025-04-23 09:21:35 +02:00
Yohan Boniface
f8b13639aa fix: show an error message if saving layer failed
This could occur when server is down or there is no network.
2025-04-23 09:02:25 +02:00
Yohan Boniface
4c71710641 fix: do not display "saved" message if some request failed 2025-04-23 08:58:17 +02:00
Yohan Boniface
92d5c47844 chore: move pure Leaflet controls to modules
pure == inheriting from Leaflet itself, not from some plugin
(which aren't ESM ready…)
2025-04-22 20:14:06 +02:00
Yohan Boniface
05493d8a48
chore: bump uvicorn from 0.34.1 to 0.34.2 (#2664)
Some checks failed
Release Charts / release (push) Has been cancelled
Test & Docs / tests (postgresql, 3.10) (push) Has been cancelled
Test & Docs / tests (postgresql, 3.12) (push) Has been cancelled
Test & Docs / lint (push) Has been cancelled
2025-04-22 15:06:34 +02:00
Yohan Boniface
fd8f403a69
chore: bump mkdocs-material from 9.6.11 to 9.6.12 (#2665) 2025-04-22 15:06:19 +02:00
Yohan Boniface
a6412c9539
chore: bump ruff from 0.11.4 to 0.11.6 (#2666) 2025-04-22 15:06:01 +02:00
Yohan Boniface
fe65a5351b
chore: bump moto[s3] from 5.1.3 to 5.1.4 (#2667) 2025-04-22 15:05:44 +02:00
dependabot[bot]
2ede25f541
chore: bump moto[s3] from 5.1.3 to 5.1.4
Bumps [moto[s3]](https://github.com/getmoto/moto) from 5.1.3 to 5.1.4.
- [Release notes](https://github.com/getmoto/moto/releases)
- [Changelog](https://github.com/getmoto/moto/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getmoto/moto/compare/5.1.3...5.1.4)

---
updated-dependencies:
- dependency-name: moto[s3]
  dependency-version: 5.1.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 17:46:08 +00:00
dependabot[bot]
b7acdcfd93
chore: bump ruff from 0.11.4 to 0.11.6
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.11.4 to 0.11.6.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.11.4...0.11.6)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.11.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 17:39:19 +00:00
dependabot[bot]
a3d2330661
chore: bump mkdocs-material from 9.6.11 to 9.6.12
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.6.11 to 9.6.12.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.6.11...9.6.12)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-version: 9.6.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 17:33:21 +00:00
dependabot[bot]
20ae374173
chore: bump uvicorn from 0.34.1 to 0.34.2
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.34.1 to 0.34.2.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/docs/release-notes.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.34.1...0.34.2)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-version: 0.34.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 17:29:12 +00:00
David Larlet
162473da9d
chore: more design system elements (#2661)
Some checks failed
Release Charts / release (push) Has been cancelled
Test & Docs / tests (postgresql, 3.10) (push) Has been cancelled
Test & Docs / tests (postgresql, 3.12) (push) Has been cancelled
Test & Docs / lint (push) Has been cancelled
2025-04-18 10:03:12 -04:00
David Larlet
78d333c217
chore: more design system elements 2025-04-17 17:29:43 -04:00
Yohan Boniface
b0fe95dbd9 feat: naive support for GeometryCollection as Feature geometry
Currently, we just skip those, but sometimes togeojson produces this
output from a KML.
This will create one feature per geometry, while in an ideal world this
should be a multi, but we lack reliable geometry tools to merge the
geometries without risking to create mistakes.
So let's say it's a first improvement.
2025-04-16 18:28:23 +02:00
Yohan Boniface
23b82975f5 chore: bump togeojson
Some checks failed
Release Charts / release (push) Has been cancelled
Test & Docs / tests (postgresql, 3.10) (push) Has been cancelled
Test & Docs / tests (postgresql, 3.12) (push) Has been cancelled
Test & Docs / lint (push) Has been cancelled
2025-04-16 17:30:17 +02:00
Yohan Boniface
169be73488 fix: allow to save a remote data with unloaded data
When loading remote data fails, the layer is in state "unloaded",
and thus it was not possible to save it.
This "isLoaded" check is made for non remote layer so that we don't
save it by mistake with no data.

Also, let's allow to edit non loaded layers, this check was there
when settings was not on db, so not all loaded at map init, again
not to override with incomplete metadata.
2025-04-16 16:00:26 +02:00
Yohan Boniface
6945a5e867
feat: pass CSRF_TRUSTED_ORIGINS env to settings (#2656)
Some checks are pending
Release Charts / release (push) Waiting to run
Test & Docs / tests (postgresql, 3.10) (push) Waiting to run
Test & Docs / tests (postgresql, 3.12) (push) Waiting to run
Test & Docs / lint (push) Waiting to run
Allow to manage djangos CSRF_TRUSTED_ORIGINS by environment variables.

Closes #2655
2025-04-16 12:34:49 +02:00
Oliver Lippert
2ed890202e
code formatting 2025-04-16 12:25:17 +02:00
Oliver Lippert
cc7685ca3f
pass CSRF_TRUSTED_ORIGINS env to settings
fixes https://github.com/umap-project/umap/issues/2655
2025-04-16 12:23:09 +02:00
David Larlet
23688b6444
feat: implement a design system for UI consistency (#2654)
Some checks are pending
Release Charts / release (push) Waiting to run
Test & Docs / tests (postgresql, 3.10) (push) Waiting to run
Test & Docs / tests (postgresql, 3.12) (push) Waiting to run
Test & Docs / lint (push) Waiting to run
2025-04-15 08:19:31 -04:00
David Larlet
d3c0947fa5
feat: implement a design system for UI consistency 2025-04-14 23:20:55 -04:00
Yohan Boniface
a135e5c3e1
chore: bump pytest-django from 4.10.0 to 4.11.1 (#2653)
Some checks are pending
Release Charts / release (push) Waiting to run
Test & Docs / tests (postgresql, 3.10) (push) Waiting to run
Test & Docs / tests (postgresql, 3.12) (push) Waiting to run
Test & Docs / lint (push) Waiting to run
2025-04-14 19:50:30 +02:00
Yohan Boniface
2ad46046f8
chore: bump uvicorn from 0.34.0 to 0.34.1 (#2651) 2025-04-14 19:50:14 +02:00
Yohan Boniface
5271d7c19d
chore: bump pydantic from 2.11.2 to 2.11.3 (#2652) 2025-04-14 19:36:42 +02:00
Yohan Boniface
a535c86f6b
chore: bump mkdocs-material from 9.6.10 to 9.6.11 (#2649) 2025-04-14 19:36:16 +02:00
Yohan Boniface
9aa1f58dc8
chore: bump pillow from 11.1.0 to 11.2.1 (#2650)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 11.1.0 to
11.2.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/python-pillow/Pillow/releases">pillow's
releases</a>.</em></p>
<blockquote>
<h2>11.2.1</h2>
<p><a
href="https://pillow.readthedocs.io/en/stable/releasenotes/11.2.1.html">https://pillow.readthedocs.io/en/stable/releasenotes/11.2.1.html</a></p>
<h2>Deprecations</h2>
<ul>
<li>Moved get_child_images() to ImageFile <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8689">#8689</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
</ul>
<h2>Documentation</h2>
<ul>
<li>Add 11.2.1 release notes <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8885">#8885</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added avif to config settings <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8875">#8875</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added release notes for <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8330">#8330</a>
<a
href="https://redirect.github.com/python-pillow/Pillow/issues/8853">#8853</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added release notes for <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8781">#8781</a>
and <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8837">#8837</a>
<a
href="https://redirect.github.com/python-pillow/Pillow/issues/8843">#8843</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added media_white_point to ImageCms documentation <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8829">#8829</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Removed FIXME <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8825">#8825</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated comment <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8822">#8822</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added release notes for <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8807">#8807</a>
<a
href="https://redirect.github.com/python-pillow/Pillow/issues/8824">#8824</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>DXT3 images are read in RGBA mode <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8817">#8817</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>JPEG comments are from the COM marker <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8788">#8788</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update Sphinx to 8.2 to remove nitpick ignore <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8763">#8763</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated AffineTransform docstring to mention it uses the inverse
matrix <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8735">#8735</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added MozJPEG documentation <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8699">#8699</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added Sphinx configuration key <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8691">#8691</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated macOS tested Pillow versions <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8654">#8654</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
</ul>
<h2>Dependencies</h2>
<ul>
<li>Updated xz to 5.8.1 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8868">#8868</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated harfbuzz to 11.0.1 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8870">#8870</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update scientific-python/upload-nightly-action action to v0.6.2 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8865">#8865</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Updated xz to 5.8.0 in macOS and Linux wheels, but not on
manylinux2014 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8836">#8836</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update dependency cibuildwheel to v2.23.2 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8832">#8832</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Updated harfbuzz to 11.0.0 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8830">#8830</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update dependency cibuildwheel to v2.23.1 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8818">#8818</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Updated Ghostscript to 10.5.0 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8814">#8814</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated libtiff to 4.7.0 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8812">#8812</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>[pre-commit.ci] pre-commit autoupdate <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8795">#8795</a>
[@<a
href="https://github.com/apps/pre-commit-ci">pre-commit-ci[bot]</a>]</li>
<li>Updated harfbuzz to 10.4.0 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8770">#8770</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update dependency mypy to v1.15.0 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8791">#8791</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Updated libpng to 1.6.47 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8764">#8764</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated lcms2 to 2.17 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8742">#8742</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update dependency cibuildwheel to v2.23.0 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8785">#8785</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Updated zlib-ng to 2.2.4 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8745">#8745</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated libimagequant to 4.3.4 on Windows <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8744">#8744</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>[pre-commit.ci] pre-commit autoupdate <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8729">#8729</a>
[@<a
href="https://github.com/apps/pre-commit-ci">pre-commit-ci[bot]</a>]</li>
<li>Updated harfbuzz to 10.2.0 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8688">#8688</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated xz to 5.6.4 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8711">#8711</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated libpng to 1.6.46 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8712">#8712</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated libimagequant to 4.3.4 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8710">#8710</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Updated libpng to 1.6.45 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8670">#8670</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst">pillow's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog (Pillow)</h1>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="339bc5db93"><code>339bc5d</code></a>
11.2.1 version bump</li>
<li><a
href="857b8846ea"><code>857b884</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8885">#8885</a>
from radarhere/releasenotes</li>
<li><a
href="7a0092f207"><code>7a0092f</code></a>
Remove incomplete 11.2.0 release, bill as 11.2.1 instead</li>
<li><a
href="d52c2db317"><code>d52c2db</code></a>
Do not include libavif in wheels</li>
<li><a
href="8dafc38371"><code>8dafc38</code></a>
Added 11.2.1 release notes</li>
<li><a
href="07d7800248"><code>07d7800</code></a>
Removed release notes update</li>
<li><a
href="04909483a7"><code>0490948</code></a>
Remove GPL v2 license (<a
href="https://redirect.github.com/python-pillow/Pillow/issues/8884">#8884</a>)</li>
<li><a
href="774d0aedce"><code>774d0ae</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8868">#8868</a>
from radarhere/xz_upgrade</li>
<li><a
href="d1e27fc86c"><code>d1e27fc</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/8870">#8870</a>
from radarhere/harfbuzz_upgrade</li>
<li><a
href="c8d98d56a0"><code>c8d98d5</code></a>
Added avif to config settings (<a
href="https://redirect.github.com/python-pillow/Pillow/issues/8875">#8875</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/python-pillow/Pillow/compare/11.1.0...11.2.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pillow&package-manager=pip&previous-version=11.1.0&new-version=11.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>
2025-04-14 19:36:00 +02:00
dependabot[bot]
102104f818
chore: bump pytest-django from 4.10.0 to 4.11.1
Bumps [pytest-django](https://github.com/pytest-dev/pytest-django) from 4.10.0 to 4.11.1.
- [Release notes](https://github.com/pytest-dev/pytest-django/releases)
- [Changelog](https://github.com/pytest-dev/pytest-django/blob/main/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.10.0...v4.11.1)

---
updated-dependencies:
- dependency-name: pytest-django
  dependency-version: 4.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 17:30:01 +00:00
dependabot[bot]
35e5a4bda6
chore: bump pydantic from 2.11.2 to 2.11.3
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.2 to 2.11.3.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.11.2...v2.11.3)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.11.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 17:29:38 +00:00
dependabot[bot]
6bae315efe
chore: bump uvicorn from 0.34.0 to 0.34.1
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.34.0 to 0.34.1.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/docs/release-notes.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.34.0...0.34.1)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 17:29:19 +00:00
dependabot[bot]
93120d91d6
chore: bump pillow from 11.1.0 to 11.2.1
Bumps [pillow](https://github.com/python-pillow/Pillow) from 11.1.0 to 11.2.1.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/11.1.0...11.2.1)

---
updated-dependencies:
- dependency-name: pillow
  dependency-version: 11.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 17:29:05 +00:00
dependabot[bot]
f037973a03
chore: bump mkdocs-material from 9.6.10 to 9.6.11
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.6.10 to 9.6.11.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.6.10...9.6.11)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-version: 9.6.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 17:28:43 +00:00
Yohan Boniface
c4614354ae 3.0.4 2025-04-14 17:57:12 +02:00
Yohan Boniface
9ed466ea9b
chore: update colors (#2647) 2025-04-14 17:55:19 +02:00
Yohan Boniface
168cc0c996 i18n 2025-04-14 17:49:09 +02:00
Yohan Boniface
ae4e7eb3e2 chore: update colors
Co-authored-by: David Larlet <david@larlet.fr>
2025-04-14 17:45:11 +02:00
Yohan Boniface
3670b7dca6
Adapt chart to match La Suite's expectations (#2646)
- env vars and config files can be loaded from existing secrets
- chart is deployed on a helm repository

to make the helm repository work with github pages, create an empty
orphaned branch called gh-pages, and under settings>pages>source select
deploy from branch and use gh-pages
2025-04-14 17:36:31 +02:00
David Larlet
1c3cf9a7c5
chore: switch helm chart job to master branch 2025-04-14 11:31:06 -04:00
Yohan Boniface
ada44fc0fc
fix: remove "hide home button" shown twice in map settings (#2645) 2025-04-14 17:30:52 +02:00
Yohan Boniface
ac6964c9f4 fix: remove "hide home button" shown twice in map settings
Co-authored-by: David Larlet <david@larlet.fr>
2025-04-14 16:30:38 +02:00
David Larlet
82dcd90405
fix: do not show "back to home" button in iframes (#2644) 2025-04-14 10:21:21 -04:00
Yohan Boniface
d9e983aed4 fix: do not show "back to home" button in iframes
Co-authored-by: David Larlet <david@larlet.fr>
2025-04-14 16:12:35 +02:00
Yohan Boniface
071a8c539d 3.0.3
Some checks failed
Test & Docs / tests (postgresql, 3.10) (push) Has been cancelled
Test & Docs / tests (postgresql, 3.12) (push) Has been cancelled
Test & Docs / lint (push) Has been cancelled
2025-04-11 18:09:14 +02:00
Yohan Boniface
ec8fa87b41 i18n 2025-04-11 17:33:22 +02:00
Yohan Boniface
ef072f0a8e
feat: allow to hide the back to home button (#2638) 2025-04-11 17:30:15 +02:00
Yohan Boniface
33f407fd60
feat: hidden download button in browser when embedControl=false (#2640)
cf #2629
2025-04-11 17:27:02 +02:00
David Larlet
324c5cf6bf feat: allow to hide the back to home button
Co-authored-by: Yohan Boniface <yohanboniface@free.fr>
2025-04-11 17:22:09 +02:00
Yohan Boniface
e53cdcb04e feat: hidden download button in browser when embedControl=false
cf #2629

Co-authored-by: David Larlet <david@larlet.fr>
2025-04-11 17:15:39 +02:00
David Larlet
5e3170891a
feat: allow to hide the layer switcher from bottom bar (#2639) 2025-04-11 10:58:54 -04:00
David Larlet
495286c261
feat: allow to hide the layer switcher from bottom bar 2025-04-11 10:44:01 -04:00
Yohan Boniface
15972bab3d
document that nginx needs to be added in Docker stack to serve statics (#2636) 2025-04-11 16:19:47 +02:00
Yohan Boniface
bd91934544
fix: do not try to remove a feature not yet added (#2637)
cf #2625

This happens while drawing a line or polygon and then hitting escape
while the path is not yet valid.
2025-04-11 16:19:29 +02:00
Yohan Boniface
581140e08a
fix: do not try to remove a feature not yet added
cf #2625

This happens while drawing a line or polygon and then hitting escape
while the path is not yet valid.
2025-04-11 10:02:31 -04:00
David Larlet
10f87c0b6e
fix: display search category on list page (#2635) 2025-04-11 08:24:07 -04:00
Yohan Boniface
0ec4e74f8f wip: add nginx in docker-compose.yml 2025-04-11 11:31:54 +02:00
Yohan Boniface
89033e04a2 chore: add a deploy overview doc page 2025-04-11 10:09:24 +02:00
David Larlet
38f4fd5bb3
fix: display search category on list page 2025-04-10 17:13:33 -04:00
Yohan Boniface
985d91a9c7
fix: display back help button in switch fields (#2634)
Some checks are pending
Test & Docs / tests (postgresql, 3.10) (push) Waiting to run
Test & Docs / tests (postgresql, 3.12) (push) Waiting to run
Test & Docs / lint (push) Waiting to run
cf #2615

Before:

![image](https://github.com/user-attachments/assets/bac68a6b-6c74-4f10-8d3c-26536dc1ecad)

After:

![image](https://github.com/user-attachments/assets/43c4a0b3-a892-423a-8c20-b7c6304f3182)
2025-04-10 21:46:27 +02:00
Yohan Boniface
7348f0bf4f fix: display back help button in switch fields
cf #2615
2025-04-10 20:24:35 +02:00
Yohan Boniface
dc35e7df6d
fix: fix pictogram categories always hidden (#2630)
Some checks failed
Test & Docs / tests (postgresql, 3.10) (push) Has been cancelled
Test & Docs / tests (postgresql, 3.12) (push) Has been cancelled
Test & Docs / lint (push) Has been cancelled
2025-04-09 17:17:29 +02:00
Yohan Boniface
d9378a484d fix: fix pictogram categories always hidden 2025-04-09 16:06:20 +02:00
Yohan Boniface
cfcdfb9ed8
chore: add missing margin-bottom in importers (#2627) 2025-04-09 15:59:00 +02:00
Yohan Boniface
0b8c7ee381
chore: redirect to user dashboard after map delete (#2626)
If user is authenticated.

We do not display alert messages on the home page.
2025-04-09 15:45:11 +02:00
Yohan Boniface
36e9433cf9
Apply suggestions from code review
Co-authored-by: David Larlet <3556+davidbgk@users.noreply.github.com>
2025-04-09 15:44:36 +02:00
Yohan Boniface
425f66b181
fix: fix text overflow on search results (#2628)
Before:
![Screenshot From 2025-04-09
09-41-21](https://github.com/user-attachments/assets/727ead82-7bb7-4cdb-b676-994f84ed8eaf)

After:
![Screenshot From 2025-04-09
09-40-58](https://github.com/user-attachments/assets/e778ba59-a255-4230-9531-cdba67c444cc)

(Please don't ask :p )
2025-04-09 15:42:57 +02:00
Yohan Boniface
18f0b6e2a7 chore: rename variable to make it more explicit 2025-04-09 11:27:29 +02:00
Yohan Boniface
50f23b4e02 fix: fix text overflow on search results 2025-04-09 09:41:37 +02:00
Yohan Boniface
36d58993a0 chore: add missing margin-bottom in importers 2025-04-09 09:32:54 +02:00
Yohan Boniface
5f2e104eec
feat: use Last-Modified header from remote data when available (#2624)
Some checks are pending
Test & Docs / tests (postgresql, 3.10) (push) Waiting to run
Test & Docs / tests (postgresql, 3.12) (push) Waiting to run
Test & Docs / lint (push) Waiting to run
fix #2589
2025-04-09 09:09:40 +02:00
Yohan Boniface
5c38bc7970 chore: redirect to user dashboard after map delete
If user is authenticated.

We do not display alert messages on the home page.
2025-04-09 08:54:44 +02:00
Yohan Boniface
dcce3ad054
Update umap/static/umap/js/modules/umap.js
Co-authored-by: David Larlet <3556+davidbgk@users.noreply.github.com>
2025-04-08 18:13:05 +02:00
Yohan Boniface
88ddb1cab3 3.0.2
Some checks are pending
Test & Docs / tests (postgresql, 3.10) (push) Waiting to run
Test & Docs / tests (postgresql, 3.12) (push) Waiting to run
Test & Docs / lint (push) Waiting to run
2025-04-08 17:23:15 +02:00
Yohan Boniface
dd7540596c
fix: give priority to small usernames on autocomplete (#2604)
Basically, when the search is "joe" we first try to search for an exact
account named "joe", and fallback to normal flow when nothing matches.

fix #2591
2025-04-08 17:21:14 +02:00
Yohan Boniface
2baeaace24 feat: use Last-Modified header from remote data when available
fix #2589
2025-04-08 17:03:06 +02:00
Yohan Boniface
14663bc56e fixup: order users autocomplete by username length
cf #2591
2025-04-08 15:47:06 +02:00
Yohan Boniface
fea0f02b80
fix: fix min-height of select in caption bar (#2622)
Before:
![Screenshot From 2025-04-08
15-26-28](https://github.com/user-attachments/assets/372d3410-a360-4ff3-a6f2-d7c18a3f26e3)

After:
![Screenshot From 2025-04-08
15-27-44](https://github.com/user-attachments/assets/defb737e-aed3-40b0-91b6-5b8c38675e55)
2025-04-08 15:37:56 +02:00
Yohan Boniface
85ba05f4b7
fix: fix result tools buttons background color (#2620) 2025-04-08 15:32:58 +02:00
Yohan Boniface
7b582a8ec1
fix: properly call endEdit for markers (#2617)
fix #2607
2025-04-08 15:32:09 +02:00
Yohan Boniface
3c70fc4267
fix: fix categorized layer crashing with null value (#2621)
Do not call toString on a null value
2025-04-08 15:31:51 +02:00
Yohan Boniface
b5d12282e0
fix: fix copiable input CSS (#2616)
Before:
![Screenshot From 2025-04-08
10-02-15](https://github.com/user-attachments/assets/49fd5f63-ac98-40bd-a7bc-befd24920f07)

After:
![Screenshot From 2025-04-08
10-21-33](https://github.com/user-attachments/assets/ce62ef66-6ad7-45dd-a37c-c0fb20d71e13)
2025-04-08 15:30:20 +02:00
Yohan Boniface
672d92152e fix: fix min-height of select in caption bar 2025-04-08 15:27:10 +02:00
Yohan Boniface
5b5102f909 fix: fix categorized layer crashing with null value
Do not call toString on a null value
2025-04-08 15:21:27 +02:00
Yohan Boniface
0a154daa6f fix: fix result tools buttons background color 2025-04-08 12:14:22 +02:00
Yohan Boniface
c38ec2c18d fix: fix copiable input CSS 2025-04-08 11:46:31 +02:00
Yohan Boniface
1e204ac16c fix: properly call endEdit for markers
fix #2607
2025-04-08 11:05:54 +02:00
Yohan Boniface
e2fed5a19d
chore: bump hatch from 1.14.0 to 1.14.1 (#2614) 2025-04-08 10:43:37 +02:00
Yohan Boniface
061b5fc60e
chore: bump pydantic from 2.11.1 to 2.11.2 (#2612) 2025-04-08 10:23:13 +02:00
dependabot[bot]
8c9d4e5777
chore: bump pydantic from 2.11.1 to 2.11.2
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.1 to 2.11.2.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.11.1...v2.11.2)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-08 07:43:11 +00:00
dependabot[bot]
efde6899bd
chore: bump hatch from 1.14.0 to 1.14.1
Bumps [hatch](https://github.com/pypa/hatch) from 1.14.0 to 1.14.1.
- [Release notes](https://github.com/pypa/hatch/releases)
- [Commits](https://github.com/pypa/hatch/compare/hatch-v1.14.0...hatch-v1.14.1)

---
updated-dependencies:
- dependency-name: hatch
  dependency-version: 1.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-08 07:42:51 +00:00
Yohan Boniface
38e862c04a
chore: bump moto[s3] from 5.1.1 to 5.1.3 (#2610)
Some checks are pending
Test & Docs / tests (postgresql, 3.10) (push) Waiting to run
Test & Docs / tests (postgresql, 3.12) (push) Waiting to run
Test & Docs / lint (push) Waiting to run
2025-04-08 09:42:12 +02:00
Yohan Boniface
2d0325f1fb
chore: bump ruff from 0.11.2 to 0.11.4 (#2611) 2025-04-08 09:41:39 +02:00
Yohan Boniface
b8ab86b075
chore: bump django-storages[s3] from 1.14.5 to 1.14.6 (#2613) 2025-04-08 09:41:11 +02:00
dependabot[bot]
7e774bc3aa
chore: bump django-storages[s3] from 1.14.5 to 1.14.6
Bumps [django-storages[s3]](https://github.com/jschneier/django-storages) from 1.14.5 to 1.14.6.
- [Changelog](https://github.com/jschneier/django-storages/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jschneier/django-storages/compare/1.14.5...1.14.6)

---
updated-dependencies:
- dependency-name: django-storages[s3]
  dependency-version: 1.14.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 18:35:07 +00:00
dependabot[bot]
f4e3e679a9
chore: bump ruff from 0.11.2 to 0.11.4
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.11.2 to 0.11.4.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.11.2...0.11.4)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.11.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 18:30:12 +00:00
dependabot[bot]
6d391a51be
chore: bump moto[s3] from 5.1.1 to 5.1.3
Bumps [moto[s3]](https://github.com/getmoto/moto) from 5.1.1 to 5.1.3.
- [Release notes](https://github.com/getmoto/moto/releases)
- [Changelog](https://github.com/getmoto/moto/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getmoto/moto/compare/5.1.1...5.1.3)

---
updated-dependencies:
- dependency-name: moto[s3]
  dependency-version: 5.1.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 18:28:07 +00:00
Yohan Boniface
f4ae51ae7e fix: give priority to small usernames when query is small
Basically, when the search is "joe" we first try to search for
an exact account named "joe", and fallback to normal flow when
nothing matches.

fix #2591
2025-04-07 15:24:44 +02:00
Oscar Hemelaar
8f3f67588a
chore: deploy charts to repository under github pages 2025-01-29 16:22:25 +01:00
Oscar Hemelaar
e97b619da8
feat: allow configuring env and conf using existing secret
useful for when the secret is created out of band using a vault api for
example
2025-01-29 15:49:05 +01:00
194 changed files with 4806 additions and 1928 deletions

26
.github/workflows/release-helm.yml vendored Normal file
View file

@ -0,0 +1,26 @@
name: Release Charts
on:
push:
branches:
- master
jobs:
release:
# depending on default permission settings for your org (contents being read-only or read-write for workloads), you will have to add permissions
# see: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Publish Helm charts
uses: stefanprodan/helm-gh-pages@v1.7.0
with:
charts_dir: charts
linting: off
token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -1,5 +1,5 @@
# This part installs deps needed at runtime. # This part installs deps needed at runtime.
FROM python:3.11-slim AS runtime FROM python:3.12-slim AS common
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
@ -13,7 +13,7 @@ RUN apt-get update && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# This part adds deps needed only at buildtime. # This part adds deps needed only at buildtime.
FROM runtime AS build FROM common AS build
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
@ -40,7 +40,7 @@ COPY . /srv/umap
RUN /venv/bin/pip install .[docker,s3,sync] RUN /venv/bin/pip install .[docker,s3,sync]
FROM runtime FROM common
COPY --from=build /srv/umap/docker/ /srv/umap/docker/ COPY --from=build /srv/umap/docker/ /srv/umap/docker/
COPY --from=build /venv/ /venv/ COPY --from=build /venv/ /venv/

View file

@ -65,7 +65,7 @@ publish: ## Publish the Python package to Pypi
test: testpy testjs test: testpy testjs
testpy: testpy:
pytest -vv umap/tests/ --dist=loadgroup --reruns 1 pytest -vv umap/tests/ --dist=loadgroup --reruns 1 --maxfail 10
test-integration: test-integration:
pytest -xv umap/tests/integration/ --dist=loadgroup pytest -xv umap/tests/integration/ --dist=loadgroup

View file

@ -66,7 +66,11 @@ spec:
{{- end }} {{- end }}
envFrom: envFrom:
- secretRef: - secretRef:
{{- if .Values.umap.envFromSecret }}
name: {{ .Values.umap.envFromSecret }}
{{- else }}
name: {{ include "umap.fullname" . }}-env name: {{ include "umap.fullname" . }}-env
{{- end }}
volumeMounts: volumeMounts:
- name: config - name: config
mountPath: /etc/umap/ mountPath: /etc/umap/
@ -80,7 +84,11 @@ spec:
volumes: volumes:
- name: config - name: config
secret: secret:
{{- if .Values.umap.configFromSecret }}
secretName: {{ .Values.umap.configFromSecret }}
{{- else }}
secretName: {{ include "umap.fullname" . }}-config secretName: {{ include "umap.fullname" . }}-config
{{- end }}
- name: statics - name: statics
emptyDir: {} emptyDir: {}
{{- if .Values.persistence.enabled }} {{- if .Values.persistence.enabled }}

View file

@ -1,3 +1,4 @@
{{ if not .Values.umap.configFromSecret }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
@ -6,4 +7,5 @@ metadata:
{{- include "umap.labels" . | nindent 4 }} {{- include "umap.labels" . | nindent 4 }}
type: Opaque type: Opaque
data: data:
umap.conf: {{ .Values.umap.config | b64enc }} umap.conf: {{ .Values.umap.config | b64enc }}
{{- end }}

View file

@ -1,3 +1,4 @@
{{ if not .Values.umap.envFromSecret }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
@ -8,4 +9,5 @@ type: Opaque
data: data:
{{- range $key, $value := .Values.umap.environment }} {{- range $key, $value := .Values.umap.environment }}
{{ $key }}: "{{ $value | b64enc }}" {{ $key }}: "{{ $value | b64enc }}"
{{- end }} {{- end }}
{{- end }}

View file

@ -77,11 +77,18 @@ umap:
SECRET_KEY: CHANGE_ME SECRET_KEY: CHANGE_ME
STATIC_ROOT: /srv/umap/static STATIC_ROOT: /srv/umap/static
MEDIA_ROOT: /srv/umap/uploads MEDIA_ROOT: /srv/umap/uploads
# Configure environment variables using an existing secret in the same namespace.
# In this case the values above are not used
envFromSecret: null
# You can also provide umap.conf content here: # You can also provide umap.conf content here:
config: | config: |
from umap.settings.base import * from umap.settings.base import *
# See: https://github.com/umap-project/umap/blob/master/umap/settings/local.py.sample # See: https://github.com/umap-project/umap/blob/master/umap/settings/local.py.sample
# Configure config file using an existing secret in the same namespace.
# In this case the values above are not used
configFromSecret: null
persistence: persistence:
enabled: true enabled: true

View file

@ -26,10 +26,10 @@ services:
condition: service_healthy condition: service_healthy
redis: redis:
condition: service_healthy condition: service_healthy
image: umap/umap:3.0.0 image: umap/umap:3.0.2
ports:
- "${PORT-8000}:8000"
environment: environment:
- STATIC_ROOT=/srv/umap/static
- MEDIA_ROOT=/srv/umap/uploads
- DATABASE_URL=postgis://postgres@db/postgres - DATABASE_URL=postgis://postgres@db/postgres
- SECRET_KEY=some-long-and-weirdly-unrandom-secret-key - SECRET_KEY=some-long-and-weirdly-unrandom-secret-key
- SITE_URL=https://umap.local/ - SITE_URL=https://umap.local/
@ -39,7 +39,20 @@ services:
- REDIS_URL=redis://redis:6379 - REDIS_URL=redis://redis:6379
volumes: volumes:
- data:/srv/umap/uploads - data:/srv/umap/uploads
- static:/srv/umap/static
proxy:
image: nginx:latest
ports:
- "8000:80"
volumes:
- ./docker/nginx.conf:/etc/nginx/nginx.conf:ro
- static:/static:ro
- data:/data:ro
depends_on:
- app
volumes: volumes:
data: data:
static:
db: db:

111
docker/nginx.conf Normal file
View file

@ -0,0 +1,111 @@
events {
worker_connections 1024; # Adjust this to your needs
}
http {
proxy_cache_path /tmp/nginx_ajax_proxy_cache levels=1:2 keys_zone=ajax_proxy:10m inactive=60m;
proxy_cache_key "$uri$is_args$args";
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
types {
application/javascript mjs;
}
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# Server block
server {
listen 80;
server_name localhost;
# Static file serving
location /static/ {
alias /static/;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
expires 365d;
access_log /dev/null;
}
# Geojson files
location /uploads/ {
alias /data/;
expires 30d;
}
location /favicon.ico {
alias /static/favicon.ico;
}
# X-Accel-Redirect
location /internal/ {
internal;
gzip_vary on;
gzip_static on;
add_header X-DataLayer-Version $upstream_http_x_datalayer_version;
alias /data/;
}
# Ajax proxy
location ~ ^/proxy/(.*) {
internal;
add_header X-Proxy-Cache $upstream_cache_status always;
proxy_cache_background_update on;
proxy_cache_use_stale updating;
proxy_cache ajax_proxy;
proxy_cache_valid 1m; # Default. Umap will override using X-Accel-Expires
set $target_url $1;
# URL is encoded, so we need a few hack to clean it back.
if ( $target_url ~ (.+)%3A%2F%2F(.+) ){ # fix :// between scheme and destination
set $target_url $1://$2;
}
if ( $target_url ~ (.+?)%3A(.*) ){ # fix : between destination and port
set $target_url $1:$2;
}
if ( $target_url ~ (.+?)%2F(.*) ){ # fix / after port, the rest will be decoded by proxy_pass
set $target_url $1/$2;
}
resolver 8.8.8.8;
add_header X-Proxy-Target $target_url; # For debugging
proxy_pass_request_headers off;
proxy_set_header Content-Type $http_content_type;
proxy_set_header Content-Encoding $http_content_encoding;
proxy_set_header Content-Length $http_content_length;
proxy_read_timeout 10s;
proxy_connect_timeout 5s;
proxy_ssl_server_name on;
proxy_pass $target_url;
proxy_intercept_errors on;
error_page 301 302 307 = @handle_proxy_redirect;
}
location @handle_proxy_redirect {
resolver 8.8.8.8;
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
# Proxy pass to ASGI server
location / {
proxy_pass http://app:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_buffering off;
}
}
}

View file

@ -1,5 +1,5 @@
# Force rtfd to use a recent version of mkdocs # Force rtfd to use a recent version of mkdocs
mkdocs==1.6.1 mkdocs==1.6.1
pymdown-extensions==10.14.3 pymdown-extensions==10.14.3
mkdocs-material==9.6.10 mkdocs-material==9.6.12
mkdocs-static-i18n==1.3.0 mkdocs-static-i18n==1.3.0

View file

@ -1,5 +1,56 @@
# Changelog # Changelog
## 3.0.5 - 2025-04-25
* allow to save a remote data with unloaded data by @yohanboniface in #2657
* allow to save/undo/sync drag'n'drop of datalayers by @yohanboniface in #2677
* setting center and zoom manually should set dirty status by @yohanboniface in #2676
* fix error when saving and deleting heatmap layer by @yohanboniface in #2681
* make rules reordering syncable, savable and undoable by @yohanboniface in #2672
* loading remote data should not make the map dirty by @yohanboniface in #2679
* implement a design system for UI consistency by @davidbgk in #2654
* pass CSRF_TRUSTED_ORIGINS env to settings by @lippoliv in #2656
* do not display "saved" message if some request failed by @yohanboniface in #2669
* show an error message if saving layer failed by @yohanboniface in #2670
* naive support for GeometryCollection as Feature geometry by @yohanboniface in #2658
* add a back button in rules form by @yohanboniface in #2673
## New Contributors
* @lippoliv made their first contribution in #2656
## 3.0.4 - 2025-04-14
* do not show "back to home" button in iframes by @yohanboniface in #2644
* remove "hide home button" shown twice in map settings by @yohanboniface in #2645
* adapt Helm chart to match La Suite's expectations by @ohemelaar in #2646
* update colors by @yohanboniface in #2647
## 3.0.3 - 2025-04-11
* do not try to remove a feature not yet added by @yohanboniface in #2637
* document that nginx needs to be added in Docker stack to serve statics by @yohanboniface in #2636
* display back help button in switch fields by @yohanboniface in #2634
* use Last-Modified header from remote data when available by @yohanboniface in #2624
* fix text overflow on search results by @yohanboniface in #2628
* redirect to user dashboard after map delete by @yohanboniface in #2626
* add missing margin-bottom in importers by @yohanboniface in #2627
* fix pictogram categories always hidden by @yohanboniface in #2630
* display search category on list page by @davidbgk in #2635
* allow to hide the layer switcher from bottom bar by @davidbgk in #2639
* hidden download button in browser when embedControl=false by @yohanboniface in #2640
* allow to hide the back to home button by @davidbgk in #2638
## 3.0.2 - 2025-04-08
* fix copiable input CSS by @yohanboniface in #2616
* fix categorized layer crashing with null value by @yohanboniface in #2621
* properly call endEdit for markers by @yohanboniface in #2617
* fix result tools buttons background color by @yohanboniface in #2620
* fix min-height of select in caption bar by @yohanboniface in #2622
* give priority to small usernames on autocomplete by @yohanboniface in #2604
## 3.0.1 - 2025-04-07 ## 3.0.1 - 2025-04-07
* fix showLabel wrongly using MultiChoices by @yohanboniface in #2609 * fix showLabel wrongly using MultiChoices by @yohanboniface in #2609
@ -23,6 +74,13 @@ Other notable changes:
Note: you may want to update your search index to include the category search, Note: you may want to update your search index to include the category search,
see https://docs.umap-project.org/en/stable/config/settings/#umap_search_configuration see https://docs.umap-project.org/en/stable/config/settings/#umap_search_configuration
### Breaking change
* The Docker image will not serve assets and data files anymore, an Nginx container must
be configured. See [docker-compose.yml](https://github.com/umap-project/umap/blob/master/docker-compose.yml)
for an example.
### New features ### New features
* add collaborative real-time map editing * add collaborative real-time map editing
* add atomic undo redo by @yohanboniface in #2570 * add atomic undo redo by @yohanboniface in #2570

View file

@ -95,6 +95,12 @@ A switch will be available for them in the "advanced properties" of the map.
See [the documentation about ASGI deployment](../deploy/asgi.md) for more information. See [the documentation about ASGI deployment](../deploy/asgi.md) for more information.
#### REDIS_URL
Connection URL to the Redis server. Only need for the real-time editing.
Default: `redis://localhost:6379`
#### SECRET_KEY #### SECRET_KEY
Must be defined to something unique and secret. Must be defined to something unique and secret.

View file

@ -1,84 +1,10 @@
# Configuring Nginx # Configuring Nginx
Here are some configuration files to use umap with nginx and [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/), a server for python, which will handle your processes for you. See [WSGI](wsgi.md) or [ASGI](asgi.md) for a basic setup.
```nginx title="nginx.conf" Then consider adding this configuration
upstream umap {
server unix:///srv/umap/umap.sock;
}
server { ## Static files and geojson
# the port your site will be served on
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
# the domain name it will serve for
server_name your-domain.org;
charset utf-8;
# max upload size
client_max_body_size 5M; # adjust to taste
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass umap;
include /srv/umap/uwsgi_params;
}
}
```
## uWSGI
```nginx title="uwsgi_params"
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
```
```ini title="uwsgi.ini"
[uwsgi]
uid = umap
gid = users
# Python related settings
# the base directory (full path)
chdir = /srv/umap/
# umap's wsgi module
module = umap.wsgi
# the virtualenv (full path)
home = /srv/umap/venv
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 4
# the socket (use the full path to be safe)
socket = /srv/umap/umap.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
stats = /srv/umap/stats.sock
# clear environment on exit
vacuum = true
plugins = python3
```
## Static files
```nginx title="nginx.conf" ```nginx title="nginx.conf"
location /static { location /static {

37
docs/deploy/overview.md Normal file
View file

@ -0,0 +1,37 @@
# Deploying uMap
uMap is a python package, running [Django](https://docs.djangoproject.com/en/5.2/howto/deployment/),
so anyone experimented with this stack will find it familiar, but there are some speficic details
to know about.
## Data
One important design point of uMap is that while metadata are stored in a PostgreSQL database, the
data itself is stored in the file system, as geojson files. This design choice has been made
to make uMap scale better, as there are much more reads than writes, and when some
map is shared a lot (like on a national media) we want to be able to serve it without needing an
overcomplex and costly stack.
So when a request for data is made (that is on a *DataLayer*), the flow is that uMap will read
the request headers to check for permissions, and then it will forward the request to Nginx,
that will properly serve the data (a geojson file), without consuming a python worker, and with
much more efficiency than python.
In DEBUG mode, uMap will serve the geojson itself, but this is not recommended in production,
unless you have a very small audience.
Data can also be stored in a [S3 like storage](../config/storage/#using-s3).
## Assets (JS, CSS…)
As any web app, uMap also needs static files to be served. In DEBUG mode, Django will do this
kindly, but not in production. See [Nginx configuration](nginx.md) for this.
Assets can also be stored in a [S3 like storage](../config/storage/#using-s3).
## python app (metadata, permissions…)
uMap needs a python server, which can either be of [WSGI](wsgi.md) or [ASGI](asgi.md) (this later
is needed in order to use the collaborative live editing).
## Redis
Still when using the collaborative live editing, uMap needs a [Redis](../config/settings.md#redis_url) server, to act as pubsub.

87
docs/deploy/wsgi.md Normal file
View file

@ -0,0 +1,87 @@
# WSGI
WSGI is the historical standard to serve python in general, and uMap in this case.
From recently, uMap also supports [ASGI](asgi.md), which is required to use the
collaborative editing feature.
## uWSGI
In Nginx host, use:
```nginx title="nginx.conf"
upstream umap {
server unix:///srv/umap/umap.sock;
}
server {
# the port your site will be served on
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
# the domain name it will serve for
server_name your-domain.org;
charset utf-8;
# max upload size
client_max_body_size 5M; # adjust to taste
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass umap;
include /srv/umap/uwsgi_params;
}
}
```
```nginx title="uwsgi_params"
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
```
```ini title="uwsgi.ini"
[uwsgi]
uid = umap
gid = users
# Python related settings
# the base directory (full path)
chdir = /srv/umap/
# umap's wsgi module
module = umap.wsgi
# the virtualenv (full path)
home = /srv/umap/venv
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 4
# the socket (use the full path to be safe)
socket = /srv/umap/umap.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
stats = /srv/umap/stats.sock
# clear environment on exit
vacuum = true
plugins = python3
```
See also [Django documentation](https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/).

View file

@ -1,5 +1,5 @@
# Force rtfd to use a recent version of mkdocs # Force rtfd to use a recent version of mkdocs
mkdocs==1.6.1 mkdocs==1.6.1
pymdown-extensions==10.14.3 pymdown-extensions==10.14.3
mkdocs-material==9.6.10 mkdocs-material==9.6.12
mkdocs-static-i18n==1.3.0 mkdocs-static-i18n==1.3.0

View file

@ -18,10 +18,12 @@ nav:
- Storage: config/storage.md - Storage: config/storage.md
- Icon packs: config/icons.md - Icon packs: config/icons.md
- Deployment: - Deployment:
- Overview: deploy/overview.md
- Docker: deploy/docker.md - Docker: deploy/docker.md
- Helm: deploy/helm.md - Helm: deploy/helm.md
- Nginx: deploy/nginx.md - Nginx: deploy/nginx.md
- ASGI: deploy/asgi.md - ASGI: deploy/asgi.md
- WSGI: deploy/wsgi.md
- Changelog: changelog.md - Changelog: changelog.md
theme: theme:
name: material name: material

View file

@ -38,7 +38,7 @@
"dependencies": { "dependencies": {
"@dwayneparton/geojson-to-gpx": "^0.2.0", "@dwayneparton/geojson-to-gpx": "^0.2.0",
"@placemarkio/tokml": "0.3.4", "@placemarkio/tokml": "0.3.4",
"@tmcw/togeojson": "^5.8.0", "@tmcw/togeojson": "^7.1.0",
"colorbrewer": "1.5.7", "colorbrewer": "1.5.7",
"csv2geojson": "github:umap-project/csv2geojson#patched", "csv2geojson": "github:umap-project/csv2geojson#patched",
"dompurify": "3.2.4", "dompurify": "3.2.4",

View file

@ -32,7 +32,7 @@ dependencies = [
"django-agnocomplete==2.2.0", "django-agnocomplete==2.2.0",
"django-environ==0.12.0", "django-environ==0.12.0",
"django-probes==1.7.0", "django-probes==1.7.0",
"Pillow==11.1.0", "Pillow==11.2.1",
"psycopg==3.2.6", "psycopg==3.2.6",
"requests==2.32.3", "requests==2.32.3",
"rcssmin==1.2.1", "rcssmin==1.2.1",
@ -43,11 +43,11 @@ dependencies = [
[project.optional-dependencies] [project.optional-dependencies]
dev = [ dev = [
"hatch==1.14.0", "hatch==1.14.1",
"ruff==0.11.2", "ruff==0.11.6",
"djlint==1.36.4", "djlint==1.36.4",
"mkdocs==1.6.1", "mkdocs==1.6.1",
"mkdocs-material==9.6.10", "mkdocs-material==9.6.12",
"mkdocs-static-i18n==1.3.0", "mkdocs-static-i18n==1.3.0",
"vermin==1.6.0", "vermin==1.6.0",
"pymdown-extensions==10.14.3", "pymdown-extensions==10.14.3",
@ -58,20 +58,20 @@ test = [
"factory-boy==3.3.3", "factory-boy==3.3.3",
"playwright>=1.39", "playwright>=1.39",
"pytest==8.3.5", "pytest==8.3.5",
"pytest-django==4.10.0", "pytest-django==4.11.1",
"pytest-playwright==0.7.0", "pytest-playwright==0.7.0",
"pytest-rerunfailures==15.0", "pytest-rerunfailures==15.0",
"pytest-xdist>=3.5.0,<4", "pytest-xdist>=3.5.0,<4",
"moto[s3]==5.1.1" "moto[s3]==5.1.4"
] ]
docker = [ docker = [
"uvicorn==0.34.0", "uvicorn==0.34.2",
] ]
s3 = [ s3 = [
"django-storages[s3]==1.14.5", "django-storages[s3]==1.14.6",
] ]
sync = [ sync = [
"pydantic==2.11.1", "pydantic==2.11.3",
"redis==5.2.1", "redis==5.2.1",
"websockets==15.0.1", "websockets==15.0.1",
] ]

View file

@ -1 +1 @@
VERSION = "3.0.1" VERSION = "3.0.5"

View file

@ -2,6 +2,7 @@ from agnocomplete.core import AgnocompleteModel
from agnocomplete.register import register from agnocomplete.register import register
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db.models.functions import Length
@register @register
@ -13,3 +14,11 @@ class AutocompleteUser(AgnocompleteModel):
data = super().item(current_item) data = super().item(current_item)
data["url"] = current_item.get_url() data["url"] = current_item.get_url()
return data return data
def build_extra_filtered_queryset(self, queryset, **kwargs):
order_by = []
for field_name in self.fields:
if not field_name[0].isalnum():
field_name = field_name[1:]
order_by.append(Length(field_name).asc())
return queryset.order_by(*order_by)

Binary file not shown.

View file

@ -13,7 +13,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: uMap\n" "Project-Id-Version: uMap\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-03-03 17:36+0000\n" "POT-Creation-Date: 2025-04-11 15:30+0000\n"
"PO-Revision-Date: 2013-11-22 14:00+0000\n" "PO-Revision-Date: 2013-11-22 14:00+0000\n"
"Last-Translator: prendi <prendi@openmailbox.org>, 2017\n" "Last-Translator: prendi <prendi@openmailbox.org>, 2017\n"
"Language-Team: Greek (http://app.transifex.com/openstreetmap/umap/language/el/)\n" "Language-Team: Greek (http://app.transifex.com/openstreetmap/umap/language/el/)\n"
@ -40,137 +40,205 @@ msgstr "Λόγω συντήρησης, ο ιστότοπος είναι μόνο
msgid "" msgid ""
"Using “%(name)s” to authenticate is deprecated and will be removed soon. " "Using “%(name)s” to authenticate is deprecated and will be removed soon. "
"Please configure another provider below before losing access to your account" "Please configure another provider below before losing access to your account"
" and maps." " and maps. Then, please logout and login again with the new provider."
msgstr "" msgstr "Η χρήση του «%(name)s» για τον έλεγχο ταυτότητας έχει ξεπεραστεί και θα καταργηθεί σύντομα. Παρακαλούμε ρυθμίστε έναν άλλο πάροχο παρακάτω πριν χάσετε την πρόσβαση στο λογαριασμό και τους χάρτες σας. Στη συνέχεια, παρακαλούμε αποσυνδεθείτε και συνδεθείτε ξανά με τον νέο πάροχο."
#: models.py:60 models.py:79 #: models.py:61 models.py:80
msgid "name" msgid "name"
msgstr "όνομα" msgstr "όνομα"
#: models.py:62 models.py:485 #: models.py:63 models.py:493
msgid "description" msgid "description"
msgstr "περιγραφή" msgstr "περιγραφή"
#: models.py:110 #: models.py:111
msgid "details" msgid "details"
msgstr "λεπτομέρειες" msgstr "λεπτομέρειες"
#: models.py:111 #: models.py:112
msgid "Link to a page where the licence is detailed." msgid "Link to a page where the licence is detailed."
msgstr "Σύνδεσμος σελίδας αναλυτικής Άδειας Χρήσης." msgstr "Σύνδεσμος σελίδας αναλυτικής Άδειας Χρήσης."
#: models.py:121 #: models.py:122
msgid "URL template using OSM tile format" msgid "URL template using OSM tile format"
msgstr "Πρότυπο URL που χρησιμοποιεί μορφοποίηση πλακιδίων OSM" msgstr "Πρότυπο URL που χρησιμοποιεί μορφοποίηση πλακιδίων OSM"
#: models.py:127 #: models.py:128
msgid "Order of the tilelayers in the edit box" msgid "Order of the tilelayers in the edit box"
msgstr "Σειρά των υπόβαθρων στο πλαίσιο επεξεργασίας" msgstr "Σειρά των υπόβαθρων στο πλαίσιο επεξεργασίας"
#: models.py:175 models.py:479 #: models.py:176 models.py:487
msgid "Only editable with secret edit link" msgid "Only editable with secret edit link"
msgstr "Επεξεργάσιμο μόνο με μυστικό σύνδεσμο" msgstr "Επεξεργάσιμο μόνο με μυστικό σύνδεσμο"
#: models.py:176 models.py:480 #: models.py:177 models.py:488
msgid "Everyone can edit" msgid "Everyone can edit"
msgstr "Όλοι μπορούν να επεξεργαστούν" msgstr "Όλοι μπορούν να επεξεργαστούν"
#: models.py:179 models.py:473 #: models.py:180 models.py:481
msgid "Everyone" msgid "Everyone"
msgstr "Οποιοσδήποτε" msgstr "Οποιοσδήποτε"
#: models.py:180 models.py:189 models.py:474 #: models.py:181 models.py:190 models.py:482
msgid "Editors and team only" msgid "Editors and team only"
msgstr "Μόνο συντάκτες και ομάδα" msgstr "Μόνο συντάκτες και ομάδα"
#: models.py:181 models.py:475 #: models.py:182 models.py:483
msgid "Owner only" msgid "Owner only"
msgstr "Μόνο ο κάτοχος" msgstr "Μόνο ο κάτοχος"
#: models.py:184 #: models.py:185
msgid "Draft (private)" msgid "Draft (private)"
msgstr "Πρόχειρο (ιδιωτικό)" msgstr "Πρόχειρο (ιδιωτικό)"
#: models.py:185 #: models.py:186
msgid "Everyone (public)" msgid "Everyone (public)"
msgstr "Όλοι (δημόσιος)" msgstr "Όλοι (δημόσιος)"
#: models.py:188 #: models.py:189
msgid "Anyone with link" msgid "Anyone with link"
msgstr "Οποιοδήποτε με τον σύνδεσμο" msgstr "Οποιοδήποτε με τον σύνδεσμο"
#: models.py:190 #: models.py:191
msgid "Blocked" msgid "Blocked"
msgstr "Αποκλεισμένος" msgstr "Αποκλεισμένος"
#: models.py:191 models.py:469 #: models.py:192 models.py:477
msgid "Deleted" msgid "Deleted"
msgstr "Διαγράφηκε" msgstr "Διαγράφηκε"
#: models.py:194 #: models.py:195
msgid "center" msgid "center"
msgstr "κέντρο" msgstr "κέντρο"
#: models.py:195 #: models.py:196
msgid "zoom" msgid "zoom"
msgstr "εστίαση" msgstr "εστίαση"
#: models.py:197 #: models.py:198
msgid "locate" msgid "locate"
msgstr "εντοπισμός θέσης" msgstr "εντοπισμός θέσης"
#: models.py:197 #: models.py:198
msgid "Locate user on load?" msgid "Locate user on load?"
msgstr "Εντοπισμός θέσης χρήστη κατά την φόρτωση;" msgstr "Εντοπισμός θέσης χρήστη κατά την φόρτωση;"
#: models.py:201 #: models.py:202
msgid "Choose the map licence." msgid "Choose the map licence."
msgstr "Επιλογή άδειας χρήσης του χάρτη." msgstr "Επιλογή άδειας χρήσης του χάρτη."
#: models.py:202 #: models.py:203
msgid "licence" msgid "licence"
msgstr "άδεια" msgstr "άδεια"
#: models.py:213 #: models.py:214
msgid "owner" msgid "owner"
msgstr "ιδιοκτήτης" msgstr "ιδιοκτήτης"
#: models.py:217 #: models.py:218
msgid "editors" msgid "editors"
msgstr "συντάκτες" msgstr "συντάκτες"
#: models.py:223 #: models.py:224
msgid "team" msgid "team"
msgstr "ομάδα" msgstr "ομάδα"
#: models.py:229 models.py:501 #: models.py:230 models.py:509
msgid "edit status" msgid "edit status"
msgstr "κατάσταση επεξεργασίας" msgstr "κατάσταση επεξεργασίας"
#: models.py:234 models.py:506 #: models.py:235 models.py:514
msgid "share status" msgid "share status"
msgstr "κατάσταση διαμοιρασμού" msgstr "κατάσταση διαμοιρασμού"
#: models.py:237 models.py:496 #: models.py:238 models.py:504
msgid "settings" msgid "settings"
msgstr "ρυθμίσεις" msgstr "ρυθμίσεις"
#: models.py:407 #: models.py:410
msgid "Clone of" msgid "Clone of"
msgstr "Κλώνος του" msgstr "Κλώνος του"
#: models.py:468 models.py:472 models.py:478 #: models.py:476 models.py:480 models.py:486
msgid "Inherit" msgid "Inherit"
msgstr "Κληρονόμοι" msgstr "Κληρονόμοι"
#: models.py:491 #: models.py:499
msgid "display on load" msgid "display on load"
msgstr "εμφάνιση κατά τη φόρτωση" msgstr "εμφάνιση κατά τη φόρτωση"
#: models.py:492 #: models.py:500
msgid "Display this layer on load." msgid "Display this layer on load."
msgstr "Εμφάνιση αυτού του επιπέδου κατά την φόρτωση." msgstr "Εμφάνιση αυτού του επιπέδου κατά την φόρτωση."
#: settings/base.py:295
msgid "Art and Culture"
msgstr "Τέχνες και Πολιτισμός"
#: settings/base.py:296
msgid "Cycling"
msgstr "Ποδηλασία"
#: settings/base.py:297
msgid "Business"
msgstr "Επιχειρήσεις"
#: settings/base.py:298
msgid "Environment"
msgstr "Περιβάλλον"
#: settings/base.py:299
msgid "Education"
msgstr "Εκπαίδευση"
#: settings/base.py:300
msgid "Food and Agriculture"
msgstr "Διατροφή και Γεωργία"
#: settings/base.py:301
msgid "Geopolitics"
msgstr "Γεωπολιτική"
#: settings/base.py:302
msgid "Health"
msgstr "Υγεία"
#: settings/base.py:303
msgid "Hiking"
msgstr "Πεζοπορία-Ορειβασία"
#: settings/base.py:304
msgid "History"
msgstr "Ιστορία"
#: settings/base.py:305
msgid "Public sector"
msgstr "Δημόσιος τομέας"
#: settings/base.py:306
msgid "Science"
msgstr "Επιστήμες"
#: settings/base.py:307
msgid "Shopping"
msgstr "Ψώνια"
#: settings/base.py:308
msgid "Sport and Leisure"
msgstr "Αθλητισμός και ελεύθερος χρόνος"
#: settings/base.py:309
msgid "Travel"
msgstr "Ταξίδια"
#: settings/base.py:310
msgid "Transports"
msgstr "Μεταφορές"
#: settings/base.py:311
msgid "Tourism"
msgstr "Τουρισμός"
#: templates/403.html:8 #: templates/403.html:8
msgid "" msgid ""
"<a href=\"https://discover.umap-project.org/support/faq/#map-statuses\" " "<a href=\"https://discover.umap-project.org/support/faq/#map-statuses\" "
@ -423,7 +491,7 @@ msgstr "Οι ομάδες μου"
msgid "Map of the uMaps" msgid "Map of the uMaps"
msgstr "Χάρτης των uMaps" msgstr "Χάρτης των uMaps"
#: templates/umap/home.html:24 #: templates/umap/home.html:25
msgid "Get inspired, browse maps" msgid "Get inspired, browse maps"
msgstr "Περιηγήσου και αναζήτησε την έμπνευση στους χάρτες!" msgstr "Περιηγήσου και αναζήτησε την έμπνευση στους χάρτες!"
@ -431,11 +499,15 @@ msgstr "Περιηγήσου και αναζήτησε την έμπνευση
msgid "You are logged in. Continuing..." msgid "You are logged in. Continuing..."
msgstr "Είστε συνδεδεμένοι. Συνέχεια..." msgstr "Είστε συνδεδεμένοι. Συνέχεια..."
#: templates/umap/map_list.html:11 views.py:437 #: templates/umap/map_list.html:18 views.py:444
msgid "by" msgid "by"
msgstr "από" msgstr "από"
#: templates/umap/map_list.html:20 #: templates/umap/map_list.html:22
msgid "See the map"
msgstr "Δες τον χάρτη"
#: templates/umap/map_list.html:28
msgid "More" msgid "More"
msgstr "Περισσότερα" msgstr "Περισσότερα"
@ -594,11 +666,15 @@ msgid_plural "%(count)s maps found:"
msgstr[0] "%(count)s χάρτης βρέθηκε:" msgstr[0] "%(count)s χάρτης βρέθηκε:"
msgstr[1] "%(count)s χάρτες βρέθηκαν:" msgstr[1] "%(count)s χάρτες βρέθηκαν:"
#: templates/umap/search.html:28 #: templates/umap/search.html:30
msgid "No map found." msgid "No map found."
msgstr "Δεν βρέθηκε κανένας χάρτης." msgstr "Δεν βρέθηκε κανένας χάρτης."
#: templates/umap/search.html:33 #: templates/umap/search.html:36
msgid "Latest created maps in category"
msgstr "Τελευταία δημιουργημένοι χάρτες στην κατηγορία"
#: templates/umap/search.html:43
msgid "Latest created maps" msgid "Latest created maps"
msgstr "Χάρτες που δημιουργήθηκαν τελευταίοι" msgstr "Χάρτες που δημιουργήθηκαν τελευταίοι"
@ -606,7 +682,11 @@ msgstr "Χάρτες που δημιουργήθηκαν τελευταίοι"
msgid "Search maps" msgid "Search maps"
msgstr "Αναζήτηση χαρτών" msgstr "Αναζήτηση χαρτών"
#: templates/umap/search_bar.html:16 #: templates/umap/search_bar.html:14
msgid "Any category"
msgstr "Οποιαδήποτε κατηγορία"
#: templates/umap/search_bar.html:19
msgid "Search" msgid "Search"
msgstr "Αναζήτηση" msgstr "Αναζήτηση"
@ -670,70 +750,70 @@ msgstr "Χρήστες"
msgid "New team" msgid "New team"
msgstr "Νέα ομάδα" msgstr "Νέα ομάδα"
#: views.py:234 #: views.py:235
msgid "Cannot delete a team with more than one member" msgid "Cannot delete a team with more than one member"
msgstr "Δεν είναι δυνατή η διαγραφή μιας ομάδας που έχει περισσότερα από ένα μέλη" msgstr "Δεν είναι δυνατή η διαγραφή μιας ομάδας που έχει περισσότερα από ένα μέλη"
#: views.py:238 #: views.py:239
#, python-format #, python-format
msgid "Team “%(name)s” has been deleted" msgid "Team “%(name)s” has been deleted"
msgstr "Η ομάδα «%(name)s» έχει διαγραφεί." msgstr "Η ομάδα «%(name)s» έχει διαγραφεί."
#: views.py:442 #: views.py:449
msgid "View the map" msgid "View the map"
msgstr "Προβολή του χάρτη" msgstr "Προβολή του χάρτη"
#: views.py:838 #: views.py:845
msgid "See full screen" msgid "See full screen"
msgstr "Προβολή πλήρους οθόνης" msgstr "Προβολή πλήρους οθόνης"
#: views.py:981 #: views.py:988
msgid "Map editors updated with success!" msgid "Map editors updated with success!"
msgstr "Η ενημέρωση των συντακτών χάρτη ήταν επιτυχής!" msgstr "Η ενημέρωση των συντακτών χάρτη ήταν επιτυχής!"
#: views.py:1017 #: views.py:1024
#, python-format #, python-format
msgid "The uMap edit link for your map: %(map_name)s" msgid "The uMap edit link for your map: %(map_name)s"
msgstr "Ο uMap σύνδεσμος επεξεργασίας του χάρτη σας: %(map_name)s" msgstr "Ο uMap σύνδεσμος επεξεργασίας του χάρτη σας: %(map_name)s"
#: views.py:1020 #: views.py:1027
#, python-format #, python-format
msgid "Here is your secret edit link: %(link)s" msgid "Here is your secret edit link: %(link)s"
msgstr "Εδώ είναι ο μυστικός σύνδεσμος επεξεργασίας: %(link)s" msgstr "Εδώ είναι ο μυστικός σύνδεσμος επεξεργασίας: %(link)s"
#: views.py:1027 #: views.py:1034
#, python-format #, python-format
msgid "Can't send email to %(email)s" msgid "Can't send email to %(email)s"
msgstr "Αδυναμία αποστολής email στο %(email)s" msgstr "Αδυναμία αποστολής email στο %(email)s"
#: views.py:1030 #: views.py:1037
#, python-format #, python-format
msgid "Email sent to %(email)s" msgid "Email sent to %(email)s"
msgstr "Μήνυμα email στάλθηκε στο %(email)s" msgstr "Μήνυμα email στάλθηκε στο %(email)s"
#: views.py:1041 #: views.py:1048
msgid "Only its owner can delete the map." msgid "Only its owner can delete the map."
msgstr "Μονό ο ιδιοκτήτης μπορεί να διαγράψει αυτό τον χάρτη." msgstr "Μονό ο ιδιοκτήτης μπορεί να διαγράψει αυτό τον χάρτη."
#: views.py:1044 #: views.py:1054
msgid "Map successfully deleted." msgid "Map successfully deleted."
msgstr "Ο χάρτης διαγράφηκε με επιτυχία." msgstr "Ο χάρτης διαγράφηκε με επιτυχία."
#: views.py:1070 #: views.py:1080
#, python-format #, python-format
msgid "" msgid ""
"Your map has been cloned! If you want to edit this map from another " "Your map has been cloned! If you want to edit this map from another "
"computer, please use this link: %(anonymous_url)s" "computer, please use this link: %(anonymous_url)s"
msgstr "Ο χάρτης κλωνοποιήθηκε! Αν θέλετε να τον επεξεργαστείτε από κάποιον άλλο υπολογιστή, παρακαλώ χρησιμοποιήστε αυτόν τον σύνδεσμο: %(anonymous_url)s" msgstr "Ο χάρτης κλωνοποιήθηκε! Αν θέλετε να τον επεξεργαστείτε από κάποιον άλλο υπολογιστή, παρακαλώ χρησιμοποιήστε αυτόν τον σύνδεσμο: %(anonymous_url)s"
#: views.py:1075 #: views.py:1085
msgid "Congratulations, your map has been cloned!" msgid "Congratulations, your map has been cloned!"
msgstr "Συγχαρητήρια ο χάρτης σας κλωνοποιήθηκε!" msgstr "Συγχαρητήρια ο χάρτης σας κλωνοποιήθηκε!"
#: views.py:1329 #: views.py:1339
msgid "Layer successfully deleted." msgid "Layer successfully deleted."
msgstr "Το επίπεδο διαγράφηκε με επιτυχία." msgstr "Το επίπεδο διαγράφηκε με επιτυχία."
#: views.py:1351 #: views.py:1361
msgid "Permissions updated with success!" msgid "Permissions updated with success!"
msgstr "Τα δικαιώματα ενημερώθηκαν με επιτυχία!" msgstr "Τα δικαιώματα ενημερώθηκαν με επιτυχία!"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-04 16:49+0000\n" "POT-Creation-Date: 2025-04-25 15:38+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -165,71 +165,71 @@ msgstr ""
msgid "Display this layer on load." msgid "Display this layer on load."
msgstr "" msgstr ""
#: settings/base.py:295 #: settings/base.py:296
msgid "Art and Culture" msgid "Art and Culture"
msgstr "" msgstr ""
#: settings/base.py:296 #: settings/base.py:297
msgid "Cycling" msgid "Cycling"
msgstr "" msgstr ""
#: settings/base.py:297 #: settings/base.py:298
msgid "Business" msgid "Business"
msgstr "" msgstr ""
#: settings/base.py:298 #: settings/base.py:299
msgid "Environment" msgid "Environment"
msgstr "" msgstr ""
#: settings/base.py:299 #: settings/base.py:300
msgid "Education" msgid "Education"
msgstr "" msgstr ""
#: settings/base.py:300 #: settings/base.py:301
msgid "Food and Agriculture" msgid "Food and Agriculture"
msgstr "" msgstr ""
#: settings/base.py:301 #: settings/base.py:302
msgid "Geopolitics" msgid "Geopolitics"
msgstr "" msgstr ""
#: settings/base.py:302 #: settings/base.py:303
msgid "Health" msgid "Health"
msgstr "" msgstr ""
#: settings/base.py:303 #: settings/base.py:304
msgid "Hiking" msgid "Hiking"
msgstr "" msgstr ""
#: settings/base.py:304 #: settings/base.py:305
msgid "History" msgid "History"
msgstr "" msgstr ""
#: settings/base.py:305 #: settings/base.py:306
msgid "Public sector" msgid "Public sector"
msgstr "" msgstr ""
#: settings/base.py:306 #: settings/base.py:307
msgid "Science" msgid "Science"
msgstr "" msgstr ""
#: settings/base.py:307 #: settings/base.py:308
msgid "Shopping" msgid "Shopping"
msgstr "" msgstr ""
#: settings/base.py:308 #: settings/base.py:309
msgid "Sport and Leisure" msgid "Sport and Leisure"
msgstr "" msgstr ""
#: settings/base.py:309 #: settings/base.py:310
msgid "Travel" msgid "Travel"
msgstr "" msgstr ""
#: settings/base.py:310 #: settings/base.py:311
msgid "Transports" msgid "Transports"
msgstr "" msgstr ""
#: settings/base.py:311 #: settings/base.py:312
msgid "Tourism" msgid "Tourism"
msgstr "" msgstr ""
@ -663,7 +663,11 @@ msgstr[1] ""
msgid "No map found." msgid "No map found."
msgstr "" msgstr ""
#: templates/umap/search.html:35 #: templates/umap/search.html:36
msgid "Latest created maps in category"
msgstr ""
#: templates/umap/search.html:43
msgid "Latest created maps" msgid "Latest created maps"
msgstr "" msgstr ""
@ -784,25 +788,25 @@ msgstr ""
msgid "Only its owner can delete the map." msgid "Only its owner can delete the map."
msgstr "" msgstr ""
#: views.py:1051 #: views.py:1054
msgid "Map successfully deleted." msgid "Map successfully deleted."
msgstr "" msgstr ""
#: views.py:1077 #: views.py:1080
#, python-format #, python-format
msgid "" msgid ""
"Your map has been cloned! If you want to edit this map from another " "Your map has been cloned! If you want to edit this map from another "
"computer, please use this link: %(anonymous_url)s" "computer, please use this link: %(anonymous_url)s"
msgstr "" msgstr ""
#: views.py:1082 #: views.py:1085
msgid "Congratulations, your map has been cloned!" msgid "Congratulations, your map has been cloned!"
msgstr "" msgstr ""
#: views.py:1336 #: views.py:1339
msgid "Layer successfully deleted." msgid "Layer successfully deleted."
msgstr "" msgstr ""
#: views.py:1358 #: views.py:1361
msgid "Permissions updated with success!" msgid "Permissions updated with success!"
msgstr "" msgstr ""

Binary file not shown.

View file

@ -17,7 +17,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: uMap\n" "Project-Id-Version: uMap\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-03-03 17:36+0000\n" "POT-Creation-Date: 2025-04-11 15:30+0000\n"
"PO-Revision-Date: 2013-11-22 14:00+0000\n" "PO-Revision-Date: 2013-11-22 14:00+0000\n"
"Last-Translator: Ignacio L'Episcopo, 2024-2025\n" "Last-Translator: Ignacio L'Episcopo, 2024-2025\n"
"Language-Team: Spanish (http://app.transifex.com/openstreetmap/umap/language/es/)\n" "Language-Team: Spanish (http://app.transifex.com/openstreetmap/umap/language/es/)\n"
@ -44,137 +44,205 @@ msgstr "Sitio en modo solo lectura por mantenimiento"
msgid "" msgid ""
"Using “%(name)s” to authenticate is deprecated and will be removed soon. " "Using “%(name)s” to authenticate is deprecated and will be removed soon. "
"Please configure another provider below before losing access to your account" "Please configure another provider below before losing access to your account"
" and maps." " and maps. Then, please logout and login again with the new provider."
msgstr "" msgstr "El uso de “%(name)s” para autenticar está obsoleto y se eliminará pronto. Por favor, configura otro proveedor a continuación antes de perder acceso a tu cuenta y mapas. Luego, cierra sesión e inicia sesión nuevamente con el nuevo proveedor."
#: models.py:60 models.py:79 #: models.py:61 models.py:80
msgid "name" msgid "name"
msgstr "nombre" msgstr "nombre"
#: models.py:62 models.py:485 #: models.py:63 models.py:493
msgid "description" msgid "description"
msgstr "descripción" msgstr "descripción"
#: models.py:110 #: models.py:111
msgid "details" msgid "details"
msgstr "detalles" msgstr "detalles"
#: models.py:111 #: models.py:112
msgid "Link to a page where the licence is detailed." msgid "Link to a page where the licence is detailed."
msgstr "Enlace a una página donde se detalla la licencia." msgstr "Enlace a una página donde se detalla la licencia."
#: models.py:121 #: models.py:122
msgid "URL template using OSM tile format" msgid "URL template using OSM tile format"
msgstr "Plantilla de URL usando el formato de teselas OSM" msgstr "Plantilla de URL usando el formato de teselas OSM"
#: models.py:127 #: models.py:128
msgid "Order of the tilelayers in the edit box" msgid "Order of the tilelayers in the edit box"
msgstr "Orden de las capas de teselas en el cuadro de edición" msgstr "Orden de las capas de teselas en el cuadro de edición"
#: models.py:175 models.py:479 #: models.py:176 models.py:487
msgid "Only editable with secret edit link" msgid "Only editable with secret edit link"
msgstr "Solo editable con enlace secreto de edición" msgstr "Solo editable con enlace secreto de edición"
#: models.py:176 models.py:480 #: models.py:177 models.py:488
msgid "Everyone can edit" msgid "Everyone can edit"
msgstr "Todos pueden editar" msgstr "Todos pueden editar"
#: models.py:179 models.py:473 #: models.py:180 models.py:481
msgid "Everyone" msgid "Everyone"
msgstr "Todos" msgstr "Todos"
#: models.py:180 models.py:189 models.py:474 #: models.py:181 models.py:190 models.py:482
msgid "Editors and team only" msgid "Editors and team only"
msgstr "Solo editores y equipo" msgstr "Solo editores y equipo"
#: models.py:181 models.py:475 #: models.py:182 models.py:483
msgid "Owner only" msgid "Owner only"
msgstr "Solo el propietario" msgstr "Solo el propietario"
#: models.py:184 #: models.py:185
msgid "Draft (private)" msgid "Draft (private)"
msgstr "Borrador (privado)" msgstr "Borrador (privado)"
#: models.py:185 #: models.py:186
msgid "Everyone (public)" msgid "Everyone (public)"
msgstr "Todos (público)" msgstr "Todos (público)"
#: models.py:188 #: models.py:189
msgid "Anyone with link" msgid "Anyone with link"
msgstr "Cualquiera con el enlace" msgstr "Cualquiera con el enlace"
#: models.py:190 #: models.py:191
msgid "Blocked" msgid "Blocked"
msgstr "Bloqueado" msgstr "Bloqueado"
#: models.py:191 models.py:469 #: models.py:192 models.py:477
msgid "Deleted" msgid "Deleted"
msgstr "Eliminado" msgstr "Eliminado"
#: models.py:194 #: models.py:195
msgid "center" msgid "center"
msgstr "centro" msgstr "centro"
#: models.py:195 #: models.py:196
msgid "zoom" msgid "zoom"
msgstr "zoom" msgstr "zoom"
#: models.py:197 #: models.py:198
msgid "locate" msgid "locate"
msgstr "localizar" msgstr "localizar"
#: models.py:197 #: models.py:198
msgid "Locate user on load?" msgid "Locate user on load?"
msgstr "¿Localizar al usuario al cargar?" msgstr "¿Localizar al usuario al cargar?"
#: models.py:201 #: models.py:202
msgid "Choose the map licence." msgid "Choose the map licence."
msgstr "Elige la licencia del mapa." msgstr "Elige la licencia del mapa."
#: models.py:202 #: models.py:203
msgid "licence" msgid "licence"
msgstr "licencia" msgstr "licencia"
#: models.py:213 #: models.py:214
msgid "owner" msgid "owner"
msgstr "propietario" msgstr "propietario"
#: models.py:217 #: models.py:218
msgid "editors" msgid "editors"
msgstr "editores" msgstr "editores"
#: models.py:223 #: models.py:224
msgid "team" msgid "team"
msgstr "equipo" msgstr "equipo"
#: models.py:229 models.py:501 #: models.py:230 models.py:509
msgid "edit status" msgid "edit status"
msgstr "estado de edición" msgstr "estado de edición"
#: models.py:234 models.py:506 #: models.py:235 models.py:514
msgid "share status" msgid "share status"
msgstr "estado de compartir" msgstr "estado de compartir"
#: models.py:237 models.py:496 #: models.py:238 models.py:504
msgid "settings" msgid "settings"
msgstr "ajustes" msgstr "ajustes"
#: models.py:407 #: models.py:410
msgid "Clone of" msgid "Clone of"
msgstr "Clon de" msgstr "Clon de"
#: models.py:468 models.py:472 models.py:478 #: models.py:476 models.py:480 models.py:486
msgid "Inherit" msgid "Inherit"
msgstr "Heredar" msgstr "Heredar"
#: models.py:491 #: models.py:499
msgid "display on load" msgid "display on load"
msgstr "mostrar al cargar" msgstr "mostrar al cargar"
#: models.py:492 #: models.py:500
msgid "Display this layer on load." msgid "Display this layer on load."
msgstr "Mostrar esta capa al cargar." msgstr "Mostrar esta capa al cargar."
#: settings/base.py:295
msgid "Art and Culture"
msgstr "Arte y cultura"
#: settings/base.py:296
msgid "Cycling"
msgstr "Ciclismo"
#: settings/base.py:297
msgid "Business"
msgstr "Negocios"
#: settings/base.py:298
msgid "Environment"
msgstr "Medio ambiente"
#: settings/base.py:299
msgid "Education"
msgstr "Educación"
#: settings/base.py:300
msgid "Food and Agriculture"
msgstr "Alimentos y agricultura"
#: settings/base.py:301
msgid "Geopolitics"
msgstr "Geopolítica"
#: settings/base.py:302
msgid "Health"
msgstr "Salud"
#: settings/base.py:303
msgid "Hiking"
msgstr "Senderismo"
#: settings/base.py:304
msgid "History"
msgstr "Historia"
#: settings/base.py:305
msgid "Public sector"
msgstr "Sector público"
#: settings/base.py:306
msgid "Science"
msgstr "Ciencia"
#: settings/base.py:307
msgid "Shopping"
msgstr "Compras"
#: settings/base.py:308
msgid "Sport and Leisure"
msgstr "Deporte y ocio"
#: settings/base.py:309
msgid "Travel"
msgstr "Viajes"
#: settings/base.py:310
msgid "Transports"
msgstr "Transporte"
#: settings/base.py:311
msgid "Tourism"
msgstr "Turismo"
#: templates/403.html:8 #: templates/403.html:8
msgid "" msgid ""
"<a href=\"https://discover.umap-project.org/support/faq/#map-statuses\" " "<a href=\"https://discover.umap-project.org/support/faq/#map-statuses\" "
@ -427,7 +495,7 @@ msgstr "Mis equipos"
msgid "Map of the uMaps" msgid "Map of the uMaps"
msgstr "Mapa de los uMaps" msgstr "Mapa de los uMaps"
#: templates/umap/home.html:24 #: templates/umap/home.html:25
msgid "Get inspired, browse maps" msgid "Get inspired, browse maps"
msgstr "Inspírate, navega por los mapas" msgstr "Inspírate, navega por los mapas"
@ -435,11 +503,15 @@ msgstr "Inspírate, navega por los mapas"
msgid "You are logged in. Continuing..." msgid "You are logged in. Continuing..."
msgstr "Has iniciado sesión. Continuando..." msgstr "Has iniciado sesión. Continuando..."
#: templates/umap/map_list.html:11 views.py:437 #: templates/umap/map_list.html:18 views.py:444
msgid "by" msgid "by"
msgstr "por" msgstr "por"
#: templates/umap/map_list.html:20 #: templates/umap/map_list.html:22
msgid "See the map"
msgstr "Ver el mapa"
#: templates/umap/map_list.html:28
msgid "More" msgid "More"
msgstr "Más" msgstr "Más"
@ -599,11 +671,15 @@ msgstr[0] "%(count)s mapa encontrado:"
msgstr[1] "%(count)s mapas encontrados:" msgstr[1] "%(count)s mapas encontrados:"
msgstr[2] "%(count)s mapas encontrados:" msgstr[2] "%(count)s mapas encontrados:"
#: templates/umap/search.html:28 #: templates/umap/search.html:30
msgid "No map found." msgid "No map found."
msgstr "No se ha encontrado ningún mapa." msgstr "No se ha encontrado ningún mapa."
#: templates/umap/search.html:33 #: templates/umap/search.html:36
msgid "Latest created maps in category"
msgstr "Últimos mapas creados en la categoría"
#: templates/umap/search.html:43
msgid "Latest created maps" msgid "Latest created maps"
msgstr "Últimos mapas creados" msgstr "Últimos mapas creados"
@ -611,7 +687,11 @@ msgstr "Últimos mapas creados"
msgid "Search maps" msgid "Search maps"
msgstr "Buscar mapas" msgstr "Buscar mapas"
#: templates/umap/search_bar.html:16 #: templates/umap/search_bar.html:14
msgid "Any category"
msgstr "Cualquier categoría"
#: templates/umap/search_bar.html:19
msgid "Search" msgid "Search"
msgstr "Buscar" msgstr "Buscar"
@ -675,70 +755,70 @@ msgstr "Usuarios"
msgid "New team" msgid "New team"
msgstr "Nuevo equipo" msgstr "Nuevo equipo"
#: views.py:234 #: views.py:235
msgid "Cannot delete a team with more than one member" msgid "Cannot delete a team with more than one member"
msgstr "No se puede eliminar un equipo con más de un miembro" msgstr "No se puede eliminar un equipo con más de un miembro"
#: views.py:238 #: views.py:239
#, python-format #, python-format
msgid "Team “%(name)s” has been deleted" msgid "Team “%(name)s” has been deleted"
msgstr "El equipo “%(name)s” ha sido eliminado" msgstr "El equipo “%(name)s” ha sido eliminado"
#: views.py:442 #: views.py:449
msgid "View the map" msgid "View the map"
msgstr "Ver el mapa" msgstr "Ver el mapa"
#: views.py:838 #: views.py:845
msgid "See full screen" msgid "See full screen"
msgstr "Ver en pantalla completa" msgstr "Ver en pantalla completa"
#: views.py:981 #: views.py:988
msgid "Map editors updated with success!" msgid "Map editors updated with success!"
msgstr "¡Los editores del mapas han sido actualizados con éxito!" msgstr "¡Los editores del mapas han sido actualizados con éxito!"
#: views.py:1017 #: views.py:1024
#, python-format #, python-format
msgid "The uMap edit link for your map: %(map_name)s" msgid "The uMap edit link for your map: %(map_name)s"
msgstr "El enlace de edición de uMap para tu mapa: %(map_name)s" msgstr "El enlace de edición de uMap para tu mapa: %(map_name)s"
#: views.py:1020 #: views.py:1027
#, python-format #, python-format
msgid "Here is your secret edit link: %(link)s" msgid "Here is your secret edit link: %(link)s"
msgstr "Aquí está tu enlace secreto de edición: %(link)s" msgstr "Aquí está tu enlace secreto de edición: %(link)s"
#: views.py:1027 #: views.py:1034
#, python-format #, python-format
msgid "Can't send email to %(email)s" msgid "Can't send email to %(email)s"
msgstr "No se puede enviar correo electrónico a %(email)s" msgstr "No se puede enviar correo electrónico a %(email)s"
#: views.py:1030 #: views.py:1037
#, python-format #, python-format
msgid "Email sent to %(email)s" msgid "Email sent to %(email)s"
msgstr "Correo electrónico enviado a %(email)s" msgstr "Correo electrónico enviado a %(email)s"
#: views.py:1041 #: views.py:1048
msgid "Only its owner can delete the map." msgid "Only its owner can delete the map."
msgstr "Sólo el propietario puede borrar el mapa." msgstr "Sólo el propietario puede borrar el mapa."
#: views.py:1044 #: views.py:1054
msgid "Map successfully deleted." msgid "Map successfully deleted."
msgstr "Mapa eliminado correctamente." msgstr "Mapa eliminado correctamente."
#: views.py:1070 #: views.py:1080
#, python-format #, python-format
msgid "" msgid ""
"Your map has been cloned! If you want to edit this map from another " "Your map has been cloned! If you want to edit this map from another "
"computer, please use this link: %(anonymous_url)s" "computer, please use this link: %(anonymous_url)s"
msgstr "¡Tu mapa ha sido clonado! Si quieres editar este mapa desde otro ordenador, usa este enlace: %(anonymous_url)s" msgstr "¡Tu mapa ha sido clonado! Si quieres editar este mapa desde otro ordenador, usa este enlace: %(anonymous_url)s"
#: views.py:1075 #: views.py:1085
msgid "Congratulations, your map has been cloned!" msgid "Congratulations, your map has been cloned!"
msgstr "¡Enhorabuena! ¡Tu mapa ha sido clonado!" msgstr "¡Enhorabuena! ¡Tu mapa ha sido clonado!"
#: views.py:1329 #: views.py:1339
msgid "Layer successfully deleted." msgid "Layer successfully deleted."
msgstr "Se eliminó la capa con éxito." msgstr "Se eliminó la capa con éxito."
#: views.py:1351 #: views.py:1361
msgid "Permissions updated with success!" msgid "Permissions updated with success!"
msgstr "¡Permisos actualizados con éxito!" msgstr "¡Permisos actualizados con éxito!"

Binary file not shown.

View file

@ -24,7 +24,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: uMap\n" "Project-Id-Version: uMap\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-04 16:49+0000\n" "POT-Creation-Date: 2025-04-11 15:30+0000\n"
"PO-Revision-Date: 2013-11-22 14:00+0000\n" "PO-Revision-Date: 2013-11-22 14:00+0000\n"
"Last-Translator: yohanboniface <yohanboniface@free.fr>, 2013-2014,2018-2019,2023-2025\n" "Last-Translator: yohanboniface <yohanboniface@free.fr>, 2013-2014,2018-2019,2023-2025\n"
"Language-Team: French (http://app.transifex.com/openstreetmap/umap/language/fr/)\n" "Language-Team: French (http://app.transifex.com/openstreetmap/umap/language/fr/)\n"
@ -682,7 +682,11 @@ msgstr[2] "%(count)s cartes trouvées :"
msgid "No map found." msgid "No map found."
msgstr "Aucune carte trouvée." msgstr "Aucune carte trouvée."
#: templates/umap/search.html:35 #: templates/umap/search.html:36
msgid "Latest created maps in category"
msgstr "Dernières cartes créées dans la catégorie"
#: templates/umap/search.html:43
msgid "Latest created maps" msgid "Latest created maps"
msgstr "Dernières cartes créées." msgstr "Dernières cartes créées."
@ -803,25 +807,25 @@ msgstr "Courriel envoyé à %(email)s"
msgid "Only its owner can delete the map." msgid "Only its owner can delete the map."
msgstr "Seul le créateur de la carte peut la supprimer." msgstr "Seul le créateur de la carte peut la supprimer."
#: views.py:1051 #: views.py:1054
msgid "Map successfully deleted." msgid "Map successfully deleted."
msgstr "La carte a bien été supprimée." msgstr "La carte a bien été supprimée."
#: views.py:1077 #: views.py:1080
#, python-format #, python-format
msgid "" msgid ""
"Your map has been cloned! If you want to edit this map from another " "Your map has been cloned! If you want to edit this map from another "
"computer, please use this link: %(anonymous_url)s" "computer, please use this link: %(anonymous_url)s"
msgstr "Votre carte a été dupliquée ! Si vous souhaitez la modifier depuis un autre ordinateur, veuillez utiliser ce lien : %(anonymous_url)s" msgstr "Votre carte a été dupliquée ! Si vous souhaitez la modifier depuis un autre ordinateur, veuillez utiliser ce lien : %(anonymous_url)s"
#: views.py:1082 #: views.py:1085
msgid "Congratulations, your map has been cloned!" msgid "Congratulations, your map has been cloned!"
msgstr "Votre carte a été dupliquée !" msgstr "Votre carte a été dupliquée !"
#: views.py:1336 #: views.py:1339
msgid "Layer successfully deleted." msgid "Layer successfully deleted."
msgstr "Calque supprimé." msgstr "Calque supprimé."
#: views.py:1358 #: views.py:1361
msgid "Permissions updated with success!" msgid "Permissions updated with success!"
msgstr "Les permissions ont bien été modifiées !" msgstr "Les permissions ont bien été modifiées !"

Binary file not shown.

View file

@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: uMap\n" "Project-Id-Version: uMap\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-03-03 17:36+0000\n" "POT-Creation-Date: 2025-04-11 15:30+0000\n"
"PO-Revision-Date: 2013-11-22 14:00+0000\n" "PO-Revision-Date: 2013-11-22 14:00+0000\n"
"Last-Translator: Gideon van Melle <translations@gvmelle.com>, 2025\n" "Last-Translator: Gideon van Melle <translations@gvmelle.com>, 2025\n"
"Language-Team: Dutch (http://app.transifex.com/openstreetmap/umap/language/nl/)\n" "Language-Team: Dutch (http://app.transifex.com/openstreetmap/umap/language/nl/)\n"
@ -38,137 +38,205 @@ msgstr "Site is 'alleen lezen' wegens onderhoud"
msgid "" msgid ""
"Using “%(name)s” to authenticate is deprecated and will be removed soon. " "Using “%(name)s” to authenticate is deprecated and will be removed soon. "
"Please configure another provider below before losing access to your account" "Please configure another provider below before losing access to your account"
" and maps." " and maps. Then, please logout and login again with the new provider."
msgstr "" msgstr "Het gebruik van %(name)s om te verifiëren is afgeschaft en zal binnenkort worden verwijderd. Configureer hieronder een andere provider voordat u de toegang tot uw account en kaarten verliest. Log uit en log opnieuw in met de nieuwe provider."
#: models.py:60 models.py:79 #: models.py:61 models.py:80
msgid "name" msgid "name"
msgstr "naam" msgstr "naam"
#: models.py:62 models.py:485 #: models.py:63 models.py:493
msgid "description" msgid "description"
msgstr "omschrijving" msgstr "omschrijving"
#: models.py:110 #: models.py:111
msgid "details" msgid "details"
msgstr "details" msgstr "details"
#: models.py:111 #: models.py:112
msgid "Link to a page where the licence is detailed." msgid "Link to a page where the licence is detailed."
msgstr "Link naar pagina waar de licentie details staan" msgstr "Link naar pagina waar de licentie details staan"
#: models.py:121 #: models.py:122
msgid "URL template using OSM tile format" msgid "URL template using OSM tile format"
msgstr "URL-sjabloon met OSM tegel-formaat" msgstr "URL-sjabloon met OSM tegel-formaat"
#: models.py:127 #: models.py:128
msgid "Order of the tilelayers in the edit box" msgid "Order of the tilelayers in the edit box"
msgstr "Volgorde van de tegel-lagen in het bewerkingsvak." msgstr "Volgorde van de tegel-lagen in het bewerkingsvak."
#: models.py:175 models.py:479 #: models.py:176 models.py:487
msgid "Only editable with secret edit link" msgid "Only editable with secret edit link"
msgstr "Alleen te bewerken met een geheime link" msgstr "Alleen te bewerken met een geheime link"
#: models.py:176 models.py:480 #: models.py:177 models.py:488
msgid "Everyone can edit" msgid "Everyone can edit"
msgstr "Iedereen kan wijzigingen maken" msgstr "Iedereen kan wijzigingen maken"
#: models.py:179 models.py:473 #: models.py:180 models.py:481
msgid "Everyone" msgid "Everyone"
msgstr "Iedereen" msgstr "Iedereen"
#: models.py:180 models.py:189 models.py:474 #: models.py:181 models.py:190 models.py:482
msgid "Editors and team only" msgid "Editors and team only"
msgstr "Alleen redacteuren en team" msgstr "Alleen redacteuren en team"
#: models.py:181 models.py:475 #: models.py:182 models.py:483
msgid "Owner only" msgid "Owner only"
msgstr "Alleen eigenaar" msgstr "Alleen eigenaar"
#: models.py:184 #: models.py:185
msgid "Draft (private)" msgid "Draft (private)"
msgstr "Ontwerp (privé)" msgstr "Ontwerp (privé)"
#: models.py:185 #: models.py:186
msgid "Everyone (public)" msgid "Everyone (public)"
msgstr "Iedereen (openbaar)" msgstr "Iedereen (openbaar)"
#: models.py:188 #: models.py:189
msgid "Anyone with link" msgid "Anyone with link"
msgstr "Iedereen met een link" msgstr "Iedereen met een link"
#: models.py:190 #: models.py:191
msgid "Blocked" msgid "Blocked"
msgstr "geblokkeerd" msgstr "geblokkeerd"
#: models.py:191 models.py:469 #: models.py:192 models.py:477
msgid "Deleted" msgid "Deleted"
msgstr "Verwijderd" msgstr "Verwijderd"
#: models.py:194 #: models.py:195
msgid "center" msgid "center"
msgstr "centreer" msgstr "centreer"
#: models.py:195 #: models.py:196
msgid "zoom" msgid "zoom"
msgstr "zoom" msgstr "zoom"
#: models.py:197 #: models.py:198
msgid "locate" msgid "locate"
msgstr "zoek" msgstr "zoek"
#: models.py:197 #: models.py:198
msgid "Locate user on load?" msgid "Locate user on load?"
msgstr "Gebruiker zoeken tijdens laden?" msgstr "Gebruiker zoeken tijdens laden?"
#: models.py:201 #: models.py:202
msgid "Choose the map licence." msgid "Choose the map licence."
msgstr "Kies de kaartlicentie" msgstr "Kies de kaartlicentie"
#: models.py:202 #: models.py:203
msgid "licence" msgid "licence"
msgstr "Licentie" msgstr "Licentie"
#: models.py:213 #: models.py:214
msgid "owner" msgid "owner"
msgstr "eigenaar" msgstr "eigenaar"
#: models.py:217 #: models.py:218
msgid "editors" msgid "editors"
msgstr "editors" msgstr "editors"
#: models.py:223 #: models.py:224
msgid "team" msgid "team"
msgstr "team" msgstr "team"
#: models.py:229 models.py:501 #: models.py:230 models.py:509
msgid "edit status" msgid "edit status"
msgstr "wijzig status" msgstr "wijzig status"
#: models.py:234 models.py:506 #: models.py:235 models.py:514
msgid "share status" msgid "share status"
msgstr "deel status" msgstr "deel status"
#: models.py:237 models.py:496 #: models.py:238 models.py:504
msgid "settings" msgid "settings"
msgstr "instellingen" msgstr "instellingen"
#: models.py:407 #: models.py:410
msgid "Clone of" msgid "Clone of"
msgstr "Kopie van" msgstr "Kopie van"
#: models.py:468 models.py:472 models.py:478 #: models.py:476 models.py:480 models.py:486
msgid "Inherit" msgid "Inherit"
msgstr "overerven" msgstr "overerven"
#: models.py:491 #: models.py:499
msgid "display on load" msgid "display on load"
msgstr "toon tijdens laden" msgstr "toon tijdens laden"
#: models.py:492 #: models.py:500
msgid "Display this layer on load." msgid "Display this layer on load."
msgstr "Toon deze laag tijdens laden." msgstr "Toon deze laag tijdens laden."
#: settings/base.py:295
msgid "Art and Culture"
msgstr "Kunst en cultuur"
#: settings/base.py:296
msgid "Cycling"
msgstr "Fietsen"
#: settings/base.py:297
msgid "Business"
msgstr "Zakelijk"
#: settings/base.py:298
msgid "Environment"
msgstr "Mlieu"
#: settings/base.py:299
msgid "Education"
msgstr "Educatie"
#: settings/base.py:300
msgid "Food and Agriculture"
msgstr "Voedsel en landbouw"
#: settings/base.py:301
msgid "Geopolitics"
msgstr "Geopolitiek"
#: settings/base.py:302
msgid "Health"
msgstr "Gezondheid"
#: settings/base.py:303
msgid "Hiking"
msgstr "Hiking"
#: settings/base.py:304
msgid "History"
msgstr "Geschiedenis"
#: settings/base.py:305
msgid "Public sector"
msgstr "Publieke sector"
#: settings/base.py:306
msgid "Science"
msgstr "Wetenschap"
#: settings/base.py:307
msgid "Shopping"
msgstr "Winkelen"
#: settings/base.py:308
msgid "Sport and Leisure"
msgstr "Sport en vrijetijd"
#: settings/base.py:309
msgid "Travel"
msgstr "Reizen"
#: settings/base.py:310
msgid "Transports"
msgstr "Transport"
#: settings/base.py:311
msgid "Tourism"
msgstr "Toerisme"
#: templates/403.html:8 #: templates/403.html:8
msgid "" msgid ""
"<a href=\"https://discover.umap-project.org/support/faq/#map-statuses\" " "<a href=\"https://discover.umap-project.org/support/faq/#map-statuses\" "
@ -421,7 +489,7 @@ msgstr "Mijn teams"
msgid "Map of the uMaps" msgid "Map of the uMaps"
msgstr "Kaart van de uMaps" msgstr "Kaart van de uMaps"
#: templates/umap/home.html:24 #: templates/umap/home.html:25
msgid "Get inspired, browse maps" msgid "Get inspired, browse maps"
msgstr "Laat u inspireren, blader door kaarten" msgstr "Laat u inspireren, blader door kaarten"
@ -429,11 +497,15 @@ msgstr "Laat u inspireren, blader door kaarten"
msgid "You are logged in. Continuing..." msgid "You are logged in. Continuing..."
msgstr "U bent ingelogd. Ga verder..." msgstr "U bent ingelogd. Ga verder..."
#: templates/umap/map_list.html:11 views.py:437 #: templates/umap/map_list.html:18 views.py:444
msgid "by" msgid "by"
msgstr "door" msgstr "door"
#: templates/umap/map_list.html:20 #: templates/umap/map_list.html:22
msgid "See the map"
msgstr "Zie de kaart"
#: templates/umap/map_list.html:28
msgid "More" msgid "More"
msgstr "Meer" msgstr "Meer"
@ -592,11 +664,15 @@ msgid_plural "%(count)s maps found:"
msgstr[0] "%(count)s kaarten gevonden:" msgstr[0] "%(count)s kaarten gevonden:"
msgstr[1] "%(count)s kaarten gevonden:" msgstr[1] "%(count)s kaarten gevonden:"
#: templates/umap/search.html:28 #: templates/umap/search.html:30
msgid "No map found." msgid "No map found."
msgstr "Geen kaart gevonden." msgstr "Geen kaart gevonden."
#: templates/umap/search.html:33 #: templates/umap/search.html:36
msgid "Latest created maps in category"
msgstr "Laatst gemaakte kaarten in categorie"
#: templates/umap/search.html:43
msgid "Latest created maps" msgid "Latest created maps"
msgstr "Laatste gemaakte kaarten" msgstr "Laatste gemaakte kaarten"
@ -604,7 +680,11 @@ msgstr "Laatste gemaakte kaarten"
msgid "Search maps" msgid "Search maps"
msgstr "Zoek kaarten" msgstr "Zoek kaarten"
#: templates/umap/search_bar.html:16 #: templates/umap/search_bar.html:14
msgid "Any category"
msgstr "Elke categorie"
#: templates/umap/search_bar.html:19
msgid "Search" msgid "Search"
msgstr "Zoeken" msgstr "Zoeken"
@ -668,70 +748,70 @@ msgstr "Gebruikers"
msgid "New team" msgid "New team"
msgstr "Nieuw Team" msgstr "Nieuw Team"
#: views.py:234 #: views.py:235
msgid "Cannot delete a team with more than one member" msgid "Cannot delete a team with more than one member"
msgstr "Kan een team met meer dan één lid niet verwijderen" msgstr "Kan een team met meer dan één lid niet verwijderen"
#: views.py:238 #: views.py:239
#, python-format #, python-format
msgid "Team “%(name)s” has been deleted" msgid "Team “%(name)s” has been deleted"
msgstr "Team “%(name)s” is verwijderd" msgstr "Team “%(name)s” is verwijderd"
#: views.py:442 #: views.py:449
msgid "View the map" msgid "View the map"
msgstr "Bekijk de kaart" msgstr "Bekijk de kaart"
#: views.py:838 #: views.py:845
msgid "See full screen" msgid "See full screen"
msgstr "Volledig scherm weergeven" msgstr "Volledig scherm weergeven"
#: views.py:981 #: views.py:988
msgid "Map editors updated with success!" msgid "Map editors updated with success!"
msgstr "Kaarteditors met succes bijgewerkt!" msgstr "Kaarteditors met succes bijgewerkt!"
#: views.py:1017 #: views.py:1024
#, python-format #, python-format
msgid "The uMap edit link for your map: %(map_name)s" msgid "The uMap edit link for your map: %(map_name)s"
msgstr "De uMap-bewerkingslink voor uw kaart: %(map_name)s" msgstr "De uMap-bewerkingslink voor uw kaart: %(map_name)s"
#: views.py:1020 #: views.py:1027
#, python-format #, python-format
msgid "Here is your secret edit link: %(link)s" msgid "Here is your secret edit link: %(link)s"
msgstr "Hier is je geheime bewerkingslink: %(link)s" msgstr "Hier is je geheime bewerkingslink: %(link)s"
#: views.py:1027 #: views.py:1034
#, python-format #, python-format
msgid "Can't send email to %(email)s" msgid "Can't send email to %(email)s"
msgstr "Kan geen e-mail verzenden naar %(email)s" msgstr "Kan geen e-mail verzenden naar %(email)s"
#: views.py:1030 #: views.py:1037
#, python-format #, python-format
msgid "Email sent to %(email)s" msgid "Email sent to %(email)s"
msgstr "E-mail verzonden naar %(email)s" msgstr "E-mail verzonden naar %(email)s"
#: views.py:1041 #: views.py:1048
msgid "Only its owner can delete the map." msgid "Only its owner can delete the map."
msgstr "Kaart kan alleen door eigenaar worden verwijderd." msgstr "Kaart kan alleen door eigenaar worden verwijderd."
#: views.py:1044 #: views.py:1054
msgid "Map successfully deleted." msgid "Map successfully deleted."
msgstr "Kaart succesvol verwijderd." msgstr "Kaart succesvol verwijderd."
#: views.py:1070 #: views.py:1080
#, python-format #, python-format
msgid "" msgid ""
"Your map has been cloned! If you want to edit this map from another " "Your map has been cloned! If you want to edit this map from another "
"computer, please use this link: %(anonymous_url)s" "computer, please use this link: %(anonymous_url)s"
msgstr "Uw kaart is gekopieerd! Als u deze kaart wilt wijzigen vanaf een andere computer, gebruik dan deze link: %(anonymous_url)s" msgstr "Uw kaart is gekopieerd! Als u deze kaart wilt wijzigen vanaf een andere computer, gebruik dan deze link: %(anonymous_url)s"
#: views.py:1075 #: views.py:1085
msgid "Congratulations, your map has been cloned!" msgid "Congratulations, your map has been cloned!"
msgstr "Gefeliciteerd, uw kaart is gekopieerd!" msgstr "Gefeliciteerd, uw kaart is gekopieerd!"
#: views.py:1329 #: views.py:1339
msgid "Layer successfully deleted." msgid "Layer successfully deleted."
msgstr "Laag is verwijderd." msgstr "Laag is verwijderd."
#: views.py:1351 #: views.py:1361
msgid "Permissions updated with success!" msgid "Permissions updated with success!"
msgstr "Machtigingen met succes bijgewerkt!" msgstr "Machtigingen met succes bijgewerkt!"

View file

@ -551,6 +551,7 @@ class DataLayer(NamedModel):
if self.old_id: if self.old_id:
metadata["old_id"] = self.old_id metadata["old_id"] = self.old_id
metadata["id"] = self.pk metadata["id"] = self.pk
metadata["rank"] = self.rank
metadata["permissions"] = {"edit_status": self.edit_status} metadata["permissions"] = {"edit_status": self.edit_status}
metadata["editMode"] = "advanced" if self.can_edit(request) else "disabled" metadata["editMode"] = "advanced" if self.can_edit(request) else "disabled"
metadata["_referenceVersion"] = self.reference_version metadata["_referenceVersion"] = self.reference_version

View file

@ -19,6 +19,7 @@ env = environ.Env()
INTERNAL_IPS = env.list("INTERNAL_IPS", default=["127.0.0.1"]) INTERNAL_IPS = env.list("INTERNAL_IPS", default=["127.0.0.1"])
ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", default=["*"]) ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", default=["*"])
CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS", default=[])
ADMINS = tuple(parseaddr(email) for email in env.list("ADMINS", default=[])) ADMINS = tuple(parseaddr(email) for email in env.list("ADMINS", default=[]))
ASGI_APPLICATION = "umap.asgi.application" ASGI_APPLICATION = "umap.asgi.application"
@ -164,8 +165,8 @@ LOGIN_REDIRECT_URL = "login_popup_end"
STATIC_URL = "/static/" STATIC_URL = "/static/"
MEDIA_URL = "/uploads/" MEDIA_URL = "/uploads/"
STATIC_ROOT = os.path.join("static") STATIC_ROOT = env("STATIC_ROOT", default=os.path.join("static"))
MEDIA_ROOT = os.path.join("uploads") MEDIA_ROOT = env("MEDIA_ROOT", default=os.path.join("uploads"))
STATICFILES_FINDERS = [ STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.FileSystemFinder",

View file

@ -235,3 +235,7 @@ dt {
display: block; display: block;
overflow-x: auto; overflow-x: auto;
} }
mark {
background-color: var(--color-lightCyan);
padding: 0 var(--small-box-padding);
}

View file

@ -1,6 +1,6 @@
.umap-main-edit-toolbox [type=button] { .umap-main-edit-toolbox [type=button] {
color: #fff; color: #fff;
font-size: 1em; font-size: 0.8rem;
background-color: var(--color-darkGray); background-color: var(--color-darkGray);
width: auto; width: auto;
margin-bottom: 0; margin-bottom: 0;
@ -167,7 +167,7 @@
.umap-caption-bar .umap-map-author { .umap-caption-bar .umap-map-author {
margin-inline-end: 10px; margin-inline-end: 10px;
} }
.umap-caption-bar > button + button:after, .umap-caption-bar:has(select:not([hidden])) > button + button:after,
.umap-caption-bar > button + button:before { .umap-caption-bar > button + button:before {
content: '|'; content: '|';
padding-inline-start: 10px; padding-inline-start: 10px;
@ -206,6 +206,7 @@
margin-top: 0; margin-top: 0;
line-height: initial; line-height: initial;
height: initial; height: initial;
min-height: initial;
width: auto; width: auto;
padding: 0 var(--text-margin); padding: 0 var(--text-margin);
} }

View file

@ -6,7 +6,7 @@ input[type="text"], input[type="password"], input[type="date"],
input[type="datetime-local"], input[type="email"], input[type="number"], input[type="datetime-local"], input[type="email"], input[type="number"],
input[type="search"], input[type="tel"], input[type="time"], input[type="file"], input[type="search"], input[type="tel"], input[type="time"], input[type="file"],
input[type="url"], textarea { input[type="url"], textarea {
background-color: white; background-color: var(--color-light);
border: 2px solid var(--color-darkBlue); border: 2px solid var(--color-darkBlue);
color: var(--text-color); color: var(--text-color);
display: block; display: block;
@ -14,7 +14,6 @@ input[type="url"], textarea {
margin: 0; margin: 0;
padding: .5rem 1rem; padding: .5rem 1rem;
width: 100%; width: 100%;
line-height: inherit;
min-height: 40px; min-height: 40px;
} }
input[type="range"] { input[type="range"] {
@ -48,7 +47,7 @@ input[type=checkbox]:checked:after {
} }
input[data-modified=true] { input[data-modified=true] {
background-color: var(--color-lightCyan); background-color: var(--color-lightCyan);
border: 1px solid var(--color-darkGray); border: 1px solid var(--color-veryDarkGray);
} }
input + select, input + select,
select + input, select + input,
@ -72,7 +71,7 @@ select {
.dark select { .dark select {
color: var(--text-color); color: var(--text-color);
background-color: var(--color-darkGray); background-color: var(--color-darkGray);
border-color: var(--color-dark); border-color: var(--color-veryDarkGray);
border-width: 1px; border-width: 1px;
} }
select[multiple="multiple"] { select[multiple="multiple"] {
@ -90,7 +89,7 @@ input[type="submit"] {
text-decoration: none; text-decoration: none;
justify-content: center; justify-content: center;
background-color: var(--color-darkBlue); background-color: var(--color-darkBlue);
color: white; color: var(--color-light);
font-weight: normal; font-weight: normal;
min-height: 40px; min-height: 40px;
} }
@ -98,21 +97,21 @@ input[type="submit"] {
.dark [type="button"] { .dark [type="button"] {
background-color: var(--color-darkerGray); background-color: var(--color-darkerGray);
color: var(--text-color); color: var(--text-color);
border: 1px solid #1b1f20; border: 1px solid var(--color-veryDarkGray);
} }
.button.primary { .button.primary {
font-weight: bold; font-weight: bold;
} }
.dark .button.primary:not([disabled]), .dark .button.primary:not([disabled]),
.dark [type="button"].primary:not([disabled]) { .dark [type="button"].primary:not([disabled]) {
background-color: var(--color-brightCyan); background-color: var(--color-verySoftCyan);
color: var(--color-dark); color: var(--color-dark);
border: 1px solid #1b1f20; border: 1px solid var(--color-veryDarkGray);
} }
.dark .button:hover, .dark .button:hover,
.dark [type="button"]:hover, .dark [type="button"]:hover,
.dark input[type="submit"]:hover { .dark input[type="submit"]:hover {
background-color: #2e3436; background-color: var(--color-darkerGray);
} }
.dark a { .dark a {
color: var(--text-color); color: var(--text-color);
@ -152,14 +151,14 @@ button.round.small {
display: block; display: block;
padding: 7px 7px; padding: 7px 7px;
margin-bottom: 14px; margin-bottom: 14px;
background: #393F3F; background: var(--color-mediumGray);
color: var(--color-lightGray); color: var(--color-lightGray);
font-size: 10px; font-size: 10px;
border-radius: 0 2px; border-radius: 0 2px;
} }
.content .helptext { .content .helptext {
background-color: #eee; background-color: var(--color-lightGray);
color: #000; color: var(--color-dark);
} }
input + .help-text { input + .help-text {
margin-top: -14px; margin-top: -14px;
@ -206,8 +205,8 @@ input + .error {
margin-top: -14px; margin-top: -14px;
margin-bottom: 14px; margin-bottom: 14px;
background: var(--color-lightGray); background: var(--color-lightGray);
color: #fff; color: var(--color-light);
background-color: #cc0000; background-color: var(--color-red);
font-size: 11px; font-size: 11px;
border-radius: 0 2px; border-radius: 0 2px;
} }
@ -215,14 +214,14 @@ input[type="file"] + .error {
margin-top: 0; margin-top: 0;
} }
input[value]:invalid { input[value]:invalid {
border-color: red; border-color: var(--color-red);
background-color: darkred; background-color: var(--color-darkRed);
} }
.dark input, .dark textarea { .dark input, .dark textarea {
background-color: var(--color-darkerGray); background-color: var(--color-darkerGray);
border-color: var(--color-dark); border-color: var(--color-veryDarkGray);
border-width: 1px; border-width: 1px;
color: #efefef; color: var(--color-lightGray);
} }
details { details {
margin-bottom: 5px; margin-bottom: 5px;
@ -230,7 +229,7 @@ details {
border-start-end-radius: 4px; border-start-end-radius: 4px;
} }
.dark details { .dark details {
border: 1px solid #222; border: 1px solid var(--color-veryDarkGray);
} }
details fieldset { details fieldset {
overflow: hidden; overflow: hidden;
@ -246,8 +245,8 @@ details summary {
padding: 0 5px; padding: 0 5px;
} }
.dark details summary { .dark details summary {
background-color: #232729; background-color: var(--color-darkerGray);
color: #fff; color: var(--color-light);
} }
.dark details fieldset { .dark details fieldset {
border: 1px solid var(--color-darkGray); border: 1px solid var(--color-darkGray);
@ -312,33 +311,34 @@ input.switch:empty ~ label:after {
width: 6em; width: 6em;
-webkit-transition: all 100ms ease-in; -webkit-transition: all 100ms ease-in;
transition: all 100ms ease-in; transition: all 100ms ease-in;
color: #c9c9c7; color: var(--color-mediumGray);
font-weight: bold; font-weight: bold;
background-color: #ededed; background-color: var(--color-lighterGray);
} }
.dark input.switch:empty ~ label:before, .dark input.switch:empty ~ label:before,
.dark input.switch:empty ~ label:after { .dark input.switch:empty ~ label:after {
background-color: #272c2e; background-color: var(--color-darkerGray);
} }
input.switch:empty ~ label:after { input.switch:empty ~ label:after {
width: 3em; width: 3em;
margin-inline-start: 0.1em; margin-inline-start: 0.1em;
background-color: #ededed; background-color: var(--color-lightGray);
content: "OFF"; content: "OFF";
text-indent: 3.5em; text-indent: 3.5em;
border: 1px solid #374E75; border: 1px solid var(--color-darkerGray);
font-weight: bold; font-weight: bold;
} }
.dark input.switch:empty ~ label:after { .dark input.switch:empty ~ label:after {
border: 1px solid #202425; border: 1px solid var(--color-veryDarkGray);
background-color: #2c3233; background-color: var(--color-darkerGray);
color: var(--color-lightGray);
} }
input.switch:checked:empty ~ label:after { input.switch:checked:empty ~ label:after {
content: ' '; content: ' ';
} }
.dark input.switch:checked ~ label:before, .dark input.switch:checked ~ label:before,
input.switch:checked ~ label:before { input.switch:checked ~ label:before {
background-color: var(--color-lightCyan); background-color: var(--color-verySoftCyan);
border: 1px solid var(--color-lightGray); border: 1px solid var(--color-lightGray);
color: var(--color-darkGray); color: var(--color-darkGray);
content: "ON"; content: "ON";
@ -348,7 +348,7 @@ input.switch:checked ~ label:before {
} }
.dark input.switch:checked ~ label:before { .dark input.switch:checked ~ label:before {
border: none; border: none;
background-color: var(--color-accent); background-color: var(--color-verySoftCyan);
} }
input.switch:checked ~ label:after { input.switch:checked ~ label:after {
margin-inline-start: 3em; margin-inline-start: 3em;
@ -388,9 +388,9 @@ input.switch:checked ~ label:after {
display: none; display: none;
} }
.umap-multiplechoice label { .umap-multiplechoice label {
border: 1px solid #374E75; border: 1px solid var(--color-veryDarkGray);
cursor: pointer; cursor: pointer;
background-color: #c9c9c7; background-color: var(--color-lightGray);
min-height: 30px; min-height: 30px;
line-height: 30px; line-height: 30px;
text-align: center; text-align: center;
@ -398,12 +398,11 @@ input.switch:checked ~ label:after {
display: inline-block; display: inline-block;
} }
.dark .umap-multiplechoice label { .dark .umap-multiplechoice label {
border: 1px solid black; border: 1px solid var(--color-veryDarkGray);
background-color: #2c3233; background-color: var(--color-darkGray);
} }
.umap-multiplechoice input[type='radio']:checked + label { .umap-multiplechoice input[type='radio']:checked + label {
background-color: var(--color-accent); background-color: var(--color-verySoftCyan);
box-shadow: inset 0 0 6px 0px #2c3233;
color: var(--color-darkGray); color: var(--color-darkGray);
} }
.inheritable .header .buttons { .inheritable .header .buttons {
@ -421,7 +420,7 @@ input.switch:checked ~ label:after {
width: initial; width: initial;
} }
.inheritable + .inheritable { .inheritable + .inheritable {
border-top: 1px solid #222; border-top: 1px solid var(--color-darkerGray);
padding-top: 5px; padding-top: 5px;
margin-top: 5px; margin-top: 5px;
} }
@ -505,7 +504,7 @@ i.info {
justify-content: space-around; justify-content: space-around;
font-size: 1.2em; font-size: 1.2em;
margin-bottom: 20px; margin-bottom: 20px;
border-bottom: 1px solid #bebebe; border-bottom: 1px solid var(--color-lighterGray);
} }
.flat-tabs button { .flat-tabs button {
padding: 10px; padding: 10px;
@ -516,14 +515,14 @@ i.info {
.flat-tabs button:hover, .flat-tabs button:hover,
.flat-tabs .on { .flat-tabs .on {
font-weight: bold; font-weight: bold;
border-bottom: 1px solid #444; border-bottom: 1px solid var(--color-mediumGray);
} }
.dark .flat-tabs button { .dark .flat-tabs button {
color: #fff; color: var(--color-light);
} }
.dark .flat-tabs button:hover, .dark .flat-tabs button:hover,
.dark .flat-tabs .on { .dark .flat-tabs .on {
border-bottom: 1px solid #fff; border-bottom: 1px solid var(--color-light);
} }
.umap-pictogram-category h6 { .umap-pictogram-category h6 {
font-size: 1.3em; font-size: 1.3em;
@ -539,11 +538,11 @@ i.info {
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
cursor: pointer; cursor: pointer;
background-color: #999; background-color: var(--color-lightGray);
text-align: center; text-align: center;
margin-bottom: 5px; margin-bottom: 5px;
display: inline-block; display: inline-block;
color: black; color: var(--color-dark);
font-weight: bold; font-weight: bold;
overflow: hidden; overflow: hidden;
} }
@ -553,10 +552,10 @@ i.info {
} }
.umap-pictogram-choice:hover, .umap-pictogram-choice:hover,
.umap-color-picker span:hover { .umap-color-picker span:hover {
background-color: #bebebe; background-color: var(--color-lighterGray);
} }
.umap-pictogram-choice.selected { .umap-pictogram-choice.selected {
box-shadow: inset 0 0 0 1px #e9e9e9; box-shadow: inset 0 0 0 1px var(--color-lighterGray);
} }
.umap-pictogram-choice .leaflet-marker-icon { .umap-pictogram-choice .leaflet-marker-icon {
@ -611,13 +610,11 @@ input[type=hidden].blur + [type="button"] {
border-radius: initial; border-radius: initial;
} }
.copiable-input button { .copiable-input button {
background-position: -46px -92px; background-color: var(--background-color);
display: inline; color: var(--text-color);
padding: 0 10px; border: 2px solid var(--color-darkBlue);
height: 32px; border-left: none;
width: 32px; width: 40px;
border: 1px solid #202425;
border-radius: initial;
} }
input.highlightable:not(:placeholder-shown) { input.highlightable:not(:placeholder-shown) {
border: 1px solid var(--color-brightCyan); border: 1px solid var(--color-brightCyan);

View file

@ -75,7 +75,7 @@ html[dir="rtl"] .icon {
background-position: calc(var(--tile) * 4) 0; background-position: calc(var(--tile) * 4) 0;
} }
.icon-copy { .icon-copy {
background-position: calc(var(--tile) * 2) calc(var(--tile) * 4); background-position: calc(var(--tile) * 4) calc(var(--tile) * 7);
} }
.icon-delete { .icon-delete {
background-position: calc(var(--tile) * 5) calc(var(--tile) * 2); background-position: calc(var(--tile) * 5) calc(var(--tile) * 2);

View file

@ -59,3 +59,16 @@
.tooltip-accent li:last-of-type { .tooltip-accent li:last-of-type {
margin-bottom: 0; margin-bottom: 0;
} }
.umap-tooltip-container.tooltip-right:before {
right: 100%;
top: calc(50% - var(--arrow-size));
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-right-color: var(--tooltip-color);
border-width: var(--arrow-size);
}

View file

@ -202,7 +202,7 @@
<path id="path8" transform="translate(0 812.36)" d="m8.1903 37.424c-0.48722-0.17411-0.79231-0.44207-0.99467-0.87363l-0.1908-0.40689-1.3703-0.0034c-1.4983-0.0037-1.5911-0.03214-1.5406-0.47225l0.026557-0.23161 2.8423-0.0451 0.19827-0.3895c0.34789-0.68343 0.86349-1.0091 1.5923-1.0058 0.71771 0.0033 1.3415 0.43242 1.6291 1.1207l0.11636 0.27848h4.6574c4.5203 0 4.66 0.0047 4.7428 0.1594 0.1159 0.21656 0.10767 0.30093-0.04419 0.45278-0.11466 0.11466-0.66063 0.1295-4.7632 0.1295h-4.6337l-0.10498 0.2903c-0.15257 0.42194-0.62749 0.84447-1.1103 0.98785-0.49622 0.14736-0.6615 0.14879-1.0524 0.0091zm0.96896-0.84513c0.698-0.33122 0.698-1.3772 0-1.7084-0.35156-0.16682-0.49258-0.16849-0.82704-0.0098-0.33761 0.16021-0.5445 0.51333-0.5445 0.92936 0 0.36801 0.16007 0.60614 0.53566 0.79693 0.31576 0.16039 0.48419 0.15875 0.83587-0.0081z" fill="#f2f2f2" stroke="#999" stroke-width=".25" style="paint-order:fill markers stroke"/> <path id="path8" transform="translate(0 812.36)" d="m8.1903 37.424c-0.48722-0.17411-0.79231-0.44207-0.99467-0.87363l-0.1908-0.40689-1.3703-0.0034c-1.4983-0.0037-1.5911-0.03214-1.5406-0.47225l0.026557-0.23161 2.8423-0.0451 0.19827-0.3895c0.34789-0.68343 0.86349-1.0091 1.5923-1.0058 0.71771 0.0033 1.3415 0.43242 1.6291 1.1207l0.11636 0.27848h4.6574c4.5203 0 4.66 0.0047 4.7428 0.1594 0.1159 0.21656 0.10767 0.30093-0.04419 0.45278-0.11466 0.11466-0.66063 0.1295-4.7632 0.1295h-4.6337l-0.10498 0.2903c-0.15257 0.42194-0.62749 0.84447-1.1103 0.98785-0.49622 0.14736-0.6615 0.14879-1.0524 0.0091zm0.96896-0.84513c0.698-0.33122 0.698-1.3772 0-1.7084-0.35156-0.16682-0.49258-0.16849-0.82704-0.0098-0.33761 0.16021-0.5445 0.51333-0.5445 0.92936 0 0.36801 0.16007 0.60614 0.53566 0.79693 0.31576 0.16039 0.48419 0.15875 0.83587-0.0081z" fill="#f2f2f2" stroke="#999" stroke-width=".25" style="paint-order:fill markers stroke"/>
<path id="path9" transform="translate(0 812.36)" d="m12.773 42.244c-0.4045-0.18728-0.73246-0.52685-0.9029-0.93487l-0.12875-0.30821-7.6214-0.04285-0.026557-0.23161c-0.055311-0.48238-0.16774-0.4688 3.8893-0.46961l3.7189-7.33e-4 0.21287-0.43192c0.65163-1.3222 2.4726-1.2846 3.1257 0.06446l0.17859 0.36892h2.2972c2.2584 0 2.2988 3e-3 2.391 0.17524 0.06808 0.12721 0.06936 0.22886 0.0047 0.37084l-0.08912 0.1956h-4.6108l-0.15493 0.35024c-0.38713 0.87516-1.4373 1.2865-2.2839 0.89448zm1.0632-0.70036c0.37802-0.15795 0.5443-0.42579 0.54116-0.87174-4e-3 -0.57358-0.36338-0.90877-0.9743-0.90877-0.31204 0-0.40386 0.04292-0.64992 0.30383-0.25777 0.27331-0.28248 0.33986-0.2461 0.66262 0.04524 0.40136 0.22819 0.65122 0.5956 0.81339 0.31718 0.14001 0.39991 0.14008 0.73356 6.68e-4z" fill="#f2f2f2" stroke="#999" stroke-width=".25" style="paint-order:fill markers stroke"/> <path id="path9" transform="translate(0 812.36)" d="m12.773 42.244c-0.4045-0.18728-0.73246-0.52685-0.9029-0.93487l-0.12875-0.30821-7.6214-0.04285-0.026557-0.23161c-0.055311-0.48238-0.16774-0.4688 3.8893-0.46961l3.7189-7.33e-4 0.21287-0.43192c0.65163-1.3222 2.4726-1.2846 3.1257 0.06446l0.17859 0.36892h2.2972c2.2584 0 2.2988 3e-3 2.391 0.17524 0.06808 0.12721 0.06936 0.22886 0.0047 0.37084l-0.08912 0.1956h-4.6108l-0.15493 0.35024c-0.38713 0.87516-1.4373 1.2865-2.2839 0.89448zm1.0632-0.70036c0.37802-0.15795 0.5443-0.42579 0.54116-0.87174-4e-3 -0.57358-0.36338-0.90877-0.9743-0.90877-0.31204 0-0.40386 0.04292-0.64992 0.30383-0.25777 0.27331-0.28248 0.33986-0.2461 0.66262 0.04524 0.40136 0.22819 0.65122 0.5956 0.81339 0.31718 0.14001 0.39991 0.14008 0.73356 6.68e-4z" fill="#f2f2f2" stroke="#999" stroke-width=".25" style="paint-order:fill markers stroke"/>
<path id="path1-67-5" d="m154.68 963.54 4.7344 4.7344-5.0508 4.6836-1.3594-1.4668 3.5274-3.2695-3.2656-3.2656z" color="#000000" fill="#f2f2f2" fill-rule="evenodd" stroke="#999" stroke-width=".25"/> <path id="path1-67-5" d="m154.68 963.54 4.7344 4.7344-5.0508 4.6836-1.3594-1.4668 3.5274-3.2695-3.2656-3.2656z" color="#000000" fill="#f2f2f2" fill-rule="evenodd" stroke="#999" stroke-width=".25"/>
<path id="copy" d="m58 914.36v3.5h4v4h3.5v-7.5zm-4 4v7.5h7.5v-7.5z" fill="#f2f2f2" style="paint-order:fill markers stroke"/> <path id="copy" d="m106.17 986.36v3.6522h4.1739v4.1739h3.6522v-7.8261zm-4.1739 4.1739v7.8261h7.8261v-7.8261z" fill="#f2f2f2" style="paint-order:fill markers stroke"/>
<g id="g1-5" transform="translate(.1 .1)"> <g id="g1-5" transform="translate(.1 .1)">
<g id="g24" fill="#f2f2f2" stroke="#999" stroke-width=".2"> <g id="g24" fill="#f2f2f2" stroke="#999" stroke-width=".2">
<path id="path24" d="m12 912.36c-4.4183 0-8 3.5817-8 8 0.00463 1.6156 0.49829 3.1919 1.416 4.5215 0.19802 0.28729 0.41463 0.56131 0.64844 0.82032 1.5128 1.6866 3.6699 2.6526 5.9355 2.6582 2.2669-6e-3 4.4249-0.97357 5.9375-2.6621 0.23535-0.26077 0.45327-0.53676 0.65234-0.82617 0.91377-1.3275 1.4053-2.9001 1.4102-4.5117 0-4.4183-3.5817-8-8-8zm-5.3242 12.506c1.3285-1.5609 3.2745-2.461 5.3242-2.4629 2.0504 1e-3 3.9972 0.90149 5.3262 2.4629 0 0-0.0035-3e-3 0.0059 6e-3 0 0-0.5371 0.5762-0.83984 0.82812-0.17533 0.14821-0.35784 0.2877-0.54687 0.41797-0.06626 0.0467-0.13333 0.0923-0.20117 0.13672-0.2448 0.15763-0.4992 0.29983-0.76172 0.42578-0.93187 0.44366-1.9503 0.67577-2.9824 0.67969-0.61808-5e-3 -1.2328-0.0915-1.8281-0.25781-0.67532-0.18416-1.3192-0.46858-1.9102-0.84375-0.0685-0.0444-0.13622-0.09-0.20312-0.13672-0.00521-4e-3 -0.010422-8e-3 -0.015625-0.0117-0.18766-0.12974-0.36887-0.26858-0.54297-0.41602-0.29972-0.24977-0.57803-0.52416-0.83203-0.82031m-0.5918-0.81445c-0.69766-1.1081-1.0705-2.3898-1.0762-3.6992 0-3.866 3.134-7 7-7l-4.1e-5 -1.6e-4c3.866 0 7 3.134 7 7-0.0054 1.3023-0.37406 2.5773-1.0645 3.6816-1.5163-1.6794-3.6729-2.6381-5.9355-2.6387-2.2613 8e-3 -4.4134 0.97341-5.9238 2.6562" style="paint-order:fill markers stroke"/> <path id="path24" d="m12 912.36c-4.4183 0-8 3.5817-8 8 0.00463 1.6156 0.49829 3.1919 1.416 4.5215 0.19802 0.28729 0.41463 0.56131 0.64844 0.82032 1.5128 1.6866 3.6699 2.6526 5.9355 2.6582 2.2669-6e-3 4.4249-0.97357 5.9375-2.6621 0.23535-0.26077 0.45327-0.53676 0.65234-0.82617 0.91377-1.3275 1.4053-2.9001 1.4102-4.5117 0-4.4183-3.5817-8-8-8zm-5.3242 12.506c1.3285-1.5609 3.2745-2.461 5.3242-2.4629 2.0504 1e-3 3.9972 0.90149 5.3262 2.4629 0 0-0.0035-3e-3 0.0059 6e-3 0 0-0.5371 0.5762-0.83984 0.82812-0.17533 0.14821-0.35784 0.2877-0.54687 0.41797-0.06626 0.0467-0.13333 0.0923-0.20117 0.13672-0.2448 0.15763-0.4992 0.29983-0.76172 0.42578-0.93187 0.44366-1.9503 0.67577-2.9824 0.67969-0.61808-5e-3 -1.2328-0.0915-1.8281-0.25781-0.67532-0.18416-1.3192-0.46858-1.9102-0.84375-0.0685-0.0444-0.13622-0.09-0.20312-0.13672-0.00521-4e-3 -0.010422-8e-3 -0.015625-0.0117-0.18766-0.12974-0.36887-0.26858-0.54297-0.41602-0.29972-0.24977-0.57803-0.52416-0.83203-0.82031m-0.5918-0.81445c-0.69766-1.1081-1.0705-2.3898-1.0762-3.6992 0-3.866 3.134-7 7-7l-4.1e-5 -1.6e-4c3.866 0 7 3.134 7 7-0.0054 1.3023-0.37406 2.5773-1.0645 3.6816-1.5163-1.6794-3.6729-2.6381-5.9355-2.6387-2.2613 8e-3 -4.4134 0.97341-5.9238 2.6562" style="paint-order:fill markers stroke"/>

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -62,5 +62,6 @@
</g> </g>
<path id="downloadfile" d="m5.6444 59.434v1.035h1.0542zm1.1759 1.6123h-1.1759c-0.32472 0-0.58796-0.25845-0.58796-0.57727v-1.1545h-2.3519v5.1955h4.1157zm-4.1157-2.3091h3.0616l1.6421 1.6123v4.1605c0 0.31882-0.26324 0.57728-0.58796 0.57728h-4.1157c-0.32472 0-0.58796-0.25845-0.58796-0.57728v-5.1955c0-0.31882 0.26324-0.57727 0.58796-0.57727zm1.7639 3.9214v-1.3236h0.58796v1.3236l0.38009-0.37318 0.41575 0.4082-1.0898 1.07-1.0898-1.07 0.41575-0.4082z" fill="#f2f2f2" fill-rule="evenodd" stroke="#999" stroke-opacity=".5098" stroke-width=".066146"/> <path id="downloadfile" d="m5.6444 59.434v1.035h1.0542zm1.1759 1.6123h-1.1759c-0.32472 0-0.58796-0.25845-0.58796-0.57727v-1.1545h-2.3519v5.1955h4.1157zm-4.1157-2.3091h3.0616l1.6421 1.6123v4.1605c0 0.31882-0.26324 0.57728-0.58796 0.57728h-4.1157c-0.32472 0-0.58796-0.25845-0.58796-0.57728v-5.1955c0-0.31882 0.26324-0.57727 0.58796-0.57727zm1.7639 3.9214v-1.3236h0.58796v1.3236l0.38009-0.37318 0.41575 0.4082-1.0898 1.07-1.0898-1.07 0.41575-0.4082z" fill="#f2f2f2" fill-rule="evenodd" stroke="#999" stroke-opacity=".5098" stroke-width=".066146"/>
<path id="path3014" d="m4.6307 2.6463c-1.5327 0-2.7792 1.2449-2.7792 2.7776 0 1.5327 1.2464 2.7771 2.7792 2.7771 1.5327 0 2.7776-1.2443 2.7776-2.7771 0-1.5327-1.2449-2.7776-2.7776-2.7776zm0 0.26355c1.3898-1e-7 2.5141 1.1243 2.5141 2.5141 0 1.3898-1.1243 2.5135-2.5141 2.5135-1.3898-1e-7 -2.5135-1.1238-2.5135-2.5135 1e-7 -1.3898 1.1238-2.5141 2.5135-2.5141zm-0.0041342 0.75034c-0.14358 0-0.29261 0.015464-0.447 0.046509-0.15439 0.030939-0.3253 0.078749-0.51211 0.14366v0.72864c0.15748-0.10213 0.30911-0.17843 0.45424-0.22944 0.14512-0.052458 0.28009-0.079065 0.40514-0.079065 0.13277 0 0.23595 0.03107 0.31006 0.093018 0.074105 0.06029 0.1111 0.14436 0.1111 0.2527-1.6e-6 0.071155-0.020845 0.1422-0.062528 0.21342-0.040142 0.071155-0.10424 0.14694-0.19224 0.22738l-0.14779 0.13488c-0.16365 0.15162-0.271 0.27666-0.32194 0.37569-0.050949 0.097508-0.076481 0.21007-0.076481 0.33693v0.11369h0.83612v-0.10439c-1.7e-6 -0.069638 0.016152-0.13347 0.048576-0.19069 0.03242-0.058808 0.1012-0.13607 0.20619-0.23203l0.14779-0.13229c0.14512-0.13769 0.24778-0.26586 0.30799-0.38499 0.060208-0.12069 0.090431-0.25714 0.090434-0.40876-2.5e-6 -0.29549-0.098491-0.51969-0.29611-0.67283-0.19762-0.15469-0.48474-0.23203-0.86145-0.23203zm-0.47956 2.7016v0.82579h0.83612v-0.82579h-0.83612z" fill="#f2f2f2" stroke="#999" stroke-width=".066146"/> <path id="path3014" d="m4.6307 2.6463c-1.5327 0-2.7792 1.2449-2.7792 2.7776 0 1.5327 1.2464 2.7771 2.7792 2.7771 1.5327 0 2.7776-1.2443 2.7776-2.7771 0-1.5327-1.2449-2.7776-2.7776-2.7776zm0 0.26355c1.3898-1e-7 2.5141 1.1243 2.5141 2.5141 0 1.3898-1.1243 2.5135-2.5141 2.5135-1.3898-1e-7 -2.5135-1.1238-2.5135-2.5135 1e-7 -1.3898 1.1238-2.5141 2.5135-2.5141zm-0.0041342 0.75034c-0.14358 0-0.29261 0.015464-0.447 0.046509-0.15439 0.030939-0.3253 0.078749-0.51211 0.14366v0.72864c0.15748-0.10213 0.30911-0.17843 0.45424-0.22944 0.14512-0.052458 0.28009-0.079065 0.40514-0.079065 0.13277 0 0.23595 0.03107 0.31006 0.093018 0.074105 0.06029 0.1111 0.14436 0.1111 0.2527-1.6e-6 0.071155-0.020845 0.1422-0.062528 0.21342-0.040142 0.071155-0.10424 0.14694-0.19224 0.22738l-0.14779 0.13488c-0.16365 0.15162-0.271 0.27666-0.32194 0.37569-0.050949 0.097508-0.076481 0.21007-0.076481 0.33693v0.11369h0.83612v-0.10439c-1.7e-6 -0.069638 0.016152-0.13347 0.048576-0.19069 0.03242-0.058808 0.1012-0.13607 0.20619-0.23203l0.14779-0.13229c0.14512-0.13769 0.24778-0.26586 0.30799-0.38499 0.060208-0.12069 0.090431-0.25714 0.090434-0.40876-2.5e-6 -0.29549-0.098491-0.51969-0.29611-0.67283-0.19762-0.15469-0.48474-0.23203-0.86145-0.23203zm-0.47956 2.7016v0.82579h0.83612v-0.82579h-0.83612z" fill="#f2f2f2" stroke="#999" stroke-width=".066146"/>
<path id="copy" d="m42.218 69.321v1.2884h1.4725v1.4725h1.2884v-2.7609zm-1.4725 1.4725v2.7609h2.7609v-2.7609z" fill="#f2f2f2" stroke-width=".26458" style="paint-order:fill markers stroke"/>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -31,7 +31,7 @@
<path id="permissions" class="sprite" d="m60.085 50.8c-0.89012-0.0021-1.6103 0.71168-1.6123 1.5875 2e-3 0.87776 0.72218 1.5861 1.6123 1.5875 0.59351-8.73e-4 1.1105-0.32112 1.3891-0.79375h0.65319l0.5209-0.50436 0.39688 0.38034 0.38034-0.37207 0.38861 0.38034 0.39688-0.38034 0.38861 0.38034 0.67799-0.65319c0.09761-0.09927 0.10002-0.17419 0-0.27285l-0.55397-0.5457h-3.2411c-0.27712-0.47713-0.79976-0.79498-1.3973-0.79375zm-0.7028 1.1576c0.23396-0.0011 0.4199 0.18746 0.42168 0.42168-0.0017 0.23096-0.18761 0.41954-0.42168 0.42168-0.23793-0.0024-0.43214-0.19072-0.42995-0.42168-0.0022-0.23422 0.19202-0.4228 0.42995-0.42168z" fill="#4d4d4d" stroke-width=".26458"/> <path id="permissions" class="sprite" d="m60.085 50.8c-0.89012-0.0021-1.6103 0.71168-1.6123 1.5875 2e-3 0.87776 0.72218 1.5861 1.6123 1.5875 0.59351-8.73e-4 1.1105-0.32112 1.3891-0.79375h0.65319l0.5209-0.50436 0.39688 0.38034 0.38034-0.37207 0.38861 0.38034 0.39688-0.38034 0.38861 0.38034 0.67799-0.65319c0.09761-0.09927 0.10002-0.17419 0-0.27285l-0.55397-0.5457h-3.2411c-0.27712-0.47713-0.79976-0.79498-1.3973-0.79375zm-0.7028 1.1576c0.23396-0.0011 0.4199 0.18746 0.42168 0.42168-0.0017 0.23096-0.18761 0.41954-0.42168 0.42168-0.23793-0.0024-0.43214-0.19072-0.42995-0.42168-0.0022-0.23422 0.19202-0.4228 0.42995-0.42168z" fill="#4d4d4d" stroke-width=".26458"/>
<polygon id="home" class="sprite" transform="matrix(.0635 0 0 .0635 30.162 20.902)" points="12.5 50 12.5 87.5 43.75 87.5 43.75 62.5 56.25 62.5 56.25 87.5 87.5 87.5 87.5 50 100 50 50 0 0 50" fill="#4d4d4d"/> <polygon id="home" class="sprite" transform="matrix(.0635 0 0 .0635 30.162 20.902)" points="12.5 50 12.5 87.5 43.75 87.5 43.75 62.5 56.25 62.5 56.25 87.5 87.5 87.5 87.5 50 100 50 50 0 0 50" fill="#4d4d4d"/>
<path id="geolocation" class="sprite" d="m7.9375 33.338c0-0.11924-0.0078-0.23671-0.02082-0.35278h-0.35666c-0.1591-1.276-1.1688-2.2856-2.4448-2.4451v-0.35631c-0.11606-0.01304-0.23354-0.02082-0.35278-0.02082s-0.23671 0.0078-0.35278 0.02082v0.35666c-1.276 0.1591-2.2856 1.1688-2.4451 2.4448h-0.3563c-0.01305 0.11606-0.02081 0.23354-0.02081 0.35278 0 0.11924 0.0078 0.23671 0.02081 0.35278h0.35666c0.1591 1.276 1.1688 2.2857 2.4448 2.4451v0.35666c0.11606 0.0127 0.23354 0.02037 0.35278 0.02037s0.23671-0.0077 0.35278-0.0209v-0.35666c1.2756-0.15944 2.2856-1.1688 2.4451-2.4448h0.35666c0.0127-0.11571 0.02046-0.23319 0.02046-0.35278zm-2.8222 2.0849v-0.32104c0-0.19508-0.15804-0.35278-0.35278-0.35278-0.19473 0-0.35278 0.15769-0.35278 0.35278v0.32104c-0.88547-0.14888-1.5829-0.84597-1.7318-1.7318l0.32068-2.65e-4c0.19509 0 0.35278-0.15805 0.35278-0.35278s-0.15769-0.35278-0.35278-0.35278h-0.32103c0.14922-0.88547 0.84667-1.5829 1.7321-1.7321v0.32103c0 0.19473 0.15804 0.35278 0.35278 0.35278 0.19473 0 0.35278-0.15804 0.35278-0.35278v-0.32103c0.88582 0.14887 1.5833 0.84632 1.7321 1.7321h-0.32103c-0.19509 0-0.35278 0.15804-0.35278 0.35278s0.15769 0.35278 0.35278 0.35278l0.32103 2.65e-4c-0.14922 0.88582-0.84631 1.5829-1.7321 1.7318z" fill="#4d4d4d" stroke-width=".26458"/> <path id="geolocation" class="sprite" d="m7.9375 33.338c0-0.11924-0.0078-0.23671-0.02082-0.35278h-0.35666c-0.1591-1.276-1.1688-2.2856-2.4448-2.4451v-0.35631c-0.11606-0.01304-0.23354-0.02082-0.35278-0.02082s-0.23671 0.0078-0.35278 0.02082v0.35666c-1.276 0.1591-2.2856 1.1688-2.4451 2.4448h-0.3563c-0.01305 0.11606-0.02081 0.23354-0.02081 0.35278 0 0.11924 0.0078 0.23671 0.02081 0.35278h0.35666c0.1591 1.276 1.1688 2.2857 2.4448 2.4451v0.35666c0.11606 0.0127 0.23354 0.02037 0.35278 0.02037s0.23671-0.0077 0.35278-0.0209v-0.35666c1.2756-0.15944 2.2856-1.1688 2.4451-2.4448h0.35666c0.0127-0.11571 0.02046-0.23319 0.02046-0.35278zm-2.8222 2.0849v-0.32104c0-0.19508-0.15804-0.35278-0.35278-0.35278-0.19473 0-0.35278 0.15769-0.35278 0.35278v0.32104c-0.88547-0.14888-1.5829-0.84597-1.7318-1.7318l0.32068-2.65e-4c0.19509 0 0.35278-0.15805 0.35278-0.35278s-0.15769-0.35278-0.35278-0.35278h-0.32103c0.14922-0.88547 0.84667-1.5829 1.7321-1.7321v0.32103c0 0.19473 0.15804 0.35278 0.35278 0.35278 0.19473 0 0.35278-0.15804 0.35278-0.35278v-0.32103c0.88582 0.14887 1.5833 0.84632 1.7321 1.7321h-0.32103c-0.19509 0-0.35278 0.15804-0.35278 0.35278s0.15769 0.35278 0.35278 0.35278l0.32103 2.65e-4c-0.14922 0.88582-0.84631 1.5829-1.7321 1.7318z" fill="#4d4d4d" stroke-width=".26458"/>
<g id="share" class="sprite" transform="matrix(.26458 0 0 .26458 -2.6458 -229.23)"> <g id="share" class="sprite" transform="matrix(.26458 0 0 .26458 -21.696 -210.18)">
<circle id="path4309" cx="100" cy="992.36" r="11" fill="none" stroke="#464646" stroke-width="2"/> <circle id="path4309" cx="100" cy="992.36" r="11" fill="none" stroke="#464646" stroke-width="2"/>
<circle id="path4819" transform="rotate(248.18)" cx="-963.89" cy="-276.04" r="2.5" fill="#464646"/> <circle id="path4819" transform="rotate(248.18)" cx="-963.89" cy="-276.04" r="2.5" fill="#464646"/>
<circle id="path4819-2" transform="rotate(248.18)" cx="-956.38" cy="-281.16" r="2.5" fill="#464646"/> <circle id="path4819-2" transform="rotate(248.18)" cx="-956.38" cy="-281.16" r="2.5" fill="#464646"/>
@ -97,5 +97,6 @@
<path id="path3789" d="m9 1046h-2.3698v-0.3223c0-0.3596 0.072207-0.6775 0.21663-0.9539 0.14442-0.2807 0.44857-0.636 0.91247-1.0658l0.42013-0.3816c0.24945-0.228 0.43107-0.4429 0.54486-0.6446 0.11816-0.2019 0.17724-0.4036 0.17724-0.6053-4.6e-6 -0.3071-0.10504-0.5462-0.3151-0.7171-0.21007-0.1756-0.50329-0.2632-0.87965-0.2632-0.35449 0-0.73742 0.075-1.1488 0.2237-0.41138 0.1446-0.84026 0.3618-1.2867 0.6513v-2.0659c0.52954-0.184 1.0131-0.32 1.4508-0.4077 0.43763-0.088 0.85995-0.1317 1.267-0.1317 1.0678 0 1.8818 0.2194 2.442 0.6579 0.56017 0.4341 0.84026 1.0702 0.84026 1.9078-7e-6 0.4298-0.08535 0.8159-0.25602 1.158-0.17068 0.3377-0.46171 0.7017-0.87308 1.092l-0.42013 0.375c-0.2976 0.272-0.49235 0.4913-0.58425 0.658-0.091909 0.1622-0.13786 0.342-0.13786 0.5394v0.296m-2.3698 0.9739h2.3698v2.342h-2.3698v-2.342" fill="#4d4d4d" stroke-width=".75"/> <path id="path3789" d="m9 1046h-2.3698v-0.3223c0-0.3596 0.072207-0.6775 0.21663-0.9539 0.14442-0.2807 0.44857-0.636 0.91247-1.0658l0.42013-0.3816c0.24945-0.228 0.43107-0.4429 0.54486-0.6446 0.11816-0.2019 0.17724-0.4036 0.17724-0.6053-4.6e-6 -0.3071-0.10504-0.5462-0.3151-0.7171-0.21007-0.1756-0.50329-0.2632-0.87965-0.2632-0.35449 0-0.73742 0.075-1.1488 0.2237-0.41138 0.1446-0.84026 0.3618-1.2867 0.6513v-2.0659c0.52954-0.184 1.0131-0.32 1.4508-0.4077 0.43763-0.088 0.85995-0.1317 1.267-0.1317 1.0678 0 1.8818 0.2194 2.442 0.6579 0.56017 0.4341 0.84026 1.0702 0.84026 1.9078-7e-6 0.4298-0.08535 0.8159-0.25602 1.158-0.17068 0.3377-0.46171 0.7017-0.87308 1.092l-0.42013 0.375c-0.2976 0.272-0.49235 0.4913-0.58425 0.658-0.091909 0.1622-0.13786 0.342-0.13786 0.5394v0.296m-2.3698 0.9739h2.3698v2.342h-2.3698v-2.342" fill="#4d4d4d" stroke-width=".75"/>
</g> </g>
</g> </g>
<path id="copy" d="m42.218 69.321v1.2884h1.4725v1.4725h1.2884v-2.7609zm-1.4725 1.4725v2.7609h2.7609v-2.7609z" fill="#4d4d4d" stroke-width=".26458" style="paint-order:fill markers stroke"/>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) --> <!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="216" height="192" id="svg2" version="1.1" inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="16-white.svg" inkscape:export-filename="16-white.png" inkscape:export-xdpi="96" inkscape:export-ydpi="96" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> <svg width="216" height="192" id="svg2" version="1.1" inkscape:version="1.4.1 (93de688d07, 2025-03-30)" sodipodi:docname="16-white.svg" inkscape:export-filename="16-white.png" inkscape:export-xdpi="96" inkscape:export-ydpi="96" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs id="defs4"> <defs id="defs4">
<clipPath id="clip0_241_10857"> <clipPath id="clip0_241_10857">
<rect width="18.049999" height="19.01" fill="#ffffff" id="rect586" x="0" y="0" /> <rect width="18.049999" height="19.01" fill="#ffffff" id="rect586" x="0" y="0" />
@ -25,7 +25,7 @@
<rect width="18.049999" height="19.01" fill="#ffffff" id="rect586-6" x="0" y="0" /> <rect width="18.049999" height="19.01" fill="#ffffff" id="rect586-6" x="0" y="0" />
</clipPath> </clipPath>
</defs> </defs>
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="4.4320814" inkscape:cx="116.08541" inkscape:cy="109.65503" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" showguides="true" inkscape:guide-bbox="true" inkscape:snap-grids="true" inkscape:snap-to-guides="true" inkscape:showpageshadow="2" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1"> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="25.78129" inkscape:cx="104.97923" inkscape:cy="178.69548" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" showguides="true" inkscape:guide-bbox="true" inkscape:snap-grids="true" inkscape:snap-to-guides="true" inkscape:showpageshadow="2" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1">
<inkscape:grid type="xygrid" id="grid3004" empspacing="4" visible="true" enabled="true" snapvisiblegridlinesonly="true" originx="0" originy="0" spacingy="1" spacingx="1" units="px" /> <inkscape:grid type="xygrid" id="grid3004" empspacing="4" visible="true" enabled="true" snapvisiblegridlinesonly="true" originx="0" originy="0" spacingy="1" spacingx="1" units="px" />
<inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="24" spacingy="24" empcolor="#203fff" empopacity="0.85490196" color="#3f3fff" opacity="0.1254902" empspacing="1" enabled="true" visible="true" /> <inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="24" spacingy="24" empcolor="#203fff" empopacity="0.85490196" color="#3f3fff" opacity="0.1254902" empspacing="1" enabled="true" visible="true" />
</sodipodi:namedview> </sodipodi:namedview>
@ -213,7 +213,7 @@
<path style="fill:#f2f2f2;stroke:#999999;stroke-width:0.25;paint-order:fill markers stroke" d="m 8.1902877,37.423896 c -0.4872187,-0.174113 -0.7923051,-0.442073 -0.9946703,-0.873627 l -0.1907982,-0.406887 -1.3702708,-0.0034 c -1.4982701,-0.0037 -1.5910875,-0.03214 -1.5406237,-0.47225 l 0.026557,-0.23161 1.4211632,-0.02255 1.4211632,-0.02255 0.1982698,-0.389502 c 0.347892,-0.683434 0.8634941,-1.009111 1.592299,-1.005764 0.7177082,0.0033 1.3415151,0.432422 1.6290831,1.120669 l 0.116359,0.278485 h 4.65745 c 4.520341,0 4.659962,0.0047 4.742759,0.159402 0.1159,0.216562 0.107667,0.300926 -0.04419,0.452784 -0.114657,0.114657 -0.660626,0.129501 -4.763204,0.129501 h -4.633703 l -0.104975,0.290304 c -0.152574,0.421935 -0.6274874,0.844474 -1.1103021,0.987854 -0.4962156,0.147361 -0.6614998,0.148792 -1.0523644,0.0091 z m 0.9689602,-0.845129 c 0.6980003,-0.331223 0.6980003,-1.377155 0,-1.708378 -0.3515556,-0.166824 -0.4925823,-0.168492 -0.8270409,-0.0098 -0.3376099,0.160207 -0.5444962,0.513326 -0.5444962,0.929363 0,0.368008 0.1600657,0.606145 0.5356626,0.796928 0.3157622,0.16039 0.4841923,0.158752 0.8358745,-0.0081 z" id="path8" transform="translate(0,812.36218)" /> <path style="fill:#f2f2f2;stroke:#999999;stroke-width:0.25;paint-order:fill markers stroke" d="m 8.1902877,37.423896 c -0.4872187,-0.174113 -0.7923051,-0.442073 -0.9946703,-0.873627 l -0.1907982,-0.406887 -1.3702708,-0.0034 c -1.4982701,-0.0037 -1.5910875,-0.03214 -1.5406237,-0.47225 l 0.026557,-0.23161 1.4211632,-0.02255 1.4211632,-0.02255 0.1982698,-0.389502 c 0.347892,-0.683434 0.8634941,-1.009111 1.592299,-1.005764 0.7177082,0.0033 1.3415151,0.432422 1.6290831,1.120669 l 0.116359,0.278485 h 4.65745 c 4.520341,0 4.659962,0.0047 4.742759,0.159402 0.1159,0.216562 0.107667,0.300926 -0.04419,0.452784 -0.114657,0.114657 -0.660626,0.129501 -4.763204,0.129501 h -4.633703 l -0.104975,0.290304 c -0.152574,0.421935 -0.6274874,0.844474 -1.1103021,0.987854 -0.4962156,0.147361 -0.6614998,0.148792 -1.0523644,0.0091 z m 0.9689602,-0.845129 c 0.6980003,-0.331223 0.6980003,-1.377155 0,-1.708378 -0.3515556,-0.166824 -0.4925823,-0.168492 -0.8270409,-0.0098 -0.3376099,0.160207 -0.5444962,0.513326 -0.5444962,0.929363 0,0.368008 0.1600657,0.606145 0.5356626,0.796928 0.3157622,0.16039 0.4841923,0.158752 0.8358745,-0.0081 z" id="path8" transform="translate(0,812.36218)" />
<path style="fill:#f2f2f2;stroke:#999999;stroke-width:0.25;paint-order:fill markers stroke" d="m 12.773494,42.243521 c -0.4045,-0.187277 -0.732456,-0.526846 -0.902897,-0.934868 l -0.128748,-0.308213 -3.8106837,-0.02143 -3.8106834,-0.02142 -0.026557,-0.23161 c -0.055311,-0.482381 -0.1677415,-0.468805 3.8892984,-0.469606 l 3.7189457,-7.33e-4 0.21287,-0.431917 c 0.651632,-1.322166 2.472575,-1.284611 3.125651,0.06446 l 0.178591,0.36892 h 2.297219 c 2.258426,0 2.298803,0.003 2.391007,0.175244 0.06808,0.127207 0.06936,0.228859 0.0047,0.370843 l -0.08912,0.1956 h -2.305381 -2.30538 l -0.15493,0.350241 c -0.387132,0.875164 -1.437261,1.286451 -2.283867,0.894485 z m 1.063202,-0.700358 c 0.378023,-0.157949 0.544298,-0.425794 0.541165,-0.871741 -0.004,-0.573585 -0.363385,-0.908772 -0.974299,-0.908772 -0.312041,0 -0.40386,0.04292 -0.649922,0.303826 -0.257768,0.273313 -0.282484,0.339859 -0.246104,0.662621 0.04524,0.401361 0.228194,0.651219 0.595596,0.813394 0.317179,0.140006 0.399909,0.140082 0.733564,6.68e-4 z" id="path9" transform="translate(0,812.36218)" /> <path style="fill:#f2f2f2;stroke:#999999;stroke-width:0.25;paint-order:fill markers stroke" d="m 12.773494,42.243521 c -0.4045,-0.187277 -0.732456,-0.526846 -0.902897,-0.934868 l -0.128748,-0.308213 -3.8106837,-0.02143 -3.8106834,-0.02142 -0.026557,-0.23161 c -0.055311,-0.482381 -0.1677415,-0.468805 3.8892984,-0.469606 l 3.7189457,-7.33e-4 0.21287,-0.431917 c 0.651632,-1.322166 2.472575,-1.284611 3.125651,0.06446 l 0.178591,0.36892 h 2.297219 c 2.258426,0 2.298803,0.003 2.391007,0.175244 0.06808,0.127207 0.06936,0.228859 0.0047,0.370843 l -0.08912,0.1956 h -2.305381 -2.30538 l -0.15493,0.350241 c -0.387132,0.875164 -1.437261,1.286451 -2.283867,0.894485 z m 1.063202,-0.700358 c 0.378023,-0.157949 0.544298,-0.425794 0.541165,-0.871741 -0.004,-0.573585 -0.363385,-0.908772 -0.974299,-0.908772 -0.312041,0 -0.40386,0.04292 -0.649922,0.303826 -0.257768,0.273313 -0.282484,0.339859 -0.246104,0.662621 0.04524,0.401361 0.228194,0.651219 0.595596,0.813394 0.317179,0.140006 0.399909,0.140082 0.733564,6.68e-4 z" id="path9" transform="translate(0,812.36218)" />
<path style="color:#000000;fill:#f2f2f2;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:0.25;stroke-dasharray:none;stroke-opacity:1" d="m 154.67579,963.53902 4.73437,4.73437 -5.05078,4.6836 -1.35938,-1.4668 3.52735,-3.26953 -3.26563,-3.26563 z" id="path1-67-5" /> <path style="color:#000000;fill:#f2f2f2;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:0.25;stroke-dasharray:none;stroke-opacity:1" d="m 154.67579,963.53902 4.73437,4.73437 -5.05078,4.6836 -1.35938,-1.4668 3.52735,-3.26953 -3.26563,-3.26563 z" id="path1-67-5" />
<path id="copy" style="fill:#f2f2f2;fill-opacity:1;paint-order:fill markers stroke" d="m 58,914.36218 v 3.5 h 4 v 4 h 3.5 v -7.5 z m -4,4 v 7.5 h 7.5 v -7.5 z" /> <path id="copy" style="fill:#f2f2f2;fill-opacity:1;stroke-width:1;paint-order:fill markers stroke" d="m 106.17392,986.36222 v 3.65217 h 4.17391 v 4.17392 h 3.65217 v -7.82609 z m -4.17392,4.17391 v 7.82609 h 7.82609 v -7.82609 z" />
<g id="g1-5" transform="translate(0.1,0.1)"> <g id="g1-5" transform="translate(0.1,0.1)">
<g id="g24"> <g id="g24">
<path d="m 12,912.36218 c -4.4182692,0 -8,3.58172 -8,8 0.00463,1.61557 0.4982915,3.19189 1.4160156,4.52148 0.1980248,0.28729 0.4146342,0.56131 0.6484375,0.82032 1.5128357,1.68659 3.6698868,2.65261 5.9355469,2.6582 2.266949,-0.006 4.424914,-0.97357 5.9375,-2.66211 0.23535,-0.26077 0.45327,-0.53676 0.652344,-0.82617 0.913769,-1.32754 1.405284,-2.9001 1.410156,-4.51172 0,-4.41828 -3.58173,-8 -8,-8 z m -5.3242188,12.50586 c 1.3285496,-1.56088 3.274489,-2.46104 5.3242188,-2.46289 2.050412,10e-4 3.997179,0.90149 5.326172,2.46289 0,0 -0.0035,-0.003 0.0059,0.006 0,0 -0.537098,0.5762 -0.839844,0.82812 -0.175326,0.14821 -0.35784,0.2877 -0.546874,0.41797 -0.06626,0.0467 -0.133328,0.0923 -0.201172,0.13672 -0.244804,0.15763 -0.499205,0.29983 -0.761719,0.42578 -0.931874,0.44366 -1.950332,0.67577 -2.982422,0.67969 -0.618083,-0.005 -1.232807,-0.0915 -1.828125,-0.25781 -0.6753225,-0.18416 -1.3192066,-0.46858 -1.9101562,-0.84375 -0.0685,-0.0444 -0.1362192,-0.09 -0.203125,-0.13672 -0.00521,-0.004 -0.010422,-0.008 -0.015625,-0.0117 -0.1876607,-0.12974 -0.3688672,-0.26858 -0.5429688,-0.41602 -0.2997188,-0.24977 -0.5780329,-0.52416 -0.8320313,-0.82031 m -0.5917968,-0.81445 c -0.6976631,-1.10814 -1.0705109,-2.38976 -1.0761719,-3.69922 0,-3.86599 3.1340146,-7 7,-7 l -4.1e-5,-1.6e-4 c 3.865985,0 7,3.13401 7,7 -0.0054,1.30234 -0.374061,2.57734 -1.064453,3.68164 -1.516341,-1.67935 -3.672913,-2.63806 -5.935547,-2.63867 -2.2612709,0.008 -4.4133749,0.97341 -5.9238281,2.65625" style="fill:#f2f2f2;stroke:#999999;stroke-width:0.2;paint-order:fill markers stroke" id="path24" sodipodi:nodetypes="scccccccsccccccccccccccccccccccc" /> <path d="m 12,912.36218 c -4.4182692,0 -8,3.58172 -8,8 0.00463,1.61557 0.4982915,3.19189 1.4160156,4.52148 0.1980248,0.28729 0.4146342,0.56131 0.6484375,0.82032 1.5128357,1.68659 3.6698868,2.65261 5.9355469,2.6582 2.266949,-0.006 4.424914,-0.97357 5.9375,-2.66211 0.23535,-0.26077 0.45327,-0.53676 0.652344,-0.82617 0.913769,-1.32754 1.405284,-2.9001 1.410156,-4.51172 0,-4.41828 -3.58173,-8 -8,-8 z m -5.3242188,12.50586 c 1.3285496,-1.56088 3.274489,-2.46104 5.3242188,-2.46289 2.050412,10e-4 3.997179,0.90149 5.326172,2.46289 0,0 -0.0035,-0.003 0.0059,0.006 0,0 -0.537098,0.5762 -0.839844,0.82812 -0.175326,0.14821 -0.35784,0.2877 -0.546874,0.41797 -0.06626,0.0467 -0.133328,0.0923 -0.201172,0.13672 -0.244804,0.15763 -0.499205,0.29983 -0.761719,0.42578 -0.931874,0.44366 -1.950332,0.67577 -2.982422,0.67969 -0.618083,-0.005 -1.232807,-0.0915 -1.828125,-0.25781 -0.6753225,-0.18416 -1.3192066,-0.46858 -1.9101562,-0.84375 -0.0685,-0.0444 -0.1362192,-0.09 -0.203125,-0.13672 -0.00521,-0.004 -0.010422,-0.008 -0.015625,-0.0117 -0.1876607,-0.12974 -0.3688672,-0.26858 -0.5429688,-0.41602 -0.2997188,-0.24977 -0.5780329,-0.52416 -0.8320313,-0.82031 m -0.5917968,-0.81445 c -0.6976631,-1.10814 -1.0705109,-2.38976 -1.0761719,-3.69922 0,-3.86599 3.1340146,-7 7,-7 l -4.1e-5,-1.6e-4 c 3.865985,0 7,3.13401 7,7 -0.0054,1.30234 -0.374061,2.57734 -1.064453,3.68164 -1.516341,-1.67935 -3.672913,-2.63806 -5.935547,-2.63867 -2.2612709,0.008 -4.4133749,0.97341 -5.9238281,2.65625" style="fill:#f2f2f2;stroke:#999999;stroke-width:0.2;paint-order:fill markers stroke" id="path24" sodipodi:nodetypes="scccccccsccccccccccccccccccccccc" />

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 80 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) --> <!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="288" height="288" viewBox="0 0 76.199991 76.199991" version="1.1" id="svg2876" inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="24-white.svg" inkscape:export-filename="../24-white.svg" inkscape:export-xdpi="7.52" inkscape:export-ydpi="7.52" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <svg width="288" height="288" viewBox="0 0 76.199991 76.199991" version="1.1" id="svg2876" inkscape:version="1.4.1 (93de688d07, 2025-03-30)" sodipodi:docname="24-white.svg" inkscape:export-filename="../24-white.svg" inkscape:export-xdpi="7.52" inkscape:export-ydpi="7.52" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview id="namedview2878" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="8.896373" inkscape:cx="51.706465" inkscape:cy="46.423413" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1"> <sodipodi:namedview id="namedview2878" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="7.9044052" inkscape:cx="138.0243" inkscape:cy="242.26997" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1">
<inkscape:grid type="xygrid" id="grid2997" empspacing="6" originx="0" originy="0" spacingy="0.2645833" spacingx="0.2645833" units="px" visible="true" /> <inkscape:grid type="xygrid" id="grid2997" empspacing="6" originx="0" originy="0" spacingy="0.2645833" spacingx="0.2645833" units="px" visible="true" />
<inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="9.5249989" spacingy="9.5249989" empcolor="#3f3fff" empopacity="0.25098039" color="#3f3fff" opacity="0.1254902" empspacing="1" dotted="false" gridanglex="30" gridanglez="30" visible="true" /> <inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="9.5249989" spacingy="9.5249989" empcolor="#3f3fff" empopacity="0.25098039" color="#3f3fff" opacity="0.1254902" empspacing="1" dotted="false" gridanglex="30" gridanglez="30" visible="true" />
</sodipodi:namedview> </sodipodi:namedview>
@ -77,5 +77,6 @@
<path d="m 5.6444435,59.43432 v 1.034991 h 1.0541546 z m 1.1759257,1.612262 h -1.1759257 c -0.3247228,0 -0.5879626,-0.258453 -0.5879626,-0.577271 v -1.154545 h -2.3518514 v 5.195451 h 4.1157397 z m -4.1157397,-2.309089 h 3.0615854 l 1.6421175,1.612259 v 4.160465 c 0,0.318822 -0.2632403,0.577275 -0.5879632,0.577275 h -4.1157397 c -0.3247231,0 -0.5879631,-0.258453 -0.5879631,-0.577275 v -5.195451 c 0,-0.31882 0.26324,-0.577273 0.5879631,-0.577273 z m 1.7638882,3.92135 v -1.323625 h 0.5879632 v 1.323625 l 0.3800861,-0.373177 0.415753,0.408196 -1.0898206,1.070004 -1.0898208,-1.070004 0.4157526,-0.408196 z" fill-rule="evenodd" id="downloadfile" style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.0661458;stroke-dasharray:none;stroke-opacity:0.509804" /> <path d="m 5.6444435,59.43432 v 1.034991 h 1.0541546 z m 1.1759257,1.612262 h -1.1759257 c -0.3247228,0 -0.5879626,-0.258453 -0.5879626,-0.577271 v -1.154545 h -2.3518514 v 5.195451 h 4.1157397 z m -4.1157397,-2.309089 h 3.0615854 l 1.6421175,1.612259 v 4.160465 c 0,0.318822 -0.2632403,0.577275 -0.5879632,0.577275 h -4.1157397 c -0.3247231,0 -0.5879631,-0.258453 -0.5879631,-0.577275 v -5.195451 c 0,-0.31882 0.26324,-0.577273 0.5879631,-0.577273 z m 1.7638882,3.92135 v -1.323625 h 0.5879632 v 1.323625 l 0.3800861,-0.373177 0.415753,0.408196 -1.0898206,1.070004 -1.0898208,-1.070004 0.4157526,-0.408196 z" fill-rule="evenodd" id="downloadfile" style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.0661458;stroke-dasharray:none;stroke-opacity:0.509804" />
<path id="path3014" style="fill:#f2f2f2;stroke:#999999;stroke-opacity:1;stroke-width:0.06614583;stroke-dasharray:none;fill-opacity:1" d="M 4.6307246 2.6463498 C 3.0979756 2.6463498 1.8515665 3.8912088 1.8515664 5.4239577 C 1.8515664 6.9567067 3.0979756 8.2010487 4.6307246 8.2010488 C 6.1634736 8.2010488 7.4083325 6.9567067 7.4083325 5.4239577 C 7.4083325 3.8912088 6.1634735 2.6463498 4.6307246 2.6463498 z M 4.6307246 2.9098996 C 6.0204823 2.9098995 7.1447827 4.0342 7.1447827 5.4239577 C 7.1447827 6.8137155 6.0204823 7.9374991 4.6307246 7.9374991 C 3.2409669 7.937499 2.1171832 6.8137154 2.1171832 5.4239577 C 2.1171833 4.0342 3.2409669 2.9098996 4.6307246 2.9098996 z M 4.6265904 3.6602413 C 4.4830079 3.6602413 4.3339769 3.6757056 4.1795894 3.7067501 C 4.0252001 3.7376887 3.8542856 3.7854994 3.667476 3.8504105 L 3.667476 4.5790481 C 3.8249518 4.476919 3.9765859 4.4006165 4.1217118 4.3496048 C 4.2668361 4.2971467 4.4017991 4.2705399 4.5268549 4.2705399 C 4.6596277 4.2705399 4.7628056 4.3016097 4.8369135 4.3635574 C 4.9110183 4.4238471 4.9480162 4.5079171 4.9480178 4.6162552 C 4.9480162 4.6874104 4.9271727 4.758453 4.8854893 4.8296788 C 4.8453469 4.9008341 4.7812531 4.9766217 4.693253 5.0570551 L 4.5454584 5.1919305 C 4.3818056 5.3435544 4.2744616 5.4685934 4.2235143 5.5676182 C 4.172565 5.6651259 4.1470332 5.7776896 4.1470332 5.9045485 L 4.1470332 6.0182366 L 4.9831578 6.0182366 L 4.9831578 5.9138502 C 4.9831561 5.8442119 4.9993102 5.7803848 5.0317336 5.7231642 C 5.0641535 5.6643561 5.1329366 5.5870926 5.2379226 5.491137 L 5.3857171 5.3588454 C 5.53084 5.2211562 5.6334948 5.0929891 5.6937086 4.973856 C 5.7539162 4.8531707 5.7841399 4.7167194 5.7841424 4.5650955 C 5.7841399 4.2696088 5.6856516 4.0454092 5.4880365 3.8922684 C 5.2904177 3.7375754 5.0032968 3.6602413 4.6265904 3.6602413 z M 4.1470332 6.3618848 L 4.1470332 7.1876741 L 4.9831578 7.1876741 L 4.9831578 6.3618848 L 4.1470332 6.3618848 z " /> <path id="path3014" style="fill:#f2f2f2;stroke:#999999;stroke-opacity:1;stroke-width:0.06614583;stroke-dasharray:none;fill-opacity:1" d="M 4.6307246 2.6463498 C 3.0979756 2.6463498 1.8515665 3.8912088 1.8515664 5.4239577 C 1.8515664 6.9567067 3.0979756 8.2010487 4.6307246 8.2010488 C 6.1634736 8.2010488 7.4083325 6.9567067 7.4083325 5.4239577 C 7.4083325 3.8912088 6.1634735 2.6463498 4.6307246 2.6463498 z M 4.6307246 2.9098996 C 6.0204823 2.9098995 7.1447827 4.0342 7.1447827 5.4239577 C 7.1447827 6.8137155 6.0204823 7.9374991 4.6307246 7.9374991 C 3.2409669 7.937499 2.1171832 6.8137154 2.1171832 5.4239577 C 2.1171833 4.0342 3.2409669 2.9098996 4.6307246 2.9098996 z M 4.6265904 3.6602413 C 4.4830079 3.6602413 4.3339769 3.6757056 4.1795894 3.7067501 C 4.0252001 3.7376887 3.8542856 3.7854994 3.667476 3.8504105 L 3.667476 4.5790481 C 3.8249518 4.476919 3.9765859 4.4006165 4.1217118 4.3496048 C 4.2668361 4.2971467 4.4017991 4.2705399 4.5268549 4.2705399 C 4.6596277 4.2705399 4.7628056 4.3016097 4.8369135 4.3635574 C 4.9110183 4.4238471 4.9480162 4.5079171 4.9480178 4.6162552 C 4.9480162 4.6874104 4.9271727 4.758453 4.8854893 4.8296788 C 4.8453469 4.9008341 4.7812531 4.9766217 4.693253 5.0570551 L 4.5454584 5.1919305 C 4.3818056 5.3435544 4.2744616 5.4685934 4.2235143 5.5676182 C 4.172565 5.6651259 4.1470332 5.7776896 4.1470332 5.9045485 L 4.1470332 6.0182366 L 4.9831578 6.0182366 L 4.9831578 5.9138502 C 4.9831561 5.8442119 4.9993102 5.7803848 5.0317336 5.7231642 C 5.0641535 5.6643561 5.1329366 5.5870926 5.2379226 5.491137 L 5.3857171 5.3588454 C 5.53084 5.2211562 5.6334948 5.0929891 5.6937086 4.973856 C 5.7539162 4.8531707 5.7841399 4.7167194 5.7841424 4.5650955 C 5.7841399 4.2696088 5.6856516 4.0454092 5.4880365 3.8922684 C 5.2904177 3.7375754 5.0032968 3.6602413 4.6265904 3.6602413 z M 4.1470332 6.3618848 L 4.1470332 7.1876741 L 4.9831578 7.1876741 L 4.9831578 6.3618848 L 4.1470332 6.3618848 z " />
<g id="text3784" style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#4d4d4d;fill-opacity:1;stroke:none;stroke-width:0.75" transform="matrix(0.35277776,0,0,0.35277776,1.8079862,-363.00384)" /> <g id="text3784" style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#4d4d4d;fill-opacity:1;stroke:none;stroke-width:0.75" transform="matrix(0.35277776,0,0,0.35277776,1.8079862,-363.00384)" />
<path id="copy" style="fill:#f2f2f2;stroke-width:0.264582;paint-order:fill markers stroke;fill-opacity:1" d="m 42.218298,69.320832 v 1.288405 h 1.472463 v 1.472465 h 1.288405 v -2.76087 z m -1.472465,1.472463 v 2.760871 h 2.760869 v -2.760871 z" />
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) --> <!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="288" height="288" viewBox="0 0 76.199999 76.199999" version="1.1" id="svg6237" inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="24.svg" inkscape:export-filename="../24.svg" inkscape:export-xdpi="7.52" inkscape:export-ydpi="7.52" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <svg width="288" height="288" viewBox="0 0 76.199999 76.199999" version="1.1" id="svg6237" inkscape:version="1.4.1 (93de688d07, 2025-03-30)" sodipodi:docname="24.svg" inkscape:export-filename="../24.svg" inkscape:export-xdpi="7.52" inkscape:export-ydpi="7.52" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview id="namedview6239" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="5.1755289" inkscape:cx="321.22321" inkscape:cy="85.788333" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1"> <sodipodi:namedview id="namedview6239" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="8.9060631" inkscape:cx="172.74748" inkscape:cy="256.79135" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1">
<inkscape:grid type="xygrid" id="grid6358" empspacing="6" originx="0" originy="0" spacingy="0.26458333" spacingx="0.26458333" units="px" visible="true" /> <inkscape:grid type="xygrid" id="grid6358" empspacing="6" originx="0" originy="0" spacingy="0.26458333" spacingx="0.26458333" units="px" visible="true" />
<inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="9.5249999" spacingy="9.5249999" empcolor="#3f3fff" empopacity="0.25098039" color="#ff0000" opacity="0.83529412" empspacing="0" dotted="false" gridanglex="30" gridanglez="30" visible="true" /> <inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="9.5249999" spacingy="9.5249999" empcolor="#3f3fff" empopacity="0.25098039" color="#ff0000" opacity="0.83529412" empspacing="0" dotted="false" gridanglex="30" gridanglez="30" visible="true" />
</sodipodi:namedview> </sodipodi:namedview>
@ -44,7 +44,7 @@
<path d="m 60.085221,50.800004 c -0.890121,-0.0021 -1.610321,0.711677 -1.612305,1.5875 0.002,0.877761 0.722184,1.586074 1.612305,1.5875 0.593513,-8.73e-4 1.110529,-0.321123 1.389062,-0.79375 h 0.65319 l 0.520899,-0.504362 0.396875,0.380339 0.380338,-0.37207 0.388607,0.380338 0.396875,-0.380338 0.388607,0.380338 0.677994,-0.65319 c 0.09761,-0.09927 0.100016,-0.174188 0,-0.272852 l -0.553971,-0.545703 h -3.241146 c -0.277124,-0.47713 -0.799763,-0.794983 -1.39733,-0.79375 z m -0.7028,1.157552 c 0.233962,-0.0011 0.419905,0.187463 0.42168,0.42168 -0.0017,0.230958 -0.187613,0.419542 -0.42168,0.42168 -0.237929,-0.0024 -0.43214,-0.190722 -0.429948,-0.42168 -0.0022,-0.234217 0.192019,-0.422799 0.429948,-0.42168 z" id="permissions" style="fill:#4d4d4d;fill-opacity:1;stroke-width:0.264583" class="sprite" /> <path d="m 60.085221,50.800004 c -0.890121,-0.0021 -1.610321,0.711677 -1.612305,1.5875 0.002,0.877761 0.722184,1.586074 1.612305,1.5875 0.593513,-8.73e-4 1.110529,-0.321123 1.389062,-0.79375 h 0.65319 l 0.520899,-0.504362 0.396875,0.380339 0.380338,-0.37207 0.388607,0.380338 0.396875,-0.380338 0.388607,0.380338 0.677994,-0.65319 c 0.09761,-0.09927 0.100016,-0.174188 0,-0.272852 l -0.553971,-0.545703 h -3.241146 c -0.277124,-0.47713 -0.799763,-0.794983 -1.39733,-0.79375 z m -0.7028,1.157552 c 0.233962,-0.0011 0.419905,0.187463 0.42168,0.42168 -0.0017,0.230958 -0.187613,0.419542 -0.42168,0.42168 -0.237929,-0.0024 -0.43214,-0.190722 -0.429948,-0.42168 -0.0022,-0.234217 0.192019,-0.422799 0.429948,-0.42168 z" id="permissions" style="fill:#4d4d4d;fill-opacity:1;stroke-width:0.264583" class="sprite" />
<polygon points="12.5,50 12.5,87.5 43.75,87.5 43.75,62.5 56.25,62.5 56.25,87.5 87.5,87.5 87.5,50 100,50 50,0 0,50 " id="home" transform="matrix(0.0635,0,0,0.0635,30.162499,20.902083)" style="fill:#4d4d4d;fill-opacity:1" class="sprite" /> <polygon points="12.5,50 12.5,87.5 43.75,87.5 43.75,62.5 56.25,62.5 56.25,87.5 87.5,87.5 87.5,50 100,50 50,0 0,50 " id="home" transform="matrix(0.0635,0,0,0.0635,30.162499,20.902083)" style="fill:#4d4d4d;fill-opacity:1" class="sprite" />
<path inkscape:connector-curvature="0" d="m 7.937502,33.337505 c 0,-0.119238 -0.0078,-0.236713 -0.02082,-0.352777 h -0.356658 c -0.159103,-1.275998 -1.168753,-2.285648 -2.44475,-2.445102 v -0.356307 c -0.116064,-0.01304 -0.233539,-0.02082 -0.352778,-0.02082 -0.119239,0 -0.236714,0.0078 -0.352778,0.02082 v 0.356659 c -1.275997,0.159102 -2.285647,1.168752 -2.445103,2.44475 h -0.356305 c -0.01305,0.116064 -0.02081,0.233539 -0.02081,0.352777 0,0.119239 0.0078,0.236714 0.02081,0.352779 h 0.356658 c 0.159103,1.275996 1.168753,2.285659 2.44475,2.445123 v 0.356658 c 0.116064,0.0127 0.233539,0.02037 0.352778,0.02037 0.119239,0 0.236714,-0.0077 0.352778,-0.0209 v -0.356658 c 1.275644,-0.159438 2.285647,-1.168757 2.445102,-2.444753 h 0.356659 c 0.0127,-0.115712 0.02046,-0.233187 0.02046,-0.352779 z m -2.822223,2.084929 v -0.32104 c 0,-0.195085 -0.158044,-0.352777 -0.352777,-0.352777 -0.194734,0 -0.352778,0.157692 -0.352778,0.352777 v 0.32104 c -0.885472,-0.148883 -1.582914,-0.845973 -1.731786,-1.731798 l 0.320675,-2.65e-4 c 0.195086,0 0.352778,-0.158046 0.352778,-0.352779 0,-0.194733 -0.157692,-0.352777 -0.352778,-0.352777 h -0.321028 c 0.149225,-0.885473 0.846667,-1.582915 1.732139,-1.73214 v 0.32103 c 0,0.194733 0.158044,0.352777 0.352778,0.352777 0.194733,0 0.352777,-0.158044 0.352777,-0.352777 v -0.32103 c 0.885825,0.148873 1.583267,0.846315 1.732139,1.73214 h -0.321028 c -0.195086,0 -0.352777,0.158044 -0.352777,0.352777 0,0.194733 0.157691,0.352779 0.352777,0.352779 l 0.321028,2.65e-4 c -0.149225,0.885825 -0.846314,1.582915 -1.732139,1.731798 z" id="geolocation" style="fill:#4d4d4d;fill-opacity:1;stroke-width:0.264583" class="sprite" /> <path inkscape:connector-curvature="0" d="m 7.937502,33.337505 c 0,-0.119238 -0.0078,-0.236713 -0.02082,-0.352777 h -0.356658 c -0.159103,-1.275998 -1.168753,-2.285648 -2.44475,-2.445102 v -0.356307 c -0.116064,-0.01304 -0.233539,-0.02082 -0.352778,-0.02082 -0.119239,0 -0.236714,0.0078 -0.352778,0.02082 v 0.356659 c -1.275997,0.159102 -2.285647,1.168752 -2.445103,2.44475 h -0.356305 c -0.01305,0.116064 -0.02081,0.233539 -0.02081,0.352777 0,0.119239 0.0078,0.236714 0.02081,0.352779 h 0.356658 c 0.159103,1.275996 1.168753,2.285659 2.44475,2.445123 v 0.356658 c 0.116064,0.0127 0.233539,0.02037 0.352778,0.02037 0.119239,0 0.236714,-0.0077 0.352778,-0.0209 v -0.356658 c 1.275644,-0.159438 2.285647,-1.168757 2.445102,-2.444753 h 0.356659 c 0.0127,-0.115712 0.02046,-0.233187 0.02046,-0.352779 z m -2.822223,2.084929 v -0.32104 c 0,-0.195085 -0.158044,-0.352777 -0.352777,-0.352777 -0.194734,0 -0.352778,0.157692 -0.352778,0.352777 v 0.32104 c -0.885472,-0.148883 -1.582914,-0.845973 -1.731786,-1.731798 l 0.320675,-2.65e-4 c 0.195086,0 0.352778,-0.158046 0.352778,-0.352779 0,-0.194733 -0.157692,-0.352777 -0.352778,-0.352777 h -0.321028 c 0.149225,-0.885473 0.846667,-1.582915 1.732139,-1.73214 v 0.32103 c 0,0.194733 0.158044,0.352777 0.352778,0.352777 0.194733,0 0.352777,-0.158044 0.352777,-0.352777 v -0.32103 c 0.885825,0.148873 1.583267,0.846315 1.732139,1.73214 h -0.321028 c -0.195086,0 -0.352777,0.158044 -0.352777,0.352777 0,0.194733 0.157691,0.352779 0.352777,0.352779 l 0.321028,2.65e-4 c -0.149225,0.885825 -0.846314,1.582915 -1.732139,1.731798 z" id="geolocation" style="fill:#4d4d4d;fill-opacity:1;stroke-width:0.264583" class="sprite" />
<g id="share" class="sprite" transform="matrix(0.26458333,0,0,0.26458333,-2.6458336,-229.22505)"> <g id="share" class="sprite" transform="matrix(0.26458333,0,0,0.26458333,-21.695832,-210.17502)">
<circle id="path4309" style="fill:none;stroke:#464646;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" cx="100" cy="992.3623" r="11" /> <circle id="path4309" style="fill:none;stroke:#464646;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" cx="100" cy="992.3623" r="11" />
<circle transform="rotate(-111.82202)" id="path4819" style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:4.28879" cx="-963.88702" cy="-276.03735" r="2.5" /> <circle transform="rotate(-111.82202)" id="path4819" style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:4.28879" cx="-963.88702" cy="-276.03735" r="2.5" />
<circle transform="rotate(-111.82202)" id="path4819-2" style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:4.28879" cx="-956.38037" cy="-281.15619" r="2.5" /> <circle transform="rotate(-111.82202)" id="path4819-2" style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:4.28879" cx="-956.38037" cy="-281.15619" r="2.5" />
@ -77,7 +77,7 @@
</g> </g>
<path style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:1.84551;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" inkscape:transform-center-x="-0.0017170804" inkscape:transform-center-y="-1.1593678" d="m 31.537126,45.771563 0.577355,-2.184903 -1.687401,-1.349931 h 2.154994 l 0.756436,-2.28465 0.754501,2.284227 h 2.154902 l -1.688682,1.351121 0.575368,2.185485 -1.798166,-1.252432 z" id="star" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccc" class="sprite" /> <path style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:1.84551;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" inkscape:transform-center-x="-0.0017170804" inkscape:transform-center-y="-1.1593678" d="m 31.537126,45.771563 0.577355,-2.184903 -1.687401,-1.349931 h 2.154994 l 0.756436,-2.28465 0.754501,2.284227 h 2.154902 l -1.688682,1.351121 0.575368,2.185485 -1.798166,-1.252432 z" id="star" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccc" class="sprite" />
<path style="fill:none;fill-opacity:1;stroke:#464646;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" inkscape:transform-center-x="-0.0017170804" inkscape:transform-center-y="-1.1593678" d="m 40.742193,45.771563 0.577355,-2.184903 -1.687401,-1.349931 h 2.154994 l 0.756436,-2.28465 0.754502,2.284227 h 2.154901 l -1.688682,1.351121 0.575368,2.185485 -1.798169,-1.252432 z" id="starred" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccc" class="sprite" /> <path style="fill:none;fill-opacity:1;stroke:#464646;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" inkscape:transform-center-x="-0.0017170804" inkscape:transform-center-y="-1.1593678" d="m 40.742193,45.771563 0.577355,-2.184903 -1.687401,-1.349931 h 2.154994 l 0.756436,-2.28465 0.754502,2.284227 h 2.154901 l -1.688682,1.351121 0.575368,2.185485 -1.798169,-1.252432 z" id="starred" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccc" class="sprite" />
<path d="m 45.33157,52.032511 0.367177,0.21791 c 0.07232,0.04294 0.09577,0.135732 0.0524,0.207275 -0.01292,0.02122 -0.03092,0.03903 -0.0524,0.0518 l -2.836254,1.6832 -2.836235,-1.6832 c -0.07233,-0.04294 -0.09579,-0.135704 -0.05238,-0.207274 0.0129,-0.02125 0.03089,-0.03905 0.05238,-0.05181 l 0.367179,-0.21791 2.469056,1.465315 z m 0,1.419992 0.367177,0.217911 c 0.07232,0.04294 0.09577,0.135731 0.0524,0.207274 -0.01292,0.02125 -0.03092,0.03903 -0.0524,0.05181 l -2.679097,1.58996 c -0.09674,0.05739 -0.217576,0.05739 -0.314315,0 l -2.679077,-1.58996 c -0.07233,-0.04292 -0.09579,-0.135705 -0.05238,-0.207249 0.0129,-0.02127 0.03089,-0.03908 0.05238,-0.05183 l 0.367179,-0.217911 2.469056,1.465315 z m -2.31192,-4.196946 2.679097,1.589967 c 0.07232,0.04292 0.09577,0.135715 0.0524,0.207256 -0.01292,0.02126 -0.03092,0.03906 -0.0524,0.05182 l -2.836254,1.683221 -2.836235,-1.683221 c -0.07233,-0.04292 -0.09579,-0.135716 -0.05238,-0.207256 0.0129,-0.02126 0.03089,-0.03906 0.05238,-0.05182 l 2.679077,-1.589967 c 0.09674,-0.05741 0.217576,-0.05741 0.314315,0 z" fill="#4d4d4d" id="datalayers" style="stroke-width:0.264583" /> <path d="m 45.33157,52.032514 0.367177,0.21791 c 0.07232,0.04294 0.09577,0.135732 0.0524,0.207275 -0.01292,0.02122 -0.03092,0.03903 -0.0524,0.0518 l -2.836254,1.6832 -2.836235,-1.6832 c -0.07233,-0.04294 -0.09579,-0.135704 -0.05238,-0.207274 0.0129,-0.02125 0.03089,-0.03905 0.05238,-0.05181 l 0.367179,-0.21791 2.469056,1.465315 z m 0,1.419992 0.367177,0.217911 c 0.07232,0.04294 0.09577,0.135731 0.0524,0.207274 -0.01292,0.02125 -0.03092,0.03903 -0.0524,0.05181 l -2.679097,1.58996 c -0.09674,0.05739 -0.217576,0.05739 -0.314315,0 l -2.679077,-1.58996 c -0.07233,-0.04292 -0.09579,-0.135705 -0.05238,-0.207249 0.0129,-0.02127 0.03089,-0.03908 0.05238,-0.05183 l 0.367179,-0.217911 2.469056,1.465315 z m -2.31192,-4.196946 2.679097,1.589967 c 0.07232,0.04292 0.09577,0.135715 0.0524,0.207256 -0.01292,0.02126 -0.03092,0.03906 -0.0524,0.05182 l -2.836254,1.683221 -2.836235,-1.683221 c -0.07233,-0.04292 -0.09579,-0.135716 -0.05238,-0.207256 0.0129,-0.02126 0.03089,-0.03906 0.05238,-0.05182 l 2.679077,-1.589967 c 0.09674,-0.05741 0.217576,-0.05741 0.314315,0 z" fill="#4d4d4d" id="datalayers" style="stroke-width:0.264583" />
<g id="tilelayers" transform="translate(19.049999,56.885416)"> <g id="tilelayers" transform="translate(19.049999,56.885416)">
<path d="m 26.772659,3.4276506 h -4.243945 c -0.07035,0 -0.137814,0.027945 -0.187558,0.077687 -0.04974,0.049744 -0.07769,0.1172104 -0.07769,0.1875578 v 4.2439431 c 0,0.070353 0.02794,0.1378215 0.07769,0.1875631 0.04974,0.049742 0.11721,0.077682 0.187558,0.077682 h 4.243945 c 0.07035,0 0.137822,-0.02794 0.187563,-0.077682 0.04974,-0.049742 0.07768,-0.1172104 0.07768,-0.1875631 v -4.2439431 c 0,-0.070347 -0.02794,-0.1378135 -0.07768,-0.1875578 -0.04974,-0.049742 -0.11721,-0.077687 -0.187563,-0.077687 z m -0.265245,4.1590648 h -3.713453 v -3.546348 h 3.713453 z" fill="#464646" id="path2349" style="stroke-width:0.264583" /> <path d="m 26.772659,3.4276506 h -4.243945 c -0.07035,0 -0.137814,0.027945 -0.187558,0.077687 -0.04974,0.049744 -0.07769,0.1172104 -0.07769,0.1875578 v 4.2439431 c 0,0.070353 0.02794,0.1378215 0.07769,0.1875631 0.04974,0.049742 0.11721,0.077682 0.187558,0.077682 h 4.243945 c 0.07035,0 0.137822,-0.02794 0.187563,-0.077682 0.04974,-0.049742 0.07768,-0.1172104 0.07768,-0.1875631 v -4.2439431 c 0,-0.070347 -0.02794,-0.1378135 -0.07768,-0.1875578 -0.04974,-0.049742 -0.11721,-0.077687 -0.187563,-0.077687 z m -0.265245,4.1590648 h -3.713453 v -3.546348 h 3.713453 z" fill="#464646" id="path2349" style="stroke-width:0.264583" />
<g mask="url(#mask0_181_11898)" id="g2376" transform="matrix(0.26458333,0,0,0.26458333,20.637501,1.8520833)"> <g mask="url(#mask0_181_11898)" id="g2376" transform="matrix(0.26458333,0,0,0.26458333,20.637501,1.8520833)">
@ -110,5 +110,6 @@
<path inkscape:connector-curvature="0" id="path3789" style="font-weight:bold;font-size:12px;-inkscape-font-specification:'Sans Bold';fill:#4d4d4d;stroke-width:0.75" d="m 9,1046.0464 h -2.3698034 v -0.3223 c 0,-0.3596 0.072207,-0.6775 0.2166302,-0.9539 0.1444174,-0.2807 0.4485749,-0.636 0.9124728,-1.0658 l 0.4201314,-0.3816 c 0.249449,-0.228 0.4310681,-0.4429 0.5448577,-0.6446 0.1181576,-0.2019 0.1772384,-0.4036 0.177243,-0.6053 -4.6e-6,-0.3071 -0.1050376,-0.5462 -0.3150985,-0.7171 -0.2100697,-0.1756 -0.5032861,-0.2632 -0.87965,-0.2632 -0.3544889,0 -0.7374207,0.075 -1.1487968,0.2237 -0.4113804,0.1446 -0.840264,0.3618 -1.2866522,0.6513 v -2.0659 c 0.5295391,-0.184 1.0131273,-0.32 1.4507661,-0.4077 0.437634,-0.088 0.8599531,-0.1317 1.2669587,-0.1317 1.0678292,0 1.8818328,0.2194 2.442012,0.6579 0.560169,0.4341 0.840256,1.0702 0.840263,1.9078 -7e-6,0.4298 -0.08535,0.8159 -0.256017,1.158 -0.170685,0.3377 -0.461713,0.7017 -0.873085,1.092 l -0.4201313,0.375 c -0.297598,0.272 -0.4923463,0.4913 -0.5842451,0.658 -0.091909,0.1622 -0.1378603,0.342 -0.1378556,0.5394 v 0.296 m -2.3698034,0.9739 h 2.3698034 v 2.342 h -2.3698034 v -2.342" sodipodi:nodetypes="ccsccccccsccccsccccccccccccc" /> <path inkscape:connector-curvature="0" id="path3789" style="font-weight:bold;font-size:12px;-inkscape-font-specification:'Sans Bold';fill:#4d4d4d;stroke-width:0.75" d="m 9,1046.0464 h -2.3698034 v -0.3223 c 0,-0.3596 0.072207,-0.6775 0.2166302,-0.9539 0.1444174,-0.2807 0.4485749,-0.636 0.9124728,-1.0658 l 0.4201314,-0.3816 c 0.249449,-0.228 0.4310681,-0.4429 0.5448577,-0.6446 0.1181576,-0.2019 0.1772384,-0.4036 0.177243,-0.6053 -4.6e-6,-0.3071 -0.1050376,-0.5462 -0.3150985,-0.7171 -0.2100697,-0.1756 -0.5032861,-0.2632 -0.87965,-0.2632 -0.3544889,0 -0.7374207,0.075 -1.1487968,0.2237 -0.4113804,0.1446 -0.840264,0.3618 -1.2866522,0.6513 v -2.0659 c 0.5295391,-0.184 1.0131273,-0.32 1.4507661,-0.4077 0.437634,-0.088 0.8599531,-0.1317 1.2669587,-0.1317 1.0678292,0 1.8818328,0.2194 2.442012,0.6579 0.560169,0.4341 0.840256,1.0702 0.840263,1.9078 -7e-6,0.4298 -0.08535,0.8159 -0.256017,1.158 -0.170685,0.3377 -0.461713,0.7017 -0.873085,1.092 l -0.4201313,0.375 c -0.297598,0.272 -0.4923463,0.4913 -0.5842451,0.658 -0.091909,0.1622 -0.1378603,0.342 -0.1378556,0.5394 v 0.296 m -2.3698034,0.9739 h 2.3698034 v 2.342 h -2.3698034 v -2.342" sodipodi:nodetypes="ccsccccccsccccsccccccccccccc" />
</g> </g>
</g> </g>
<path id="copy" style="fill:#4d4d4d;stroke-width:0.264582;paint-order:fill markers stroke" d="m 42.218298,69.320832 v 1.288405 h 1.472463 v 1.472465 h 1.288405 v -2.76087 z m -1.472465,1.472463 v 2.760871 h 2.760869 v -2.760871 z" />
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View file

@ -7,6 +7,7 @@ import {
import { translate } from './i18n.js' import { translate } from './i18n.js'
import { Request, ServerRequest } from './request.js' import { Request, ServerRequest } from './request.js'
import { escapeHTML, generateId } from './utils.js' import { escapeHTML, generateId } from './utils.js'
import * as Utils from './utils.js'
export class BaseAutocomplete { export class BaseAutocomplete {
constructor(parent, options) { constructor(parent, options) {
@ -291,10 +292,9 @@ class BaseServerAjax extends BaseAjax {
export const SingleMixin = (Base) => export const SingleMixin = (Base) =>
class extends Base { class extends Base {
initSelectedContainer() { initSelectedContainer() {
return DomUtil.after( const el = Utils.loadTemplate('<div class="umap-singleresult"></div>')
this.input, this.input.parentNode.insertBefore(el, this.input.nextSibling)
DomUtil.element({ tagName: 'div', className: 'umap-singleresult' }) return el
)
} }
displaySelected(result) { displaySelected(result) {
@ -322,10 +322,9 @@ export const SingleMixin = (Base) =>
export const MultipleMixin = (Base) => export const MultipleMixin = (Base) =>
class extends Base { class extends Base {
initSelectedContainer() { initSelectedContainer() {
return DomUtil.after( const el = Utils.loadTemplate('<ul class="umap-multiresult"></ul>')
this.input, this.input.parentNode.insertBefore(el, this.input.nextSibling)
DomUtil.element({ tagName: 'ul', className: 'umap-multiresult' }) return el
)
} }
displaySelected(result) { displaySelected(result) {

View file

@ -5,6 +5,7 @@ import { translate } from './i18n.js'
import * as Icon from './rendering/icon.js' import * as Icon from './rendering/icon.js'
import ContextMenu from './ui/contextmenu.js' import ContextMenu from './ui/contextmenu.js'
import * as Utils from './utils.js' import * as Utils from './utils.js'
import { SCHEMA } from './schema.js'
export default class Browser { export default class Browser {
constructor(umap, leafletMap) { constructor(umap, leafletMap) {
@ -21,35 +22,24 @@ export default class Browser {
addFeature(feature, parent) { addFeature(feature, parent) {
if (feature.isFiltered()) return if (feature.isFiltered()) return
if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return
const row = DomUtil.create('li', `${feature.getClassName()} feature`) const template = `
const zoom_to = DomUtil.createButtonIcon( <li class="feature ${feature.getClassName()}">
row, <button class="icon icon-16 icon-zoom" title="${translate('Bring feature to center')}" data-ref=zoom></button>
'icon-zoom', <button class="icon icon-16 show-on-edit icon-edit" title="${translate('Edit this feature')}" data-ref=edit></button>
translate('Bring feature to center') <button class="icon icon-16 show-on-edit icon-delete" title="${translate('Delete this feature')}" data-ref=remove></button>
) <i class="icon icon-16 icon-${feature.getClassName()} feature-color" data-ref=colorBox></i>
const edit = DomUtil.createButtonIcon( <span class="feature-title" data-ref=label></span>
row, </li>
'show-on-edit icon-edit', `
translate('Edit this feature') const [row, { zoom, edit, remove, colorBox, label }] =
) Utils.loadTemplateWithRefs(template)
const del = DomUtil.createButtonIcon( label.textContent = label.title = feature.getDisplayName() || '—'
row,
'show-on-edit icon-delete',
translate('Delete this feature')
)
const colorBox = DomUtil.create(
'i',
`icon icon-16 icon-${feature.getClassName()} feature-color`,
row
)
const title = DomUtil.create('span', 'feature-title', row)
const symbol = feature._getIconUrl const symbol = feature._getIconUrl
? Icon.formatUrl(feature._getIconUrl(), feature) ? Icon.formatUrl(feature._getIconUrl(), feature)
: null : null
title.textContent = title.title = feature.getDisplayName() || '—'
const bgcolor = feature.getPreviewColor() const bgcolor = feature.getPreviewColor()
colorBox.style.backgroundColor = bgcolor colorBox.style.backgroundColor = bgcolor
if (symbol && symbol !== U.SCHEMA.iconUrl.default) { if (symbol && symbol !== SCHEMA.iconUrl.default) {
const icon = Icon.makeElement(symbol, colorBox) const icon = Icon.makeElement(symbol, colorBox)
Icon.setContrast(icon, colorBox, symbol, bgcolor) Icon.setContrast(icon, colorBox, symbol, bgcolor)
} else if (DomUtil.contrastedColor(colorBox, bgcolor)) { } else if (DomUtil.contrastedColor(colorBox, bgcolor)) {
@ -58,10 +48,10 @@ export default class Browser {
const viewFeature = (e) => { const viewFeature = (e) => {
feature.zoomTo({ ...e, callback: () => feature.view() }) feature.zoomTo({ ...e, callback: () => feature.view() })
} }
DomEvent.on(zoom_to, 'click', viewFeature) zoom.addEventListener('click', viewFeature)
DomEvent.on(title, 'click', viewFeature) label.addEventListener('click', viewFeature)
DomEvent.on(edit, 'click', feature.edit, feature) edit.addEventListener('click', () => feature.edit())
DomEvent.on(del, 'click', feature.del, feature) remove.addEventListener('click', () => feature.del())
// HOTFIX. Remove when this is released: // HOTFIX. Remove when this is released:
// https://github.com/Leaflet/Leaflet/pull/9052 // https://github.com/Leaflet/Leaflet/pull/9052
DomEvent.disableClickPropagation(row) DomEvent.disableClickPropagation(row)
@ -73,51 +63,51 @@ export default class Browser {
} }
addDataLayer(datalayer, parent) { addDataLayer(datalayer, parent) {
let className = `datalayer ${datalayer.getHidableClass()}` const open = this.mode !== 'layers' ? ' open' : ''
if (this.mode !== 'layers') className += ' show-list' const [container, { headline, toolbox, label }] = Utils.loadTemplateWithRefs(`
const container = DomUtil.create('div', className, parent) <details class="datalayer ${datalayer.getHidableClass()}" id="${this.datalayerId(datalayer)}"${open}>
const headline = DomUtil.create('h5', '', container) <summary data-ref=headline>
container.id = this.datalayerId(datalayer) <span data-ref=toolbox></span>
const ul = DomUtil.create('ul', '', container) <span class="datalayer-name" data-id="${datalayer.id}" data-ref=label></span>
<span class="datalayer-counter"></span>
</summary>
<ul></ul>
</details>
`)
datalayer.renderToolbox(toolbox)
parent.appendChild(container)
this.updateDatalayer(datalayer) this.updateDatalayer(datalayer)
} }
updateDatalayer(datalayer) { updateDatalayer(datalayer) {
// Compute once, but use it for each feature later. // Compute once, but use it for each feature later.
this.bounds = this._leafletMap.getBounds() this.bounds = this._leafletMap.getBounds()
const parent = DomUtil.get(this.datalayerId(datalayer)) const id = this.datalayerId(datalayer)
const parent = document.getElementById(id)
// Panel is not open // Panel is not open
if (!parent) return if (!parent) return
parent.classList.toggle('off', !datalayer.isVisible()) parent.classList.toggle('off', !datalayer.isVisible())
const label = parent.querySelector('.datalayer-name')
const container = parent.querySelector('ul') const container = parent.querySelector('ul')
const headline = parent.querySelector('h5')
const toggleList = () => parent.classList.toggle('show-list')
headline.innerHTML = ''
const toggle = DomUtil.create('i', 'icon icon-16 datalayer-toggle-list', headline)
DomEvent.on(toggle, 'click', toggleList)
datalayer.renderToolbox(headline)
const name = DomUtil.create('span', 'datalayer-name', headline)
name.textContent = name.title = datalayer.options.name
DomEvent.on(name, 'click', toggleList)
container.innerHTML = '' container.innerHTML = ''
datalayer.eachFeature((feature) => this.addFeature(feature, container)) datalayer.eachFeature((feature) => this.addFeature(feature, container))
datalayer.propagate(['properties.name'])
const total = datalayer.count() const total = datalayer.count()
if (!total) return if (!total) return
const current = container.querySelectorAll('li').length const current = container.querySelectorAll('li').length
const count = total === current ? total : `${current}/${total}` const count = total === current ? total : `${current}/${total}`
const counter = DomUtil.create('span', 'datalayer-counter', headline) const counter = parent.querySelector('.datalayer-counter')
counter.textContent = `(${count})` counter.textContent = `(${count})`
counter.title = translate(`Features in this layer: ${count}`) counter.title = translate(`Features in this layer: ${count}`)
} }
toggleBadge() { toggleBadge() {
U.Utils.toggleBadge(this.filtersTitle, this.hasFilters()) Utils.toggleBadge(this.filtersTitle, this.hasFilters())
U.Utils.toggleBadge('.umap-control-browse', this.hasFilters()) Utils.toggleBadge('.umap-control-browse', this.hasFilters())
} }
onFormChange() { onFormChange() {
this._umap.eachBrowsableDataLayer((datalayer) => { this._umap.datalayers.browsable().map((datalayer) => {
datalayer.resetLayer(true) datalayer.resetLayer(true)
this.updateDatalayer(datalayer) this.updateDatalayer(datalayer)
if (this._umap.fullPanel?.isOpen()) datalayer.tableEdit() if (this._umap.fullPanel?.isOpen()) datalayer.tableEdit()
@ -140,7 +130,7 @@ export default class Browser {
onMoveEnd() { onMoveEnd() {
if (!this.isOpen()) return if (!this.isOpen()) return
const isListDynamic = this.options.inBbox const isListDynamic = this.options.inBbox
this._umap.eachBrowsableDataLayer((datalayer) => { this._umap.datalayers.browsable().map((datalayer) => {
if (!isListDynamic && !datalayer.hasDynamicData()) return if (!isListDynamic && !datalayer.hasDynamicData()) return
this.updateDatalayer(datalayer) this.updateDatalayer(datalayer)
}) })
@ -149,7 +139,7 @@ export default class Browser {
update() { update() {
if (!this.isOpen()) return if (!this.isOpen()) return
this.dataContainer.innerHTML = '' this.dataContainer.innerHTML = ''
this._umap.eachBrowsableDataLayer((datalayer) => { this._umap.datalayers.browsable().map((datalayer) => {
this.addDataLayer(datalayer, this.dataContainer) this.addDataLayer(datalayer, this.dataContainer)
}) })
} }
@ -157,21 +147,51 @@ export default class Browser {
open(mode) { open(mode) {
// Force only if mode is known, otherwise keep current mode. // Force only if mode is known, otherwise keep current mode.
if (mode) this.mode = mode if (mode) this.mode = mode
const container = DomUtil.create('div') const template = `
<div>
<h3><i class="icon icon-16 icon-layers"></i>${translate('Data browser')}</h3>
<details class="filters" data-ref="details">
<summary data-ref=filtersTitle><i class="icon icon-16 icon-filters"></i>${translate('Filters')}</summary>
<fieldset>
<div data-ref=formContainer>
</div>
<button class="flat" type="button" data-ref=reset><i class="icon icon-16 icon-restore" title=""></i>${translate('Reset all')}</button>
</fieldset>
</details>
<div class="main-toolbox">
<i class="icon icon-16 icon-eye" title="${translate('show/hide all layers')}" data-ref="toggle"></i>
<i class="icon icon-16 icon-zoom" title="${translate('zoom to data extent')}" data-ref="fitBounds"></i>
<i class="icon icon-16 icon-download" title="${translate('download visible data')}" data-ref="download"></i>
</div>
<div data-ref=dataContainer></div>
</div>
`
const [
container,
{
details,
filtersTitle,
toggle,
fitBounds,
download,
dataContainer,
formContainer,
reset,
},
] = Utils.loadTemplateWithRefs(template)
// HOTFIX. Remove when this is released: // HOTFIX. Remove when this is released:
// https://github.com/Leaflet/Leaflet/pull/9052 // https://github.com/Leaflet/Leaflet/pull/9052
DomEvent.disableClickPropagation(container) DomEvent.disableClickPropagation(container)
details.open = this.mode === 'filters'
toggle.addEventListener('click', () => this.toggleLayers())
fitBounds.addEventListener('click', () => this._umap.fitDataBounds())
download.addEventListener('click', () => this.downloadVisible(download))
download.hidden = this._umap.getProperty('embedControl') === false
DomUtil.createTitle(container, translate('Data browser'), 'icon-layers') this.filtersTitle = filtersTitle
this.formContainer = DomUtil.createFieldset(container, L._('Filters'), { this.dataContainer = dataContainer
on: this.mode === 'filters', this.formContainer = formContainer
className: 'filters',
icon: 'icon-filters',
})
this.filtersTitle = container.querySelector('summary')
this.toggleBadge() this.toggleBadge()
this.addMainToolbox(container)
this.dataContainer = DomUtil.create('div', '', container)
let fields = [ let fields = [
[ [
@ -184,27 +204,19 @@ export default class Browser {
builder.on('set', () => this.onFormChange()) builder.on('set', () => this.onFormChange())
let filtersBuilder let filtersBuilder
this.formContainer.appendChild(builder.build()) this.formContainer.appendChild(builder.build())
DomEvent.on(builder.form, 'reset', () => { builder.form.addEventListener('reset', () => {
window.setTimeout(builder.syncAll.bind(builder)) window.setTimeout(builder.syncAll.bind(builder))
}) })
if (this._umap.properties.facetKey) { if (this._umap.properties.facetKey) {
fields = this._umap.facets.build() fields = this._umap.facets.build()
filtersBuilder = new Form(this._umap.facets, fields) filtersBuilder = new Form(this._umap.facets, fields)
filtersBuilder.on('set', () => this.onFormChange()) filtersBuilder.on('set', () => this.onFormChange())
DomEvent.on(filtersBuilder.form, 'reset', () => { filtersBuilder.form.addEventListener('reset', () => {
window.setTimeout(filtersBuilder.syncAll.bind(filtersBuilder)) window.setTimeout(filtersBuilder.syncAll.bind(filtersBuilder))
}) })
this.formContainer.appendChild(filtersBuilder.build()) this.formContainer.appendChild(filtersBuilder.build())
} }
const reset = DomUtil.createButton('flat', this.formContainer, '', () => reset.addEventListener('click', () => this.resetFilters())
this.resetFilters()
)
DomUtil.createIcon(reset, 'icon-restore')
DomUtil.element({
tagName: 'span',
parent: reset,
textContent: translate('Reset all'),
})
this._umap.panel.open({ this._umap.panel.open({
content: container, content: container,
@ -220,20 +232,6 @@ export default class Browser {
} }
} }
addMainToolbox(container) {
const [toolbox, { toggle, fitBounds, download }] = Utils.loadTemplateWithRefs(`
<div class="main-toolbox">
<i class="icon icon-16 icon-eye" title="${translate('show/hide all layers')}" data-ref="toggle"></i>
<i class="icon icon-16 icon-zoom" title="${translate('zoom to data extent')}" data-ref="fitBounds"></i>
<i class="icon icon-16 icon-download" title="${translate('download visible data')}" data-ref="download"></i>
</div>
`)
container.appendChild(toolbox)
toggle.addEventListener('click', () => this.toggleLayers())
fitBounds.addEventListener('click', () => this._umap.fitDataBounds())
download.addEventListener('click', () => this.downloadVisible(download))
}
downloadVisible(element) { downloadVisible(element) {
const menu = new ContextMenu({ fixed: true }) const menu = new ContextMenu({ fixed: true })
const items = [] const items = []
@ -250,10 +248,10 @@ export default class Browser {
// If at least one layer is shown, hide it // If at least one layer is shown, hide it
// otherwise show all // otherwise show all
let allHidden = true let allHidden = true
this._umap.eachBrowsableDataLayer((datalayer) => { this._umap.datalayers.browsable().map((datalayer) => {
if (datalayer.isVisible()) allHidden = false if (datalayer.isVisible()) allHidden = false
}) })
this._umap.eachBrowsableDataLayer((datalayer) => { this._umap.datalayers.browsable().map((datalayer) => {
datalayer._forcedVisibility = true datalayer._forcedVisibility = true
if (allHidden) { if (allHidden) {
datalayer.show() datalayer.show()
@ -264,15 +262,13 @@ export default class Browser {
} }
static backButton(umap) { static backButton(umap) {
const button = DomUtil.createButtonIcon( const button = Utils.loadTemplate(
DomUtil.create('li', '', undefined), `<button class="icon icon-16 icon-back" title="${translate('Back to browser')}"></button>`
'icon-back',
translate('Back to browser')
) )
// Fixme: remove me when this is merged and released // Fixme: remove me when this is merged and released
// https://github.com/Leaflet/Leaflet/pull/9052 // https://github.com/Leaflet/Leaflet/pull/9052
DomEvent.disableClickPropagation(button) DomEvent.disableClickPropagation(button)
DomEvent.on(button, 'click', () => umap.openBrowser()) button.addEventListener('click', () => umap.openBrowser())
return button return button
} }
} }

View file

@ -68,16 +68,18 @@ export default class Caption extends Utils.WithTemplate {
this.elements.description.hidden = true this.elements.description.hidden = true
} }
this.elements.datalayersContainer.innerHTML = '' this.elements.datalayersContainer.innerHTML = ''
this._umap.eachDataLayerReverse((datalayer) => this._umap.datalayers
this.addDataLayer(datalayer, this.elements.datalayersContainer) .reverse()
) .map((datalayer) =>
this.addDataLayer(datalayer, this.elements.datalayersContainer)
)
this.addCredits() this.addCredits()
if (this._umap.properties.created_at) { if (this._umap.properties.created_at) {
const created_at = translate('created at {date}', { const created_at = translate('created at {date}', {
date: new Date(this._umap.properties.created_at).toLocaleDateString(), date: this._umap.createdAt.toLocaleDateString(),
}) })
const modified_at = translate('modified at {date}', { const modified_at = translate('modified at {date}', {
date: new Date(this._umap.properties.modified_at).toLocaleDateString(), date: this._umap.modifiedAt.toLocaleDateString(),
}) })
this.elements.dates.innerHTML = `${created_at} - ${modified_at}` this.elements.dates.innerHTML = `${created_at} - ${modified_at}`
} else { } else {
@ -85,7 +87,7 @@ export default class Caption extends Utils.WithTemplate {
} }
this._umap.panel.open({ content: this.element }).then(() => { this._umap.panel.open({ content: this.element }).then(() => {
// Create the legend when the panel is actually on the DOM // Create the legend when the panel is actually on the DOM
this._umap.eachDataLayerReverse((datalayer) => datalayer.renderLegend()) this._umap.datalayers.reverse().map((datalayer) => datalayer.renderLegend())
this._umap.propagate() this._umap.propagate()
}) })
} }

View file

@ -22,7 +22,6 @@ class Feature {
constructor(umap, datalayer, geojson = {}, id = null) { constructor(umap, datalayer, geojson = {}, id = null) {
this._umap = umap this._umap = umap
this.sync = umap.syncEngine.proxy(this) this.sync = umap.syncEngine.proxy(this)
this._isDirty = false
this._ui = null this._ui = null
// DataLayer the feature belongs to // DataLayer the feature belongs to
@ -54,17 +53,6 @@ class Feature {
} }
} }
set isDirty(status) {
this._isDirty = status
if (this.datalayer) {
this.datalayer.isDirty = status
}
}
get isDirty() {
return this._isDirty
}
get ui() { get ui() {
if (!this._ui) this.makeUI() if (!this._ui) this.makeUI()
return this._ui return this._ui
@ -146,14 +134,13 @@ class Feature {
} }
onCommit() { onCommit() {
this.pullGeometry(false)
// When the layer is a remote layer, we don't want to sync the creation of the // When the layer is a remote layer, we don't want to sync the creation of the
// points via the websocket, as the other peers will get them themselves. // points via the websocket, as the other peers will get them themselves.
const oldGeoJSON = this._just_married ? null : Utils.CopyJSON(this.toGeoJSON())
this.pullGeometry(false)
if (this.datalayer?.isRemoteLayer()) return if (this.datalayer?.isRemoteLayer()) return
if (this._just_married) { if (this._needs_upsert) {
this.sync.upsert(this.toGeoJSON(), null) this.sync.upsert(this.toGeoJSON(), null)
this._just_married = false this._needs_upsert = false
} else { } else {
this.sync.update('geometry', this.geometry, this._geometry_bk) this.sync.update('geometry', this.geometry, this._geometry_bk)
} }
@ -218,6 +205,7 @@ class Feature {
edit(event) { edit(event) {
if (!this._umap.editEnabled || this.isReadOnly()) return if (!this._umap.editEnabled || this.isReadOnly()) return
if (this._umap.editedFeature === this) return
const container = DomUtil.create('div', 'umap-feature-container') const container = DomUtil.create('div', 'umap-feature-container')
DomUtil.createTitle( DomUtil.createTitle(
container, container,
@ -326,7 +314,9 @@ class Feature {
] ]
} }
endEdit() {} endEdit() {
this.ui.disableEdit()
}
getDisplayName() { getDisplayName() {
const keys = U.LABEL_KEYS.slice() // Copy. const keys = U.LABEL_KEYS.slice() // Copy.
@ -365,7 +355,6 @@ class Feature {
} }
del(sync) { del(sync) {
this.isDirty = true
this._umap._leafletMap.closePopup() this._umap._leafletMap.closePopup()
if (this.datalayer) { if (this.datalayer) {
this.datalayer.removeFeature(this, sync) this.datalayer.removeFeature(this, sync)
@ -410,13 +399,11 @@ class Feature {
changeDataLayer(datalayer) { changeDataLayer(datalayer) {
if (this.datalayer) { if (this.datalayer) {
this.datalayer.isDirty = true
this.datalayer.removeFeature(this) this.datalayer.removeFeature(this)
} }
datalayer.addFeature(this) datalayer.addFeature(this)
this.sync.upsert(this.toGeoJSON()) this.sync.upsert(this.toGeoJSON())
datalayer.isDirty = true
this.redraw() this.redraw()
} }
@ -483,7 +470,6 @@ class Feature {
deleteProperty(property) { deleteProperty(property) {
delete this.properties[property] delete this.properties[property]
this.isDirty = true
} }
renameProperty(from, to) { renameProperty(from, to) {
@ -576,7 +562,6 @@ class Feature {
delete geojson.id delete geojson.id
delete geojson.properties.id delete geojson.properties.id
const feature = this.datalayer.makeFeature(geojson) const feature = this.datalayer.makeFeature(geojson)
feature.isDirty = true
feature.edit() feature.edit()
return feature return feature
} }
@ -612,7 +597,7 @@ class Feature {
this.datalayer.hideFeature(this) this.datalayer.hideFeature(this)
this.makeUI() this.makeUI()
this.datalayer.showFeature(this) this.datalayer.showFeature(this)
} else { } else if (this.datalayer?.isBrowsable()) {
this.ui._redraw() this.ui._redraw()
} }
} }
@ -828,11 +813,6 @@ class Path extends Feature {
) )
} }
endEdit() {
this.ui.disableEdit()
super.endEdit()
}
transferShape(at, to) { transferShape(at, to) {
const shape = this.ui.enableEdit().deleteShapeAt(at) const shape = this.ui.enableEdit().deleteShapeAt(at)
// FIXME: make Leaflet.Editable send an event instead // FIXME: make Leaflet.Editable send an event instead
@ -1056,7 +1036,6 @@ export class LineString extends Path {
this.pullGeometry() this.pullGeometry()
if (!this.ui.editEnabled()) this.edit() if (!this.ui.editEnabled()) this.edit()
this.ui.editor.reset() this.ui.editor.reset()
this.isDirty = true
} }
isMulti() { isMulti() {

View file

@ -64,6 +64,9 @@ export class DataLayer {
this.setOptions(data) this.setOptions(data)
this.pane.dataset.id = this.id this.pane.dataset.id = this.id
if (this.options.rank === undefined) {
this.options.rank = this._umap.datalayers.count()
}
if (!Utils.isObject(this.options.remoteData)) { if (!Utils.isObject(this.options.remoteData)) {
this.options.remoteData = {} this.options.remoteData = {}
@ -122,6 +125,20 @@ export class DataLayer {
return `datalayer-${stamp(this)}` return `datalayer-${stamp(this)}`
} }
get rank() {
// Make sure we always have a valid rank. Undefined rank may happen
// after importing an old umap backup, and not touching the layers
// after that.
if (this.options.rank === undefined) {
this.options.rank = this.getDOMOrder()
}
return this.options.rank
}
set rank(value) {
this.options.rank = value
}
getSyncMetadata() { getSyncMetadata() {
return { return {
subject: 'datalayer', subject: 'datalayer',
@ -130,6 +147,10 @@ export class DataLayer {
} }
render(fields, builder) { render(fields, builder) {
// Propagate will remove the fields it has already
// processed
fields = this.propagate(fields)
const impacts = Utils.getImpactsFromSchema(fields) const impacts = Utils.getImpactsFromSchema(fields)
for (const impact of impacts) { for (const impact of impacts) {
@ -149,10 +170,36 @@ export class DataLayer {
case 'remote-data': case 'remote-data':
this.fetchRemoteData() this.fetchRemoteData()
break break
case 'datalayer-rank':
this._umap.reorderDataLayers()
break
} }
} }
} }
// This method does a targeted update of the UI,
// it whould be merged with `render`` method and the
// SCHEMA at some point
propagate(fields = []) {
const impacts = {
'properties.name': () => {
Utils.eachElement('.datalayer-name', (el) => {
if (el.dataset.id === this.id) {
el.textContent = this.getName()
el.title = this.getName()
}
})
},
}
for (const [field, impact] of Object.entries(impacts)) {
if (!fields.length || fields.includes(field)) {
impact()
fields = fields.filter((item) => item !== field)
}
}
return fields
}
showAtLoad() { showAtLoad() {
return this.autoLoaded() && this.showAtZoom() return this.autoLoaded() && this.showAtZoom()
} }
@ -220,17 +267,11 @@ export class DataLayer {
this._loading = true this._loading = true
const [geojson, response, error] = await this._umap.server.get(this._dataUrl()) const [geojson, response, error] = await this._umap.server.get(this._dataUrl())
if (!error) { if (!error) {
this._umap.modifiedAt = response.headers.get('last-modified')
this.setReferenceVersion({ response, sync: false }) this.setReferenceVersion({ response, sync: false })
// FIXME: for now the _umap_options property is set dynamically from backend delete geojson._umap_options
// And thus it's not in the geojson file in the server
// So do not let all options to be reset
// Fix is a proper migration so all datalayers settings are
// in DB, and we remove it from geojson flat files.
if (geojson._umap_options) {
geojson._umap_options.editMode = this.options.editMode
}
// In case of maps pre 1.0 still around // In case of maps pre 1.0 still around
if (geojson._storage) geojson._storage.editMode = this.options.editMode delete geojson._storage
await this.fromUmapGeoJSON(geojson) await this.fromUmapGeoJSON(geojson)
this.backupOptions() this.backupOptions()
this._loading = false this._loading = false
@ -259,7 +300,6 @@ export class DataLayer {
async fromUmapGeoJSON(geojson) { async fromUmapGeoJSON(geojson) {
if (geojson._storage) geojson._umap_options = geojson._storage // Retrocompat if (geojson._storage) geojson._umap_options = geojson._storage // Retrocompat
geojson._umap_options.id = this.id
if (geojson._umap_options) this.setOptions(geojson._umap_options) if (geojson._umap_options) this.setOptions(geojson._umap_options)
if (this.isRemoteLayer()) { if (this.isRemoteLayer()) {
await this.fetchRemoteData() await this.fetchRemoteData()
@ -268,15 +308,6 @@ export class DataLayer {
} }
} }
clear() {
this.sync.startBatch()
for (const feature of Object.values(this._features)) {
feature.del()
}
this.sync.commitBatch()
this.dataChanged()
}
backupData() { backupData() {
if (this._geojson) { if (this._geojson) {
this._geojson_bk = Utils.CopyJSON(this._geojson) this._geojson_bk = Utils.CopyJSON(this._geojson)
@ -303,7 +334,10 @@ export class DataLayer {
async getUrl(url, initialUrl) { async getUrl(url, initialUrl) {
const response = await this._umap.request.get(url) const response = await this._umap.request.get(url)
return new Promise((resolve) => { return new Promise((resolve) => {
if (response?.ok) return resolve(response.text()) if (response?.ok) {
this._umap.modifiedAt = response.headers.get('last-modified')
return resolve(response.text())
}
Alert.error( Alert.error(
translate('Cannot load remote data for layer "{layer}" with url "{url}"', { translate('Cannot load remote data for layer "{layer}" with url "{url}"', {
layer: this.getName(), layer: this.getName(),
@ -324,7 +358,7 @@ export class DataLayer {
url = this._umap.proxyUrl(url, this.options.remoteData.ttl) url = this._umap.proxyUrl(url, this.options.remoteData.ttl)
} }
return await this.getUrl(url, remoteUrl).then((raw) => { return await this.getUrl(url, remoteUrl).then((raw) => {
this.clear() this.clear(false)
return this._umap.formatter return this._umap.formatter
.parse(raw, this.options.remoteData.format) .parse(raw, this.options.remoteData.format)
.then((geojson) => this.fromGeoJSON(geojson, false)) .then((geojson) => this.fromGeoJSON(geojson, false))
@ -364,12 +398,7 @@ export class DataLayer {
} }
connectToMap() { connectToMap() {
if (!this._umap.datalayers[this.id]) { this._umap.datalayers.add(this)
this._umap.datalayers[this.id] = this
}
if (!this._umap.datalayersIndex.includes(this)) {
this._umap.datalayersIndex.push(this)
}
this._umap.onDataLayersChanged() this._umap.onDataLayersChanged()
} }
@ -414,6 +443,10 @@ export class DataLayer {
removeFeature(feature, sync) { removeFeature(feature, sync) {
const id = stamp(feature) const id = stamp(feature)
// This feature was not yet added, may be after
// hitting Escape while drawing a new line or
// polygon, not yet valid (not enough points)
if (!this._index.includes(id)) return
if (sync !== false) { if (sync !== false) {
const oldValue = feature.toGeoJSON() const oldValue = feature.toGeoJSON()
feature.sync.delete(oldValue) feature.sync.delete(oldValue)
@ -484,8 +517,19 @@ export class DataLayer {
const features = [] const features = []
this.sortFeatures(collection) this.sortFeatures(collection)
for (const featureJson of collection) { for (const featureJson of collection) {
const feature = this.makeFeature(featureJson, sync) if (featureJson.geometry?.type === 'GeometryCollection') {
if (feature) features.push(feature) for (const geometry of featureJson.geometry.geometries) {
const feature = this.makeFeature({
type: 'Feature',
geometry,
properties: featureJson.properties,
})
if (feature) features.push(feature)
}
} else {
const feature = this.makeFeature(featureJson, sync)
if (feature) features.push(feature)
}
} }
return features return features
} }
@ -598,16 +642,33 @@ export class DataLayer {
del(sync = true) { del(sync = true) {
const oldValue = Utils.CopyJSON(this.umapGeoJSON()) const oldValue = Utils.CopyJSON(this.umapGeoJSON())
this.erase() // TODO merge datalayer del and features del in same
// batch
this.clear()
if (sync) { if (sync) {
this.isDeleted = true this.isDeleted = true
this.sync.delete(oldValue) this.sync.delete(oldValue)
} }
this.hide()
this.parentPane.removeChild(this.pane)
this._umap.onDataLayersChanged()
this.layer.onDelete(this._leafletMap)
this.propagateDelete()
this._leaflet_events_bk = this._leaflet_events
} }
empty() { empty() {
if (this.isRemoteLayer()) return if (this.isRemoteLayer()) return
this.sync.startBatch()
this.clear() this.clear()
this.sync.commitBatch()
}
clear(sync = true) {
for (const feature of Object.values(this._features)) {
feature.del(sync)
}
this.dataChanged()
} }
clone() { clone() {
@ -620,24 +681,13 @@ export class DataLayer {
return datalayer return datalayer
} }
erase() {
this.hide()
this._umap.datalayersIndex.splice(this.getRank(), 1)
this.parentPane.removeChild(this.pane)
this._umap.onDataLayersChanged()
this.layer.onDelete(this._leafletMap)
this.propagateDelete()
this._leaflet_events_bk = this._leaflet_events
this.clear()
}
redraw() { redraw() {
if (!this.isVisible()) return if (!this.isVisible()) return
this.eachFeature((feature) => feature.redraw()) this.eachFeature((feature) => feature.redraw())
} }
edit() { edit() {
if (!this._umap.editEnabled || !this.isLoaded()) { if (!this._umap.editEnabled) {
return return
} }
const container = DomUtil.create('div', 'umap-layer-properties-container') const container = DomUtil.create('div', 'umap-layer-properties-container')
@ -1045,23 +1095,11 @@ export class DataLayer {
} }
getPreviousBrowsable() { getPreviousBrowsable() {
let id = this.getRank() return this._umap.datalayers.prev(this)
let next
const index = this._umap.datalayersIndex
while (((id = index[++id] ? id : 0), (next = index[id]))) {
if (next === this || next.canBrowse()) break
}
return next
} }
getNextBrowsable() { getNextBrowsable() {
let id = this.getRank() return this._umap.datalayers.next(this)
let prev
const index = this._umap.datalayersIndex
while (((id = index[--id] ? id : index.length - 1), (prev = index[id]))) {
if (prev === this || prev.canBrowse()) break
}
return prev
} }
umapGeoJSON() { umapGeoJSON() {
@ -1072,8 +1110,8 @@ export class DataLayer {
} }
} }
getRank() { getDOMOrder() {
return this._umap.datalayersIndex.indexOf(this) return Array.from(this.parentPane.children).indexOf(this.pane)
} }
isReadOnly() { isReadOnly() {
@ -1095,15 +1133,21 @@ export class DataLayer {
} }
} }
prepareOptions() {
const options = Utils.CopyJSON(this.options)
delete options.permissions
return JSON.stringify(options)
}
async save() { async save() {
if (this.isDeleted) return await this.saveDelete() if (this.isDeleted) return await this.saveDelete()
if (!this.isLoaded()) return if (!this.isRemoteLayer() && !this.isLoaded()) return
const geojson = this.umapGeoJSON() const geojson = this.umapGeoJSON()
const formData = new FormData() const formData = new FormData()
formData.append('name', this.options.name) formData.append('name', this.options.name)
formData.append('display_on_load', !!this.options.displayOnLoad) formData.append('display_on_load', !!this.options.displayOnLoad)
formData.append('rank', this.getRank()) formData.append('rank', this.rank)
formData.append('settings', JSON.stringify(this.options)) formData.append('settings', this.prepareOptions())
// Filename support is shaky, don't do it for now. // Filename support is shaky, don't do it for now.
const blob = new Blob([JSON.stringify(geojson)], { type: 'application/json' }) const blob = new Blob([JSON.stringify(geojson)], { type: 'application/json' })
formData.append('geojson', blob) formData.append('geojson', blob)
@ -1138,12 +1182,15 @@ export class DataLayer {
await this._umap.saveAll() await this._umap.saveAll()
} }
) )
} else {
console.debug(error)
Alert.error(translate('Cannot save layer, please try again in a few minutes.'))
} }
} else { } else {
// Response contains geojson only if save has conflicted and conflicts have // Response contains geojson only if save has conflicted and conflicts have
// been resolved. So we need to reload to get extra data (added by someone else) // been resolved. So we need to reload to get extra data (added by someone else)
if (data.geojson) { if (data.geojson) {
this.clear() this.clear(false)
this.fromGeoJSON(data.geojson) this.fromGeoJSON(data.geojson)
delete data.geojson delete data.geojson
} }

View file

@ -24,7 +24,7 @@ export default class Facets {
this.selected[name] = selected this.selected[name] = selected
} }
this._umap.eachBrowsableDataLayer((datalayer) => { this._umap.datalayers.browsable().map((datalayer) => {
datalayer.eachFeature((feature) => { datalayer.eachFeature((feature) => {
for (const name of names) { for (const name of names) {
let value = feature.properties[name] let value = feature.properties[name]

View file

@ -560,7 +560,7 @@ Fields.SlideshowDelay = class extends Fields.IntSelect {
Fields.DataLayerSwitcher = class extends Fields.Select { Fields.DataLayerSwitcher = class extends Fields.Select {
getOptions() { getOptions() {
const options = [] const options = []
this.builder._umap.eachDataLayerReverse((datalayer) => { this.builder._umap.datalayers.reverse().map((datalayer) => {
if ( if (
datalayer.isLoaded() && datalayer.isLoaded() &&
!datalayer.isDataReadOnly() && !datalayer.isDataReadOnly() &&
@ -808,9 +808,10 @@ Fields.IconUrl = class extends Fields.BlurInput {
} }
addCategory(items, name) { addCategory(items, name) {
const hidden = name ? '' : ' hidden'
const [parent, { grid }] = Utils.loadTemplateWithRefs(` const [parent, { grid }] = Utils.loadTemplateWithRefs(`
<div class="umap-pictogram-category"> <div class="umap-pictogram-category">
<h6 hidden=${!name}>${name}</h6> <h6${hidden}>${name}</h6>
<div class="umap-pictogram-grid" data-ref=grid></div> <div class="umap-pictogram-grid" data-ref=grid></div>
</div> </div>
`) `)
@ -924,7 +925,8 @@ Fields.Url = class extends Fields.Input {
Fields.Switch = class extends Fields.CheckBox { Fields.Switch = class extends Fields.CheckBox {
getTemplate() { getTemplate() {
const label = this.properties.label const label = this.properties.label
return `${super.getTemplate()}<label title="${label}" for="${this.id}" data-ref=customLabel>${label}</label>` const help = this.properties.helpEntries?.join() || ''
return `${super.getTemplate()}<label title="${label}" for="${this.id}" data-ref=customLabel data-help="${help}">${label}</label>`
} }
build() { build() {

View file

@ -243,7 +243,7 @@ export default class Importer extends Utils.WithTemplate {
this.raw = null this.raw = null
const layerSelect = this.qs('[name="layer-id"]') const layerSelect = this.qs('[name="layer-id"]')
layerSelect.innerHTML = '' layerSelect.innerHTML = ''
this._umap.eachDataLayerReverse((datalayer) => { this._umap.datalayers.reverse().map((datalayer) => {
if (datalayer.isLoaded() && !datalayer.isRemoteLayer()) { if (datalayer.isLoaded() && !datalayer.isRemoteLayer()) {
DomUtil.element({ DomUtil.element({
tagName: 'option', tagName: 'option',

View file

@ -8,18 +8,20 @@ import { AutocompleteCommunes } from './communesfr.js'
const TEMPLATE = ` const TEMPLATE = `
<h3>Cadastre</h3> <h3>Cadastre</h3>
<p>Importer les données cadastrales dune commune française.</p> <p>Importer les données cadastrales dune commune française.</p>
<select name="theme"> <div class="formbox">
<option value="batiments">Bâtiments</option> <select name="theme">
<option value="communes">Communes</option> <option value="batiments">Bâtiments</option>
<option value="feuilles">Feuilles</option> <option value="communes">Communes</option>
<option value="lieux_dits">Lieux dits</option> <option value="feuilles">Feuilles</option>
<option value="parcelles" selected>Parcelles</option> <option value="lieux_dits">Lieux dits</option>
<option value="prefixes_sections">Préfixes sections</option> <option value="parcelles" selected>Parcelles</option>
<option value="sections">Sections</option> <option value="prefixes_sections">Préfixes sections</option>
<option value="subdivisions_fiscales">Subdivisions fiscales</option> <option value="sections">Sections</option>
</select> <option value="subdivisions_fiscales">Subdivisions fiscales</option>
<label id="boundary"> </select>
</label> <label id="boundary">
</label>
</div>
` `
export class Importer { export class Importer {

View file

@ -16,15 +16,17 @@ const BOUNDARY_TYPES = {
const TEMPLATE = ` const TEMPLATE = `
<h3>GeoDataMine</h3> <h3>GeoDataMine</h3>
<p>${translate('GeoDataMine: thematic data from OpenStreetMap')}.</p> <p>${translate('GeoDataMine: thematic data from OpenStreetMap')}.</p>
<select name="theme"> <div class="formbox">
<option value="">${translate('Choose a theme')}</option> <select name="theme">
</select> <option value="">${translate('Choose a theme')}</option>
<label> </select>
<input type="checkbox" name="aspoint" /> <label>
${translate('Symplify all geometries to points')} <input type="checkbox" name="aspoint" />
</label> ${translate('Simplify all geometries to points')}
<label id="boundary"> </label>
</label> <label id="boundary">
</label>
</div>
` `
class Autocomplete extends SingleMixin(BaseAjax) { class Autocomplete extends SingleMixin(BaseAjax) {

View file

@ -0,0 +1,46 @@
export class DataLayerManager extends Object {
add(datalayer) {
this[datalayer.id] = datalayer
}
active() {
return Object.values(this)
.filter((datalayer) => !datalayer.isDeleted)
.sort((a, b) => a.rank > b.rank)
}
reverse() {
return this.active().reverse()
}
count() {
return this.active().length
}
find(func) {
for (const datalayer of this.reverse()) {
if (func.call(datalayer, datalayer)) {
return datalayer
}
}
}
filter(func) {
return this.active().filter(func)
}
visible() {
return this.filter((datalayer) => datalayer.isVisible())
}
browsable() {
return this.reverse().filter((datalayer) => datalayer.allowBrowse())
}
prev(datalayer) {
const browsable = this.browsable()
const current = browsable.indexOf(datalayer)
const prev = browsable[current - 1] || browsable[browsable.length - 1]
if (!prev.canBrowse()) return this.prev(prev)
return prev
}
next(datalayer) {
const browsable = this.browsable()
const current = browsable.indexOf(datalayer)
const next = browsable[current + 1] || browsable[0]
if (!next.canBrowse()) return this.next(next)
return next
}
}

View file

@ -159,7 +159,7 @@ export class MapPermissions {
`<fieldset class="separator"><legend>${translate('Datalayers')}</legend></fieldset>` `<fieldset class="separator"><legend>${translate('Datalayers')}</legend></fieldset>`
) )
container.appendChild(fieldset) container.appendChild(fieldset)
this._umap.eachDataLayer((datalayer) => { this._umap.datalayers.active().map((datalayer) => {
datalayer.permissions.edit(fieldset) datalayer.permissions.edit(fieldset)
}) })
} }

View file

@ -0,0 +1,251 @@
import { Control } from '../../../vendors/leaflet/leaflet-src.esm.js'
import * as Utils from '../utils.js'
import { translate } from '../i18n.js'
export const HomeControl = Control.extend({
options: {
position: 'topleft',
},
onAdd: (map) => {
const path = map._umap.getStaticPathFor('home.svg')
const container = Utils.loadTemplate(
`<a href="/" class="home-button" title="${translate('Back to home')}"><img src="${path}" alt="${translate('Home logo')}" width="38px" height="38px" /></a>`
)
return container
},
})
export const EditControl = Control.extend({
options: {
position: 'topright',
},
onAdd: (map) => {
const template = `
<div class="edit-enable">
<button type="button" data-ref="button">${translate('Edit')}</button>
</div>
`
const [container, { button }] = Utils.loadTemplateWithRefs(template)
button.addEventListener('click', () => map._umap.enableEdit())
button.addEventListener('mouseover', () => {
map._umap.tooltip.open({
content: map._umap.help.displayLabel('TOGGLE_EDIT'),
anchor: button,
position: 'bottom',
delay: 750,
duration: 5000,
})
})
return container
},
})
export const MoreControl = Control.extend({
options: {
position: 'topleft',
},
onAdd: function (map) {
const pos = this.getPosition()
const corner = map._controlCorners[pos]
const className = 'umap-more-controls'
const template = `
<div class="umap-control-text">
<button class="umap-control-more" type="button" data-ref="button"></button>
</div>
`
const [container, { button }] = Utils.loadTemplateWithRefs(template)
button.addEventListener('click', () => corner.classList.toggle(className))
button.addEventListener('mouseover', () => {
const extended = corner.classList.contains(className)
map._umap.tooltip.open({
content: extended ? translate('Hide controls') : translate('More controls'),
anchor: button,
position: 'right',
delay: 750,
})
})
return container
},
})
export const PermanentCreditsControl = Control.extend({
options: {
position: 'bottomleft',
},
onAdd: (map) => {
const container = Utils.loadTemplate(
`<div class="umap-permanent-credits-container text">${Utils.toHTML(map.options.permanentCredit)}</div>`
)
const background = map.options.permanentCreditBackground ? '#FFFFFFB0' : ''
container.style.backgroundColor = background
return container
},
})
const BaseButton = Control.extend({
initialize: function (umap, options) {
this._umap = umap
Control.prototype.initialize.call(this, options)
},
onAdd: function (map) {
const template = `
<div class="${this.options.className} umap-control">
<button type="button" title="${this.options.title}" data-ref="button"></button>
</div>
`
const [container, { button }] = Utils.loadTemplateWithRefs(template)
button.addEventListener('click', (event) => {
event.stopPropagation()
this.onClick()
})
button.addEventListener('dblclick', (event) => {
event.stopPropagation()
})
this.afterAdd(container)
return container
},
afterAdd: (container) => {},
})
export const DataLayersControl = BaseButton.extend({
options: {
position: 'topleft',
className: 'umap-control-browse',
title: translate('Open browser'),
},
afterAdd: function (container) {
Utils.toggleBadge(container, this._umap.browser?.hasFilters())
},
onClick: function () {
this._umap.openBrowser()
},
})
export const CaptionControl = BaseButton.extend({
options: {
position: 'topleft',
className: 'umap-control-caption',
title: translate('About'),
},
onClick: function () {
this._umap.openCaption()
},
})
export const EmbedControl = BaseButton.extend({
options: {
position: 'topleft',
title: translate('Share and download'),
className: 'leaflet-control-embed',
},
onClick: function () {
this._umap.share.open()
},
})
export const AttributionControl = Control.Attribution.extend({
options: {
prefix: '',
},
_update: function () {
// Layer is no more on the map
if (!this._map) return
Control.Attribution.prototype._update.call(this)
const shortCredit = this._map._umap.getProperty('shortCredit')
const captionMenus = this._map._umap.getProperty('captionMenus')
// Use our own container, so we can hide/show on small screens
const originalCredits = this._container.innerHTML
this._container.innerHTML = ''
const template = `
<div class="attribution-container">
${originalCredits}
<span data-ref="short"> ${Utils.toHTML(shortCredit)}</span>
<a href="#" data-ref="caption"> ${translate('Open caption')}</a>
<a href="/" data-ref="home"> ${translate('Home')}</a>
<a href="https://umap-project.org/" data-ref="site"> ${translate('Powered by uMap')}</a>
<a href="#" class="attribution-toggle"></a>
</div>
`
const [container, { short, caption, home, site }] =
Utils.loadTemplateWithRefs(template)
caption.addEventListener('click', () => this._map._umap.openCaption())
this._container.appendChild(container)
short.hidden = !shortCredit
caption.hidden = !captionMenus
site.hidden = !captionMenus
home.hidden = this._map._umap.isEmbed || !captionMenus
},
})
/* Used in edit mode to define the default tilelayer */
export const TileLayerChooser = BaseButton.extend({
options: {
position: 'topleft',
},
onClick: function () {
this.openSwitcher({ edit: true })
},
openSwitcher: function (options = {}) {
const template = `
<div class="umap-edit-tilelayers">
<h3><i class="icon icon-16 icon-tilelayer" title=""></i><span class="">${translate('Change tilelayers')}</span></h3>
<ul data-ref="tileContainer"></ul>
</div>
`
const [container, { tileContainer }] = Utils.loadTemplateWithRefs(template)
this.buildList(tileContainer, options)
const panel = options.edit ? this._umap.editPanel : this._umap.panel
panel.open({ content: container, highlight: 'tilelayers' })
},
buildList: function (container, options) {
this._umap._leafletMap.eachTileLayer((tilelayer) => {
const browserIsHttps = window.location.protocol === 'https:'
const tileLayerIsHttp = tilelayer.options.url_template.indexOf('http:') === 0
if (browserIsHttps && tileLayerIsHttp) return
container.appendChild(this.addTileLayerElement(tilelayer, options))
})
},
addTileLayerElement: function (tilelayer, options) {
const selectedClass = this._umap._leafletMap.hasLayer(tilelayer) ? 'selected' : ''
const src = Utils.template(
tilelayer.options.url_template,
this._umap._leafletMap.options.demoTileInfos
)
const template = `
<li>
<img src="${src}" loading="lazy" />
<div>${tilelayer.options.name}</div>
</li>
`
const li = Utils.loadTemplate(template)
li.addEventListener('click', () => {
const oldTileLayer = this._umap.properties.tilelayer
this._umap._leafletMap.selectTileLayer(tilelayer)
this._umap._leafletMap._controls.tilelayers.setLayers()
if (options?.edit) {
this._umap.properties.tilelayer = tilelayer.toJSON()
this._umap.sync.update(
'properties.tilelayer',
this._umap.properties.tilelayer,
oldTileLayer
)
}
})
return li
},
})

View file

@ -41,6 +41,11 @@ export const Heat = L.HeatLayer.extend({
} }
}, },
removeLayer: (layer) => {
// No op, there is no "removeLatLng" in Leaflet.heat
// but this method is expected by DataLayer
},
onAdd: function (map) { onAdd: function (map) {
LayerMixin.onAdd.call(this, map) LayerMixin.onAdd.call(this, map)
return L.HeatLayer.prototype.onAdd.call(this, map) return L.HeatLayer.prototype.onAdd.call(this, map)

View file

@ -11,6 +11,17 @@ import {
import { uMapAlert as Alert } from '../../components/alerts/alert.js' import { uMapAlert as Alert } from '../../components/alerts/alert.js'
import DropControl from '../drop.js' import DropControl from '../drop.js'
import { translate } from '../i18n.js' import { translate } from '../i18n.js'
import {
AttributionControl,
CaptionControl,
DataLayersControl,
EmbedControl,
EditControl,
HomeControl,
MoreControl,
PermanentCreditsControl,
TileLayerChooser,
} from './controls.js'
import * as Utils from '../utils.js' import * as Utils from '../utils.js'
import * as Icon from './icon.js' import * as Icon from './icon.js'
@ -23,6 +34,7 @@ BaseMap.mergeOptions({
const ControlsMixin = { const ControlsMixin = {
HIDDABLE_CONTROLS: [ HIDDABLE_CONTROLS: [
'home',
'zoom', 'zoom',
'search', 'search',
'fullscreen', 'fullscreen',
@ -39,14 +51,15 @@ const ControlsMixin = {
this._controls = {} this._controls = {}
if (this._umap.hasEditMode() && !this.options.noControl) { if (this._umap.hasEditMode() && !this.options.noControl) {
new U.EditControl(this).addTo(this) new EditControl(this).addTo(this)
} }
this._controls.home = new HomeControl(this._umap)
this._controls.zoom = new Control.Zoom({ this._controls.zoom = new Control.Zoom({
zoomInTitle: translate('Zoom in'), zoomInTitle: translate('Zoom in'),
zoomOutTitle: translate('Zoom out'), zoomOutTitle: translate('Zoom out'),
}) })
this._controls.datalayers = new U.DataLayersControl(this._umap) this._controls.datalayers = new DataLayersControl(this._umap)
this._controls.caption = new U.CaptionControl(this._umap) this._controls.caption = new CaptionControl(this._umap)
this._controls.locate = new U.Locate(this, { this._controls.locate = new U.Locate(this, {
strings: { strings: {
title: translate('Center map on your location'), title: translate('Center map on your location'),
@ -67,8 +80,8 @@ const ControlsMixin = {
}, },
}) })
this._controls.search = new U.SearchControl() this._controls.search = new U.SearchControl()
this._controls.embed = new Control.Embed(this._umap) this._controls.embed = new EmbedControl(this._umap)
this._controls.tilelayersChooser = new U.TileLayerChooser(this) this._controls.tilelayersChooser = new TileLayerChooser(this._umap)
this._controls.editinosm = new Control.EditInOSM({ this._controls.editinosm = new Control.EditInOSM({
position: 'topleft', position: 'topleft',
widgetOptions: { widgetOptions: {
@ -78,9 +91,9 @@ const ControlsMixin = {
}, },
}) })
this._controls.measure = new L.MeasureControl().initHandler(this) this._controls.measure = new L.MeasureControl().initHandler(this)
this._controls.more = new U.MoreControls() this._controls.more = new MoreControl()
this._controls.scale = L.control.scale() this._controls.scale = L.control.scale()
this._controls.permanentCredit = new U.PermanentCreditsControl(this) this._controls.permanentCredit = new PermanentCreditsControl(this)
this._umap.drop = new DropControl(this._umap, this, this._container) this._umap.drop = new DropControl(this._umap, this, this._container)
this._controls.tilelayers = new U.TileLayerControl(this) this._controls.tilelayers = new U.TileLayerControl(this)
}, },
@ -91,11 +104,7 @@ const ControlsMixin = {
} }
if (this.options.noControl) return if (this.options.noControl) return
// Do not display in an iframe. this._controls.attribution = new AttributionControl().addTo(this)
if (window.self === window.top) {
this._controls.home = new U.HomeControl().addTo(this)
}
this._controls.attribution = new U.AttributionControl().addTo(this)
if (this.options.miniMap) { if (this.options.miniMap) {
this.whenReady(function () { this.whenReady(function () {
if (this.selectedTilelayer) { if (this.selectedTilelayer) {
@ -318,7 +327,7 @@ export const LeafletMap = BaseMap.extend({
} else if (this.options.defaultView === 'latest') { } else if (this.options.defaultView === 'latest') {
this._umap.onceDataLoaded(() => { this._umap.onceDataLoaded(() => {
if (!this._umap.hasData()) return if (!this._umap.hasData()) return
const datalayer = this._umap.firstVisibleDatalayer() const datalayer = this._umap.datalayers.visible()[0]
let feature let feature
if (datalayer) { if (datalayer) {
const feature = datalayer.getFeatureByIndex(-1) const feature = datalayer.getFeatureByIndex(-1)

View file

@ -109,9 +109,7 @@ const PointMixin = {
addInteractions() { addInteractions() {
FeatureMixin.addInteractions.call(this) FeatureMixin.addInteractions.call(this)
this.on('dragend', (event) => { this.on('dragend', (event) => {
this.isDirty = true
this.feature.edit(event) this.feature.edit(event)
// this.feature.pullGeometry(false)
}) })
if (!this.feature.isReadOnly()) this.on('mouseover', this._enableDragging) if (!this.feature.isReadOnly()) this.on('mouseover', this._enableDragging)
this.on('mouseout', this._onMouseOut) this.on('mouseout', this._onMouseOut)

View file

@ -1,4 +1,4 @@
import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.js' import { stamp } from '../../vendors/leaflet/leaflet-src.esm.js'
import { AutocompleteDatalist } from './autocomplete.js' import { AutocompleteDatalist } from './autocomplete.js'
import { MutatingForm } from './form/builder.js' import { MutatingForm } from './form/builder.js'
import { translate } from './i18n.js' import { translate } from './i18n.js'
@ -119,10 +119,9 @@ class Rule {
'options.smoothFactor', 'options.smoothFactor',
'options.dashArray', 'options.dashArray',
] ]
const container = DomUtil.create('div')
const builder = new MutatingForm(this, options) const builder = new MutatingForm(this, options)
const defaultShapeProperties = DomUtil.add('div', '', container) const container = document.createElement('div')
defaultShapeProperties.appendChild(builder.build()) container.appendChild(builder.build())
const autocomplete = new AutocompleteDatalist(builder.helpers.condition.input) const autocomplete = new AutocompleteDatalist(builder.helpers.condition.input)
const properties = this._umap.allProperties() const properties = this._umap.allProperties()
autocomplete.suggestions = properties autocomplete.suggestions = properties
@ -137,43 +136,45 @@ class Rule {
.map((str) => `${value}${str || ''}`) .map((str) => `${value}${str || ''}`)
} }
}) })
this._umap.editPanel.open({ content: container, highlight: 'settings' }) const backButton = Utils.loadTemplate(`
<button class="flat" type="button" data-ref="add">
<i class="icon icon-16 icon-back" title="${translate('Back to list')}"></i>
</button>`)
backButton.addEventListener('click', () =>
this._umap.edit().then(() => {
this._umap.editPanel.container.querySelector('details#rules').open = true
})
)
this._umap.editPanel.open({
content: container,
highlight: 'settings',
actions: [backButton],
})
} }
renderToolbox(row) { renderToolbox(ul) {
row.classList.toggle('off', !this.active) const template = `
const toggle = DomUtil.createButtonIcon( <li data-id="${stamp(this)}" class="orderable">
row, <button class="icon icon-16 icon-eye" title="${translate('Toggle rule')}" data-ref=toggle></button>
'icon-eye', <button class="icon icon-16 icon-edit show-on-edit" title="${translate('Edit')}" data-ref=edit></button>
translate('Show/hide layer') <button class="icon icon-16 icon-delete show-on-edit" title="${translate('Delete rule')}" data-ref=remove></button>
) <span>${this.condition || translate('empty rule')}</span>
const edit = DomUtil.createButtonIcon( <i class="icon icon-16 icon-drag" title="${translate('Drag to reorder')}"></i>
row, </li>
'icon-edit show-on-edit', `
translate('Edit') const [li, { toggle, edit, remove }] = Utils.loadTemplateWithRefs(template)
) ul.appendChild(li)
const remove = DomUtil.createButtonIcon( li.classList.toggle('off', !this.active)
row, edit.addEventListener('click', () => this.edit())
'icon-delete show-on-edit', remove.addEventListener('click', () => {
translate('Delete layer') if (!confirm(translate('Are you sure you want to delete this rule?'))) return
) this._delete()
DomEvent.on(edit, 'click', this.edit, this) this._umap.editPanel.close()
DomEvent.on( })
remove, toggle.addEventListener('click', () => {
'click',
function () {
if (!confirm(translate('Are you sure you want to delete this rule?'))) return
this._delete()
this._umap.editPanel.close()
},
this
)
DomUtil.add('span', '', row, this.condition || translate('empty rule'))
DomUtil.createIcon(row, 'icon-drag', translate('Drag to reorder'))
row.dataset.id = stamp(this)
DomEvent.on(toggle, 'click', () => {
this.active = !this.active this.active = !this.active
row.classList.toggle('off', !this.active) li.classList.toggle('off', !this.active)
this._umap.render(['rules']) this._umap.render(['rules'])
}) })
} }
@ -207,8 +208,9 @@ export default class Rules {
} }
onReorder(src, dst, initialIndex, finalIndex) { onReorder(src, dst, initialIndex, finalIndex) {
const moved = this.rules.find((rule) => stamp(rule) === src.dataset.id) const oldRules = Utils.CopyJSON(this._umap.properties.rules || {})
const reference = this.rules.find((rule) => stamp(rule) === dst.dataset.id) const moved = this.rules.find((rule) => stamp(rule) === +src.dataset.id)
const reference = this.rules.find((rule) => stamp(rule) === +dst.dataset.id)
const movedIdx = this.rules.indexOf(moved) const movedIdx = this.rules.indexOf(moved)
let referenceIdx = this.rules.indexOf(reference) let referenceIdx = this.rules.indexOf(reference)
const minIndex = Math.min(movedIdx, referenceIdx) const minIndex = Math.min(movedIdx, referenceIdx)
@ -222,20 +224,28 @@ export default class Rules {
this.rules.splice(newIdx, 0, moved) this.rules.splice(newIdx, 0, moved)
this._umap.render(['rules']) this._umap.render(['rules'])
this.commit() this.commit()
this._umap.sync.update('properties.rules', this._umap.properties.rules, oldRules)
} }
edit(container) { edit(container) {
const body = DomUtil.createFieldset(container, translate('Conditional style rules')) const template = `
<details id="rules">
<summary>${translate('Conditional style rules')}</summary>
<fieldset>
<ul data-ref=ul></ul>
<button class="umap-add" type="button" data-ref=add>${translate('Add rule')}</button>
</fieldset>
</details>
`
const [body, { ul, add }] = Utils.loadTemplateWithRefs(template)
if (this.rules.length) { if (this.rules.length) {
const ul = DomUtil.create('ul', '', body)
for (const rule of this.rules) { for (const rule of this.rules) {
rule.renderToolbox(DomUtil.create('li', 'orderable', ul)) rule.renderToolbox(ul)
} }
const orderable = new Orderable(ul, this.onReorder.bind(this)) const orderable = new Orderable(ul, this.onReorder.bind(this))
} }
add.addEventListener('click', () => this.addRule())
DomUtil.createButton('umap-add', body, translate('Add rule'), this.addRule, this) container.appendChild(body)
} }
addRule() { addRule() {

View file

@ -10,7 +10,7 @@ import { translate } from './i18n.js'
* - `type`: The type of the data * - `type`: The type of the data
* - `impacts`: A list of impacts than happen when this property is updated, among * - `impacts`: A list of impacts than happen when this property is updated, among
* 'ui', 'data', 'limit-bounds', 'datalayer-index', 'remote-data', * 'ui', 'data', 'limit-bounds', 'datalayer-index', 'remote-data',
* 'background' 'sync'. * 'background', 'sync', 'datalayer-rank'.
* *
* - Extra keys are being passed to the FormBuilder automatically. * - Extra keys are being passed to the FormBuilder automatically.
*/ */
@ -204,6 +204,12 @@ export const SCHEMA = {
type: Object, type: Object,
impacts: ['data'], impacts: ['data'],
}, },
homeControl: {
type: Boolean,
impacts: ['ui'],
label: translate('Display the back to home icon'),
default: true,
},
iconClass: { iconClass: {
type: String, type: String,
impacts: ['data'], impacts: ['data'],
@ -275,6 +281,12 @@ export const SCHEMA = {
label: translate('Label key'), label: translate('Label key'),
inheritable: true, inheritable: true,
}, },
layerSwitcher: {
type: Boolean,
impacts: ['ui'],
label: translate('Do you want to display layer switcher in caption bar?'),
default: true,
},
licence: { licence: {
type: String, type: String,
impacts: ['ui'], impacts: ['ui'],
@ -424,6 +436,10 @@ export const SCHEMA = {
], ],
default: 'Default', default: 'Default',
}, },
rank: {
type: Number,
impacts: ['datalayer-rank'],
},
remoteData: { remoteData: {
type: Object, type: Object,
impacts: ['remote-data'], impacts: ['remote-data'],

View file

@ -204,8 +204,8 @@ class IframeExporter {
delete this.queryString.feature delete this.queryString.feature
} }
if (this.options.keepCurrentDatalayers) { if (this.options.keepCurrentDatalayers) {
this._umap.eachDataLayer((datalayer) => { this._umap.datalayers.visible().map((datalayer) => {
if (datalayer.isVisible() && datalayer.createdOnServer) { if (datalayer.createdOnServer) {
datalayers.push(datalayer.id) datalayers.push(datalayer.id)
} }
}) })

View file

@ -66,7 +66,7 @@ export default class Slideshow extends WithTemplate {
} }
defaultDatalayer() { defaultDatalayer() {
return this._umap.findDataLayer((d) => d.canBrowse()) return this._umap.datalayers.find((d) => d.canBrowse())
} }
startSpinner() { startSpinner() {

View file

@ -207,31 +207,45 @@ export class SyncEngine {
this._send(operation) this._send(operation)
} }
async save() { _getDirtyObjects() {
const needSave = new Map() const dirty = new Map()
if (!this._umap.id) { if (!this._umap.id) {
// There is no operation for first map save // There is no operation for first map save
needSave.set(this._umap, []) dirty.set(this._umap, [])
}
const addDirtyObject = (operation) => {
const updater = this._getUpdater(operation.subject)
const obj = updater.getStoredObject(operation.metadata)
if (!dirty.has(obj)) {
dirty.set(obj, [])
}
dirty.get(obj).push(operation)
} }
for (const operation of this._operations.sorted()) { for (const operation of this._operations.sorted()) {
if (operation.dirty) { if (operation.dirty) {
const updater = this._getUpdater(operation.subject) addDirtyObject(operation)
const obj = updater.getStoredObject(operation.metadata) if (operation.verb === 'batch') {
if (!needSave.has(obj)) { for (const op of operation.operations) {
needSave.set(obj, []) addDirtyObject(op)
}
} }
needSave.get(obj).push(operation)
} }
} }
return dirty
}
async save() {
const needSave = this._getDirtyObjects()
for (const [obj, operations] of needSave.entries()) { for (const [obj, operations] of needSave.entries()) {
const ok = await obj.save() const ok = await obj.save()
if (!ok) break if (!ok) return false
for (const operation of operations) { for (const operation of operations) {
operation.dirty = false operation.dirty = false
} }
} }
this.saved() this.saved()
this._undoManager.toggleState() this._undoManager.toggleState()
return true
} }
saved() { saved() {

View file

@ -180,7 +180,7 @@ const BOTTOM_BAR_TEMPLATE = `
<button class="umap-about-link flat" type="button" title="${translate('Open caption')}" data-ref="caption">${translate('Open caption')}</button> <button class="umap-about-link flat" type="button" title="${translate('Open caption')}" data-ref="caption">${translate('Open caption')}</button>
<button class="umap-open-browser-link flat" type="button" title="${translate('Browse data')}" data-ref="browse">${translate('Browse data')}</button> <button class="umap-open-browser-link flat" type="button" title="${translate('Browse data')}" data-ref="browse">${translate('Browse data')}</button>
<button class="umap-open-browser-link flat" type="button" title="${translate('Filter data')}" data-ref="filter">${translate('Filter data')}</button> <button class="umap-open-browser-link flat" type="button" title="${translate('Filter data')}" data-ref="filter">${translate('Filter data')}</button>
<select data-ref=layers></select> <select data-ref="layers"></select>
</div> </div>
` `
@ -207,7 +207,7 @@ export class BottomBar extends WithTemplate {
const select = this.elements.layers const select = this.elements.layers
const selected = select.options[select.selectedIndex].value const selected = select.options[select.selectedIndex].value
if (!selected) return if (!selected) return
this._umap.eachDataLayer((datalayer) => { this._umap.datalayers.active().map((datalayer) => {
datalayer.toggle(datalayer.id === selected) datalayer.toggle(datalayer.id === selected)
}) })
}) })
@ -228,12 +228,12 @@ export class BottomBar extends WithTemplate {
buildDataLayerSwitcher() { buildDataLayerSwitcher() {
this.elements.layers.innerHTML = '' this.elements.layers.innerHTML = ''
const datalayers = this._umap.datalayersIndex.filter((d) => d.options.inCaption) const datalayers = this._umap.datalayers.filter((d) => d.options.inCaption)
if (datalayers.length < 2) { if (datalayers.length < 2) {
this.elements.layers.hidden = true this.elements.layers.hidden = true
} else { } else {
this.elements.layers.appendChild(Utils.loadTemplate(`<option value=""></option>`)) this.elements.layers.appendChild(Utils.loadTemplate(`<option value=""></option>`))
this.elements.layers.hidden = false this.elements.layers.hidden = !this._umap.getProperty('layerSwitcher')
const visible = datalayers.filter((datalayer) => datalayer.isVisible()) const visible = datalayers.filter((datalayer) => datalayer.isVisible())
for (const datalayer of datalayers) { for (const datalayer of datalayers) {
const selected = visible.length === 1 && datalayer.isVisible() ? 'selected' : '' const selected = visible.length === 1 && datalayer.isVisible() ? 'selected' : ''

View file

@ -4,6 +4,8 @@ export class Positioned {
this.anchorTop(anchor) this.anchorTop(anchor)
} else if (anchor && position === 'bottom') { } else if (anchor && position === 'bottom') {
this.anchorBottom(anchor) this.anchorBottom(anchor)
} else if (anchor && position === 'right') {
this.anchorRight(anchor)
} else { } else {
this.anchorAbsolute() this.anchorAbsolute()
} }
@ -12,6 +14,7 @@ export class Positioned {
toggleClassPosition(position) { toggleClassPosition(position) {
this.container.classList.toggle('tooltip-bottom', position === 'bottom') this.container.classList.toggle('tooltip-bottom', position === 'bottom')
this.container.classList.toggle('tooltip-top', position === 'top') this.container.classList.toggle('tooltip-top', position === 'top')
this.container.classList.toggle('tooltip-right', position === 'right')
} }
anchorTop(el) { anchorTop(el) {
@ -33,6 +36,16 @@ export class Positioned {
}) })
} }
anchorRight(el) {
this.toggleClassPosition('right')
const coords = this.getPosition(el)
console.log(coords)
this.setPosition({
left: coords.right + 11,
top: coords.top,
})
}
anchorAbsolute() { anchorAbsolute() {
const left = const left =
this.parent.offsetLeft + this.parent.offsetLeft +

View file

@ -33,6 +33,7 @@ import { EditPanel, FullPanel, Panel } from './ui/panel.js'
import Tooltip from './ui/tooltip.js' import Tooltip from './ui/tooltip.js'
import URLs from './urls.js' import URLs from './urls.js'
import * as Utils from './utils.js' import * as Utils from './utils.js'
import { DataLayerManager } from './managers.js'
export default class Umap { export default class Umap {
constructor(element, geojson) { constructor(element, geojson) {
@ -57,6 +58,8 @@ export default class Umap {
}, },
geojson.properties geojson.properties
) )
this.createdAt = new Date(this.properties.created_at)
this.modifiedAt = this.properties.modified_at
this.searchParams = new URLSearchParams(window.location.search) this.searchParams = new URLSearchParams(window.location.search)
// Locale name (pt_PT, en_US…) // Locale name (pt_PT, en_US…)
@ -104,6 +107,11 @@ export default class Umap {
if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema) if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema)
// Do not display in an iframe.
if (this.isEmbed) {
this.properties.homeControl = false
}
this._leafletMap.setup() this._leafletMap.setup()
this.panel = new Panel(this, this._leafletMap) this.panel = new Panel(this, this._leafletMap)
@ -159,8 +167,7 @@ export default class Umap {
} }
// Global storage for retrieving datalayers and features. // Global storage for retrieving datalayers and features.
this.datalayers = {} // All datalayers, including deleted. this.datalayers = new DataLayerManager()
this.datalayersIndex = [] // Datalayers actually on the map and ordered.
this.featuresIndex = {} this.featuresIndex = {}
this.formatter = new Formatter(this) this.formatter = new Formatter(this)
@ -210,7 +217,6 @@ export default class Umap {
} }
window.onbeforeunload = () => (this.editEnabled && this.isDirty) || null window.onbeforeunload = () => (this.editEnabled && this.isDirty) || null
this.backup()
} }
get isDirty() { get isDirty() {
@ -237,6 +243,24 @@ export default class Umap {
this._activeFeature = feature this._activeFeature = feature
} }
get modifiedAt() {
return this._modifiedAt
}
set modifiedAt(at) {
if (!at) return
if (typeof at === 'string') {
at = new Date(at)
}
if (!this._modifiedAt || at > this._modifiedAt) {
this._modifiedAt = at
}
}
get isEmbed() {
return window.self !== window.top
}
setPropertiesFromQueryString() { setPropertiesFromQueryString() {
const asBoolean = (key) => { const asBoolean = (key) => {
const value = this.searchParams.get(key) const value = this.searchParams.get(key)
@ -525,7 +549,6 @@ export default class Umap {
'Ctrl+e': { 'Ctrl+e': {
if: () => this.hasEditMode(), if: () => this.hasEditMode(),
do: () => { do: () => {
console.log('doing')
if (!this.editEnabled) this.enableEdit() if (!this.editEnabled) this.enableEdit()
else if (!this.isDirty) this.disableEdit() else if (!this.isDirty) this.disableEdit()
}, },
@ -592,7 +615,7 @@ export default class Umap {
this.datalayersLoaded = true this.datalayersLoaded = true
this.fire('datalayersloaded') this.fire('datalayersloaded')
const toLoad = [] const toLoad = []
for (const datalayer of this.datalayersIndex) { for (const datalayer of this.datalayers.active()) {
if (datalayer.showAtLoad()) toLoad.push(() => datalayer.show()) if (datalayer.showAtLoad()) toLoad.push(() => datalayer.show())
} }
while (toLoad.length) { while (toLoad.length) {
@ -606,7 +629,7 @@ export default class Umap {
createDataLayer(options = {}, sync = true) { createDataLayer(options = {}, sync = true) {
options.name = options.name =
options.name || `${translate('Layer')} ${this.datalayersIndex.length + 1}` options.name || `${translate('Layer')} ${this.datalayers.count() + 1}`
const datalayer = new DataLayer(this, this._leafletMap, options) const datalayer = new DataLayer(this, this._leafletMap, options)
if (sync !== false) { if (sync !== false) {
@ -617,7 +640,6 @@ export default class Umap {
createDirtyDataLayer(options) { createDirtyDataLayer(options) {
const datalayer = this.createDataLayer(options, true) const datalayer = this.createDataLayer(options, true)
datalayer.isDirty = true
return datalayer return datalayer
} }
@ -627,19 +649,19 @@ export default class Umap {
} }
reindexDataLayers() { reindexDataLayers() {
this.eachDataLayer((datalayer) => datalayer.reindex()) this.datalayers.active().map((datalayer) => datalayer.reindex())
this.onDataLayersChanged() this.onDataLayersChanged()
} }
indexDatalayers() { reorderDataLayers() {
const panes = this._leafletMap.getPane('overlayPane') const parent = this._leafletMap.getPane('overlayPane')
const datalayers = Object.values(this.datalayers)
this.datalayersIndex = [] .filter((datalayer) => !datalayer._isDeleted)
for (const pane of panes.children) { .sort((datalayer1, datalayer2) => datalayer1.rank > datalayer2.rank)
if (!pane.dataset || !pane.dataset.id) continue for (const datalayer of datalayers) {
this.datalayersIndex.push(this.datalayers[pane.dataset.id]) const child = parent.querySelector(`[data-id="${datalayer.id}"]`)
parent.appendChild(child)
} }
this.onDataLayersChanged()
} }
onceDatalayersLoaded(callback, context) { onceDatalayersLoaded(callback, context) {
@ -670,8 +692,8 @@ export default class Umap {
async saveAll() { async saveAll() {
if (!this.isDirty) return if (!this.isDirty) return
if (this._defaultExtent) this._setCenterAndZoom() if (this._defaultExtent) this._setCenterAndZoom()
this.backup() const status = await this.sync.save()
await this.sync.save() if (!status) return
// Do a blind render for now, as we are not sure what could // Do a blind render for now, as we are not sure what could
// have changed, we'll be more subtil when we'll remove the // have changed, we'll be more subtil when we'll remove the
// save action // save action
@ -689,24 +711,6 @@ export default class Umap {
return this.properties.name || translate('Untitled map') return this.properties.name || translate('Untitled map')
} }
backup() {
this.backupProperties()
this._datalayersIndex_bk = [].concat(this.datalayersIndex)
}
backupProperties() {
this._backupProperties = Object.assign({}, this.properties)
this._backupProperties.tilelayer = Object.assign({}, this.properties.tilelayer)
this._backupProperties.limitBounds = Object.assign({}, this.properties.limitBounds)
this._backupProperties.permissions = Object.assign({}, this.permissions.properties)
}
resetProperties() {
this.properties = Object.assign({}, this._backupProperties)
this.properties.tilelayer = Object.assign({}, this._backupProperties.tilelayer)
this.permissions.properties = Object.assign({}, this._backupProperties.permissions)
}
setProperties(newProperties) { setProperties(newProperties) {
for (const key of Object.keys(SCHEMA)) { for (const key of Object.keys(SCHEMA)) {
if (newProperties[key] !== undefined) { if (newProperties[key] !== undefined) {
@ -719,24 +723,24 @@ export default class Umap {
} }
hasData() { hasData() {
for (const datalayer of this.datalayersIndex) { for (const datalayer of this.datalayers.active()) {
if (datalayer.hasData()) return true if (datalayer.hasData()) return true
} }
} }
hasLayers() { hasLayers() {
return Boolean(this.datalayersIndex.length) return Boolean(this.datalayers.count())
} }
allProperties() { allProperties() {
return [].concat(...this.datalayersIndex.map((dl) => dl.allProperties())) return [].concat(...this.datalayers.active().map((dl) => dl.allProperties()))
} }
sortedValues(property) { sortedValues(property) {
return [] return []
.concat(...this.datalayersIndex.map((dl) => dl.sortedValues(property))) .concat(...this.datalayers.active().map((dl) => dl.sortedValues(property)))
.filter((val, idx, arr) => arr.indexOf(val) === idx) .filter((val, idx, arr) => arr.indexOf(val) === idx)
.sort(U.Utils.naturalSort) .sort(Utils.naturalSort)
} }
editCaption() { editCaption() {
@ -799,7 +803,7 @@ export default class Umap {
`<button type="button">${translate('Use current center and zoom')}</button>` `<button type="button">${translate('Use current center and zoom')}</button>`
) )
button.addEventListener('click', () => { button.addEventListener('click', () => {
this._setCenterAndZoom() this.setCenterAndZoom()
builder.fetchAll() builder.fetchAll()
}) })
container.appendChild(form) container.appendChild(form)
@ -821,6 +825,7 @@ export default class Umap {
'properties.displayPopupFooter', 'properties.displayPopupFooter',
'properties.captionBar', 'properties.captionBar',
'properties.captionMenus', 'properties.captionMenus',
'properties.layerSwitcher',
]) ])
const builder = new MutatingForm(this, UIFields, { umap: this }) const builder = new MutatingForm(this, UIFields, { umap: this })
const controlsOptions = DomUtil.createFieldset( const controlsOptions = DomUtil.createFieldset(
@ -1156,7 +1161,7 @@ export default class Umap {
} }
this._advancedActions(container) this._advancedActions(container)
this.editPanel.open({ return this.editPanel.open({
content: container, content: container,
className: 'dark', className: 'dark',
highlight: 'settings', highlight: 'settings',
@ -1210,12 +1215,8 @@ export default class Umap {
}) })
} }
} else { } else {
if (!this.permissions.isDirty) { this.permissions.setProperties(data.permissions)
// Do not override local changes to permissions, this.permissions.commit()
// but update in case some other editors changed them in the meantime.
this.permissions.setProperties(data.permissions)
this.permissions.commit()
}
this._leafletMap.once('saved', () => { this._leafletMap.once('saved', () => {
Alert.success(data.info || translate('Map has been saved!')) Alert.success(data.info || translate('Map has been saved!'))
}) })
@ -1252,7 +1253,7 @@ export default class Umap {
toGeoJSON() { toGeoJSON() {
let features = [] let features = []
this.eachDataLayer((datalayer) => { this.datalayers.active().map((datalayer) => {
if (datalayer.isVisible()) { if (datalayer.isVisible()) {
features = features.concat(datalayer.featuresToGeoJSON()) features = features.concat(datalayer.featuresToGeoJSON())
} }
@ -1328,13 +1329,20 @@ export default class Umap {
if (fields.includes('properties.rules')) { if (fields.includes('properties.rules')) {
this.rules.load() this.rules.load()
} }
this.eachVisibleDataLayer((datalayer) => { this.datalayers.visible().map((datalayer) => {
datalayer.redraw() datalayer.redraw()
}) })
break break
case 'datalayer-index': case 'datalayer-index':
this.reindexDataLayers() this.reindexDataLayers()
break break
case 'datalayer-rank':
// When drag'n'dropping datalayers,
// this get called once per datalayers.
// (and same for undo/redo of the action)
// TODO: call only once
this.reorderDataLayers()
break
case 'background': case 'background':
this._leafletMap.initTileLayers() this._leafletMap.initTileLayers()
break break
@ -1423,7 +1431,7 @@ export default class Umap {
) { ) {
return datalayer return datalayer
} }
datalayer = this.findDataLayer((datalayer) => { datalayer = this.datalayers.find((datalayer) => {
if (!datalayer.isDataReadOnly() && datalayer.isBrowsable()) { if (!datalayer.isDataReadOnly() && datalayer.isBrowsable()) {
fallback = datalayer fallback = datalayer
if (datalayer.isVisible()) return true if (datalayer.isVisible()) return true
@ -1438,61 +1446,37 @@ export default class Umap {
return this.createDirtyDataLayer() return this.createDirtyDataLayer()
} }
findDataLayer(method, context) { eachFeature(callback) {
for (let i = this.datalayersIndex.length - 1; i >= 0; i--) { this.datalayers.browsable().map((datalayer) => {
if (method.call(context, this.datalayersIndex[i])) { if (datalayer.isVisible()) datalayer.eachFeature(callback)
return this.datalayersIndex[i]
}
}
}
eachDataLayer(method, context) {
for (let i = 0; i < this.datalayersIndex.length; i++) {
method.call(context, this.datalayersIndex[i])
}
}
eachDataLayerReverse(method, context, filter) {
for (let i = this.datalayersIndex.length - 1; i >= 0; i--) {
if (filter && !filter.call(context, this.datalayersIndex[i])) continue
method.call(context, this.datalayersIndex[i])
}
}
eachBrowsableDataLayer(method, context) {
this.eachDataLayerReverse(method, context, (d) => d.allowBrowse())
}
eachVisibleDataLayer(method, context) {
this.eachDataLayerReverse(method, context, (d) => d.isVisible())
}
eachFeature(callback, context) {
this.eachBrowsableDataLayer((datalayer) => {
if (datalayer.isVisible()) datalayer.eachFeature(callback, context)
}) })
} }
removeDataLayers() { removeDataLayers() {
this.eachDataLayerReverse((datalayer) => { this.datalayers.active().map((datalayer) => {
datalayer.del() datalayer.del()
}) })
} }
emptyDataLayers() { emptyDataLayers() {
this.eachDataLayerReverse((datalayer) => { this.datalayers.active().map((datalayer) => {
datalayer.empty() datalayer.empty()
}) })
} }
editDatalayers() { editDatalayers() {
if (!this.editEnabled) return if (!this.editEnabled) return
const container = DomUtil.create('div') const template = `
DomUtil.createTitle(container, translate('Manage layers'), 'icon-layers') <div>
const ul = DomUtil.create('ul', '', container) <h3><i class="icon icon-16 icon-layers"></i>${translate('Manage layers')}</h3>
this.eachDataLayerReverse((datalayer) => { <ul data-ref=ul></ul>
const row = DomUtil.create('li', 'orderable', ul) </div>
DomUtil.createIcon(row, 'icon-drag', translate('Drag to reorder')) `
const [container, { ul }] = Utils.loadTemplateWithRefs(template)
this.datalayers.reverse().map((datalayer) => {
const row = Utils.loadTemplate(
`<li class="orderable"><i class="icon icon-16 icon-drag" title="${translate('Drag to reorder')}"></i></li>`
)
datalayer.renderToolbox(row) datalayer.renderToolbox(row)
const builder = new MutatingForm( const builder = new MutatingForm(
datalayer, datalayer,
@ -1503,20 +1487,27 @@ export default class Umap {
row.appendChild(form) row.appendChild(form)
row.classList.toggle('off', !datalayer.isVisible()) row.classList.toggle('off', !datalayer.isVisible())
row.dataset.id = datalayer.id row.dataset.id = datalayer.id
ul.appendChild(row)
}) })
const onReorder = (src, dst, initialIndex, finalIndex) => { const onReorder = (src, dst, initialIndex, finalIndex) => {
const movedLayer = this.datalayers[src.dataset.id] const movedLayer = this.datalayers[src.dataset.id]
const targetLayer = this.datalayers[dst.dataset.id] const targetLayer = this.datalayers[dst.dataset.id]
const minIndex = Math.min(movedLayer.getRank(), targetLayer.getRank()) const minIndex = Math.min(movedLayer.getDOMOrder(), targetLayer.getDOMOrder())
const maxIndex = Math.max(movedLayer.getRank(), targetLayer.getRank()) const maxIndex = Math.max(movedLayer.getDOMOrder(), targetLayer.getDOMOrder())
if (finalIndex === 0) movedLayer.bringToTop() if (finalIndex === 0) movedLayer.bringToTop()
else if (finalIndex > initialIndex) movedLayer.insertBefore(targetLayer) else if (finalIndex > initialIndex) movedLayer.insertBefore(targetLayer)
else movedLayer.insertAfter(targetLayer) else movedLayer.insertAfter(targetLayer)
this.eachDataLayerReverse((datalayer) => { this.sync.startBatch()
if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex) this.datalayers.reverse().map((datalayer) => {
datalayer.isDirty = true const rank = datalayer.getDOMOrder()
if (rank >= minIndex && rank <= maxIndex) {
const oldRank = datalayer.rank
datalayer.rank = rank
datalayer.sync.update('options.rank', rank, oldRank)
}
}) })
this.indexDatalayers() this.sync.commitBatch()
this.onDataLayersChanged()
} }
const orderable = new Orderable(ul, onReorder) const orderable = new Orderable(ul, onReorder)
@ -1538,18 +1529,6 @@ export default class Umap {
return datalayer return datalayer
} }
firstVisibleDatalayer() {
return this.findDataLayer((datalayer) => {
if (datalayer.isVisible()) return true
})
}
ensurePanesOrder() {
this.eachDataLayer((datalayer) => {
datalayer.bringToTop()
})
}
openBrowser(mode) { openBrowser(mode) {
this.onceDatalayersLoaded(() => this.browser.open(mode)) this.onceDatalayersLoaded(() => this.browser.open(mode))
} }
@ -1700,7 +1679,7 @@ export default class Umap {
getLayersBounds() { getLayersBounds() {
const bounds = new latLngBounds() const bounds = new latLngBounds()
this.eachBrowsableDataLayer((d) => { this.datalayers.browsable().map((d) => {
if (d.isVisible()) bounds.extend(d.layer.getBounds()) if (d.isVisible()) bounds.extend(d.layer.getBounds())
}) })
return bounds return bounds

View file

@ -283,6 +283,8 @@ export function greedyTemplate(str, data, ignore) {
} }
export function naturalSort(a, b, lang) { export function naturalSort(a, b, lang) {
a ??= ''
b ??= ''
return a return a
.toString() .toString()
.toLowerCase() .toLowerCase()

View file

@ -1,183 +1,3 @@
U.HomeControl = L.Control.extend({
options: {
position: 'topleft',
},
onAdd: (map) => {
const path = map._umap.getStaticPathFor('home.svg')
const container = U.Utils.loadTemplate(
`<a href="/" class="home-button" title="${L._('Back to home')}"><img src="${path}" alt="${L._('Home logo')}" width="38px" height="38px" /></a>`
)
return container
},
})
U.EditControl = L.Control.extend({
options: {
position: 'topright',
},
onAdd: function (map) {
const container = L.DomUtil.create('div', 'edit-enable')
const enableEditing = L.DomUtil.createButton(
'',
container,
L._('Edit'),
map._umap.enableEdit,
map._umap
)
L.DomEvent.on(
enableEditing,
'mouseover',
() => {
map._umap.tooltip.open({
content: map._umap.help.displayLabel('TOGGLE_EDIT'),
anchor: enableEditing,
position: 'bottom',
delay: 750,
duration: 5000,
})
},
this
)
return container
},
})
U.MoreControls = L.Control.extend({
options: {
position: 'topleft',
},
onAdd: function () {
const container = L.DomUtil.create('div', 'umap-control-text')
const moreButton = L.DomUtil.createButton(
'umap-control-more',
container,
L._('More controls'),
this.toggle,
this
)
const lessButton = L.DomUtil.createButton(
'umap-control-less',
container,
L._('Hide controls'),
this.toggle,
this
)
return container
},
toggle: function () {
const pos = this.getPosition()
const corner = this._map._controlCorners[pos]
const className = 'umap-more-controls'
if (L.DomUtil.hasClass(corner, className)) L.DomUtil.removeClass(corner, className)
else L.DomUtil.addClass(corner, className)
},
})
U.PermanentCreditsControl = L.Control.extend({
options: {
position: 'bottomleft',
},
initialize: function (map, options) {
this.map = map
L.Control.prototype.initialize.call(this, options)
},
onAdd: function () {
this.paragraphContainer = L.DomUtil.create(
'div',
'umap-permanent-credits-container text'
)
this.setCredits()
this.setBackground()
return this.paragraphContainer
},
setCredits: function () {
this.paragraphContainer.innerHTML = U.Utils.toHTML(this.map.options.permanentCredit)
},
setBackground: function () {
if (this.map.options.permanentCreditBackground) {
this.paragraphContainer.style.backgroundColor = '#FFFFFFB0'
} else {
this.paragraphContainer.style.backgroundColor = ''
}
},
})
L.Control.Button = L.Control.extend({
initialize: function (umap, options) {
this._umap = umap
L.Control.prototype.initialize.call(this, options)
},
getClassName: function () {
return this.options.className
},
onAdd: function (map) {
const container = L.DomUtil.create('div', `${this.getClassName()} umap-control`)
const button = L.DomUtil.createButton(
'',
container,
this.options.title,
this.onClick,
this
)
L.DomEvent.on(button, 'dblclick', L.DomEvent.stopPropagation)
this.afterAdd(container)
return container
},
afterAdd: (container) => {},
})
U.DataLayersControl = L.Control.Button.extend({
options: {
position: 'topleft',
className: 'umap-control-browse',
title: L._('Open browser'),
},
afterAdd: function (container) {
U.Utils.toggleBadge(container, this._umap.browser?.hasFilters())
},
onClick: function () {
this._umap.openBrowser()
},
})
U.CaptionControl = L.Control.Button.extend({
options: {
position: 'topleft',
className: 'umap-control-caption',
title: L._('About'),
},
onClick: function () {
this._umap.openCaption()
},
})
L.Control.Embed = L.Control.Button.extend({
options: {
position: 'topleft',
title: L._('Share and download'),
className: 'leaflet-control-embed umap-control',
},
onClick: function () {
this._umap.share.open()
},
})
/* Used in view mode to define the current tilelayer */ /* Used in view mode to define the current tilelayer */
U.TileLayerControl = L.Control.IconLayers.extend({ U.TileLayerControl = L.Control.IconLayers.extend({
initialize: function (map, options) { initialize: function (map, options) {
@ -238,128 +58,6 @@ U.TileLayerControl = L.Control.IconLayers.extend({
}, },
}) })
/* Used in edit mode to define the default tilelayer */
U.TileLayerChooser = L.Control.extend({
options: {
position: 'topleft',
},
initialize: function (map, options = {}) {
this.map = map
L.Control.prototype.initialize.call(this, options)
},
onAdd: function () {
const container = L.DomUtil.create('div', 'leaflet-control-tilelayers umap-control')
const changeMapBackgroundButton = L.DomUtil.createButton(
'',
container,
L._('Change map background'),
this.openSwitcher,
this
)
L.DomEvent.on(changeMapBackgroundButton, 'dblclick', L.DomEvent.stopPropagation)
return container
},
openSwitcher: function (options = {}) {
const container = L.DomUtil.create('div', 'umap-edit-tilelayers')
L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer')
this._tilelayers_container = L.DomUtil.create('ul', '', container)
this.buildList(options)
const panel = options.edit ? this.map._umap.editPanel : this.map._umap.panel
panel.open({ content: container, highlight: 'tilelayers' })
},
buildList: function (options) {
this.map.eachTileLayer(function (tilelayer) {
if (
window.location.protocol === 'https:' &&
tilelayer.options.url_template.indexOf('http:') === 0
)
return
this.addTileLayerElement(tilelayer, options)
}, this)
},
addTileLayerElement: function (tilelayer, options) {
const selectedClass = this.map.hasLayer(tilelayer) ? 'selected' : ''
const el = L.DomUtil.create('li', selectedClass, this._tilelayers_container)
const img = L.DomUtil.create('img', '', el)
const name = L.DomUtil.create('div', '', el)
img.src = U.Utils.template(
tilelayer.options.url_template,
this.map.options.demoTileInfos
)
img.loading = 'lazy'
name.textContent = tilelayer.options.name
L.DomEvent.on(
el,
'click',
() => {
const oldTileLayer = this.map._umap.properties.tilelayer
this.map.selectTileLayer(tilelayer)
this.map._controls.tilelayers.setLayers()
if (options?.edit) {
this.map._umap.properties.tilelayer = tilelayer.toJSON()
this.map._umap.isDirty = true
this.map._umap.sync.update(
'properties.tilelayer',
this.map._umap.properties.tilelayer,
oldTileLayer
)
}
},
this
)
},
})
U.AttributionControl = L.Control.Attribution.extend({
options: {
prefix: '',
},
_update: function () {
// Layer is no more on the map
if (!this._map) return
L.Control.Attribution.prototype._update.call(this)
// Use our own container, so we can hide/show on small screens
const credits = this._container.innerHTML
this._container.innerHTML = ''
const container = L.DomUtil.create('div', 'attribution-container', this._container)
container.innerHTML = credits
const shortCredit = this._map._umap.getProperty('shortCredit')
const captionMenus = this._map._umap.getProperty('captionMenus')
if (shortCredit) {
L.DomUtil.element({
tagName: 'span',
parent: container,
safeHTML: `${U.Utils.toHTML(shortCredit)}`,
})
}
if (captionMenus) {
const link = L.DomUtil.add('a', '', container, `${L._('Open caption')}`)
L.DomEvent.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', () => this._map._umap.openCaption())
.on(link, 'dblclick', L.DomEvent.stop)
}
if (window.top === window.self && captionMenus) {
// We are not in iframe mode
L.DomUtil.createLink('', container, `${L._('Home')}`, '/')
}
if (captionMenus) {
L.DomUtil.createLink(
'',
container,
`${L._('Powered by uMap')}`,
'https://umap-project.org/'
)
}
L.DomUtil.createLink('attribution-toggle', this._container, '')
},
})
/* /*
* Take control over L.Control.Locate to be able to * Take control over L.Control.Locate to be able to
* call start() before adding the control (and thus the button) to the map. * call start() before adding the control (and thus the button) to the map.
@ -461,7 +159,6 @@ U.Search = L.PhotonSearch.extend({
event.stopPropagation() event.stopPropagation()
const datalayer = this.map._umap.defaultEditDataLayer() const datalayer = this.map._umap.defaultEditDataLayer()
const marker = datalayer.makeFeature(feature) const marker = datalayer.makeFeature(feature)
marker.isDirty = true
marker.edit() marker.edit()
}) })
geom.addEventListener('mousedown', async (event) => { geom.addEventListener('mousedown', async (event) => {
@ -602,14 +299,8 @@ U.Editable = L.Editable.extend({
if (event.layer instanceof U.LeafletMarker) event.layer.feature.del() if (event.layer instanceof U.LeafletMarker) event.layer.feature.del()
}) })
this.on('editable:drawing:commit', function (event) { this.on('editable:drawing:commit', function (event) {
event.layer.feature.isDirty = true
if (this._umap.editedFeature !== event.layer) event.layer.feature.edit(event) if (this._umap.editedFeature !== event.layer) event.layer.feature.edit(event)
}) })
this.on('editable:editing', (event) => {
const feature = event.layer.feature
feature.isDirty = true
// feature.pullGeometry(false)
})
this.on('editable:vertex:ctrlclick', (event) => { this.on('editable:vertex:ctrlclick', (event) => {
const index = event.vertex.getIndex() const index = event.vertex.getIndex()
if ( if (
@ -629,7 +320,7 @@ U.Editable = L.Editable.extend({
const line = new U.LineString(this._umap, datalayer, { const line = new U.LineString(this._umap, datalayer, {
geometry: { type: 'LineString', coordinates: [] }, geometry: { type: 'LineString', coordinates: [] },
}) })
line._just_married = true line._needs_upsert = true
return line.ui return line.ui
}, },
@ -638,7 +329,7 @@ U.Editable = L.Editable.extend({
const poly = new U.Polygon(this._umap, datalayer, { const poly = new U.Polygon(this._umap, datalayer, {
geometry: { type: 'Polygon', coordinates: [] }, geometry: { type: 'Polygon', coordinates: [] },
}) })
poly._just_married = true poly._needs_upsert = true
return poly.ui return poly.ui
}, },
@ -647,7 +338,7 @@ U.Editable = L.Editable.extend({
const point = new U.Point(this._umap, datalayer, { const point = new U.Point(this._umap, datalayer, {
geometry: { type: 'Point', coordinates: [latlng.lng, latlng.lat] }, geometry: { type: 'Point', coordinates: [latlng.lng, latlng.lat] },
}) })
point._just_married = true point._needs_upsert = true
return point.ui return point.ui
}, },
@ -663,7 +354,6 @@ U.Editable = L.Editable.extend({
// Overrided from Leaflet.Editable // Overrided from Leaflet.Editable
const datalayer = this._umap.defaultEditDataLayer() const datalayer = this._umap.defaultEditDataLayer()
datalayer.addFeature(layer.feature) datalayer.addFeature(layer.feature)
layer.isDirty = true
return layer return layer
}, },

View file

@ -65,18 +65,6 @@ L.DomUtil.createButton = (className, container, content, callback, context) => {
return el return el
} }
L.DomUtil.createLink = (className, container, content, url, target, title) => {
const el = L.DomUtil.add('a', className, container, content)
el.href = url
if (target) {
el.target = target
}
if (title) {
el.title = title
}
return el
}
L.DomUtil.createIcon = (parent, className, title, size = 16) => { L.DomUtil.createIcon = (parent, className, title, size = 16) => {
return L.DomUtil.element({ return L.DomUtil.element({
tagName: 'i', tagName: 'i',
@ -113,8 +101,12 @@ L.DomUtil.createCopiableInput = (parent, label, value) => {
input.type = 'text' input.type = 'text'
input.readOnly = true input.readOnly = true
input.value = value input.value = value
const button = L.DomUtil.createButtonIcon(wrapper, 'icon-copy', L._('copy'), () => const button = L.DomUtil.createButtonIcon(
L.Util.copyToClipboard(input.value) wrapper,
'icon-copy',
L._('copy'),
() => L.Util.copyToClipboard(input.value),
24
) )
button.type = 'button' button.type = 'button'
return input return input
@ -136,16 +128,6 @@ L.DomUtil.element = ({ tagName, parent, ...attrs }) => {
return el return el
} }
L.DomUtil.before = (target, el) => {
target.parentNode.insertBefore(el, target)
return el
}
L.DomUtil.after = (target, el) => {
target.parentNode.insertBefore(el, target.nextSibling)
return el
}
// From https://gist.github.com/Accudio/b9cb16e0e3df858cef0d31e38f1fe46f // From https://gist.github.com/Accudio/b9cb16e0e3df858cef0d31e38f1fe46f
// convert colour in range 0-255 to the modifier used within luminance calculation // convert colour in range 0-255 to the modifier used within luminance calculation
L.DomUtil.colourMod = (colour) => { L.DomUtil.colourMod = (colour) => {
@ -210,24 +192,6 @@ L.DomUtil.contrastedColor = (el, bgcolor) => {
if (bgcolor) _CACHE_CONSTRAST[bgcolor] = out if (bgcolor) _CACHE_CONSTRAST[bgcolor] = out
return out return out
} }
L.DomEvent.once = (el, types, fn, context) => {
// cf https://github.com/Leaflet/Leaflet/pull/3528#issuecomment-134551575
if (typeof types === 'object') {
for (const type in types) {
L.DomEvent.once(el, type, types[type], fn)
}
return L.DomEvent
}
const handler = L.bind(() => {
L.DomEvent.off(el, types, fn, context).off(el, types, handler, context)
}, L.DomEvent)
// add a listener that's executed once and removed after that
return L.DomEvent.on(el, types, fn, context).on(el, types, handler, context)
}
L.LatLng.prototype.isValid = function () { L.LatLng.prototype.isValid = function () {
return ( return (
Number.isFinite(this.lat) && Number.isFinite(this.lat) &&

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "ካፕሽን", "Caption": "ካፕሽን",
"Center map on your location": "መገኛዎን የሚያሳየውን ካርታ ወደ መሀል ያድርጉ", "Center map on your location": "መገኛዎን የሚያሳየውን ካርታ ወደ መሀል ያድርጉ",
"Change map background": "የካርታውን የጀርባ ገፅታ ይቀይሩ",
"Change tilelayers": "የታይልሌየሩን", "Change tilelayers": "የታይልሌየሩን",
"Change": "Change", "Change": "Change",
"Choose the data format": "የረጃውን ፎርማት ቀይር", "Choose the data format": "የረጃውን ፎርማት ቀይር",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("am_ET", locale) L.registerLocale("am_ET", locale)
L.setLocale("am_ET") L.setLocale("am_ET")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "ካፕሽን", "Caption": "ካፕሽን",
"Center map on your location": "መገኛዎን የሚያሳየውን ካርታ ወደ መሀል ያድርጉ", "Center map on your location": "መገኛዎን የሚያሳየውን ካርታ ወደ መሀል ያድርጉ",
"Change map background": "የካርታውን የጀርባ ገፅታ ይቀይሩ",
"Change tilelayers": "የታይልሌየሩን", "Change tilelayers": "የታይልሌየሩን",
"Change": "Change", "Change": "Change",
"Choose the data format": "የረጃውን ፎርማት ቀይር", "Choose the data format": "የረጃውን ፎርማት ቀይር",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "شرح", "Caption": "شرح",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Change map background",
"Change tilelayers": "Change tilelayers", "Change tilelayers": "Change tilelayers",
"Change": "Change", "Change": "Change",
"Choose the data format": "اختر تنسيق البيانات", "Choose the data format": "اختر تنسيق البيانات",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("ar", locale) L.registerLocale("ar", locale)
L.setLocale("ar") L.setLocale("ar")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "شرح", "Caption": "شرح",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Change map background",
"Change tilelayers": "Change tilelayers", "Change tilelayers": "Change tilelayers",
"Change": "Change", "Change": "Change",
"Choose the data format": "اختر تنسيق البيانات", "Choose the data format": "اختر تنسيق البيانات",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Caption", "Caption": "Caption",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Change map background",
"Change tilelayers": "Change tilelayers", "Change tilelayers": "Change tilelayers",
"Change": "Change", "Change": "Change",
"Choose the data format": "Choose the data format", "Choose the data format": "Choose the data format",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("ast", locale) L.registerLocale("ast", locale)
L.setLocale("ast") L.setLocale("ast")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Caption", "Caption": "Caption",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Change map background",
"Change tilelayers": "Change tilelayers", "Change tilelayers": "Change tilelayers",
"Change": "Change", "Change": "Change",
"Choose the data format": "Choose the data format", "Choose the data format": "Choose the data format",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Надпис", "Caption": "Надпис",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Промяна фона на картата",
"Change tilelayers": "Променете слоевете", "Change tilelayers": "Променете слоевете",
"Change": "Change", "Change": "Change",
"Choose the data format": "Изберете формата на данните", "Choose the data format": "Изберете формата на данните",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("bg", locale) L.registerLocale("bg", locale)
L.setLocale("bg") L.setLocale("bg")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Надпис", "Caption": "Надпис",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Промяна фона на картата",
"Change tilelayers": "Променете слоевете", "Change tilelayers": "Променете слоевете",
"Change": "Change", "Change": "Change",
"Choose the data format": "Изберете формата на данните", "Choose the data format": "Изберете формата на данните",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Alc'hwez", "Caption": "Alc'hwez",
"Center map on your location": "Kreizañ ar gartenn war al lec'h m'emaoc'h", "Center map on your location": "Kreizañ ar gartenn war al lec'h m'emaoc'h",
"Change map background": "Cheñch foñs ar gartenn",
"Change tilelayers": "Cheñch foñs ar gartenn", "Change tilelayers": "Cheñch foñs ar gartenn",
"Change": "Kemmañ", "Change": "Kemmañ",
"Choose the data format": "Diuzañ furmad ar roadennoù", "Choose the data format": "Diuzañ furmad ar roadennoù",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Dibab an hollad cheñchamantoù-mañ", "Choose this dataset": "Dibab an hollad cheñchamantoù-mañ",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Dibab un tem", "Choose a theme": "Dibab un tem",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Dibab ar roadennoù-mañ", "Choose this data": "Dibab ar roadennoù-mañ",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("br", locale) L.registerLocale("br", locale)
L.setLocale("br") L.setLocale("br")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Alc'hwez", "Caption": "Alc'hwez",
"Center map on your location": "Kreizañ ar gartenn war al lec'h m'emaoc'h", "Center map on your location": "Kreizañ ar gartenn war al lec'h m'emaoc'h",
"Change map background": "Cheñch foñs ar gartenn",
"Change tilelayers": "Cheñch foñs ar gartenn", "Change tilelayers": "Cheñch foñs ar gartenn",
"Change": "Kemmañ", "Change": "Kemmañ",
"Choose the data format": "Diuzañ furmad ar roadennoù", "Choose the data format": "Diuzañ furmad ar roadennoù",
@ -457,7 +456,6 @@
"Choose this dataset": "Dibab an hollad cheñchamantoù-mañ", "Choose this dataset": "Dibab an hollad cheñchamantoù-mañ",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Dibab un tem", "Choose a theme": "Dibab un tem",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Dibab ar roadennoù-mañ", "Choose this data": "Dibab ar roadennoù-mañ",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Petició proxy en memòria cau", "Cache proxied request": "Petició proxy en memòria cau",
"Caption": "Llegenda", "Caption": "Llegenda",
"Center map on your location": "Centra el mapa a la vostra ubicació", "Center map on your location": "Centra el mapa a la vostra ubicació",
"Change map background": "Canvia el fons del mapa",
"Change tilelayers": "Canvia les capes de tessel·les", "Change tilelayers": "Canvia les capes de tessel·les",
"Change": "Change", "Change": "Change",
"Choose the data format": "Trieu el format de dades", "Choose the data format": "Trieu el format de dades",
@ -85,7 +84,7 @@ const locale = {
"Custom background": "Fons personalitzat", "Custom background": "Fons personalitzat",
"Custom overlay": "Superposició personalitzada", "Custom overlay": "Superposició personalitzada",
"dash array": "matriu de guions", "dash array": "matriu de guions",
"Data is browsable": "Data is browsable", "Data is browsable": "Les dades es poden navegar",
"Datalayers": "Capes de dades", "Datalayers": "Capes de dades",
"Default interaction options": "Opcions d'interacció predeterminades", "Default interaction options": "Opcions d'interacció predeterminades",
"Default properties": "Propietats predeterminades", "Default properties": "Propietats predeterminades",
@ -177,12 +176,12 @@ const locale = {
"Icon shape": "forma de la icona", "Icon shape": "forma de la icona",
"Icon symbol": "Imatge de la icona", "Icon symbol": "Imatge de la icona",
"If false, the polygon or line will act as a part of the underlying map.": "If false, the polygon or line will act as a part of the underlying map.", "If false, the polygon or line will act as a part of the underlying map.": "If false, the polygon or line will act as a part of the underlying map.",
"Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}", "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe amb alçada personalitzada (height en px): {{{https://iframe.url.com|height}}}",
"Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}", "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe amb alçada i amplada personalitzada (height i width en px): {{{https://iframe.url.com|height*width}}}",
"iframe": "iframe", "iframe": "iframe",
"Iframe: {{{https://iframe.url.com}}}": "Iframe: {{{https://iframe.url.com}}}", "Iframe: {{{https://iframe.url.com}}}": "Iframe: {{{https://iframe.url.com}}}",
"Image with custom width (in px): {{https://image.url.com|width}}": "Image with custom width (in px): {{https://image.url.com|width}}", "Image with custom width (in px): {{https://image.url.com|width}}": "Imatge amb amplada personalitzada (width en px): {{https://image.url.com|width}}",
"Image: {{https://image.url.com}}": "Image: {{https://image.url.com}}", "Image: {{https://image.url.com}}": "Imatge: {{https://image.url.com}}",
"Import data": "Importa dades", "Import data": "Importa dades",
"Import in a new layer": "Import in a new layer", "Import in a new layer": "Import in a new layer",
"Imports all umap data, including layers and settings.": "Imports all umap data, including layers and settings.", "Imports all umap data, including layers and settings.": "Imports all umap data, including layers and settings.",
@ -203,14 +202,14 @@ const locale = {
"Labels are clickable": "Les etiquetes es poden fer clic", "Labels are clickable": "Les etiquetes es poden fer clic",
"Latest feature": "Darrera característica", "Latest feature": "Darrera característica",
"Latitude": "Latitud", "Latitude": "Latitud",
"Layer properties": "Layer properties", "Layer properties": "Propietats de la capa",
"Layer": "Capa", "Layer": "Capa",
"Licence": "Llicència", "Licence": "Llicència",
"licence": "llicència", "licence": "llicència",
"Limit bounds": "Límits", "Limit bounds": "Límits",
"Link to view the map": "Enllaç per veure el mapa", "Link to view the map": "Enllaç per veure el mapa",
"Link to…": "Link to…", "Link to…": "Link to…",
"Link with text: [[https://example.com|text of the link]]": "Link with text: [[https://example.com|text of the link]]", "Link with text: [[https://example.com|text of the link]]": "Enllaç amb text:  [[https://example.com|text de l'enllaç]]",
"Long credits": "Crèdits llargs", "Long credits": "Crèdits llargs",
"Longitude": "Longitud", "Longitude": "Longitud",
"Make main shape": "Make main shape", "Make main shape": "Make main shape",
@ -302,17 +301,17 @@ const locale = {
"Secret edit link:": "Secret edit link:", "Secret edit link:": "Secret edit link:",
"See full screen": "Mostra-ho a pantalla completa", "See full screen": "Mostra-ho a pantalla completa",
"See on OpenStreetMap": "See on OpenStreetMap", "See on OpenStreetMap": "See on OpenStreetMap",
"Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Estableix-lo com a fals per ocultar aquesta capa de la presentació de diapositives, el navegador de dades, la navegació emergent...",
"settings": "settings", "settings": "settings",
"Shape properties": "Shape properties", "Shape properties": "Propietats de la forma",
"Share and download": "Comparteix i baixa", "Share and download": "Comparteix i baixa",
"Share this link to open a customized map view": "Comparteix aquest enllaç per obrir una vista de mapa personalitzada", "Share this link to open a customized map view": "Comparteix aquest enllaç per obrir una vista de mapa personalitzada",
"Short credits": "Crèdits curts", "Short credits": "Crèdits curts",
"Short link": "Enllaç curt", "Short link": "Enllaç curt",
"Show this layer in the caption": "Show this layer in the caption", "Show this layer in the caption": "Mostra aquesta capa a la llegenda",
"Show/hide layer": "Mostra/amaga la capa", "Show/hide layer": "Mostra/amaga la capa",
"Side panel": "panell lateral", "Side panel": "panell lateral",
"Simple link: [[https://example.com]]": "Simple link: [[https://example.com]]", "Simple link: [[https://example.com]]": "Enllaç senzill: [[https://example.com]]",
"Simplify": "Simplificar", "Simplify": "Simplificar",
"Skipping unknown geometry.type: {type}": "S'està ometent el tipus de geometria desconegut: {type}", "Skipping unknown geometry.type: {type}": "S'està ometent el tipus de geometria desconegut: {type}",
"Slideshow": "Presentació", "Slideshow": "Presentació",
@ -324,7 +323,7 @@ const locale = {
"Stop editing": "Atura l'edició", "Stop editing": "Atura l'edició",
"Stop slideshow": "Atura la presentació", "Stop slideshow": "Atura la presentació",
"Street": "Street", "Street": "Street",
"stroke": "stroke", "stroke": "línia",
"Supported scheme": "Esquema suportat", "Supported scheme": "Esquema suportat",
"Supported variables that will be dynamically replaced": "Supported variables that will be dynamically replaced", "Supported variables that will be dynamically replaced": "Supported variables that will be dynamically replaced",
"Symbol": "Symbol", "Symbol": "Symbol",
@ -365,7 +364,7 @@ const locale = {
"Visibility: {status}": "Visibilitat: {status}", "Visibility: {status}": "Visibilitat: {status}",
"weight": "pes", "weight": "pes",
"Where do we go from here?": "On anem des d'aquí?", "Where do we go from here?": "On anem des d'aquí?",
"Whether to display or not polygons paths.": "Whether to display or not polygons paths.", "Whether to display or not polygons paths.": "Si es mostren o no els camins de polígons.",
"Whether to fill polygons with color.": "emplenar polígons amb color..", "Whether to fill polygons with color.": "emplenar polígons amb color..",
"Who can edit \"{layer}\"": "Qui pot editar \"{layer}\"", "Who can edit \"{layer}\"": "Qui pot editar \"{layer}\"",
"Who can edit": "Qui pot editar", "Who can edit": "Qui pot editar",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -504,7 +502,7 @@ const locale = {
"Type editor's username": "Escriviu el nom d'usuari de l'editor", "Type editor's username": "Escriviu el nom d'usuari de l'editor",
"Map": "Mapa", "Map": "Mapa",
"Manage collaborators": "Gestiona els col·laboradors", "Manage collaborators": "Gestiona els col·laboradors",
"show/hide all layers": "show/hide all layers", "show/hide all layers": "mostrar/ocultar totes les capes",
"zoom to data extent": "zoom to data extent", "zoom to data extent": "zoom to data extent",
"download visible data": "download visible data", "download visible data": "download visible data",
"Import helpers": "Import helpers", "Import helpers": "Import helpers",
@ -522,10 +520,10 @@ const locale = {
"Anonymous": "Anonymous", "Anonymous": "Anonymous",
"created at {date}": "created at {date}", "created at {date}": "created at {date}",
"modified at {date}": "modified at {date}", "modified at {date}": "modified at {date}",
"Default zoom": "Default zoom", "Default zoom": "Zoom predeterminat",
"Default latitude": "Default latitude", "Default latitude": "Latitud predeterminada",
"Default longitude": "Default longitude", "Default longitude": "Longitud predeterminada",
"Edit map default view": "Edit map default view", "Edit map default view": "Edita la visualització predeterminada del mapa",
"Use current center and zoom": "Use current center and zoom", "Use current center and zoom": "Use current center and zoom",
"Layer permalink": "Layer permalink", "Layer permalink": "Layer permalink",
"Back to home": "Back to home", "Back to home": "Back to home",
@ -535,10 +533,17 @@ const locale = {
"Cancel last edit": "Cancel last edit", "Cancel last edit": "Cancel last edit",
"Redo last edit": "Redo last edit", "Redo last edit": "Redo last edit",
"Links": "Links", "Links": "Links",
"Images": "Images", "Images": "Imatges",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("ca", locale) L.registerLocale("ca", locale)
L.setLocale("ca") L.setLocale("ca")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Petició proxy en memòria cau", "Cache proxied request": "Petició proxy en memòria cau",
"Caption": "Llegenda", "Caption": "Llegenda",
"Center map on your location": "Centra el mapa a la vostra ubicació", "Center map on your location": "Centra el mapa a la vostra ubicació",
"Change map background": "Canvia el fons del mapa",
"Change tilelayers": "Canvia les capes de tessel·les", "Change tilelayers": "Canvia les capes de tessel·les",
"Change": "Change", "Change": "Change",
"Choose the data format": "Trieu el format de dades", "Choose the data format": "Trieu el format de dades",
@ -85,7 +84,7 @@
"Custom background": "Fons personalitzat", "Custom background": "Fons personalitzat",
"Custom overlay": "Superposició personalitzada", "Custom overlay": "Superposició personalitzada",
"dash array": "matriu de guions", "dash array": "matriu de guions",
"Data is browsable": "Data is browsable", "Data is browsable": "Les dades es poden navegar",
"Datalayers": "Capes de dades", "Datalayers": "Capes de dades",
"Default interaction options": "Opcions d'interacció predeterminades", "Default interaction options": "Opcions d'interacció predeterminades",
"Default properties": "Propietats predeterminades", "Default properties": "Propietats predeterminades",
@ -177,12 +176,12 @@
"Icon shape": "forma de la icona", "Icon shape": "forma de la icona",
"Icon symbol": "Imatge de la icona", "Icon symbol": "Imatge de la icona",
"If false, the polygon or line will act as a part of the underlying map.": "If false, the polygon or line will act as a part of the underlying map.", "If false, the polygon or line will act as a part of the underlying map.": "If false, the polygon or line will act as a part of the underlying map.",
"Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}", "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe amb alçada personalitzada (height en px): {{{https://iframe.url.com|height}}}",
"Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}", "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe amb alçada i amplada personalitzada (height i width en px): {{{https://iframe.url.com|height*width}}}",
"iframe": "iframe", "iframe": "iframe",
"Iframe: {{{https://iframe.url.com}}}": "Iframe: {{{https://iframe.url.com}}}", "Iframe: {{{https://iframe.url.com}}}": "Iframe: {{{https://iframe.url.com}}}",
"Image with custom width (in px): {{https://image.url.com|width}}": "Image with custom width (in px): {{https://image.url.com|width}}", "Image with custom width (in px): {{https://image.url.com|width}}": "Imatge amb amplada personalitzada (width en px): {{https://image.url.com|width}}",
"Image: {{https://image.url.com}}": "Image: {{https://image.url.com}}", "Image: {{https://image.url.com}}": "Imatge: {{https://image.url.com}}",
"Import data": "Importa dades", "Import data": "Importa dades",
"Import in a new layer": "Import in a new layer", "Import in a new layer": "Import in a new layer",
"Imports all umap data, including layers and settings.": "Imports all umap data, including layers and settings.", "Imports all umap data, including layers and settings.": "Imports all umap data, including layers and settings.",
@ -203,14 +202,14 @@
"Labels are clickable": "Les etiquetes es poden fer clic", "Labels are clickable": "Les etiquetes es poden fer clic",
"Latest feature": "Darrera característica", "Latest feature": "Darrera característica",
"Latitude": "Latitud", "Latitude": "Latitud",
"Layer properties": "Layer properties", "Layer properties": "Propietats de la capa",
"Layer": "Capa", "Layer": "Capa",
"Licence": "Llicència", "Licence": "Llicència",
"licence": "llicència", "licence": "llicència",
"Limit bounds": "Límits", "Limit bounds": "Límits",
"Link to view the map": "Enllaç per veure el mapa", "Link to view the map": "Enllaç per veure el mapa",
"Link to…": "Link to…", "Link to…": "Link to…",
"Link with text: [[https://example.com|text of the link]]": "Link with text: [[https://example.com|text of the link]]", "Link with text: [[https://example.com|text of the link]]": "Enllaç amb text:  [[https://example.com|text de l'enllaç]]",
"Long credits": "Crèdits llargs", "Long credits": "Crèdits llargs",
"Longitude": "Longitud", "Longitude": "Longitud",
"Make main shape": "Make main shape", "Make main shape": "Make main shape",
@ -302,17 +301,17 @@
"Secret edit link:": "Secret edit link:", "Secret edit link:": "Secret edit link:",
"See full screen": "Mostra-ho a pantalla completa", "See full screen": "Mostra-ho a pantalla completa",
"See on OpenStreetMap": "See on OpenStreetMap", "See on OpenStreetMap": "See on OpenStreetMap",
"Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Estableix-lo com a fals per ocultar aquesta capa de la presentació de diapositives, el navegador de dades, la navegació emergent...",
"settings": "settings", "settings": "settings",
"Shape properties": "Shape properties", "Shape properties": "Propietats de la forma",
"Share and download": "Comparteix i baixa", "Share and download": "Comparteix i baixa",
"Share this link to open a customized map view": "Comparteix aquest enllaç per obrir una vista de mapa personalitzada", "Share this link to open a customized map view": "Comparteix aquest enllaç per obrir una vista de mapa personalitzada",
"Short credits": "Crèdits curts", "Short credits": "Crèdits curts",
"Short link": "Enllaç curt", "Short link": "Enllaç curt",
"Show this layer in the caption": "Show this layer in the caption", "Show this layer in the caption": "Mostra aquesta capa a la llegenda",
"Show/hide layer": "Mostra/amaga la capa", "Show/hide layer": "Mostra/amaga la capa",
"Side panel": "panell lateral", "Side panel": "panell lateral",
"Simple link: [[https://example.com]]": "Simple link: [[https://example.com]]", "Simple link: [[https://example.com]]": "Enllaç senzill: [[https://example.com]]",
"Simplify": "Simplificar", "Simplify": "Simplificar",
"Skipping unknown geometry.type: {type}": "S'està ometent el tipus de geometria desconegut: {type}", "Skipping unknown geometry.type: {type}": "S'està ometent el tipus de geometria desconegut: {type}",
"Slideshow": "Presentació", "Slideshow": "Presentació",
@ -324,7 +323,7 @@
"Stop editing": "Atura l'edició", "Stop editing": "Atura l'edició",
"Stop slideshow": "Atura la presentació", "Stop slideshow": "Atura la presentació",
"Street": "Street", "Street": "Street",
"stroke": "stroke", "stroke": "línia",
"Supported scheme": "Esquema suportat", "Supported scheme": "Esquema suportat",
"Supported variables that will be dynamically replaced": "Supported variables that will be dynamically replaced", "Supported variables that will be dynamically replaced": "Supported variables that will be dynamically replaced",
"Symbol": "Symbol", "Symbol": "Symbol",
@ -365,7 +364,7 @@
"Visibility: {status}": "Visibilitat: {status}", "Visibility: {status}": "Visibilitat: {status}",
"weight": "pes", "weight": "pes",
"Where do we go from here?": "On anem des d'aquí?", "Where do we go from here?": "On anem des d'aquí?",
"Whether to display or not polygons paths.": "Whether to display or not polygons paths.", "Whether to display or not polygons paths.": "Si es mostren o no els camins de polígons.",
"Whether to fill polygons with color.": "emplenar polígons amb color..", "Whether to fill polygons with color.": "emplenar polígons amb color..",
"Who can edit \"{layer}\"": "Qui pot editar \"{layer}\"", "Who can edit \"{layer}\"": "Qui pot editar \"{layer}\"",
"Who can edit": "Qui pot editar", "Who can edit": "Qui pot editar",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -504,7 +502,7 @@
"Type editor's username": "Escriviu el nom d'usuari de l'editor", "Type editor's username": "Escriviu el nom d'usuari de l'editor",
"Map": "Mapa", "Map": "Mapa",
"Manage collaborators": "Gestiona els col·laboradors", "Manage collaborators": "Gestiona els col·laboradors",
"show/hide all layers": "show/hide all layers", "show/hide all layers": "mostrar/ocultar totes les capes",
"zoom to data extent": "zoom to data extent", "zoom to data extent": "zoom to data extent",
"download visible data": "download visible data", "download visible data": "download visible data",
"Import helpers": "Import helpers", "Import helpers": "Import helpers",
@ -522,10 +520,10 @@
"Anonymous": "Anonymous", "Anonymous": "Anonymous",
"created at {date}": "created at {date}", "created at {date}": "created at {date}",
"modified at {date}": "modified at {date}", "modified at {date}": "modified at {date}",
"Default zoom": "Default zoom", "Default zoom": "Zoom predeterminat",
"Default latitude": "Default latitude", "Default latitude": "Latitud predeterminada",
"Default longitude": "Default longitude", "Default longitude": "Longitud predeterminada",
"Edit map default view": "Edit map default view", "Edit map default view": "Edita la visualització predeterminada del mapa",
"Use current center and zoom": "Use current center and zoom", "Use current center and zoom": "Use current center and zoom",
"Layer permalink": "Layer permalink", "Layer permalink": "Layer permalink",
"Back to home": "Back to home", "Back to home": "Back to home",
@ -535,8 +533,15 @@
"Cancel last edit": "Cancel last edit", "Cancel last edit": "Cancel last edit",
"Redo last edit": "Redo last edit", "Redo last edit": "Redo last edit",
"Links": "Links", "Links": "Links",
"Images": "Images", "Images": "Imatges",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Požadavek na zástupnou mezipaměť", "Cache proxied request": "Požadavek na zástupnou mezipaměť",
"Caption": "Popisek", "Caption": "Popisek",
"Center map on your location": "Přemístit se na mapě na vaši polohu", "Center map on your location": "Přemístit se na mapě na vaši polohu",
"Change map background": "Změnit pozadí mapy",
"Change tilelayers": "Změnit pozadí mapy", "Change tilelayers": "Změnit pozadí mapy",
"Change": "Změnit", "Change": "Změnit",
"Choose the data format": "Vyberte formát dat", "Choose the data format": "Vyberte formát dat",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Vyberte tuto datovou sadu", "Choose this dataset": "Vyberte tuto datovou sadu",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: tematická data z OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: tematická data z OpenStreetMap",
"Choose a theme": "Vyberte si téma", "Choose a theme": "Vyberte si téma",
"Symplify all geometries to points": "Zjednodušte všechny geometrie na body",
"Choose this data": "Zvolte tato data", "Choose this data": "Zvolte tato data",
"Search admin boundary": "Hledat hranici správce", "Search admin boundary": "Hledat hranici správce",
"Please choose a theme and a boundary first.": "Nejprve si vyberte téma a hranice.", "Please choose a theme and a boundary first.": "Nejprve si vyberte téma a hranice.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("cs_CZ", locale) L.registerLocale("cs_CZ", locale)
L.setLocale("cs_CZ") L.setLocale("cs_CZ")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Požadavek na zástupnou mezipaměť", "Cache proxied request": "Požadavek na zástupnou mezipaměť",
"Caption": "Popisek", "Caption": "Popisek",
"Center map on your location": "Přemístit se na mapě na vaši polohu", "Center map on your location": "Přemístit se na mapě na vaši polohu",
"Change map background": "Změnit pozadí mapy",
"Change tilelayers": "Změnit pozadí mapy", "Change tilelayers": "Změnit pozadí mapy",
"Change": "Změnit", "Change": "Změnit",
"Choose the data format": "Vyberte formát dat", "Choose the data format": "Vyberte formát dat",
@ -457,7 +456,6 @@
"Choose this dataset": "Vyberte tuto datovou sadu", "Choose this dataset": "Vyberte tuto datovou sadu",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: tematická data z OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: tematická data z OpenStreetMap",
"Choose a theme": "Vyberte si téma", "Choose a theme": "Vyberte si téma",
"Symplify all geometries to points": "Zjednodušte všechny geometrie na body",
"Choose this data": "Zvolte tato data", "Choose this data": "Zvolte tato data",
"Search admin boundary": "Hledat hranici správce", "Search admin boundary": "Hledat hranici správce",
"Please choose a theme and a boundary first.": "Nejprve si vyberte téma a hranice.", "Please choose a theme and a boundary first.": "Nejprve si vyberte téma a hranice.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Forespørgsel i proxycache", "Cache proxied request": "Forespørgsel i proxycache",
"Caption": "Billedtekst", "Caption": "Billedtekst",
"Center map on your location": "Centrer kort på din placering", "Center map on your location": "Centrer kort på din placering",
"Change map background": "Skift kortbaggrund",
"Change tilelayers": "Skift kortlag", "Change tilelayers": "Skift kortlag",
"Change": "Change", "Change": "Change",
"Choose the data format": "Vælg dataformat", "Choose the data format": "Vælg dataformat",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("da", locale) L.registerLocale("da", locale)
L.setLocale("da") L.setLocale("da")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Forespørgsel i proxycache", "Cache proxied request": "Forespørgsel i proxycache",
"Caption": "Billedtekst", "Caption": "Billedtekst",
"Center map on your location": "Centrer kort på din placering", "Center map on your location": "Centrer kort på din placering",
"Change map background": "Skift kortbaggrund",
"Change tilelayers": "Skift kortlag", "Change tilelayers": "Skift kortlag",
"Change": "Change", "Change": "Change",
"Choose the data format": "Vælg dataformat", "Choose the data format": "Vælg dataformat",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Proxycache-Anfrage", "Cache proxied request": "Proxycache-Anfrage",
"Caption": "Überschrift", "Caption": "Überschrift",
"Center map on your location": "Die Karte auf deinen Standort ausrichten", "Center map on your location": "Die Karte auf deinen Standort ausrichten",
"Change map background": "Hintergrundkarte ändern",
"Change tilelayers": "Kachelebenen ändern", "Change tilelayers": "Kachelebenen ändern",
"Change": "Ändern", "Change": "Ändern",
"Choose the data format": "Wähle das Datenformat", "Choose the data format": "Wähle das Datenformat",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Diesen Datensatz auswählen", "Choose this dataset": "Diesen Datensatz auswählen",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematische Daten von OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematische Daten von OpenStreetMap",
"Choose a theme": "Thema auswählen", "Choose a theme": "Thema auswählen",
"Symplify all geometries to points": "Alle Geometrien zu Punkten vereinfachen",
"Choose this data": "Diese Daten auswählen", "Choose this data": "Diese Daten auswählen",
"Search admin boundary": "Administrative Grenze suchen", "Search admin boundary": "Administrative Grenze suchen",
"Please choose a theme and a boundary first.": "Bitte wähle zuerst ein Thema und eine administrative Grenze.", "Please choose a theme and a boundary first.": "Bitte wähle zuerst ein Thema und eine administrative Grenze.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("de", locale) L.registerLocale("de", locale)
L.setLocale("de") L.setLocale("de")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Proxycache-Anfrage", "Cache proxied request": "Proxycache-Anfrage",
"Caption": "Überschrift", "Caption": "Überschrift",
"Center map on your location": "Die Karte auf deinen Standort ausrichten", "Center map on your location": "Die Karte auf deinen Standort ausrichten",
"Change map background": "Hintergrundkarte ändern",
"Change tilelayers": "Kachelebenen ändern", "Change tilelayers": "Kachelebenen ändern",
"Change": "Ändern", "Change": "Ändern",
"Choose the data format": "Wähle das Datenformat", "Choose the data format": "Wähle das Datenformat",
@ -457,7 +456,6 @@
"Choose this dataset": "Diesen Datensatz auswählen", "Choose this dataset": "Diesen Datensatz auswählen",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematische Daten von OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematische Daten von OpenStreetMap",
"Choose a theme": "Thema auswählen", "Choose a theme": "Thema auswählen",
"Symplify all geometries to points": "Alle Geometrien zu Punkten vereinfachen",
"Choose this data": "Diese Daten auswählen", "Choose this data": "Diese Daten auswählen",
"Search admin boundary": "Administrative Grenze suchen", "Search admin boundary": "Administrative Grenze suchen",
"Please choose a theme and a boundary first.": "Bitte wähle zuerst ein Thema und eine administrative Grenze.", "Please choose a theme and a boundary first.": "Bitte wähle zuerst ein Thema und eine administrative Grenze.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Αίτημα μεσολάβησης προσωρινής μνήμης", "Cache proxied request": "Αίτημα μεσολάβησης προσωρινής μνήμης",
"Caption": "Λεζάντα", "Caption": "Λεζάντα",
"Center map on your location": "Κεντράρισμα του χάρτη στην τοποθεσία σας", "Center map on your location": "Κεντράρισμα του χάρτη στην τοποθεσία σας",
"Change map background": "Αλλαγή υποβάθρου του χάρτη",
"Change tilelayers": "Αλλαγή χαρτογραφικού υπόβαθρου", "Change tilelayers": "Αλλαγή χαρτογραφικού υπόβαθρου",
"Change": "Αλλαγή", "Change": "Αλλαγή",
"Choose the data format": "Επιλογή μορφοποίησης δεδομένων", "Choose the data format": "Επιλογή μορφοποίησης δεδομένων",
@ -434,111 +433,117 @@ const locale = {
"key~value (eg. name~Grisy)": "κλειδί~τιμή (π.χ. όνομα~Grisy)", "key~value (eg. name~Grisy)": "κλειδί~τιμή (π.χ. όνομα~Grisy)",
"key=\"value|value2\" (eg. name=\"Paris|Berlin\")": "κλειδί=\"value|value2\" (eg. όνομα=\"Παρίσι|Βερολίνο\")", "key=\"value|value2\" (eg. name=\"Paris|Berlin\")": "κλειδί=\"value|value2\" (eg. όνομα=\"Παρίσι|Βερολίνο\")",
"More info about Overpass syntax": "Περισσότερες πληροφορίες σχετικά με τη σύνταξη της Υπέρβασης", "More info about Overpass syntax": "Περισσότερες πληροφορίες σχετικά με τη σύνταξη της Υπέρβασης",
"For more complex needs, see": "For more complex needs, see", "For more complex needs, see": "Για πιο σύνθετες ανάγκες, βλ.",
"Choose data": "Choose data", "Choose data": "Επιλογή δεδομένων",
"Choose the format": "Choose the format", "Choose the format": "Επιλογή μορφοποίησης",
"Choose the layer": "Choose the layer", "Choose the layer": "Επιλογή επιπέδου",
"Layer name": "Layer name", "Layer name": "Όνομα επιπέδου",
"Choose import mode": "Choose import mode", "Choose import mode": "Επιλογή τρόπου εισαγωγής",
"Copy into the layer": "Copy into the layer", "Copy into the layer": "Αντιγραφή στο επίπεδο",
"Link to the layer as remote data": "Link to the layer as remote data", "Link to the layer as remote data": "Σύνδεση με το επίπεδο ως απομακρυσμένα δεδομένα",
"Condition": "Συνθήκη", "Condition": "Συνθήκη",
"key=value or key!=value": "key=value ή key!=value", "key=value or key!=value": "key=value ή key!=value",
"Are you sure you want to delete this rule?": "Θέλετε σίγουρα να διαγραφεί αυτός ο κανόνας;", "Are you sure you want to delete this rule?": "Θέλετε σίγουρα να διαγραφεί αυτός ο κανόνας;",
"empty rule": "κενός κανόνας", "empty rule": "κενός κανόνας",
"Conditional style rules": "Κανόνες μορφοποίησης υπό όρους", "Conditional style rules": "Κανόνες μορφοποίησης υπό όρους",
"Add rule": "Προσθήκη κανόνα", "Add rule": "Προσθήκη κανόνα",
"Browser: data": "Browser: data", "Browser: data": "Περιηγητής: δεδομένα",
"Browser: layers": "Browser: layers", "Browser: layers": "Περιηγητής: επίπεδα",
"Browser: filters": "Browser: filters", "Browser: filters": "Περιηγητής: φίλτρα",
"Enable real-time collaboration": "Enable real-time collaboration", "Enable real-time collaboration": "Ενεργοποίηση συνεργασίας σε πραγματικό χρόνο",
"✅ Copied!": "✅ Αντιγράφηκε!", "✅ Copied!": "✅ Αντιγράφηκε!",
"Choose a dataset": "Choose a dataset", "Choose a dataset": "Επιλογή συνόλου δεδομένων",
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Επιλογή αυτού του συνόλου δεδομένων",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: θεματικά δεδομένα από το OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Επιλογή θέματος",
"Symplify all geometries to points": "Symplify all geometries to points", "Choose this data": "Επιλογή αυτών των δεδομένων",
"Choose this data": "Choose this data",
"Search admin boundary": "Αναζήτηση διοικητικού ορίου", "Search admin boundary": "Αναζήτηση διοικητικού ορίου",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Επιλέξτε πρώτα ένα θέμα και ένα όριο.",
"Expression": "Έκφραση", "Expression": "Έκφραση",
"Geometry mode": "Λειτουργία γεωμετρίας", "Geometry mode": "Λειτουργία γεωμετρίας",
"Only geometry centers": "Only geometry centers", "Only geometry centers": "Μόνο γεωμετρικά κέντρα",
"Search area": "Search area", "Search area": "Περιοχή αναζήτησης",
"Type area name, or let empty to load data in current map view": "Type area name, or let empty to load data in current map view", "Type area name, or let empty to load data in current map view": "Πληκτρολογήστε το όνομα της περιοχής ή αφήστε το κενό, για να φορτώσετε δεδομένα στην τρέχουσα προβολή χάρτη.",
"Data successfully imported!": "Data successfully imported!", "Data successfully imported!": "Τα δεδομένα εισήχθησαν επιτυχώς!",
"Clear data": "Clear data", "Clear data": "Εκκαθάριση δεδομένων",
"Remove layers": "Remove layers", "Remove layers": "Αφαίρεση επιπέδων",
"Categorized": "Categorized", "Categorized": "Κατηγοριοποιημένο",
"Alphabetical": "Alphabetical", "Alphabetical": "Αλφαβητικά",
"Category property": "Category property", "Category property": "Ιδιότητα κατηγορίας",
"Color palette": "Παλέτα χρωμάτων", "Color palette": "Παλέτα χρωμάτων",
"Categories": "Κατηγορίες", "Categories": "Κατηγορίες",
"Comma separated list of categories.": "Λίστα κατηγοριών χωρισμένες με κόμμα.", "Comma separated list of categories.": "Λίστα κατηγοριών χωρισμένες με κόμμα.",
"Categories mode": "Λειτουργία κατηγοριών", "Categories mode": "Λειτουργία κατηγοριών",
"Remove filter for this column": "Remove filter for this column", "Remove filter for this column": "Αφαίρεση φίλτρου από αυτή τη στήλη",
"Add filter for this column": "Add filter for this column", "Add filter for this column": "Προσθήκη φίλτρου από αυτή τη στήλη",
"Rename this column": "Rename this column", "Rename this column": "Μετονομασία αυτής της στήλης",
"Delete this column": "Delete this column", "Delete this column": "Διαγραφή αυτής της στήλης",
"Name “{name}” should not contain a dot.": "Name “{name}” should not contain a dot.", "Name “{name}” should not contain a dot.": "Το όνομα \"{name}\" δεν πρέπει να περιέχει τελεία.",
"This name already exists: “{name}”": "This name already exists: “{name}”", "This name already exists: “{name}”": "Αυτό το όνομα υπάρχει ήδη: \"{name}\"",
"Delete selected rows": "Delete selected rows", "Delete selected rows": "Διαγραφή επιλεγμένων γραμμών",
"Found {count} rows. Are you sure you want to delete all?": "Found {count} rows. Are you sure you want to delete all?", "Found {count} rows. Are you sure you want to delete all?": "Βρέθηκαν {count} σειρές. Είστε σίγουροι ότι θέλετε να τις διαγράψετε όλες;",
"Expression is empty": "Η έκφραση είναι κενή", "Expression is empty": "Η έκφραση είναι κενή",
"OK": "OK", "OK": "OK",
"Cancel": "Άκυρο", "Cancel": "Άκυρο",
"Attach map to a team": "Attach map to a team", "Attach map to a team": "Σύνδεση χάρτη με μια ομάδα",
"Display the polygon inverted": "Display the polygon inverted", "Display the polygon inverted": "Εμφανίζει το πολύγωνο ανεστραμμένο",
"Proportional circles": "Proportional circles", "Proportional circles": "Αναλογικοί κύκλοι",
"Property name to compute circles": "Property name to compute circles", "Property name to compute circles": "Όνομα ιδιότητας για τον υπολογισμό κύκλων",
"Min circle radius": "Min circle radius", "Min circle radius": "Ελάχιστη ακτίνα κύκλου",
"Max circle radius": "Max circle radius", "Max circle radius": "Μέγιστη ακτίνα κύκλου",
"Display the open browser control": "Display the open browser control", "Display the open browser control": "Εμφάνιση του χειριστηρίου ανοικτού προγράμματος περιήγησης",
"Copy as GeoJSON": "Copy as GeoJSON", "Copy as GeoJSON": "Αντιγραφή ως GeoJSON",
"Please zoom in to edit the geometry": "Please zoom in to edit the geometry", "Please zoom in to edit the geometry": "Παρακαλώ εστιάστε για να επεξεργαστείτε τη γεωμετρία",
"New map": "New map", "New map": "Νέος χάρτης",
"My maps": "My maps", "My maps": "Οι χάρτες μου",
"My teams": "My teams", "My teams": "Οι ομάδες μου",
"My profile": "My profile", "My profile": "Το προφίλ μου",
"Type new owner's username": "Type new owner's username", "Type new owner's username": "Πληκτρολογήστε το όνομα χρήστη του νέου ιδιοκτήτη",
"Type editor's username": "Type editor's username", "Type editor's username": "Πληκτρολογήστε το όνομα χρήστη του συντάκτη",
"Map": "Map", "Map": "Χάρτης",
"Manage collaborators": "Manage collaborators", "Manage collaborators": "Διαχείριση συνεργατών",
"show/hide all layers": "show/hide all layers", "show/hide all layers": "εμφάνιση/απόκρυψη όλων των επιπέδων",
"zoom to data extent": "zoom to data extent", "zoom to data extent": "εστίαση στην έκταση των δεδομένων",
"download visible data": "download visible data", "download visible data": "λήψη ορατών δεδομένων",
"Import helpers": "Import helpers", "Import helpers": "Βοηθοί εισαγωγής",
"Import helpers will fill the URL field for you.": "Import helpers will fill the URL field for you.", "Import helpers will fill the URL field for you.": "Οι βοηθοί εισαγωγής θα συμπληρώσουν το πεδίο URL για εσάς.",
"Wikipedia": "Wikipedia", "Wikipedia": "Wikipedia",
"Save draft": "Save draft", "Save draft": "Αποθήκευση προσχεδίου",
"No data has been found for import": "No data has been found for import", "No data has been found for import": "Δεν βρέθηκαν δεδομένα για την εισαγωγή",
"Successfully imported {count} feature(s)": "Successfully imported {count} feature(s)", "Successfully imported {count} feature(s)": "Εισήχθησαν επιτυχώς {count} χαρακτηριστικό(ά)",
"Disconnected": "Disconnected", "Disconnected": "Αποσυνδεδεμένο",
"You must be logged in": "You must be logged in", "You must be logged in": "Πρέπει να συνδεθείτε",
"on hover": "on hover", "on hover": "στην αιώρηση",
"Cannot load remote data for layer \"{layer}\" with url \"{url}\"": "Cannot load remote data for layer \"{layer}\" with url \"{url}\"", "Cannot load remote data for layer \"{layer}\" with url \"{url}\"": "Δεν είναι δυνατή η φόρτωση απομακρυσμένων δεδομένων για το επίπεδο \"{layer}\" με url \"{url}\"",
"Cannot parse remote data for layer \"{layer}\" with url \"{url}\"": "Cannot parse remote data for layer \"{layer}\" with url \"{url}\"", "Cannot parse remote data for layer \"{layer}\" with url \"{url}\"": "Δεν είναι δυνατή η ανάλυση απομακρυσμένων δεδομένων για το επίπεδο \"{layer}\" με url \"{url}\"",
"Import failed: invalid data": "Import failed: invalid data", "Import failed: invalid data": "Η εισαγωγή απέτυχε: μη έγκυρα δεδομένα",
"Anonymous": "Anonymous", "Anonymous": "Ανώνυμος",
"created at {date}": "created at {date}", "created at {date}": "δημιουργήθηκε {ημερομηνία}",
"modified at {date}": "modified at {date}", "modified at {date}": "τροποποιήθηκε {ημερομηνία}",
"Default zoom": "Default zoom", "Default zoom": "Προκαθορισμένη εστίαση",
"Default latitude": "Default latitude", "Default latitude": "Προκαθορισμένο γεωγραφικό πλάτος",
"Default longitude": "Default longitude", "Default longitude": "Προκαθορισμένο γεωγραφικό μήκος",
"Edit map default view": "Edit map default view", "Edit map default view": "Επεξεργασία προεπιλεγμένης προβολής χάρτη",
"Use current center and zoom": "Use current center and zoom", "Use current center and zoom": "Χρήση τρέχοντος κέντρου και εστίασης",
"Layer permalink": "Layer permalink", "Layer permalink": "νιμο url του επιπέδου",
"Back to home": "Back to home", "Back to home": "Επιστροφή στην αρχική σελίδα",
"Home logo": "Home logo", "Home logo": "Λογότυπο αρχικής σελίδας",
"Add this geometry to my map": "Add this geometry to my map", "Add this geometry to my map": "Προσθήκη αυτής της γεωμετρίας στο χάρτη μου",
"Add this place to my map": "Add this place to my map", "Add this place to my map": "Προσθήκη αυτής της τοποθεσίας στον χάρτη μου",
"Cancel last edit": "Cancel last edit", "Cancel last edit": "Ακύρωση τελευταίας επεξεργασίας",
"Redo last edit": "Redo last edit", "Redo last edit": "Αναίρεση ακύρωσης τελευταίας επεξεργασίας",
"Links": "Links", "Links": "Σύνδεσμοι",
"Images": "Images", "Images": "Εικόνες",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Ετικέτες",
"Geocode": "Geocode" "Geocode": "Γεωκωδικοποίηση",
"Display the back to home icon": "Εμφάνιση του εικονιδίου επιστροφής στην αρχική σελίδα",
"Do you want to display layer switcher in caption bar?": "Θέλετε να εμφανίσετε τον διακόπτη επιπέδων στη γραμμή λεζάντας;",
"Simplify all geometries to points": "Απλοποίηση όλων των γεωμετριών σε σημεία",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("el", locale) L.registerLocale("el", locale)
L.setLocale("el") L.setLocale("el")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Αίτημα μεσολάβησης προσωρινής μνήμης", "Cache proxied request": "Αίτημα μεσολάβησης προσωρινής μνήμης",
"Caption": "Λεζάντα", "Caption": "Λεζάντα",
"Center map on your location": "Κεντράρισμα του χάρτη στην τοποθεσία σας", "Center map on your location": "Κεντράρισμα του χάρτη στην τοποθεσία σας",
"Change map background": "Αλλαγή υποβάθρου του χάρτη",
"Change tilelayers": "Αλλαγή χαρτογραφικού υπόβαθρου", "Change tilelayers": "Αλλαγή χαρτογραφικού υπόβαθρου",
"Change": "Αλλαγή", "Change": "Αλλαγή",
"Choose the data format": "Επιλογή μορφοποίησης δεδομένων", "Choose the data format": "Επιλογή μορφοποίησης δεδομένων",
@ -434,109 +433,115 @@
"key~value (eg. name~Grisy)": "κλειδί~τιμή (π.χ. όνομα~Grisy)", "key~value (eg. name~Grisy)": "κλειδί~τιμή (π.χ. όνομα~Grisy)",
"key=\"value|value2\" (eg. name=\"Paris|Berlin\")": "κλειδί=\"value|value2\" (eg. όνομα=\"Παρίσι|Βερολίνο\")", "key=\"value|value2\" (eg. name=\"Paris|Berlin\")": "κλειδί=\"value|value2\" (eg. όνομα=\"Παρίσι|Βερολίνο\")",
"More info about Overpass syntax": "Περισσότερες πληροφορίες σχετικά με τη σύνταξη της Υπέρβασης", "More info about Overpass syntax": "Περισσότερες πληροφορίες σχετικά με τη σύνταξη της Υπέρβασης",
"For more complex needs, see": "For more complex needs, see", "For more complex needs, see": "Για πιο σύνθετες ανάγκες, βλ.",
"Choose data": "Choose data", "Choose data": "Επιλογή δεδομένων",
"Choose the format": "Choose the format", "Choose the format": "Επιλογή μορφοποίησης",
"Choose the layer": "Choose the layer", "Choose the layer": "Επιλογή επιπέδου",
"Layer name": "Layer name", "Layer name": "Όνομα επιπέδου",
"Choose import mode": "Choose import mode", "Choose import mode": "Επιλογή τρόπου εισαγωγής",
"Copy into the layer": "Copy into the layer", "Copy into the layer": "Αντιγραφή στο επίπεδο",
"Link to the layer as remote data": "Link to the layer as remote data", "Link to the layer as remote data": "Σύνδεση με το επίπεδο ως απομακρυσμένα δεδομένα",
"Condition": "Συνθήκη", "Condition": "Συνθήκη",
"key=value or key!=value": "key=value ή key!=value", "key=value or key!=value": "key=value ή key!=value",
"Are you sure you want to delete this rule?": "Θέλετε σίγουρα να διαγραφεί αυτός ο κανόνας;", "Are you sure you want to delete this rule?": "Θέλετε σίγουρα να διαγραφεί αυτός ο κανόνας;",
"empty rule": "κενός κανόνας", "empty rule": "κενός κανόνας",
"Conditional style rules": "Κανόνες μορφοποίησης υπό όρους", "Conditional style rules": "Κανόνες μορφοποίησης υπό όρους",
"Add rule": "Προσθήκη κανόνα", "Add rule": "Προσθήκη κανόνα",
"Browser: data": "Browser: data", "Browser: data": "Περιηγητής: δεδομένα",
"Browser: layers": "Browser: layers", "Browser: layers": "Περιηγητής: επίπεδα",
"Browser: filters": "Browser: filters", "Browser: filters": "Περιηγητής: φίλτρα",
"Enable real-time collaboration": "Enable real-time collaboration", "Enable real-time collaboration": "Ενεργοποίηση συνεργασίας σε πραγματικό χρόνο",
"✅ Copied!": "✅ Αντιγράφηκε!", "✅ Copied!": "✅ Αντιγράφηκε!",
"Choose a dataset": "Choose a dataset", "Choose a dataset": "Επιλογή συνόλου δεδομένων",
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Επιλογή αυτού του συνόλου δεδομένων",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: θεματικά δεδομένα από το OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Επιλογή θέματος",
"Symplify all geometries to points": "Symplify all geometries to points", "Choose this data": "Επιλογή αυτών των δεδομένων",
"Choose this data": "Choose this data",
"Search admin boundary": "Αναζήτηση διοικητικού ορίου", "Search admin boundary": "Αναζήτηση διοικητικού ορίου",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Επιλέξτε πρώτα ένα θέμα και ένα όριο.",
"Expression": "Έκφραση", "Expression": "Έκφραση",
"Geometry mode": "Λειτουργία γεωμετρίας", "Geometry mode": "Λειτουργία γεωμετρίας",
"Only geometry centers": "Only geometry centers", "Only geometry centers": "Μόνο γεωμετρικά κέντρα",
"Search area": "Search area", "Search area": "Περιοχή αναζήτησης",
"Type area name, or let empty to load data in current map view": "Type area name, or let empty to load data in current map view", "Type area name, or let empty to load data in current map view": "Πληκτρολογήστε το όνομα της περιοχής ή αφήστε το κενό, για να φορτώσετε δεδομένα στην τρέχουσα προβολή χάρτη.",
"Data successfully imported!": "Data successfully imported!", "Data successfully imported!": "Τα δεδομένα εισήχθησαν επιτυχώς!",
"Clear data": "Clear data", "Clear data": "Εκκαθάριση δεδομένων",
"Remove layers": "Remove layers", "Remove layers": "Αφαίρεση επιπέδων",
"Categorized": "Categorized", "Categorized": "Κατηγοριοποιημένο",
"Alphabetical": "Alphabetical", "Alphabetical": "Αλφαβητικά",
"Category property": "Category property", "Category property": "Ιδιότητα κατηγορίας",
"Color palette": "Παλέτα χρωμάτων", "Color palette": "Παλέτα χρωμάτων",
"Categories": "Κατηγορίες", "Categories": "Κατηγορίες",
"Comma separated list of categories.": "Λίστα κατηγοριών χωρισμένες με κόμμα.", "Comma separated list of categories.": "Λίστα κατηγοριών χωρισμένες με κόμμα.",
"Categories mode": "Λειτουργία κατηγοριών", "Categories mode": "Λειτουργία κατηγοριών",
"Remove filter for this column": "Remove filter for this column", "Remove filter for this column": "Αφαίρεση φίλτρου από αυτή τη στήλη",
"Add filter for this column": "Add filter for this column", "Add filter for this column": "Προσθήκη φίλτρου από αυτή τη στήλη",
"Rename this column": "Rename this column", "Rename this column": "Μετονομασία αυτής της στήλης",
"Delete this column": "Delete this column", "Delete this column": "Διαγραφή αυτής της στήλης",
"Name “{name}” should not contain a dot.": "Name “{name}” should not contain a dot.", "Name “{name}” should not contain a dot.": "Το όνομα \"{name}\" δεν πρέπει να περιέχει τελεία.",
"This name already exists: “{name}”": "This name already exists: “{name}”", "This name already exists: “{name}”": "Αυτό το όνομα υπάρχει ήδη: \"{name}\"",
"Delete selected rows": "Delete selected rows", "Delete selected rows": "Διαγραφή επιλεγμένων γραμμών",
"Found {count} rows. Are you sure you want to delete all?": "Found {count} rows. Are you sure you want to delete all?", "Found {count} rows. Are you sure you want to delete all?": "Βρέθηκαν {count} σειρές. Είστε σίγουροι ότι θέλετε να τις διαγράψετε όλες;",
"Expression is empty": "Η έκφραση είναι κενή", "Expression is empty": "Η έκφραση είναι κενή",
"OK": "OK", "OK": "OK",
"Cancel": "Άκυρο", "Cancel": "Άκυρο",
"Attach map to a team": "Attach map to a team", "Attach map to a team": "Σύνδεση χάρτη με μια ομάδα",
"Display the polygon inverted": "Display the polygon inverted", "Display the polygon inverted": "Εμφανίζει το πολύγωνο ανεστραμμένο",
"Proportional circles": "Proportional circles", "Proportional circles": "Αναλογικοί κύκλοι",
"Property name to compute circles": "Property name to compute circles", "Property name to compute circles": "Όνομα ιδιότητας για τον υπολογισμό κύκλων",
"Min circle radius": "Min circle radius", "Min circle radius": "Ελάχιστη ακτίνα κύκλου",
"Max circle radius": "Max circle radius", "Max circle radius": "Μέγιστη ακτίνα κύκλου",
"Display the open browser control": "Display the open browser control", "Display the open browser control": "Εμφάνιση του χειριστηρίου ανοικτού προγράμματος περιήγησης",
"Copy as GeoJSON": "Copy as GeoJSON", "Copy as GeoJSON": "Αντιγραφή ως GeoJSON",
"Please zoom in to edit the geometry": "Please zoom in to edit the geometry", "Please zoom in to edit the geometry": "Παρακαλώ εστιάστε για να επεξεργαστείτε τη γεωμετρία",
"New map": "New map", "New map": "Νέος χάρτης",
"My maps": "My maps", "My maps": "Οι χάρτες μου",
"My teams": "My teams", "My teams": "Οι ομάδες μου",
"My profile": "My profile", "My profile": "Το προφίλ μου",
"Type new owner's username": "Type new owner's username", "Type new owner's username": "Πληκτρολογήστε το όνομα χρήστη του νέου ιδιοκτήτη",
"Type editor's username": "Type editor's username", "Type editor's username": "Πληκτρολογήστε το όνομα χρήστη του συντάκτη",
"Map": "Map", "Map": "Χάρτης",
"Manage collaborators": "Manage collaborators", "Manage collaborators": "Διαχείριση συνεργατών",
"show/hide all layers": "show/hide all layers", "show/hide all layers": "εμφάνιση/απόκρυψη όλων των επιπέδων",
"zoom to data extent": "zoom to data extent", "zoom to data extent": "εστίαση στην έκταση των δεδομένων",
"download visible data": "download visible data", "download visible data": "λήψη ορατών δεδομένων",
"Import helpers": "Import helpers", "Import helpers": "Βοηθοί εισαγωγής",
"Import helpers will fill the URL field for you.": "Import helpers will fill the URL field for you.", "Import helpers will fill the URL field for you.": "Οι βοηθοί εισαγωγής θα συμπληρώσουν το πεδίο URL για εσάς.",
"Wikipedia": "Wikipedia", "Wikipedia": "Wikipedia",
"Save draft": "Save draft", "Save draft": "Αποθήκευση προσχεδίου",
"No data has been found for import": "No data has been found for import", "No data has been found for import": "Δεν βρέθηκαν δεδομένα για την εισαγωγή",
"Successfully imported {count} feature(s)": "Successfully imported {count} feature(s)", "Successfully imported {count} feature(s)": "Εισήχθησαν επιτυχώς {count} χαρακτηριστικό(ά)",
"Disconnected": "Disconnected", "Disconnected": "Αποσυνδεδεμένο",
"You must be logged in": "You must be logged in", "You must be logged in": "Πρέπει να συνδεθείτε",
"on hover": "on hover", "on hover": "στην αιώρηση",
"Cannot load remote data for layer \"{layer}\" with url \"{url}\"": "Cannot load remote data for layer \"{layer}\" with url \"{url}\"", "Cannot load remote data for layer \"{layer}\" with url \"{url}\"": "Δεν είναι δυνατή η φόρτωση απομακρυσμένων δεδομένων για το επίπεδο \"{layer}\" με url \"{url}\"",
"Cannot parse remote data for layer \"{layer}\" with url \"{url}\"": "Cannot parse remote data for layer \"{layer}\" with url \"{url}\"", "Cannot parse remote data for layer \"{layer}\" with url \"{url}\"": "Δεν είναι δυνατή η ανάλυση απομακρυσμένων δεδομένων για το επίπεδο \"{layer}\" με url \"{url}\"",
"Import failed: invalid data": "Import failed: invalid data", "Import failed: invalid data": "Η εισαγωγή απέτυχε: μη έγκυρα δεδομένα",
"Anonymous": "Anonymous", "Anonymous": "Ανώνυμος",
"created at {date}": "created at {date}", "created at {date}": "δημιουργήθηκε {ημερομηνία}",
"modified at {date}": "modified at {date}", "modified at {date}": "τροποποιήθηκε {ημερομηνία}",
"Default zoom": "Default zoom", "Default zoom": "Προκαθορισμένη εστίαση",
"Default latitude": "Default latitude", "Default latitude": "Προκαθορισμένο γεωγραφικό πλάτος",
"Default longitude": "Default longitude", "Default longitude": "Προκαθορισμένο γεωγραφικό μήκος",
"Edit map default view": "Edit map default view", "Edit map default view": "Επεξεργασία προεπιλεγμένης προβολής χάρτη",
"Use current center and zoom": "Use current center and zoom", "Use current center and zoom": "Χρήση τρέχοντος κέντρου και εστίασης",
"Layer permalink": "Layer permalink", "Layer permalink": "νιμο url του επιπέδου",
"Back to home": "Back to home", "Back to home": "Επιστροφή στην αρχική σελίδα",
"Home logo": "Home logo", "Home logo": "Λογότυπο αρχικής σελίδας",
"Add this geometry to my map": "Add this geometry to my map", "Add this geometry to my map": "Προσθήκη αυτής της γεωμετρίας στο χάρτη μου",
"Add this place to my map": "Add this place to my map", "Add this place to my map": "Προσθήκη αυτής της τοποθεσίας στον χάρτη μου",
"Cancel last edit": "Cancel last edit", "Cancel last edit": "Ακύρωση τελευταίας επεξεργασίας",
"Redo last edit": "Redo last edit", "Redo last edit": "Αναίρεση ακύρωσης τελευταίας επεξεργασίας",
"Links": "Links", "Links": "Σύνδεσμοι",
"Images": "Images", "Images": "Εικόνες",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Ετικέτες",
"Geocode": "Geocode" "Geocode": "Γεωκωδικοποίηση",
"Display the back to home icon": "Εμφάνιση του εικονιδίου επιστροφής στην αρχική σελίδα",
"Do you want to display layer switcher in caption bar?": "Θέλετε να εμφανίσετε τον διακόπτη επιπέδων στη γραμμή λεζάντας;",
"Simplify all geometries to points": "Απλοποίηση όλων των γεωμετριών σε σημεία",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Caption", "Caption": "Caption",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Change map background",
"Change tilelayers": "Change tilelayers", "Change tilelayers": "Change tilelayers",
"Change": "Change", "Change": "Change",
"Choose the data format": "Choose the data format", "Choose the data format": "Choose the data format",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("en", locale) L.registerLocale("en", locale)
L.setLocale("en") L.setLocale("en")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Caption", "Caption": "Caption",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Change map background",
"Change tilelayers": "Change tilelayers", "Change tilelayers": "Change tilelayers",
"Change": "Change", "Change": "Change",
"Choose the data format": "Choose the data format", "Choose the data format": "Choose the data format",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Caption", "Caption": "Caption",
"Center map on your location": "Center map on your location", "Center map on your location": "Center map on your location",
"Change map background": "Change basemap",
"Change tilelayers": "Set map background", "Change tilelayers": "Set map background",
"Change": "Change", "Change": "Change",
"Choose the data format": "Choose...", "Choose the data format": "Choose...",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Almacenar en caché la solicitud de proxy", "Cache proxied request": "Almacenar en caché la solicitud de proxy",
"Caption": "Leyenda", "Caption": "Leyenda",
"Center map on your location": "Centrar el mapa en tu ubicación", "Center map on your location": "Centrar el mapa en tu ubicación",
"Change map background": "Cambiar el fondo del mapa",
"Change tilelayers": "Cambiar capas de teselas", "Change tilelayers": "Cambiar capas de teselas",
"Change": "Cambiar", "Change": "Cambiar",
"Choose the data format": "Elegir el formato de datos", "Choose the data format": "Elegir el formato de datos",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Elegir este conjunto de datos", "Choose this dataset": "Elegir este conjunto de datos",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: datos temáticos de OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: datos temáticos de OpenStreetMap",
"Choose a theme": "Elegir un tema", "Choose a theme": "Elegir un tema",
"Symplify all geometries to points": "Simplificar todas las geometrías a puntos",
"Choose this data": "Elegir estos datos", "Choose this data": "Elegir estos datos",
"Search admin boundary": "Buscar límite administrativo", "Search admin boundary": "Buscar límite administrativo",
"Please choose a theme and a boundary first.": "Primero elige un tema y un límite.", "Please choose a theme and a boundary first.": "Primero elige un tema y un límite.",
@ -527,18 +525,25 @@ const locale = {
"Default longitude": "Longitud predeterminada", "Default longitude": "Longitud predeterminada",
"Edit map default view": "Editar vista predeterminada del mapa", "Edit map default view": "Editar vista predeterminada del mapa",
"Use current center and zoom": "Usar el centro y zoom actuales", "Use current center and zoom": "Usar el centro y zoom actuales",
"Layer permalink": "Layer permalink", "Layer permalink": "Enlace permanente de la capa",
"Back to home": "Back to home", "Back to home": "Volver al inicio",
"Home logo": "Home logo", "Home logo": "Logo de inicio",
"Add this geometry to my map": "Add this geometry to my map", "Add this geometry to my map": "Agregar esta geometría a mi mapa",
"Add this place to my map": "Add this place to my map", "Add this place to my map": "Agregar este lugar a mi mapa",
"Cancel last edit": "Cancel last edit", "Cancel last edit": "Cancelar la última edición",
"Redo last edit": "Redo last edit", "Redo last edit": "Rehacer la última edición",
"Links": "Links", "Links": "Enlaces",
"Images": "Images", "Images": "Imágenes",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Etiquetas",
"Geocode": "Geocode" "Geocode": "Geocodificar",
"Display the back to home icon": "Mostrar el ícono de volver al inicio",
"Do you want to display layer switcher in caption bar?": "¿Quieres mostrar el selector de capas en la barra de título?",
"Simplify all geometries to points": "Simplificar todas las geometrías a puntos",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("es", locale) L.registerLocale("es", locale)
L.setLocale("es") L.setLocale("es")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Almacenar en caché la solicitud de proxy", "Cache proxied request": "Almacenar en caché la solicitud de proxy",
"Caption": "Leyenda", "Caption": "Leyenda",
"Center map on your location": "Centrar el mapa en tu ubicación", "Center map on your location": "Centrar el mapa en tu ubicación",
"Change map background": "Cambiar el fondo del mapa",
"Change tilelayers": "Cambiar capas de teselas", "Change tilelayers": "Cambiar capas de teselas",
"Change": "Cambiar", "Change": "Cambiar",
"Choose the data format": "Elegir el formato de datos", "Choose the data format": "Elegir el formato de datos",
@ -457,7 +456,6 @@
"Choose this dataset": "Elegir este conjunto de datos", "Choose this dataset": "Elegir este conjunto de datos",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: datos temáticos de OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: datos temáticos de OpenStreetMap",
"Choose a theme": "Elegir un tema", "Choose a theme": "Elegir un tema",
"Symplify all geometries to points": "Simplificar todas las geometrías a puntos",
"Choose this data": "Elegir estos datos", "Choose this data": "Elegir estos datos",
"Search admin boundary": "Buscar límite administrativo", "Search admin boundary": "Buscar límite administrativo",
"Please choose a theme and a boundary first.": "Primero elige un tema y un límite.", "Please choose a theme and a boundary first.": "Primero elige un tema y un límite.",
@ -527,16 +525,23 @@
"Default longitude": "Longitud predeterminada", "Default longitude": "Longitud predeterminada",
"Edit map default view": "Editar vista predeterminada del mapa", "Edit map default view": "Editar vista predeterminada del mapa",
"Use current center and zoom": "Usar el centro y zoom actuales", "Use current center and zoom": "Usar el centro y zoom actuales",
"Layer permalink": "Layer permalink", "Layer permalink": "Enlace permanente de la capa",
"Back to home": "Back to home", "Back to home": "Volver al inicio",
"Home logo": "Home logo", "Home logo": "Logo de inicio",
"Add this geometry to my map": "Add this geometry to my map", "Add this geometry to my map": "Agregar esta geometría a mi mapa",
"Add this place to my map": "Add this place to my map", "Add this place to my map": "Agregar este lugar a mi mapa",
"Cancel last edit": "Cancel last edit", "Cancel last edit": "Cancelar la última edición",
"Redo last edit": "Redo last edit", "Redo last edit": "Rehacer la última edición",
"Links": "Links", "Links": "Enlaces",
"Images": "Images", "Images": "Imágenes",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Etiquetas",
"Geocode": "Geocode" "Geocode": "Geocodificar",
"Display the back to home icon": "Mostrar el ícono de volver al inicio",
"Do you want to display layer switcher in caption bar?": "¿Quieres mostrar el selector de capas en la barra de título?",
"Simplify all geometries to points": "Simplificar todas las geometrías a puntos",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Legend", "Caption": "Legend",
"Center map on your location": "Sea oma asukoht keskpunktiks", "Center map on your location": "Sea oma asukoht keskpunktiks",
"Change map background": "Vaheta kaardi taust",
"Change tilelayers": "Vaheta kaardi taust", "Change tilelayers": "Vaheta kaardi taust",
"Change": "Change", "Change": "Change",
"Choose the data format": "Vali andmevorming", "Choose the data format": "Vali andmevorming",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("et", locale) L.registerLocale("et", locale)
L.setLocale("et") L.setLocale("et")

View file

@ -45,7 +45,6 @@
"Cache proxied request": "Cache proxied request", "Cache proxied request": "Cache proxied request",
"Caption": "Legend", "Caption": "Legend",
"Center map on your location": "Sea oma asukoht keskpunktiks", "Center map on your location": "Sea oma asukoht keskpunktiks",
"Change map background": "Vaheta kaardi taust",
"Change tilelayers": "Vaheta kaardi taust", "Change tilelayers": "Vaheta kaardi taust",
"Change": "Change", "Change": "Change",
"Choose the data format": "Vali andmevorming", "Choose the data format": "Vali andmevorming",
@ -457,7 +456,6 @@
"Choose this dataset": "Choose this dataset", "Choose this dataset": "Choose this dataset",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
"Choose a theme": "Choose a theme", "Choose a theme": "Choose a theme",
"Symplify all geometries to points": "Symplify all geometries to points",
"Choose this data": "Choose this data", "Choose this data": "Choose this data",
"Search admin boundary": "Search admin boundary", "Search admin boundary": "Search admin boundary",
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.", "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@ -538,5 +536,12 @@
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }

View file

@ -45,7 +45,6 @@ const locale = {
"Cache proxied request": "Cache proxy eskaera", "Cache proxied request": "Cache proxy eskaera",
"Caption": "Testua", "Caption": "Testua",
"Center map on your location": "Zentratu mapa zure kokapenean", "Center map on your location": "Zentratu mapa zure kokapenean",
"Change map background": "Aldatu maparen atzeko planoa",
"Change tilelayers": "Aldatu lauzen geruza", "Change tilelayers": "Aldatu lauzen geruza",
"Change": "Aldatu", "Change": "Aldatu",
"Choose the data format": "Aukeratu data-formatua", "Choose the data format": "Aukeratu data-formatua",
@ -457,7 +456,6 @@ const locale = {
"Choose this dataset": "Aukeratu datu-multzo hau", "Choose this dataset": "Aukeratu datu-multzo hau",
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: OpenStreetMap-eko datu tematikoak", "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: OpenStreetMap-eko datu tematikoak",
"Choose a theme": "Aukeratu gai bat", "Choose a theme": "Aukeratu gai bat",
"Symplify all geometries to points": "Sinplifikatu geometria guztiak puntutan",
"Choose this data": "Aukeratu datu hauek", "Choose this data": "Aukeratu datu hauek",
"Search admin boundary": "Bilatu muga administratiboa", "Search admin boundary": "Bilatu muga administratiboa",
"Please choose a theme and a boundary first.": "Aukeratu gai bat eta muga bat.", "Please choose a theme and a boundary first.": "Aukeratu gai bat eta muga bat.",
@ -538,7 +536,14 @@ const locale = {
"Images": "Images", "Images": "Images",
"Iframes": "Iframes", "Iframes": "Iframes",
"Tags": "Tags", "Tags": "Tags",
"Geocode": "Geocode" "Geocode": "Geocode",
"Display the back to home icon": "Display the back to home icon",
"Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
"Simplify all geometries to points": "Simplify all geometries to points",
"Back to list": "Back to list",
"Toggle rule": "Toggle rule",
"Delete rule": "Delete rule",
"Cannot save layer, please try again in a few minutes.": "Cannot save layer, please try again in a few minutes."
} }
L.registerLocale("eu", locale) L.registerLocale("eu", locale)
L.setLocale("eu") L.setLocale("eu")

Some files were not shown because too many files have changed in this diff Show more