diff --git a/Docs/BuiltinIndex.md b/Docs/BuiltinIndex.md
index 75a5ccafb4..5e79db2e1f 100644
--- a/Docs/BuiltinIndex.md
+++ b/Docs/BuiltinIndex.md
@@ -21,6 +21,7 @@
+ [description](#description)
+ [payment-options](#payment-options)
+ [payment-options-advanced](#payment-options-advanced)
+ + [payment-options-split](#payment-options-split)
+ [opening_hours_24_7](#opening_hours_24_7)
+ [level](#level)
+ [bicycle_rental.*bicycle_rental](#bicycle_rental*bicycle_rental)
@@ -46,7 +47,6 @@
+ [opening_hours_by_appointment](#opening_hours_by_appointment)
+ [multilevels](#multilevels)
+ [induction-loop](#induction-loop)
- + [payment-options-split](#payment-options-split)
+ [denominations-coins](#denominations-coins)
+ [check_date](#check_date)
+ [all_tags](#all_tags)
@@ -56,6 +56,7 @@
+ [mastodon](#mastodon)
+ [contact](#contact)
+ [etymology.wikipedia-etymology](#etymologywikipedia-etymology)
+ + [toilet.relevant-questions](#toiletrelevant-questions)
+ [denominations-notes](#denominations-notes)
+ [single_level](#single_level)
+ [survey_date](#survey_date)
@@ -410,6 +411,23 @@
+### payment-options-split
+
+
+
+
+
+ - bicycle_tube_vending_machine
+ - elongated_coin
+ - parking_ticket_machine
+ - shower
+ - ticket_machine
+ - toilet
+ - vending_machine
+
+
+
+
### opening_hours_24_7
@@ -753,22 +771,6 @@
-### payment-options-split
-
-
-
-
-
- - elongated_coin
- - parking_ticket_machine
- - shower
- - ticket_machine
- - toilet
- - vending_machine
-
-
-
-
### denominations-coins
@@ -866,6 +868,17 @@
+ - indoors
+
+
+
+
+### toilet.relevant-questions
+
+
+
+
+
- indoors
diff --git a/Docs/Layers/all_vending_machine.md b/Docs/Layers/all_vending_machine.md
index 469cc7e90d..a099628927 100644
--- a/Docs/Layers/all_vending_machine.md
+++ b/Docs/Layers/all_vending_machine.md
@@ -47,7 +47,7 @@ this quick overview is incomplete
attribute | type | values which are supported by this layer
----------- | ------ | ------------------------------------------
[
](https://taginfo.openstreetmap.org/keys/id#values) [id](https://wiki.openstreetmap.org/wiki/Key:id) | Multiple choice |
-[
](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | [string](../SpecialInputElements.md#string) | [drinks](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddrinks) [sweets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dsweets) [food](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfood) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcigarettes) [condoms](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcondoms) [coffee](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcoffee) [water](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dwater) [newspapers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dnewspapers) [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [milk](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmilk) [bread](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbread) [eggs](https://wiki.openstreetmap.org/wiki/Tag:vending%3Deggs) [cheese](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcheese) [honey](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dhoney) [potatoes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpotatoes) [flowers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dflowers) [parking_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dparking_tickets) [elongated_coin](https://wiki.openstreetmap.org/wiki/Tag:vending%3Delongated_coin) [public_transport_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpublic_transport_tickets) [meat](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmeat)
+[
](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | [string](../SpecialInputElements.md#string) | [drinks](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddrinks) [sweets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dsweets) [food](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfood) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcigarettes) [condoms](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcondoms) [coffee](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcoffee) [water](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dwater) [newspapers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dnewspapers) [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [milk](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmilk) [bread](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbread) [eggs](https://wiki.openstreetmap.org/wiki/Tag:vending%3Deggs) [cheese](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcheese) [honey](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dhoney) [potatoes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpotatoes) [meat](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmeat) [flowers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dflowers) [parking_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dparking_tickets) [elongated_coin](https://wiki.openstreetmap.org/wiki/Tag:vending%3Delongated_coin) [public_transport_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpublic_transport_tickets) [bicycle_light](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_light) [gloves](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dgloves) [bicycle_repair_kit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_repair_kit) [bicycle_pump](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_pump) [bicycle_lock](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_lock)
[
](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | [24/7](https://wiki.openstreetmap.org/wiki/Tag:opening_hours%3D24/7)
[
](https://taginfo.openstreetmap.org/keys/payment:coins:denominations#values) [payment:coins:denominations](https://wiki.openstreetmap.org/wiki/Key:payment:coins:denominations) | Multiple choice | [0.01 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.01 EUR) [0.02 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.02 EUR) [0.05 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.05 EUR) [0.10 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.10 EUR) [0.20 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.20 EUR) [0.50 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.50 EUR) [1 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D1 EUR) [2 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D2 EUR) [0.05 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.05 CHF) [0.10 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.10 CHF) [0.20 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.20 CHF) [0.50 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.50 CHF) [1 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D1 CHF) [2 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D2 CHF) [5 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D5 CHF)
[
](https://taginfo.openstreetmap.org/keys/payment:notes:denominations#values) [payment:notes:denominations](https://wiki.openstreetmap.org/wiki/Key:payment:notes:denominations) | Multiple choice | [5 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D5 EUR) [10 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D10 EUR) [20 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D20 EUR) [50 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D50 EUR) [100 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D100 EUR) [200 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D200 EUR) [500 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D500 EUR) [10 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D10 CHF) [20 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D20 CHF) [50 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D50 CHF) [100 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D100 CHF) [200 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D200 CHF) [1000 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D1000 CHF)
@@ -119,11 +119,16 @@ This is rendered with `This vending machine sells {vending}`
- *Cheese is sold* corresponds with `vending=cheese`
- *Honey is sold* corresponds with `vending=honey`
- *Potatoes are sold* corresponds with `vending=potatoes`
+ - *Meat is sold* corresponds with `vending=meat`
- *Flowers are sold* corresponds with `vending=flowers`
- *Parking tickets are sold* corresponds with `vending=parking_tickets`
- *Pressed pennies are sold* corresponds with `vending=elongated_coin`
- *Public transport tickets are sold* corresponds with `vending=public_transport_tickets`
- - *Meat products are being sold* corresponds with `vending=meat`
+ - *Bicycle lights are sold* corresponds with `vending=bicycle_light`
+ - *Gloves are sold* corresponds with `vending=gloves`
+ - *Bicycle repair kits are sold* corresponds with `vending=bicycle_repair_kit`
+ - *Bicycle pumps are sold* corresponds with `vending=bicycle_pump`
+ - *Bicycle locks are sold* corresponds with `vending=bicycle_lock`
@@ -429,11 +434,16 @@ vending.12 | Sale of eggs | vending~^(.*eggs.*)$
vending.13 | Sale of cheese | vending~^(.*cheese.*)$
vending.14 | Sale of honey | vending~^(.*honey.*)$
vending.15 | Sale of potatoes | vending~^(.*potatoes.*)$
-vending.16 | Sale of flowers | vending~^(.*flowers.*)$
-vending.17 | Sale of parking | vending~^(.*parking_tickets.*)$
-vending.18 | Sale of pressed pennies | vending=elongated_coin
-vending.19 | Sale of public transport tickets | vending~^(.*public_transport_tickets.*)$
-vending.20 | Sale of meat products | vending=meat
+vending.16 | Sale of meat | vending~^(.*meat.*)$
+vending.17 | Sale of flowers | vending~^(.*flowers.*)$
+vending.18 | Sale of parking tickets | vending~^(.*parking_tickets.*)$
+vending.19 | Sale of pressed pennies | vending=elongated_coin
+vending.20 | Sale of public transport tickets | vending~^(.*public_transport_tickets.*)$
+vending.21 | Sale of bicycle lights | vending=bicycle_light
+vending.22 | Sale of gloves | vending=gloves
+vending.23 | Sale of bicycle repair kits | vending=bicycle_repair_kit
+vending.24 | Sale of bicycle pumps | vending=bicycle_pump
+vending.25 | Sale of bicycle locks | vending=bicycle_lock
This document is autogenerated from [assets/themes/vending_machine/vending_machine.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/vending_machine/vending_machine.json)
diff --git a/Docs/Layers/bicycle_tube_vending_machine.md b/Docs/Layers/bicycle_tube_vending_machine.md
index 5a127bab09..2859ae3448 100644
--- a/Docs/Layers/bicycle_tube_vending_machine.md
+++ b/Docs/Layers/bicycle_tube_vending_machine.md
@@ -51,6 +51,7 @@ attribute | type | values which are supported by this layer
[
](https://taginfo.openstreetmap.org/keys/charge#values) [charge](https://wiki.openstreetmap.org/wiki/Key:charge) | [string](../SpecialInputElements.md#string) |
[
](https://taginfo.openstreetmap.org/keys/brand#values) [brand](https://wiki.openstreetmap.org/wiki/Key:brand) | [string](../SpecialInputElements.md#string) | [Continental](https://wiki.openstreetmap.org/wiki/Tag:brand%3DContinental) [Schwalbe](https://wiki.openstreetmap.org/wiki/Tag:brand%3DSchwalbe)
[
](https://taginfo.openstreetmap.org/keys/operator#values) [operator](https://wiki.openstreetmap.org/wiki/Key:operator) | [string](../SpecialInputElements.md#string) | [Schwalbe](https://wiki.openstreetmap.org/wiki/Tag:operator%3DSchwalbe) [Continental](https://wiki.openstreetmap.org/wiki/Tag:operator%3DContinental)
+[
](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | Multiple choice | [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [bicycle_light](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_light) [gloves](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dgloves) [bicycle_repair_kit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_repair_kit) [bicycle_pump](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_pump) [bicycle_lock](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_lock)
@@ -121,22 +122,32 @@ This is rendered with `A bicycle tube costs {charge}`
-### vending-machine-payment-methods
+### payment-options-split
-The question is *How can one pay at this tube vending machine?*
+The question is *Which methods of payment are accepted here?*
- - *Payment with coins is possible* corresponds with `payment:coins=yes`
+ - *Cash is accepted here* corresponds with `payment:cash=yes`
+ - This option cannot be chosen as answer
+ - Unselecting this answer will add
+ - *Payment cards are accepted here* corresponds with `payment:cards=yes`
+ - This option cannot be chosen as answer
+ - Unselecting this answer will add
+ - *Payment by QR-code is possible here* corresponds with `payment:qr_code=yes`
+ - Unselecting this answer will add payment:qr_code=no
+ - *Coins are accepted here* corresponds with `payment:coins=yes`
- Unselecting this answer will add payment:coins=no
- - *Payment with notes is possible* corresponds with `payment:notes=yes`
+ - *Bank notes are accepted here* corresponds with `payment:notes=yes`
- Unselecting this answer will add payment:notes=no
- - *Payment with cards is possible* corresponds with `payment:cards=yes`
- - Unselecting this answer will add payment:cards=no
+ - *Debit cards are accepted here* corresponds with `payment:debit_cards=yes`
+ - Unselecting this answer will add payment:debit_cards=no
+ - *Credit cards are accepted here* corresponds with `payment:credit_cards=yes`
+ - Unselecting this answer will add payment:credit_cards=no
@@ -181,26 +192,22 @@ This is rendered with `This vending machine is maintained by {operator}`
-### bicycle_tube_vending_maching-other-items
+### other-items-vending
-The question is *Are other bicycle bicycle accessories sold here?*
+The question is *Are other biycle accessories sold here?*
- - *Bicycle lights are sold here* corresponds with `vending:bicycle_light=yes`
- - Unselecting this answer will add vending:bicycle_light=no
- - *Gloves are sold here* corresponds with `vending:gloves=yes`
- - Unselecting this answer will add vending:gloves=no
- - *Bicycle repair kits are sold here* corresponds with `vending:bicycle_repair_kit=yes`
- - Unselecting this answer will add vending:bicycle_repair_kit=no
- - *Bicycle pumps are sold here* corresponds with `vending:bicycle_pump=yes`
- - Unselecting this answer will add vending:bicycle_pump=no
- - *Bicycle locks are sold here* corresponds with `vending:bicycle_lock=yes`
- - Unselecting this answer will add vending:bicycle_lock=no
+ - *Bicycle inner tubes are sold here* corresponds with `vending=bicycle_tube`
+ - *Bicycle lights are sold here* corresponds with `vending=bicycle_light`
+ - *Gloves are sold here* corresponds with `vending=gloves`
+ - *Bicycle repair kits are sold here* corresponds with `vending=bicycle_repair_kit`
+ - *Bicycle pumps are sold here* corresponds with `vending=bicycle_pump`
+ - *Bicycle locks are sold here* corresponds with `vending=bicycle_lock`
diff --git a/Docs/Layers/indoors.md b/Docs/Layers/indoors.md
index 25feafe577..76a0e44b80 100644
--- a/Docs/Layers/indoors.md
+++ b/Docs/Layers/indoors.md
@@ -55,6 +55,17 @@ attribute | type | values which are supported by this layer
[
](https://taginfo.openstreetmap.org/keys/room#values) [room](https://wiki.openstreetmap.org/wiki/Key:room) | Multiple choice | [administration](https://wiki.openstreetmap.org/wiki/Tag:room%3Dadministration) [auditorium](https://wiki.openstreetmap.org/wiki/Tag:room%3Dauditorium) [bedroom](https://wiki.openstreetmap.org/wiki/Tag:room%3Dbedroom) [chapel](https://wiki.openstreetmap.org/wiki/Tag:room%3Dchapel) [class](https://wiki.openstreetmap.org/wiki/Tag:room%3Dclass) [computer](https://wiki.openstreetmap.org/wiki/Tag:room%3Dcomputer) [conference](https://wiki.openstreetmap.org/wiki/Tag:room%3Dconference) [crypt](https://wiki.openstreetmap.org/wiki/Tag:room%3Dcrypt) [kitchen](https://wiki.openstreetmap.org/wiki/Tag:room%3Dkitchen) [laboratory](https://wiki.openstreetmap.org/wiki/Tag:room%3Dlaboratory) [library](https://wiki.openstreetmap.org/wiki/Tag:room%3Dlibrary) [locker](https://wiki.openstreetmap.org/wiki/Tag:room%3Dlocker) [nursery](https://wiki.openstreetmap.org/wiki/Tag:room%3Dnursery) [office](https://wiki.openstreetmap.org/wiki/Tag:room%3Doffice) [prison_cell](https://wiki.openstreetmap.org/wiki/Tag:room%3Dprison_cell) [restaurant](https://wiki.openstreetmap.org/wiki/Tag:room%3Drestaurant) [security_check](https://wiki.openstreetmap.org/wiki/Tag:room%3Dsecurity_check) [sport](https://wiki.openstreetmap.org/wiki/Tag:room%3Dsport) [storage](https://wiki.openstreetmap.org/wiki/Tag:room%3Dstorage) [technical](https://wiki.openstreetmap.org/wiki/Tag:room%3Dtechnical) [toilets](https://wiki.openstreetmap.org/wiki/Tag:room%3Dtoilets) [waiting](https://wiki.openstreetmap.org/wiki/Tag:room%3Dwaiting)
[
](https://taginfo.openstreetmap.org/keys/capacity#values) [capacity](https://wiki.openstreetmap.org/wiki/Key:capacity) | [pnat](../SpecialInputElements.md#pnat) |
[
](https://taginfo.openstreetmap.org/keys/name:etymology:wikidata#values) [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) | [wikidata](../SpecialInputElements.md#wikidata) |
+[
](https://taginfo.openstreetmap.org/keys/access#values) [access](https://wiki.openstreetmap.org/wiki/Key:access) | [string](../SpecialInputElements.md#string) | [yes](https://wiki.openstreetmap.org/wiki/Tag:access%3Dyes) [customers](https://wiki.openstreetmap.org/wiki/Tag:access%3Dcustomers) [no](https://wiki.openstreetmap.org/wiki/Tag:access%3Dno) [key](https://wiki.openstreetmap.org/wiki/Tag:access%3Dkey)
+[
](https://taginfo.openstreetmap.org/keys/fee#values) [fee](https://wiki.openstreetmap.org/wiki/Key:fee) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:fee%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:fee%3Dno)
+[
](https://taginfo.openstreetmap.org/keys/charge#values) [charge](https://wiki.openstreetmap.org/wiki/Key:charge) | [string](../SpecialInputElements.md#string) |
+[
](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | [24/7](https://wiki.openstreetmap.org/wiki/Tag:opening_hours%3D24/7)
+[
](https://taginfo.openstreetmap.org/keys/wheelchair#values) [wheelchair](https://wiki.openstreetmap.org/wiki/Key:wheelchair) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dno) [designated](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Ddesignated)
+[
](https://taginfo.openstreetmap.org/keys/door:width#values) [door:width](https://wiki.openstreetmap.org/wiki/Key:door:width) | [pfloat](../SpecialInputElements.md#pfloat) |
+[
](https://taginfo.openstreetmap.org/keys/toilets:position#values) [toilets:position](https://wiki.openstreetmap.org/wiki/Key:toilets:position) | Multiple choice | [seated](https://wiki.openstreetmap.org/wiki/Tag:toilets:position%3Dseated) [urinal](https://wiki.openstreetmap.org/wiki/Tag:toilets:position%3Durinal) [squat](https://wiki.openstreetmap.org/wiki/Tag:toilets:position%3Dsquat) [seated;urinal](https://wiki.openstreetmap.org/wiki/Tag:toilets:position%3Dseated;urinal)
+[
](https://taginfo.openstreetmap.org/keys/changing_table#values) [changing_table](https://wiki.openstreetmap.org/wiki/Key:changing_table) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:changing_table%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:changing_table%3Dno)
+[
](https://taginfo.openstreetmap.org/keys/changing_table:location#values) [changing_table:location](https://wiki.openstreetmap.org/wiki/Key:changing_table:location) | [string](../SpecialInputElements.md#string) | [female_toilet](https://wiki.openstreetmap.org/wiki/Tag:changing_table:location%3Dfemale_toilet) [male_toilet](https://wiki.openstreetmap.org/wiki/Tag:changing_table:location%3Dmale_toilet) [wheelchair_toilet](https://wiki.openstreetmap.org/wiki/Tag:changing_table:location%3Dwheelchair_toilet) [dedicated_room](https://wiki.openstreetmap.org/wiki/Tag:changing_table:location%3Ddedicated_room)
+[
](https://taginfo.openstreetmap.org/keys/toilets:handwashing#values) [toilets:handwashing](https://wiki.openstreetmap.org/wiki/Key:toilets:handwashing) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:toilets:handwashing%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:toilets:handwashing%3Dno)
+[
](https://taginfo.openstreetmap.org/keys/toilets:paper_supplied#values) [toilets:paper_supplied](https://wiki.openstreetmap.org/wiki/Key:toilets:paper_supplied) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:toilets:paper_supplied%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:toilets:paper_supplied%3Dno)
@@ -231,6 +242,276 @@ This is rendered with `
Wikipedia article of the name giver
{wikipedia(n
+### toilet-access
+
+
+
+The question is *Are these toilets publicly accessible?*
+
+This rendering asks information about the property [access](https://wiki.openstreetmap.org/wiki/Key:access)
+
+This is rendered with `Access is {access}`
+
+
+
+
+
+ - *Public access* corresponds with `access=yes`
+ - *Only access to customers* corresponds with `access=customers`
+ - *Not accessible* corresponds with `access=no`
+ - *Accessible, but one has to ask a key to enter* corresponds with `access=key`
+ - *Public access* corresponds with `access=public`
+ - This option cannot be chosen as answer
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### toilets-fee
+
+
+
+The question is *Are these toilets free to use?*
+
+
+
+
+
+ - *These are paid toilets* corresponds with `fee=yes`
+ - *Free to use* corresponds with `fee=no`
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets&access!=no`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### toilet-charge
+
+
+
+The question is *How much does one have to pay for these toilets?*
+
+This rendering asks information about the property [charge](https://wiki.openstreetmap.org/wiki/Key:charge)
+
+This is rendered with `The fee is {charge}`
+
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets&fee=yes`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### payment-options-split
+
+
+
+The question is *Which methods of payment are accepted here?*
+
+
+
+
+
+ - *Cash is accepted here* corresponds with `payment:cash=yes`
+ - This option cannot be chosen as answer
+ - Unselecting this answer will add
+ - *Payment cards are accepted here* corresponds with `payment:cards=yes`
+ - This option cannot be chosen as answer
+ - Unselecting this answer will add
+ - *Payment by QR-code is possible here* corresponds with `payment:qr_code=yes`
+ - Unselecting this answer will add payment:qr_code=no
+ - *Coins are accepted here* corresponds with `payment:coins=yes`
+ - Unselecting this answer will add payment:coins=no
+ - *Bank notes are accepted here* corresponds with `payment:notes=yes`
+ - Unselecting this answer will add payment:notes=no
+ - *Debit cards are accepted here* corresponds with `payment:debit_cards=yes`
+ - Unselecting this answer will add payment:debit_cards=no
+ - *Credit cards are accepted here* corresponds with `payment:credit_cards=yes`
+ - Unselecting this answer will add payment:credit_cards=no
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets&fee=yes`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### opening_hours_24_7
+
+
+
+The question is *When are these toilets opened?*
+
+This rendering asks information about the property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours)
+
+This is rendered with `Opening hours
{opening_hours_table(opening_hours)}`
+
+
+
+
+
+ - *24/7 opened (including holidays)* corresponds with `opening_hours=24/7`
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets&access!=no`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### toilets-wheelchair
+
+
+
+The question is *Is there a dedicated toilet for wheelchair users?*
+
+
+
+
+
+ - *There is a dedicated toilet for wheelchair users* corresponds with `wheelchair=yes`
+ - *No wheelchair access* corresponds with `wheelchair=no`
+ - *There is only a dedicated toilet for wheelchair users* corresponds with `wheelchair=designated`
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### wheelchair-door-width
+
+
+
+The question is *What is the width of the door to the wheelchair accessible toilet?*
+
+This rendering asks information about the property [door:width](https://wiki.openstreetmap.org/wiki/Key:door:width)
+
+This is rendered with `The door to the wheelchair-accessible toilet is {canonical(door:width)} wide`
+
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets&wheelchair=yes|wheelchair=designated`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### toilets-type
+
+
+
+The question is *Which kind of toilets are this?*
+
+
+
+
+
+ - *There are only seated toilets* corresponds with `toilets:position=seated`
+ - *There are only urinals here* corresponds with `toilets:position=urinal`
+ - *There are only squat toilets here* corresponds with `toilets:position=squat`
+ - *Both seated toilets and urinals are available here* corresponds with `toilets:position=seated;urinal`
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### toilets-changing-table
+
+
+
+The question is *Is a changing table (to change diapers) available?*
+
+
+
+
+
+ - *A changing table is available* corresponds with `changing_table=yes`
+ - *No changing table is available* corresponds with `changing_table=no`
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### toilet-changing_table:location
+
+
+
+The question is *Where is the changing table located?*
+
+This rendering asks information about the property [changing_table:location](https://wiki.openstreetmap.org/wiki/Key:changing_table:location)
+
+This is rendered with `The changing table is located at {changing_table:location}`
+
+
+
+
+
+ - *The changing table is in the toilet for women. * corresponds with `changing_table:location=female_toilet`
+ - *The changing table is in the toilet for men. * corresponds with `changing_table:location=male_toilet`
+ - *The changing table is in the toilet for wheelchair users. * corresponds with `changing_table:location=wheelchair_toilet`
+ - *The changing table is in a dedicated room. * corresponds with `changing_table:location=dedicated_room`
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets&changing_table=yes`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### toilet-handwashing
+
+
+
+The question is *Do these toilets have a sink to wash your hands?*
+
+
+
+
+
+ - *This toilets have a sink to wash your hands* corresponds with `toilets:handwashing=yes`
+ - *This toilets don't have a sink to wash your hands* corresponds with `toilets:handwashing=no`
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets`
+
+This tagrendering has labels `relevant-questions`
+
+
+
+### toilet-has-paper
+
+
+
+The question is *Does one have to bring their own toilet paper to this toilet?*
+
+
+
+
+
+ - *This toilet is equipped with toilet paper* corresponds with `toilets:paper_supplied=yes`
+ - *You have to bring your own toilet paper to this toilet* corresponds with `toilets:paper_supplied=no`
+
+
+This tagrendering is only visible in the popup if the following condition is met: `amenity=toilets&toilets:position!=urinal`
+
+This tagrendering has labels `relevant-questions`
+
+
+
### leftover-questions
diff --git a/Docs/Layers/toilet.md b/Docs/Layers/toilet.md
index 19e914f89b..a2a4674368 100644
--- a/Docs/Layers/toilet.md
+++ b/Docs/Layers/toilet.md
@@ -161,6 +161,8 @@ This is rendered with `Access is {access}`
- This option cannot be chosen as answer
+This tagrendering has labels `relevant-questions`
+
### toilets-fee
@@ -177,6 +179,8 @@ The question is *Are these toilets free to use?*
- *Free to use* corresponds with `fee=no`
+This tagrendering has labels `relevant-questions`
+
### toilet-charge
@@ -193,6 +197,8 @@ This is rendered with `The fee is {charge}`
This tagrendering is only visible in the popup if the following condition is met: `fee=yes`
+This tagrendering has labels `relevant-questions`
+
### payment-options-split
@@ -225,6 +231,8 @@ The question is *Which methods of payment are accepted here?*
This tagrendering is only visible in the popup if the following condition is met: `fee=yes`
+This tagrendering has labels `relevant-questions`
+
### opening_hours_24_7
@@ -244,6 +252,8 @@ This is rendered with `Opening hours
{opening_hours_table(opening_hours
- *24/7 opened (including holidays)* corresponds with `opening_hours=24/7`
+This tagrendering has labels `relevant-questions`
+
### toilets-wheelchair
@@ -261,6 +271,8 @@ The question is *Is there a dedicated toilet for wheelchair users?*
- *There is only a dedicated toilet for wheelchair users* corresponds with `wheelchair=designated`
+This tagrendering has labels `relevant-questions`
+
### wheelchair-door-width
@@ -277,6 +289,8 @@ This is rendered with `The door to the wheelchair-accessible toilet is {canonic
This tagrendering is only visible in the popup if the following condition is met: `wheelchair=yes|wheelchair=designated`
+This tagrendering has labels `relevant-questions`
+
### toilets-type
@@ -295,6 +309,8 @@ The question is *Which kind of toilets are this?*
- *Both seated toilets and urinals are available here* corresponds with `toilets:position=seated;urinal`
+This tagrendering has labels `relevant-questions`
+
### toilets-changing-table
@@ -311,6 +327,8 @@ The question is *Is a changing table (to change diapers) available?*
- *No changing table is available* corresponds with `changing_table=no`
+This tagrendering has labels `relevant-questions`
+
### toilet-changing_table:location
@@ -335,6 +353,8 @@ This is rendered with `The changing table is located at {changing_table:locatio
This tagrendering is only visible in the popup if the following condition is met: `changing_table=yes`
+This tagrendering has labels `relevant-questions`
+
### toilet-handwashing
@@ -351,6 +371,8 @@ The question is *Do these toilets have a sink to wash your hands?*
- *This toilets don't have a sink to wash your hands* corresponds with `toilets:handwashing=no`
+This tagrendering has labels `relevant-questions`
+
### toilet-has-paper
@@ -367,6 +389,8 @@ The question is *Does one have to bring their own toilet paper to this toilet?*
- *You have to bring your own toilet paper to this toilet* corresponds with `toilets:paper_supplied=no`
+This tagrendering has labels `relevant-questions`
+
### description
diff --git a/Docs/Layers/toilet_at_amenity.md b/Docs/Layers/toilet_at_amenity.md
index 0644230f1b..2e4ea44c3d 100644
--- a/Docs/Layers/toilet_at_amenity.md
+++ b/Docs/Layers/toilet_at_amenity.md
@@ -255,6 +255,8 @@ The question is *Which kind of toilets are this?*
- *Both seated toilets and urinals are available here* corresponds with `toilets:position=seated;urinal`
+This tagrendering has labels `relevant-questions`
+
### toilets-changing-table
@@ -271,6 +273,8 @@ The question is *Is a changing table (to change diapers) available?*
- *No changing table is available* corresponds with `changing_table=no`
+This tagrendering has labels `relevant-questions`
+
### toilet-changing_table:location
@@ -295,6 +299,8 @@ This is rendered with `The changing table is located at {changing_table:locatio
This tagrendering is only visible in the popup if the following condition is met: `changing_table=yes`
+This tagrendering has labels `relevant-questions`
+
### toilet-handwashing
@@ -311,6 +317,8 @@ The question is *Do these toilets have a sink to wash your hands?*
- *This toilets don't have a sink to wash your hands* corresponds with `toilets:handwashing=no`
+This tagrendering has labels `relevant-questions`
+
### toilet-has-paper
@@ -327,6 +335,8 @@ The question is *Does one have to bring their own toilet paper to this toilet?*
- *You have to bring your own toilet paper to this toilet* corresponds with `toilets:paper_supplied=no`
+This tagrendering has labels `relevant-questions`
+
### description
diff --git a/Docs/Layers/vending_machine.md b/Docs/Layers/vending_machine.md
index 5e53008667..3b592ab050 100644
--- a/Docs/Layers/vending_machine.md
+++ b/Docs/Layers/vending_machine.md
@@ -47,7 +47,7 @@ this quick overview is incomplete
attribute | type | values which are supported by this layer
----------- | ------ | ------------------------------------------
[
](https://taginfo.openstreetmap.org/keys/id#values) [id](https://wiki.openstreetmap.org/wiki/Key:id) | Multiple choice |
-[
](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | [string](../SpecialInputElements.md#string) | [drinks](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddrinks) [sweets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dsweets) [food](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfood) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcigarettes) [condoms](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcondoms) [coffee](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcoffee) [water](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dwater) [newspapers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dnewspapers) [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [milk](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmilk) [bread](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbread) [eggs](https://wiki.openstreetmap.org/wiki/Tag:vending%3Deggs) [cheese](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcheese) [honey](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dhoney) [potatoes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpotatoes) [flowers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dflowers) [parking_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dparking_tickets) [elongated_coin](https://wiki.openstreetmap.org/wiki/Tag:vending%3Delongated_coin) [public_transport_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpublic_transport_tickets) [meat](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmeat)
+[
](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | [string](../SpecialInputElements.md#string) | [drinks](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddrinks) [sweets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dsweets) [food](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfood) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcigarettes) [condoms](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcondoms) [coffee](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcoffee) [water](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dwater) [newspapers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dnewspapers) [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [milk](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmilk) [bread](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbread) [eggs](https://wiki.openstreetmap.org/wiki/Tag:vending%3Deggs) [cheese](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcheese) [honey](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dhoney) [potatoes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpotatoes) [meat](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmeat) [flowers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dflowers) [parking_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dparking_tickets) [elongated_coin](https://wiki.openstreetmap.org/wiki/Tag:vending%3Delongated_coin) [public_transport_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpublic_transport_tickets) [bicycle_light](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_light) [gloves](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dgloves) [bicycle_repair_kit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_repair_kit) [bicycle_pump](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_pump) [bicycle_lock](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_lock)
[
](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | [24/7](https://wiki.openstreetmap.org/wiki/Tag:opening_hours%3D24/7)
[
](https://taginfo.openstreetmap.org/keys/payment:coins:denominations#values) [payment:coins:denominations](https://wiki.openstreetmap.org/wiki/Key:payment:coins:denominations) | Multiple choice | [0.01 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.01 EUR) [0.02 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.02 EUR) [0.05 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.05 EUR) [0.10 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.10 EUR) [0.20 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.20 EUR) [0.50 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.50 EUR) [1 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D1 EUR) [2 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D2 EUR) [0.05 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.05 CHF) [0.10 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.10 CHF) [0.20 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.20 CHF) [0.50 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.50 CHF) [1 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D1 CHF) [2 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D2 CHF) [5 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D5 CHF)
[
](https://taginfo.openstreetmap.org/keys/payment:notes:denominations#values) [payment:notes:denominations](https://wiki.openstreetmap.org/wiki/Key:payment:notes:denominations) | Multiple choice | [5 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D5 EUR) [10 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D10 EUR) [20 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D20 EUR) [50 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D50 EUR) [100 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D100 EUR) [200 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D200 EUR) [500 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D500 EUR) [10 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D10 CHF) [20 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D20 CHF) [50 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D50 CHF) [100 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D100 CHF) [200 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D200 CHF) [1000 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D1000 CHF)
@@ -119,11 +119,16 @@ This is rendered with `This vending machine sells {vending}`
- *Cheese is sold* corresponds with `vending=cheese`
- *Honey is sold* corresponds with `vending=honey`
- *Potatoes are sold* corresponds with `vending=potatoes`
+ - *Meat is sold* corresponds with `vending=meat`
- *Flowers are sold* corresponds with `vending=flowers`
- *Parking tickets are sold* corresponds with `vending=parking_tickets`
- *Pressed pennies are sold* corresponds with `vending=elongated_coin`
- *Public transport tickets are sold* corresponds with `vending=public_transport_tickets`
- - *Meat products are being sold* corresponds with `vending=meat`
+ - *Bicycle lights are sold* corresponds with `vending=bicycle_light`
+ - *Gloves are sold* corresponds with `vending=gloves`
+ - *Bicycle repair kits are sold* corresponds with `vending=bicycle_repair_kit`
+ - *Bicycle pumps are sold* corresponds with `vending=bicycle_pump`
+ - *Bicycle locks are sold* corresponds with `vending=bicycle_lock`
@@ -429,11 +434,16 @@ vending.12 | Sale of eggs | vending~^(.*eggs.*)$
vending.13 | Sale of cheese | vending~^(.*cheese.*)$
vending.14 | Sale of honey | vending~^(.*honey.*)$
vending.15 | Sale of potatoes | vending~^(.*potatoes.*)$
-vending.16 | Sale of flowers | vending~^(.*flowers.*)$
-vending.17 | Sale of parking | vending~^(.*parking_tickets.*)$
-vending.18 | Sale of pressed pennies | vending=elongated_coin
-vending.19 | Sale of public transport tickets | vending~^(.*public_transport_tickets.*)$
-vending.20 | Sale of meat products | vending=meat
+vending.16 | Sale of meat | vending~^(.*meat.*)$
+vending.17 | Sale of flowers | vending~^(.*flowers.*)$
+vending.18 | Sale of parking tickets | vending~^(.*parking_tickets.*)$
+vending.19 | Sale of pressed pennies | vending=elongated_coin
+vending.20 | Sale of public transport tickets | vending~^(.*public_transport_tickets.*)$
+vending.21 | Sale of bicycle lights | vending=bicycle_light
+vending.22 | Sale of gloves | vending=gloves
+vending.23 | Sale of bicycle repair kits | vending=bicycle_repair_kit
+vending.24 | Sale of bicycle pumps | vending=bicycle_pump
+vending.25 | Sale of bicycle locks | vending=bicycle_lock
This document is autogenerated from [assets/layers/vending_machine/vending_machine.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/vending_machine/vending_machine.json)
diff --git a/Docs/Layers/waste_basket.md b/Docs/Layers/waste_basket.md
index d916b8de3d..479b1e21ad 100644
--- a/Docs/Layers/waste_basket.md
+++ b/Docs/Layers/waste_basket.md
@@ -49,7 +49,7 @@ this quick overview is incomplete
attribute | type | values which are supported by this layer
----------- | ------ | ------------------------------------------
[
](https://taginfo.openstreetmap.org/keys/id#values) [id](https://wiki.openstreetmap.org/wiki/Key:id) | Multiple choice |
-[
](https://taginfo.openstreetmap.org/keys/waste#values) [waste](https://wiki.openstreetmap.org/wiki/Key:waste) | Multiple choice | [trash](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dtrash) [dog_excrement](https://wiki.openstreetmap.org/wiki/Tag:waste%3Ddog_excrement) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dcigarettes) [drugs](https://wiki.openstreetmap.org/wiki/Tag:waste%3Ddrugs) [sharps](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dsharps) [plastic](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dplastic)
+[
](https://taginfo.openstreetmap.org/keys/waste#values) [waste](https://wiki.openstreetmap.org/wiki/Key:waste) | Multiple choice | [trash](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dtrash) [dog_excrement](https://wiki.openstreetmap.org/wiki/Tag:waste%3Ddog_excrement) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dcigarettes) [drugs](https://wiki.openstreetmap.org/wiki/Tag:waste%3Ddrugs) [sharps](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dsharps) [plastic](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dplastic) [paper](https://wiki.openstreetmap.org/wiki/Tag:waste%3Dpaper)
[
](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | Multiple choice | [dog_excrement_bag](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddog_excrement_bag) [](https://wiki.openstreetmap.org/wiki/Tag:vending%3D)
@@ -104,6 +104,7 @@ The question is *What kind of waste basket is this?*
- *A waste basket for drugs* corresponds with `waste=drugs`
- *A waste basket for needles and other sharp objects* corresponds with `waste=sharps`
- *A waste basket for plastic* corresponds with `waste=plastic`
+ - *A waste basket for paper* corresponds with `waste=paper`
diff --git a/Docs/TagInfo/mapcomplete_cyclofix.json b/Docs/TagInfo/mapcomplete_cyclofix.json
index e2c867d7f3..4a050062cc 100644
--- a/Docs/TagInfo/mapcomplete_cyclofix.json
+++ b/Docs/TagInfo/mapcomplete_cyclofix.json
@@ -988,18 +988,38 @@
"description": "Layer 'Bicycle tube vending machine' shows and asks freeform values for key 'charge' (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')"
},
{
- "key": "payment:coins",
- "description": "Layer 'Bicycle tube vending machine' shows payment:coins=yes with a fixed text, namely 'Payment with coins is possible' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
- "value": "yes"
- },
- {
- "key": "payment:notes",
- "description": "Layer 'Bicycle tube vending machine' shows payment:notes=yes with a fixed text, namely 'Payment with notes is possible' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "key": "payment:cash",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:cash=yes with a fixed text, namely 'Cash is accepted here' (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
"value": "yes"
},
{
"key": "payment:cards",
- "description": "Layer 'Bicycle tube vending machine' shows payment:cards=yes with a fixed text, namely 'Payment with cards is possible' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:cards=yes with a fixed text, namely 'Payment cards are accepted here' (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:qr_code",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:qr_code=yes with a fixed text, namely 'Payment by QR-code is possible here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:coins",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:coins=yes with a fixed text, namely 'Coins are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:notes",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:notes=yes with a fixed text, namely 'Bank notes are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:debit_cards",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:debit_cards=yes with a fixed text, namely 'Debit cards are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:credit_cards",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:credit_cards=yes with a fixed text, namely 'Credit cards are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
"value": "yes"
},
{
@@ -1031,29 +1051,34 @@
"value": "Continental"
},
{
- "key": "vending:bicycle_light",
- "description": "Layer 'Bicycle tube vending machine' shows vending:bicycle_light=yes with a fixed text, namely 'Bicycle lights are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_tube with a fixed text, namely 'Bicycle inner tubes are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "bicycle_tube"
},
{
- "key": "vending:gloves",
- "description": "Layer 'Bicycle tube vending machine' shows vending:gloves=yes with a fixed text, namely 'Gloves are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_light with a fixed text, namely 'Bicycle lights are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "bicycle_light"
},
{
- "key": "vending:bicycle_repair_kit",
- "description": "Layer 'Bicycle tube vending machine' shows vending:bicycle_repair_kit=yes with a fixed text, namely 'Bicycle repair kits are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=gloves with a fixed text, namely 'Gloves are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "gloves"
},
{
- "key": "vending:bicycle_pump",
- "description": "Layer 'Bicycle tube vending machine' shows vending:bicycle_pump=yes with a fixed text, namely 'Bicycle pumps are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_repair_kit with a fixed text, namely 'Bicycle repair kits are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "bicycle_repair_kit"
},
{
- "key": "vending:bicycle_lock",
- "description": "Layer 'Bicycle tube vending machine' shows vending:bicycle_lock=yes with a fixed text, namely 'Bicycle locks are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_pump with a fixed text, namely 'Bicycle pumps are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "bicycle_pump"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_lock with a fixed text, namely 'Bicycle locks are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Cyclofix - a map for cyclists')",
+ "value": "bicycle_lock"
},
{
"key": "amenity",
diff --git a/Docs/TagInfo/mapcomplete_indoors.json b/Docs/TagInfo/mapcomplete_indoors.json
index b28e95e767..9b9327b267 100644
--- a/Docs/TagInfo/mapcomplete_indoors.json
+++ b/Docs/TagInfo/mapcomplete_indoors.json
@@ -215,6 +215,186 @@
"key": "name:etymology:wikidata",
"description": "Layer 'Indoors' shows and asks freeform values for key 'name:etymology:wikidata' (in the mapcomplete.org theme 'Indoors') (This is only shown if name:etymology!=unknown)"
},
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'access' (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=yes with a fixed text, namely 'Public access' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "yes"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=customers with a fixed text, namely 'Only access to customers' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "customers"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=no with a fixed text, namely 'Not accessible' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "no"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=key with a fixed text, namely 'Accessible, but one has to ask a key to enter' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "key"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=public with a fixed text, namely 'Public access' (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "public"
+ },
+ {
+ "key": "fee",
+ "description": "Layer 'Indoors' shows fee=yes with a fixed text, namely 'These are paid toilets' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&access!=no)",
+ "value": "yes"
+ },
+ {
+ "key": "fee",
+ "description": "Layer 'Indoors' shows fee=no with a fixed text, namely 'Free to use' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&access!=no)",
+ "value": "no"
+ },
+ {
+ "key": "charge",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'charge' (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&fee=yes)"
+ },
+ {
+ "key": "payment:cash",
+ "description": "Layer 'Indoors' shows payment:cash=yes with a fixed text, namely 'Cash is accepted here' (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:cards",
+ "description": "Layer 'Indoors' shows payment:cards=yes with a fixed text, namely 'Payment cards are accepted here' (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:qr_code",
+ "description": "Layer 'Indoors' shows payment:qr_code=yes with a fixed text, namely 'Payment by QR-code is possible here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:coins",
+ "description": "Layer 'Indoors' shows payment:coins=yes with a fixed text, namely 'Coins are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:notes",
+ "description": "Layer 'Indoors' shows payment:notes=yes with a fixed text, namely 'Bank notes are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:debit_cards",
+ "description": "Layer 'Indoors' shows payment:debit_cards=yes with a fixed text, namely 'Debit cards are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:credit_cards",
+ "description": "Layer 'Indoors' shows payment:credit_cards=yes with a fixed text, namely 'Credit cards are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "opening_hours",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'opening_hours' (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&access!=no)"
+ },
+ {
+ "key": "opening_hours",
+ "description": "Layer 'Indoors' shows opening_hours=24/7 with a fixed text, namely '24/7 opened (including holidays)' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&access!=no)",
+ "value": "24/7"
+ },
+ {
+ "key": "wheelchair",
+ "description": "Layer 'Indoors' shows wheelchair=yes with a fixed text, namely 'There is a dedicated toilet for wheelchair users' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "yes"
+ },
+ {
+ "key": "wheelchair",
+ "description": "Layer 'Indoors' shows wheelchair=no with a fixed text, namely 'No wheelchair access' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "no"
+ },
+ {
+ "key": "wheelchair",
+ "description": "Layer 'Indoors' shows wheelchair=designated with a fixed text, namely 'There is only a dedicated toilet for wheelchair users' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "designated"
+ },
+ {
+ "key": "door:width",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'door:width' (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&wheelchair=yes|wheelchair=designated)"
+ },
+ {
+ "key": "toilets:position",
+ "description": "Layer 'Indoors' shows toilets:position=seated with a fixed text, namely 'There are only seated toilets' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "seated"
+ },
+ {
+ "key": "toilets:position",
+ "description": "Layer 'Indoors' shows toilets:position=urinal with a fixed text, namely 'There are only urinals here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "urinal"
+ },
+ {
+ "key": "toilets:position",
+ "description": "Layer 'Indoors' shows toilets:position=squat with a fixed text, namely 'There are only squat toilets here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "squat"
+ },
+ {
+ "key": "toilets:position",
+ "description": "Layer 'Indoors' shows toilets:position=seated;urinal with a fixed text, namely 'Both seated toilets and urinals are available here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "seated;urinal"
+ },
+ {
+ "key": "changing_table",
+ "description": "Layer 'Indoors' shows changing_table=yes with a fixed text, namely 'A changing table is available' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "yes"
+ },
+ {
+ "key": "changing_table",
+ "description": "Layer 'Indoors' shows changing_table=no with a fixed text, namely 'No changing table is available' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "no"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'changing_table:location' (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&changing_table=yes)"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows changing_table:location=female_toilet with a fixed text, namely 'The changing table is in the toilet for women. ' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&changing_table=yes)",
+ "value": "female_toilet"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows changing_table:location=male_toilet with a fixed text, namely 'The changing table is in the toilet for men. ' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&changing_table=yes)",
+ "value": "male_toilet"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows changing_table:location=wheelchair_toilet with a fixed text, namely 'The changing table is in the toilet for wheelchair users. ' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&changing_table=yes)",
+ "value": "wheelchair_toilet"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows changing_table:location=dedicated_room with a fixed text, namely 'The changing table is in a dedicated room. ' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&changing_table=yes)",
+ "value": "dedicated_room"
+ },
+ {
+ "key": "toilets:handwashing",
+ "description": "Layer 'Indoors' shows toilets:handwashing=yes with a fixed text, namely 'This toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "yes"
+ },
+ {
+ "key": "toilets:handwashing",
+ "description": "Layer 'Indoors' shows toilets:handwashing=no with a fixed text, namely 'This toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets)",
+ "value": "no"
+ },
+ {
+ "key": "toilets:paper_supplied",
+ "description": "Layer 'Indoors' shows toilets:paper_supplied=yes with a fixed text, namely 'This toilet is equipped with toilet paper' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&toilets:position!=urinal)",
+ "value": "yes"
+ },
+ {
+ "key": "toilets:paper_supplied",
+ "description": "Layer 'Indoors' shows toilets:paper_supplied=no with a fixed text, namely 'You have to bring your own toilet paper to this toilet' and allows to pick this as a default answer (in the mapcomplete.org theme 'Indoors') (This is only shown if amenity=toilets&toilets:position!=urinal)",
+ "value": "no"
+ },
{
"key": "highway",
"description": "The MapComplete theme Indoors has a layer Pedestrian paths showing features with this tag",
diff --git a/Docs/TagInfo/mapcomplete_personal.json b/Docs/TagInfo/mapcomplete_personal.json
index 09d70051e7..168f357459 100644
--- a/Docs/TagInfo/mapcomplete_personal.json
+++ b/Docs/TagInfo/mapcomplete_personal.json
@@ -1514,18 +1514,38 @@
"description": "Layer 'Bicycle tube vending machine' shows and asks freeform values for key 'charge' (in the mapcomplete.org theme 'Personal theme')"
},
{
- "key": "payment:coins",
- "description": "Layer 'Bicycle tube vending machine' shows payment:coins=yes with a fixed text, namely 'Payment with coins is possible' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
- "value": "yes"
- },
- {
- "key": "payment:notes",
- "description": "Layer 'Bicycle tube vending machine' shows payment:notes=yes with a fixed text, namely 'Payment with notes is possible' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "key": "payment:cash",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:cash=yes with a fixed text, namely 'Cash is accepted here' (in the mapcomplete.org theme 'Personal theme')",
"value": "yes"
},
{
"key": "payment:cards",
- "description": "Layer 'Bicycle tube vending machine' shows payment:cards=yes with a fixed text, namely 'Payment with cards is possible' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:cards=yes with a fixed text, namely 'Payment cards are accepted here' (in the mapcomplete.org theme 'Personal theme')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:qr_code",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:qr_code=yes with a fixed text, namely 'Payment by QR-code is possible here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:coins",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:coins=yes with a fixed text, namely 'Coins are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:notes",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:notes=yes with a fixed text, namely 'Bank notes are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:debit_cards",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:debit_cards=yes with a fixed text, namely 'Debit cards are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "yes"
+ },
+ {
+ "key": "payment:credit_cards",
+ "description": "Layer 'Bicycle tube vending machine' shows payment:credit_cards=yes with a fixed text, namely 'Credit cards are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
"value": "yes"
},
{
@@ -1557,29 +1577,34 @@
"value": "Continental"
},
{
- "key": "vending:bicycle_light",
- "description": "Layer 'Bicycle tube vending machine' shows vending:bicycle_light=yes with a fixed text, namely 'Bicycle lights are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_tube with a fixed text, namely 'Bicycle inner tubes are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_tube"
},
{
- "key": "vending:gloves",
- "description": "Layer 'Bicycle tube vending machine' shows vending:gloves=yes with a fixed text, namely 'Gloves are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_light with a fixed text, namely 'Bicycle lights are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_light"
},
{
- "key": "vending:bicycle_repair_kit",
- "description": "Layer 'Bicycle tube vending machine' shows vending:bicycle_repair_kit=yes with a fixed text, namely 'Bicycle repair kits are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=gloves with a fixed text, namely 'Gloves are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "gloves"
},
{
- "key": "vending:bicycle_pump",
- "description": "Layer 'Bicycle tube vending machine' shows vending:bicycle_pump=yes with a fixed text, namely 'Bicycle pumps are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_repair_kit with a fixed text, namely 'Bicycle repair kits are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_repair_kit"
},
{
- "key": "vending:bicycle_lock",
- "description": "Layer 'Bicycle tube vending machine' shows vending:bicycle_lock=yes with a fixed text, namely 'Bicycle locks are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
- "value": "yes"
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_pump with a fixed text, namely 'Bicycle pumps are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_pump"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Bicycle tube vending machine' shows vending=bicycle_lock with a fixed text, namely 'Bicycle locks are sold here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_lock"
},
{
"key": "amenity",
@@ -8548,6 +8573,186 @@
"key": "name:etymology:wikidata",
"description": "Layer 'Indoors' shows and asks freeform values for key 'name:etymology:wikidata' (in the mapcomplete.org theme 'Personal theme') (This is only shown if name:etymology!=unknown)"
},
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'access' (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=yes with a fixed text, namely 'Public access' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "yes"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=customers with a fixed text, namely 'Only access to customers' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "customers"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=no with a fixed text, namely 'Not accessible' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "no"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=key with a fixed text, namely 'Accessible, but one has to ask a key to enter' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "key"
+ },
+ {
+ "key": "access",
+ "description": "Layer 'Indoors' shows access=public with a fixed text, namely 'Public access' (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "public"
+ },
+ {
+ "key": "fee",
+ "description": "Layer 'Indoors' shows fee=yes with a fixed text, namely 'These are paid toilets' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&access!=no)",
+ "value": "yes"
+ },
+ {
+ "key": "fee",
+ "description": "Layer 'Indoors' shows fee=no with a fixed text, namely 'Free to use' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&access!=no)",
+ "value": "no"
+ },
+ {
+ "key": "charge",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'charge' (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&fee=yes)"
+ },
+ {
+ "key": "payment:cash",
+ "description": "Layer 'Indoors' shows payment:cash=yes with a fixed text, namely 'Cash is accepted here' (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:cards",
+ "description": "Layer 'Indoors' shows payment:cards=yes with a fixed text, namely 'Payment cards are accepted here' (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:qr_code",
+ "description": "Layer 'Indoors' shows payment:qr_code=yes with a fixed text, namely 'Payment by QR-code is possible here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:coins",
+ "description": "Layer 'Indoors' shows payment:coins=yes with a fixed text, namely 'Coins are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:notes",
+ "description": "Layer 'Indoors' shows payment:notes=yes with a fixed text, namely 'Bank notes are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:debit_cards",
+ "description": "Layer 'Indoors' shows payment:debit_cards=yes with a fixed text, namely 'Debit cards are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "payment:credit_cards",
+ "description": "Layer 'Indoors' shows payment:credit_cards=yes with a fixed text, namely 'Credit cards are accepted here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&fee=yes)",
+ "value": "yes"
+ },
+ {
+ "key": "opening_hours",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'opening_hours' (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&access!=no)"
+ },
+ {
+ "key": "opening_hours",
+ "description": "Layer 'Indoors' shows opening_hours=24/7 with a fixed text, namely '24/7 opened (including holidays)' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&access!=no)",
+ "value": "24/7"
+ },
+ {
+ "key": "wheelchair",
+ "description": "Layer 'Indoors' shows wheelchair=yes with a fixed text, namely 'There is a dedicated toilet for wheelchair users' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "yes"
+ },
+ {
+ "key": "wheelchair",
+ "description": "Layer 'Indoors' shows wheelchair=no with a fixed text, namely 'No wheelchair access' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "no"
+ },
+ {
+ "key": "wheelchair",
+ "description": "Layer 'Indoors' shows wheelchair=designated with a fixed text, namely 'There is only a dedicated toilet for wheelchair users' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "designated"
+ },
+ {
+ "key": "door:width",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'door:width' (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&wheelchair=yes|wheelchair=designated)"
+ },
+ {
+ "key": "toilets:position",
+ "description": "Layer 'Indoors' shows toilets:position=seated with a fixed text, namely 'There are only seated toilets' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "seated"
+ },
+ {
+ "key": "toilets:position",
+ "description": "Layer 'Indoors' shows toilets:position=urinal with a fixed text, namely 'There are only urinals here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "urinal"
+ },
+ {
+ "key": "toilets:position",
+ "description": "Layer 'Indoors' shows toilets:position=squat with a fixed text, namely 'There are only squat toilets here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "squat"
+ },
+ {
+ "key": "toilets:position",
+ "description": "Layer 'Indoors' shows toilets:position=seated;urinal with a fixed text, namely 'Both seated toilets and urinals are available here' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "seated;urinal"
+ },
+ {
+ "key": "changing_table",
+ "description": "Layer 'Indoors' shows changing_table=yes with a fixed text, namely 'A changing table is available' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "yes"
+ },
+ {
+ "key": "changing_table",
+ "description": "Layer 'Indoors' shows changing_table=no with a fixed text, namely 'No changing table is available' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "no"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows and asks freeform values for key 'changing_table:location' (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&changing_table=yes)"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows changing_table:location=female_toilet with a fixed text, namely 'The changing table is in the toilet for women. ' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&changing_table=yes)",
+ "value": "female_toilet"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows changing_table:location=male_toilet with a fixed text, namely 'The changing table is in the toilet for men. ' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&changing_table=yes)",
+ "value": "male_toilet"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows changing_table:location=wheelchair_toilet with a fixed text, namely 'The changing table is in the toilet for wheelchair users. ' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&changing_table=yes)",
+ "value": "wheelchair_toilet"
+ },
+ {
+ "key": "changing_table:location",
+ "description": "Layer 'Indoors' shows changing_table:location=dedicated_room with a fixed text, namely 'The changing table is in a dedicated room. ' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&changing_table=yes)",
+ "value": "dedicated_room"
+ },
+ {
+ "key": "toilets:handwashing",
+ "description": "Layer 'Indoors' shows toilets:handwashing=yes with a fixed text, namely 'This toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "yes"
+ },
+ {
+ "key": "toilets:handwashing",
+ "description": "Layer 'Indoors' shows toilets:handwashing=no with a fixed text, namely 'This toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets)",
+ "value": "no"
+ },
+ {
+ "key": "toilets:paper_supplied",
+ "description": "Layer 'Indoors' shows toilets:paper_supplied=yes with a fixed text, namely 'This toilet is equipped with toilet paper' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&toilets:position!=urinal)",
+ "value": "yes"
+ },
+ {
+ "key": "toilets:paper_supplied",
+ "description": "Layer 'Indoors' shows toilets:paper_supplied=no with a fixed text, namely 'You have to bring your own toilet paper to this toilet' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if amenity=toilets&toilets:position!=urinal)",
+ "value": "no"
+ },
{
"key": "information",
"description": "The MapComplete theme Personal theme has a layer Information boards showing features with this tag",
@@ -14229,6 +14434,11 @@
"description": "Layer 'Vending Machines' shows vending=potatoes with a fixed text, namely 'Potatoes are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
"value": "potatoes"
},
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=meat with a fixed text, namely 'Meat is sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "meat"
+ },
{
"key": "vending",
"description": "Layer 'Vending Machines' shows vending=flowers with a fixed text, namely 'Flowers are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
@@ -14251,8 +14461,28 @@
},
{
"key": "vending",
- "description": "Layer 'Vending Machines' shows vending=meat with a fixed text, namely 'Meat products are being sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
- "value": "meat"
+ "description": "Layer 'Vending Machines' shows vending=bicycle_light with a fixed text, namely 'Bicycle lights are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_light"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=gloves with a fixed text, namely 'Gloves are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "gloves"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=bicycle_repair_kit with a fixed text, namely 'Bicycle repair kits are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_repair_kit"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=bicycle_pump with a fixed text, namely 'Bicycle pumps are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_pump"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=bicycle_lock with a fixed text, namely 'Bicycle locks are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "bicycle_lock"
},
{
"key": "opening_hours",
@@ -14587,6 +14817,11 @@
"description": "Layer 'Waste Basket' shows waste=plastic with a fixed text, namely 'A waste basket for plastic' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
"value": "plastic"
},
+ {
+ "key": "waste",
+ "description": "Layer 'Waste Basket' shows waste=paper with a fixed text, namely 'A waste basket for paper' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme')",
+ "value": "paper"
+ },
{
"key": "vending",
"description": "Layer 'Waste Basket' shows vending=dog_excrement_bag with a fixed text, namely 'This waste basket has a dispenser for (dog) excrement bags' and allows to pick this as a default answer (in the mapcomplete.org theme 'Personal theme') (This is only shown if waste=dog_excrement|waste=trash|)",
diff --git a/Docs/TagInfo/mapcomplete_vending_machine.json b/Docs/TagInfo/mapcomplete_vending_machine.json
index 98450f9883..f71c8e6db9 100644
--- a/Docs/TagInfo/mapcomplete_vending_machine.json
+++ b/Docs/TagInfo/mapcomplete_vending_machine.json
@@ -114,6 +114,11 @@
"description": "Layer 'Vending Machines' shows vending=potatoes with a fixed text, namely 'Potatoes are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
"value": "potatoes"
},
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=meat with a fixed text, namely 'Meat is sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
+ "value": "meat"
+ },
{
"key": "vending",
"description": "Layer 'Vending Machines' shows vending=flowers with a fixed text, namely 'Flowers are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
@@ -136,8 +141,28 @@
},
{
"key": "vending",
- "description": "Layer 'Vending Machines' shows vending=meat with a fixed text, namely 'Meat products are being sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
- "value": "meat"
+ "description": "Layer 'Vending Machines' shows vending=bicycle_light with a fixed text, namely 'Bicycle lights are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
+ "value": "bicycle_light"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=gloves with a fixed text, namely 'Gloves are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
+ "value": "gloves"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=bicycle_repair_kit with a fixed text, namely 'Bicycle repair kits are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
+ "value": "bicycle_repair_kit"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=bicycle_pump with a fixed text, namely 'Bicycle pumps are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
+ "value": "bicycle_pump"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=bicycle_lock with a fixed text, namely 'Bicycle locks are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
+ "value": "bicycle_lock"
},
{
"key": "opening_hours",
diff --git a/Docs/TagInfo/mapcomplete_waste.json b/Docs/TagInfo/mapcomplete_waste.json
index 7aaf9b8a70..4f8a8b2eff 100644
--- a/Docs/TagInfo/mapcomplete_waste.json
+++ b/Docs/TagInfo/mapcomplete_waste.json
@@ -70,6 +70,11 @@
"description": "Layer 'Waste Basket' shows waste=plastic with a fixed text, namely 'A waste basket for plastic' and allows to pick this as a default answer (in the mapcomplete.org theme 'Waste')",
"value": "plastic"
},
+ {
+ "key": "waste",
+ "description": "Layer 'Waste Basket' shows waste=paper with a fixed text, namely 'A waste basket for paper' and allows to pick this as a default answer (in the mapcomplete.org theme 'Waste')",
+ "value": "paper"
+ },
{
"key": "vending",
"description": "Layer 'Waste Basket' shows vending=dog_excrement_bag with a fixed text, namely 'This waste basket has a dispenser for (dog) excrement bags' and allows to pick this as a default answer (in the mapcomplete.org theme 'Waste') (This is only shown if waste=dog_excrement|waste=trash|)",
diff --git a/Docs/TagInfo/mapcomplete_waste_basket.json b/Docs/TagInfo/mapcomplete_waste_basket.json
index 260e1695bf..6b95079eaa 100644
--- a/Docs/TagInfo/mapcomplete_waste_basket.json
+++ b/Docs/TagInfo/mapcomplete_waste_basket.json
@@ -70,6 +70,11 @@
"description": "Layer 'Waste Basket' shows waste=plastic with a fixed text, namely 'A waste basket for plastic' and allows to pick this as a default answer (in the mapcomplete.org theme 'Waste Basket')",
"value": "plastic"
},
+ {
+ "key": "waste",
+ "description": "Layer 'Waste Basket' shows waste=paper with a fixed text, namely 'A waste basket for paper' and allows to pick this as a default answer (in the mapcomplete.org theme 'Waste Basket')",
+ "value": "paper"
+ },
{
"key": "vending",
"description": "Layer 'Waste Basket' shows vending=dog_excrement_bag with a fixed text, namely 'This waste basket has a dispenser for (dog) excrement bags' and allows to pick this as a default answer (in the mapcomplete.org theme 'Waste Basket') (This is only shown if waste=dog_excrement|waste=trash|)",
diff --git a/src/UI/Map/ShowDataLayer.ts b/src/UI/Map/ShowDataLayer.ts
index 80c1aa360a..1f439acc5d 100644
--- a/src/UI/Map/ShowDataLayer.ts
+++ b/src/UI/Map/ShowDataLayer.ts
@@ -1,21 +1,21 @@
-import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource";
-import type { Map as MlMap } from "maplibre-gl";
-import { GeoJSONSource, Marker } from "maplibre-gl";
-import { ShowDataLayerOptions } from "./ShowDataLayerOptions";
-import { GeoOperations } from "../../Logic/GeoOperations";
-import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
-import PointRenderingConfig from "../../Models/ThemeConfig/PointRenderingConfig";
-import { OsmTags } from "../../Models/OsmFeature";
-import { FeatureSource, FeatureSourceForLayer } from "../../Logic/FeatureSource/FeatureSource";
-import { BBox } from "../../Logic/BBox";
-import { Feature, Point } from "geojson";
-import LineRenderingConfig from "../../Models/ThemeConfig/LineRenderingConfig";
-import { Utils } from "../../Utils";
-import * as range_layer from "../../../assets/layers/range/range.json";
-import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson";
-import PerLayerFeatureSourceSplitter from "../../Logic/FeatureSource/PerLayerFeatureSourceSplitter";
-import FilteredLayer from "../../Models/FilteredLayer";
-import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource";
+import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
+import type { Map as MlMap } from "maplibre-gl"
+import { GeoJSONSource, Marker } from "maplibre-gl"
+import { ShowDataLayerOptions } from "./ShowDataLayerOptions"
+import { GeoOperations } from "../../Logic/GeoOperations"
+import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
+import PointRenderingConfig from "../../Models/ThemeConfig/PointRenderingConfig"
+import { OsmTags } from "../../Models/OsmFeature"
+import { FeatureSource, FeatureSourceForLayer } from "../../Logic/FeatureSource/FeatureSource"
+import { BBox } from "../../Logic/BBox"
+import { Feature, Point } from "geojson"
+import LineRenderingConfig from "../../Models/ThemeConfig/LineRenderingConfig"
+import { Utils } from "../../Utils"
+import * as range_layer from "../../../assets/layers/range/range.json"
+import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
+import PerLayerFeatureSourceSplitter from "../../Logic/FeatureSource/PerLayerFeatureSourceSplitter"
+import FilteredLayer from "../../Models/FilteredLayer"
+import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource"
class PointRenderingLayer {
private readonly _config: PointRenderingConfig
@@ -284,18 +284,19 @@ class LineRenderingLayer {
// Already up to date
return
}
- {// Add source to the map or update the features
+ {
+ // Add source to the map or update the features
if (src === undefined) {
- this.currentSourceData = features;
+ this.currentSourceData = features
map.addSource(this._layername, {
type: "geojson",
data: {
type: "FeatureCollection",
- features
+ features,
},
- promoteId: "id"
- });
- const linelayer = this._layername + "_line";
+ promoteId: "id",
+ })
+ const linelayer = this._layername + "_line"
map.addLayer({
source: this._layername,
id: linelayer,
@@ -304,12 +305,12 @@ class LineRenderingLayer {
"line-color": ["feature-state", "color"],
"line-opacity": ["feature-state", "color-opacity"],
"line-width": ["feature-state", "width"],
- "line-offset": ["feature-state", "offset"]
+ "line-offset": ["feature-state", "offset"],
},
layout: {
- "line-cap": "round"
- }
- });
+ "line-cap": "round",
+ },
+ })
for (const feature of features) {
map.setFeatureState(
@@ -320,10 +321,10 @@ class LineRenderingLayer {
map.on("click", linelayer, (e) => {
// line-layer-listener
- e.originalEvent["consumed"] = true;
- this._onClick(e.features[0]);
- });
- const polylayer = this._layername + "_polygon";
+ e.originalEvent["consumed"] = true
+ this._onClick(e.features[0])
+ })
+ const polylayer = this._layername + "_polygon"
map.addLayer({
source: this._layername,
@@ -333,41 +334,41 @@ class LineRenderingLayer {
layout: {},
paint: {
"fill-color": ["feature-state", "fillColor"],
- "fill-opacity": ["feature-state", "fillColor-opacity"]
- }
- });
+ "fill-opacity": ["feature-state", "fillColor-opacity"],
+ },
+ })
if (this._onClick) {
map.on("click", polylayer, (e) => {
// polygon-layer-listener
if (e.originalEvent["consumed"]) {
// This is a polygon beneath a marker, we can ignore it
- return;
+ return
}
- e.originalEvent["consumed"] = true;
- console.log("Got features:", e.features, e);
- this._onClick(e.features[0]);
- });
+ e.originalEvent["consumed"] = true
+ console.log("Got features:", e.features, e)
+ this._onClick(e.features[0])
+ })
}
this._visibility?.addCallbackAndRunD((visible) => {
try {
- map.setLayoutProperty(linelayer, "visibility", visible ? "visible" : "none");
- map.setLayoutProperty(polylayer, "visibility", visible ? "visible" : "none");
+ map.setLayoutProperty(linelayer, "visibility", visible ? "visible" : "none")
+ map.setLayoutProperty(polylayer, "visibility", visible ? "visible" : "none")
} catch (e) {
console.warn(
"Error while setting visibility of layers ",
linelayer,
polylayer,
e
- );
+ )
}
- });
+ })
} else {
- this.currentSourceData = features;
+ this.currentSourceData = features
src.setData({
type: "FeatureCollection",
- features: this.currentSourceData
- });
+ features: this.currentSourceData,
+ })
}
}
for (let i = 0; i < features.length; i++) {
@@ -400,7 +401,7 @@ class LineRenderingLayer {
const tags = this._fetchStore(id)
this._listenerInstalledOn.add(id)
tags.addCallbackAndRunD((properties) => {
- if(!map.getLayer(this._layername)){
+ if (!map.getLayer(this._layername)) {
return
}
map.setFeatureState(
diff --git a/src/Utils.ts b/src/Utils.ts
index 7c214c5bbb..1f196de6ef 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -1,5 +1,5 @@
-import colors from "./assets/colors.json";
-import DOMPurify from "dompurify";
+import colors from "./assets/colors.json"
+import DOMPurify from "dompurify"
export class Utils {
/**
@@ -7,12 +7,12 @@ export class Utils {
* However, ts-node crashes when it sees 'document'. When running from console, we flag this and disable all code where document is needed.
* This is a workaround and yet another hack
*/
- public static runningFromConsole = typeof window === "undefined";
- public static readonly assets_path = "./assets/svg/";
+ public static runningFromConsole = typeof window === "undefined"
+ public static readonly assets_path = "./assets/svg/"
public static externalDownloadFunction: (
url: string,
headers?: any
- ) => Promise<{ content: string } | { redirect: string }>;
+ ) => Promise<{ content: string } | { redirect: string }>
public static Special_visualizations_tagsToApplyHelpText = `These can either be a tag to add, such as \`amenity=fast_food\` or can use a substitution, e.g. \`addr:housenumber=$number\`.
This new point will then have the tags \`amenity=fast_food\` and \`addr:housenumber\` with the value that was saved in \`number\` in the original feature.
@@ -23,8 +23,8 @@ This supports multiple values, e.g. \`ref=$source:geometry:type/$source:geometry
Remark that the syntax is slightly different then expected; it uses '$' to note a value to copy, followed by a name (matched with \`[a-zA-Z0-9_:]*\`). Sadly, delimiting with \`{}\` as these already mark the boundaries of the special rendering...
Note that these values can be prepare with javascript in the theme by using a [calculatedTag](calculatedTags.md#calculating-tags-with-javascript)
- `;
- public static readonly imageExtensions = new Set(["jpg", "png", "svg", "jpeg", ".gif"]);
+ `
+ public static readonly imageExtensions = new Set(["jpg", "png", "svg", "jpeg", ".gif"])
public static readonly special_visualizations_importRequirementDocs = `#### Importing a dataset into OpenStreetMap: requirements
If you want to import a dataset, make sure that:
@@ -47,7 +47,7 @@ There are also some technicalities in your theme to keep in mind:
The import button can be tested in an unofficial theme by adding \`test=true\` or \`backend=osm-test\` as [URL-paramter](URL_Parameters.md).
The import button will show up then. If in testmode, you can read the changeset-XML directly in the web console.
-In the case that MapComplete is pointed to the testing grounds, the edit will be made on https://master.apis.dev.openstreetmap.org`;
+In the case that MapComplete is pointed to the testing grounds, the edit will be made on https://master.apis.dev.openstreetmap.org`
private static knownKeys = [
"addExtraTags",
"and",
@@ -116,8 +116,8 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
"version",
"wayHandling",
"widenFactor",
- "width"
- ];
+ "width",
+ ]
private static extraKeys = [
"nl",
"en",
@@ -135,36 +135,36 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
"yes",
"no",
"true",
- "false"
- ];
- private static injectedDownloads = {};
+ "false",
+ ]
+ private static injectedDownloads = {}
private static _download_cache = new Map<
string,
{
promise: Promise
timestamp: number
}
- >();
+ >()
public static initDomPurify() {
if (Utils.runningFromConsole) {
- return;
+ return
}
- DOMPurify.addHook("afterSanitizeAttributes", function(node) {
+ DOMPurify.addHook("afterSanitizeAttributes", function (node) {
// set all elements owning target to target=_blank + add noopener noreferrer
- const target = node.getAttribute("target");
+ const target = node.getAttribute("target")
if (target) {
- node.setAttribute("target", "_blank");
- node.setAttribute("rel", "noopener noreferrer");
+ node.setAttribute("target", "_blank")
+ node.setAttribute("rel", "noopener noreferrer")
}
- });
+ })
}
public static purify(src: string): string {
return DOMPurify.sanitize(src, {
USE_PROFILES: { html: true },
- ADD_ATTR: ["target"] // Don't remove target='_blank'. Note that Utils.initDomPurify does add a hook which automatically adds 'rel=noopener'
- });
+ ADD_ATTR: ["target"], // Don't remove target='_blank'. Note that Utils.initDomPurify does add a hook which automatically adds 'rel=noopener'
+ })
}
/**
@@ -174,7 +174,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
specs: { name: string; defaultValue?: string }[],
args: string[]
): Record {
- const parsed: Record = {};
+ const parsed: Record = {}
if (args.length > specs.length) {
throw (
"To much arguments for special visualization: got " +
@@ -182,23 +182,23 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
" but expected only " +
args.length +
" arguments"
- );
+ )
}
for (let i = 0; i < specs.length; i++) {
- const spec = specs[i];
- let arg = args[i]?.trim();
+ const spec = specs[i]
+ let arg = args[i]?.trim()
if (arg === undefined || arg === "") {
- arg = spec.defaultValue;
+ arg = spec.defaultValue
}
- parsed[spec.name] = arg;
+ parsed[spec.name] = arg
}
- return parsed;
+ return parsed
}
static EncodeXmlValue(str) {
if (typeof str !== "string") {
- str = "" + str;
+ str = "" + str
}
return str
@@ -206,7 +206,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
.replace(//g, ">")
.replace(/"/g, """)
- .replace(/'/g, "'");
+ .replace(/'/g, "'")
}
/**
@@ -215,24 +215,24 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
static asFloat(str): number {
if (str) {
- const i = parseFloat(str);
+ const i = parseFloat(str)
if (isNaN(i)) {
- return undefined;
+ return undefined
}
- return i;
+ return i
}
- return undefined;
+ return undefined
}
public static Upper(str: string) {
- return str.substr(0, 1).toUpperCase() + str.substr(1);
+ return str.substr(0, 1).toUpperCase() + str.substr(1)
}
public static TwoDigits(i: number) {
if (i < 10) {
- return "0" + i;
+ return "0" + i
}
- return "" + i;
+ return "" + i
}
/**
@@ -242,37 +242,37 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
public static Round7(i: number): number {
if (i == undefined) {
- return undefined;
+ return undefined
}
- return Math.round(i * 10000000) / 10000000;
+ return Math.round(i * 10000000) / 10000000
}
public static Times(f: (i: number) => string, count: number): string {
- let res = "";
+ let res = ""
for (let i = 0; i < count; i++) {
- res += f(i);
+ res += f(i)
}
- return res;
+ return res
}
public static TimesT(count: number, f: (i: number) => T): T[] {
- const res: T[] = [];
+ const res: T[] = []
for (let i = 0; i < count; i++) {
- res.push(f(i));
+ res.push(f(i))
}
- return res;
+ return res
}
public static NoNull(array: T[]): NonNullable[] {
- return array?.filter((o) => o !== undefined && o !== null);
+ return array?.filter((o) => o !== undefined && o !== null)
}
public static Hist(array: string[]): Map {
- const hist = new Map();
+ const hist = new Map()
for (const s of array) {
- hist.set(s, 1 + (hist.get(s) ?? 0));
+ hist.set(s, 1 + (hist.get(s) ?? 0))
}
- return hist;
+ return hist
}
/**
@@ -284,27 +284,27 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*
*/
public static NoEmpty(array: string[]): string[] {
- const ls: string[] = [];
+ const ls: string[] = []
if (!array) {
- return ls;
+ return ls
}
for (const t of array) {
if (t === "") {
- continue;
+ continue
}
- ls.push(t);
+ ls.push(t)
}
- return ls;
+ return ls
}
public static EllipsesAfter(str: string, l: number = 100) {
if (str === undefined || str === null) {
- return undefined;
+ return undefined
}
if (str.length <= l) {
- return str;
+ return str
}
- return str.substr(0, l - 3) + "...";
+ return str.substr(0, l - 3) + "..."
}
/**
@@ -326,14 +326,14 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
enumerable: false,
configurable: true,
get: () => {
- delete object[name];
- object[name] = init();
+ delete object[name]
+ object[name] = init()
if (whenDone) {
- whenDone();
+ whenDone()
}
- return object[name];
- }
- });
+ return object[name]
+ },
+ })
}
/**
@@ -350,22 +350,22 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
configurable: true,
get: () => {
init().then((r) => {
- delete object[name];
- object[name] = r;
+ delete object[name]
+ object[name] = r
if (whenDone) {
- whenDone();
+ whenDone()
}
- });
- }
- });
+ })
+ },
+ })
}
public static FixedLength(str: string, l: number) {
- str = Utils.EllipsesAfter(str, l);
+ str = Utils.EllipsesAfter(str, l)
while (str.length < l) {
- str = " " + str;
+ str = " " + str
}
- return str;
+ return str
}
/**
@@ -376,30 +376,30 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
public static Dedup(arr: string[]): string[] {
if (arr === undefined) {
- return undefined;
+ return undefined
}
- const newArr = [];
+ const newArr = []
for (const string of arr) {
if (newArr.indexOf(string) < 0) {
- newArr.push(string);
+ newArr.push(string)
}
}
- return newArr;
+ return newArr
}
public static Duplicates(arr: string[]): string[] {
if (arr === undefined) {
- return undefined;
+ return undefined
}
- const newArr = [];
- const seen = new Set();
+ const newArr = []
+ const seen = new Set()
for (const string of arr) {
if (seen.has(string)) {
- newArr.push(string);
+ newArr.push(string)
}
- seen.add(string);
+ seen.add(string)
}
- return newArr;
+ return newArr
}
/**
@@ -408,15 +408,15 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
* Utils.Flatten([ [1,2], 3, [4, [5 ,6]] ]) // => [1, 2, 3, 4, [5, 6]]
*/
public static Flatten(list: (T | T[])[]): T[] {
- const result = [];
+ const result = []
for (const value of list) {
if (Array.isArray(value)) {
- result.push(...value);
+ result.push(...value)
} else {
- result.push(value);
+ result.push(value)
}
}
- return result;
+ return result
}
/**
@@ -426,37 +426,37 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
public static Identical(t1: T[], t2: T[], eq?: (t: T, t0: T) => boolean): boolean {
if (t1.length !== t2.length) {
- return false;
+ return false
}
- eq = (a, b) => a === b;
+ eq = (a, b) => a === b
for (let i = 0; i < t1.length; i++) {
if (!eq(t1[i], t2[i])) {
- return false;
+ return false
}
}
- return true;
+ return true
}
/**
* Utils.MergeTags({k0:"v0","common":"0"},{k1:"v1", common: "1"}) // => {k0: "v0", k1:"v1", common: "1"}
*/
public static MergeTags(a: any, b: any) {
- const t = {};
+ const t = {}
for (const k in a) {
- t[k] = a[k];
+ t[k] = a[k]
}
for (const k in b) {
- t[k] = b[k];
+ t[k] = b[k]
}
- return t;
+ return t
}
public static SplitFirst(a: string, sep: string): string[] {
- const index = a.indexOf(sep);
+ const index = a.indexOf(sep)
if (index < 0) {
- return [a];
+ return [a]
}
- return [a.substr(0, index), a.substr(index + sep.length)];
+ return [a.substr(0, index), a.substr(index + sep.length)]
}
/**
@@ -478,32 +478,32 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
useLang?: string
): string | undefined {
if (txt === undefined) {
- return undefined;
+ return undefined
}
- const regex = /(.*?){([^}]*)}(.*)/s;
+ const regex = /(.*?){([^}]*)}(.*)/s
- let match = txt.match(regex);
+ let match = txt.match(regex)
if (!match) {
- return txt;
+ return txt
}
- let result = "";
+ let result = ""
while (match) {
- const [_, normal, key, leftover] = match;
- let v = tags === undefined ? undefined : tags[key];
+ const [_, normal, key, leftover] = match
+ let v = tags === undefined ? undefined : tags[key]
if (v !== undefined && v !== null) {
if (v["toISOString"] != undefined) {
// This is a date, probably the timestamp of the object
// @ts-ignore
- const date: Date = el;
- v = date.toISOString();
+ const date: Date = el
+ v = date.toISOString()
}
if (useLang !== undefined && v?.translations !== undefined) {
v =
v.translations[useLang] ??
v.translations["*"] ??
- (v.textFor !== undefined ? v.textFor(useLang) : v);
+ (v.textFor !== undefined ? v.textFor(useLang) : v)
}
if (v.InnerConstructElement !== undefined) {
@@ -512,45 +512,45 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
key,
"\nThe value is",
v
- );
- v = v.InnerConstructElement()?.textContent;
+ )
+ v = v.InnerConstructElement()?.textContent
}
if (typeof v !== "string") {
- v = "" + v;
+ v = "" + v
}
- v = v.replace(/\n/g, "
");
+ v = v.replace(/\n/g, "
")
} else {
// v === undefined
- v = "";
+ v = ""
}
- result += normal + v;
- match = leftover.match(regex);
+ result += normal + v
+ match = leftover.match(regex)
if (!match) {
- result += leftover;
+ result += leftover
}
}
- return result;
+ return result
}
public static LoadCustomCss(location: string) {
- const head = document.getElementsByTagName("head")[0];
- const link = document.createElement("link");
- link.id = "customCss";
- link.rel = "stylesheet";
- link.type = "text/css";
- link.href = location;
- link.media = "all";
- head.appendChild(link);
- console.log("Added custom css file ", location);
+ const head = document.getElementsByTagName("head")[0]
+ const link = document.createElement("link")
+ link.id = "customCss"
+ link.rel = "stylesheet"
+ link.type = "text/css"
+ link.href = location
+ link.media = "all"
+ head.appendChild(link)
+ console.log("Added custom css file ", location)
}
public static PushList(target: T[], source?: T[]) {
if (source === undefined) {
- return;
+ return
}
- target.push(...source);
+ target.push(...source)
}
/**
@@ -561,8 +561,8 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
* @constructor
* @private
*/
- private static CleanMergeObject(obj: any){
- if(Array.isArray(obj)){
+ private static CleanMergeObject(obj: any) {
+ if (Array.isArray(obj)) {
const result = []
for (const el of obj) {
result.push(Utils.CleanMergeObject(el))
@@ -570,14 +570,14 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
return result
}
if (typeof obj !== "object") {
- return obj;
+ return obj
}
const newObj = {}
for (let objKey in obj) {
let cleanKey = objKey
- if(objKey.startsWith("+") || objKey.startsWith("=")){
+ if (objKey.startsWith("+") || objKey.startsWith("=")) {
cleanKey = objKey.substring(1)
- }else if(objKey.endsWith("+") || objKey.endsWith("=")){
+ } else if (objKey.endsWith("+") || objKey.endsWith("=")) {
cleanKey = objKey.substring(0, objKey.length - 1)
}
newObj[cleanKey] = Utils.CleanMergeObject(obj[objKey])
@@ -633,62 +633,70 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
static Merge(source: Readonly, target: T): T & S {
if (target === null) {
- return Utils.CleanMergeObject(source);
+ return Utils.CleanMergeObject(source)
}
for (const key in source) {
if (!source.hasOwnProperty(key)) {
- continue;
+ continue
}
if (key.startsWith("=")) {
- const trimmedKey = key.substr(1);
- target[trimmedKey] = source[key];
- continue;
+ const trimmedKey = key.substr(1)
+ target[trimmedKey] = source[key]
+ continue
}
if (key.startsWith("+") || key.endsWith("+")) {
- const trimmedKey = key.replace("+", "");
- const sourceV = source[key];
- const targetV = target[trimmedKey] ?? [];
+ const trimmedKey = key.replace("+", "")
+ const sourceV = source[key]
+ const targetV = target[trimmedKey] ?? []
- let newList: any[];
+ let newList: any[]
if (key.startsWith("+")) {
- if(!Array.isArray(targetV)){
- throw new Error("Cannot concatenate: value to add is not an array: "+JSON.stringify(targetV))
+ if (!Array.isArray(targetV)) {
+ throw new Error(
+ "Cannot concatenate: value to add is not an array: " +
+ JSON.stringify(targetV)
+ )
}
if (Array.isArray(sourceV)) {
- newList = sourceV.concat(targetV) ?? targetV;
+ newList = sourceV.concat(targetV) ?? targetV
} else {
- throw new Error("Could not merge concatenate " + JSON.stringify(sourceV) + " and " + JSON.stringify(targetV));
+ throw new Error(
+ "Could not merge concatenate " +
+ JSON.stringify(sourceV) +
+ " and " +
+ JSON.stringify(targetV)
+ )
}
} else {
- newList = targetV.concat(sourceV ?? []);
+ newList = targetV.concat(sourceV ?? [])
}
- target[trimmedKey] = newList;
- continue;
+ target[trimmedKey] = newList
+ continue
}
- const sourceV = source[key];
+ const sourceV = source[key]
// @ts-ignore
- const targetV = target[key];
+ const targetV = target[key]
if (typeof sourceV === "object") {
if (sourceV === null) {
// @ts-ignore
- target[key] = null;
+ target[key] = null
} else if (targetV === undefined) {
// @ts-ignore
- target[key] = Utils.CleanMergeObject(sourceV);
+ target[key] = Utils.CleanMergeObject(sourceV)
} else {
- Utils.Merge(sourceV, targetV);
+ Utils.Merge(sourceV, targetV)
}
} else {
// @ts-ignore
- target[key] = Utils.CleanMergeObject(sourceV);
+ target[key] = Utils.CleanMergeObject(sourceV)
}
}
// @ts-ignore
- return target;
+ return target
}
/**
@@ -706,39 +714,39 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
travelledPath: string[] = []
): void {
if (object == null) {
- return;
+ return
}
- const head = path[0];
+ const head = path[0]
if (path.length === 1) {
// We have reached the leaf
- const leaf = object[head];
+ const leaf = object[head]
if (leaf !== undefined) {
if (Array.isArray(leaf)) {
- object[head] = leaf.map((o) => replaceLeaf(o, travelledPath));
+ object[head] = leaf.map((o) => replaceLeaf(o, travelledPath))
} else {
- object[head] = replaceLeaf(leaf, travelledPath);
+ object[head] = replaceLeaf(leaf, travelledPath)
if (object[head] === undefined) {
- delete object[head];
+ delete object[head]
}
}
}
- return;
+ return
}
- const sub = object[head];
+ const sub = object[head]
if (sub === undefined) {
- return;
+ return
}
if (typeof sub !== "object") {
- return;
+ return
}
if (Array.isArray(sub)) {
sub.forEach((el, i) =>
Utils.WalkPath(path.slice(1), el, replaceLeaf, [...travelledPath, head, "" + i])
- );
- return;
+ )
+ return
}
- Utils.WalkPath(path.slice(1), sub, replaceLeaf, [...travelledPath, head]);
+ Utils.WalkPath(path.slice(1), sub, replaceLeaf, [...travelledPath, head])
}
/**
@@ -754,41 +762,41 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
travelledPath: string[] = []
): { leaf: any; path: string[] }[] {
if (object === undefined || object === null) {
- return collectedList;
+ return collectedList
}
- const head = path[0];
- travelledPath = [...travelledPath, head];
+ const head = path[0]
+ travelledPath = [...travelledPath, head]
if (path.length === 1) {
// We have reached the leaf
- const leaf = object[head];
+ const leaf = object[head]
if (leaf === undefined || leaf === null) {
- return collectedList;
+ return collectedList
}
if (Array.isArray(leaf)) {
for (let i = 0; i < (leaf).length; i++) {
- const l = (leaf)[i];
- collectedList.push({ leaf: l, path: [...travelledPath, "" + i] });
+ const l = (leaf)[i]
+ collectedList.push({ leaf: l, path: [...travelledPath, "" + i] })
}
} else {
- collectedList.push({ leaf, path: travelledPath });
+ collectedList.push({ leaf, path: travelledPath })
}
- return collectedList;
+ return collectedList
}
- const sub = object[head];
+ const sub = object[head]
if (sub === undefined || sub === null) {
- return collectedList;
+ return collectedList
}
if (Array.isArray(sub)) {
sub.forEach((el, i) =>
Utils.CollectPath(path.slice(1), el, collectedList, [...travelledPath, "" + i])
- );
- return collectedList;
+ )
+ return collectedList
}
if (typeof sub !== "object") {
- return collectedList;
+ return collectedList
}
- return Utils.CollectPath(path.slice(1), sub, collectedList, travelledPath);
+ return Utils.CollectPath(path.slice(1), sub, collectedList, travelledPath)
}
/**
@@ -828,31 +836,31 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
path: string[] = []
) {
if (json === undefined || json === null) {
- return f(json, path);
+ return f(json, path)
}
- const jtp = typeof json;
+ const jtp = typeof json
if (isLeaf !== undefined) {
if (jtp === "object") {
if (isLeaf(json)) {
- return f(json, path);
+ return f(json, path)
}
} else {
- return json;
+ return json
}
} else if (jtp === "boolean" || jtp === "string" || jtp === "number") {
- return f(json, path);
+ return f(json, path)
}
if (Array.isArray(json)) {
return json.map((sub, i) => {
- return Utils.WalkJson(sub, f, isLeaf, [...path, "" + i]);
- });
+ return Utils.WalkJson(sub, f, isLeaf, [...path, "" + i])
+ })
}
- const cp = { ...json };
+ const cp = { ...json }
for (const key in json) {
- cp[key] = Utils.WalkJson(json[key], f, isLeaf, [...path, key]);
+ cp[key] = Utils.WalkJson(json[key], f, isLeaf, [...path, key])
}
- return cp;
+ return cp
}
/**
@@ -867,94 +875,94 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
path = []
): void {
if (json === undefined) {
- return;
+ return
}
- const jtp = typeof json;
+ const jtp = typeof json
if (isLeaf !== undefined) {
if (jtp !== "object") {
- return;
+ return
}
if (isLeaf(json)) {
- return collect(json, path);
+ return collect(json, path)
}
} else if (jtp === "boolean" || jtp === "string" || jtp === "number") {
- collect(json, path);
- return;
+ collect(json, path)
+ return
}
if (Array.isArray(json)) {
json.map((sub, i) => {
- return Utils.WalkObject(sub, collect, isLeaf, [...path, i]);
- });
- return;
+ return Utils.WalkObject(sub, collect, isLeaf, [...path, i])
+ })
+ return
}
for (const key in json) {
- Utils.WalkObject(json[key], collect, isLeaf, [...path, key]);
+ Utils.WalkObject(json[key], collect, isLeaf, [...path, key])
}
}
static getOrSetDefault(dict: Map, k: K, v: () => V) {
- const found = dict.get(k);
+ const found = dict.get(k)
if (found !== undefined) {
- return found;
+ return found
}
- dict.set(k, v());
- return dict.get(k);
+ dict.set(k, v())
+ return dict.get(k)
}
/**
* Tries to minify the given JSON by applying some compression
*/
public static MinifyJSON(stringified: string): string {
- stringified = stringified.replace(/\|/g, "||");
+ stringified = stringified.replace(/\|/g, "||")
- const keys = Utils.knownKeys.concat(Utils.extraKeys);
+ const keys = Utils.knownKeys.concat(Utils.extraKeys)
for (let i = 0; i < keys.length; i++) {
- const knownKey = keys[i];
- let code = i;
+ const knownKey = keys[i]
+ let code = i
if (i >= 124) {
- code += 1; // Character 127 is our 'escape' character |
+ code += 1 // Character 127 is our 'escape' character |
}
- const replacement = "|" + String.fromCharCode(code);
- stringified = stringified.replace(new RegExp(`\"${knownKey}\":`, "g"), replacement);
+ const replacement = "|" + String.fromCharCode(code)
+ stringified = stringified.replace(new RegExp(`\"${knownKey}\":`, "g"), replacement)
}
- return stringified;
+ return stringified
}
public static UnMinify(minified: string): string {
if (minified === undefined || minified === null) {
- return undefined;
+ return undefined
}
- const parts = minified.split("|");
- let result = parts.shift();
- const keys = Utils.knownKeys.concat(Utils.extraKeys);
+ const parts = minified.split("|")
+ let result = parts.shift()
+ const keys = Utils.knownKeys.concat(Utils.extraKeys)
for (const part of parts) {
if (part == "") {
// Empty string => this was a || originally
- result += "|";
- continue;
+ result += "|"
+ continue
}
- const i = part.charCodeAt(0);
- result += "\"" + keys[i] + "\":" + part.substring(1);
+ const i = part.charCodeAt(0)
+ result += '"' + keys[i] + '":' + part.substring(1)
}
- return result;
+ return result
}
public static injectJsonDownloadForTests(url: string, data) {
- Utils.injectedDownloads[url] = data;
+ Utils.injectedDownloads[url] = data
}
public static async download(url: string, headers?: any): Promise {
- const result = await Utils.downloadAdvanced(url, headers);
+ const result = await Utils.downloadAdvanced(url, headers)
if (result["error"] !== undefined) {
- throw result["error"];
+ throw result["error"]
}
- return result["content"];
+ return result["content"]
}
/**
@@ -971,60 +979,60 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
| { error: string; url: string; statuscode?: number }
> {
if (this.externalDownloadFunction !== undefined) {
- return this.externalDownloadFunction(url, headers);
+ return this.externalDownloadFunction(url, headers)
}
return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
+ const xhr = new XMLHttpRequest()
xhr.onload = () => {
if (xhr.status == 200) {
- resolve({ content: xhr.response });
+ resolve({ content: xhr.response })
} else if (xhr.status === 302) {
- resolve({ redirect: xhr.getResponseHeader("location") });
+ resolve({ redirect: xhr.getResponseHeader("location") })
} else if (xhr.status === 509 || xhr.status === 429) {
- resolve({ error: "rate limited", url, statuscode: xhr.status });
+ resolve({ error: "rate limited", url, statuscode: xhr.status })
} else {
resolve({
error: "other error: " + xhr.statusText,
url,
- statuscode: xhr.status
- });
+ statuscode: xhr.status,
+ })
}
- };
- xhr.open("GET", url);
+ }
+ xhr.open("GET", url)
if (headers !== undefined) {
for (const key in headers) {
- xhr.setRequestHeader(key, headers[key]);
+ xhr.setRequestHeader(key, headers[key])
}
}
- xhr.send();
- xhr.onerror = reject;
- });
+ xhr.send()
+ xhr.onerror = reject
+ })
}
public static upload(url: string, data, headers?: any): Promise {
return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
+ const xhr = new XMLHttpRequest()
xhr.onload = () => {
if (xhr.status == 200) {
- resolve(xhr.response);
+ resolve(xhr.response)
} else if (xhr.status === 509 || xhr.status === 429) {
- reject("rate limited");
+ reject("rate limited")
} else {
- reject(xhr.statusText);
+ reject(xhr.statusText)
}
- };
- xhr.open("POST", url);
+ }
+ xhr.open("POST", url)
if (headers !== undefined) {
for (const key in headers) {
- xhr.setRequestHeader(key, headers[key]);
+ xhr.setRequestHeader(key, headers[key])
}
}
- xhr.send(data);
- xhr.onerror = reject;
- });
+ xhr.send(data)
+ xhr.onerror = reject
+ })
}
public static async downloadJsonCached(
@@ -1032,11 +1040,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
maxCacheTimeMs: number,
headers?: any
): Promise {
- const result = await Utils.downloadJsonAdvanced(url, headers);
+ const result = await Utils.downloadJsonAdvanced(url, headers)
if (result["content"]) {
- return result["content"];
+ return result["content"]
}
- throw result["error"];
+ throw result["error"]
}
public static async downloadJsonCachedAdvanced(
@@ -1044,54 +1052,54 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
maxCacheTimeMs: number,
headers?: any
): Promise<{ content: any } | { error: string; url: string; statuscode?: number }> {
- const cached = Utils._download_cache.get(url);
+ const cached = Utils._download_cache.get(url)
if (cached !== undefined) {
if (new Date().getTime() - cached.timestamp <= maxCacheTimeMs) {
- return cached.promise;
+ return cached.promise
}
}
const promise =
/*NO AWAIT as we work with the promise directly */ Utils.downloadJsonAdvanced(
- url,
- headers
- );
- Utils._download_cache.set(url, { promise, timestamp: new Date().getTime() });
- return await promise;
+ url,
+ headers
+ )
+ Utils._download_cache.set(url, { promise, timestamp: new Date().getTime() })
+ return await promise
}
public static async downloadJson(url: string, headers?: any): Promise {
- const result = await Utils.downloadJsonAdvanced(url, headers);
+ const result = await Utils.downloadJsonAdvanced(url, headers)
if (result["content"]) {
- return result["content"];
+ return result["content"]
}
- throw result["error"];
+ throw result["error"]
}
public static async downloadJsonAdvanced(
url: string,
headers?: any
): Promise<{ content: any } | { error: string; url: string; statuscode?: number }> {
- const injected = Utils.injectedDownloads[url];
+ const injected = Utils.injectedDownloads[url]
if (injected !== undefined) {
- console.log("Using injected resource for test for URL", url);
- return new Promise((resolve, _) => resolve({ content: injected }));
+ console.log("Using injected resource for test for URL", url)
+ return new Promise((resolve, _) => resolve({ content: injected }))
}
const result = await Utils.downloadAdvanced(
url,
Utils.Merge({ accept: "application/json" }, headers ?? {})
- );
+ )
if (result["error"] !== undefined) {
- return <{ error: string; url: string; statuscode?: number }>result;
+ return <{ error: string; url: string; statuscode?: number }>result
}
- const data = result["content"];
+ const data = result["content"]
try {
if (typeof data === "string") {
- return { content: JSON.parse(data) };
+ return { content: JSON.parse(data) }
}
- return { content: data };
+ return { content: data }
} catch (e) {
- console.error("Could not parse ", data, "due to", e, "\n", e.stack);
- return { error: "malformed", url };
+ console.error("Could not parse ", data, "due to", e, "\n", e.stack)
+ return { error: "malformed", url }
}
}
@@ -1112,53 +1120,53 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
| "image/png"
}
) {
- const element = document.createElement("a");
- let file;
+ const element = document.createElement("a")
+ let file
if (typeof contents === "string") {
- file = new Blob([contents], { type: options?.mimetype ?? "text/plain" });
+ file = new Blob([contents], { type: options?.mimetype ?? "text/plain" })
} else {
- file = contents;
+ file = contents
}
- element.href = URL.createObjectURL(file);
- element.download = fileName;
- document.body.appendChild(element); // Required for this to work in FireFox
- element.click();
+ element.href = URL.createObjectURL(file)
+ element.download = fileName
+ document.body.appendChild(element) // Required for this to work in FireFox
+ element.click()
}
public static ColourNameToHex(color: string): string {
- return colors[color.toLowerCase()] ?? color;
+ return colors[color.toLowerCase()] ?? color
}
public static HexToColourName(hex: string): string {
- hex = hex.toLowerCase();
+ hex = hex.toLowerCase()
if (!hex.startsWith("#")) {
- return hex;
+ return hex
}
- const c = Utils.color(hex);
+ const c = Utils.color(hex)
- let smallestDiff = Number.MAX_VALUE;
- let bestColor = undefined;
+ let smallestDiff = Number.MAX_VALUE
+ let bestColor = undefined
for (const color in colors) {
if (!colors.hasOwnProperty(color)) {
- continue;
+ continue
}
- const foundhex = colors[color];
+ const foundhex = colors[color]
if (typeof foundhex !== "string") {
- continue;
+ continue
}
if (foundhex === hex) {
- return color;
+ return color
}
- const diff = this.colorDiff(Utils.color(foundhex), c);
+ const diff = this.colorDiff(Utils.color(foundhex), c)
if (diff > 50) {
- continue;
+ continue
}
if (diff < smallestDiff) {
- smallestDiff = diff;
- bestColor = color;
+ smallestDiff = diff
+ bestColor = color
}
}
- return bestColor ?? hex;
+ return bestColor ?? hex
}
/**
@@ -1168,37 +1176,37 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
* JSON.stringify(sorted) // => '{"abc":{"a":"a","x":"x"},"def":"def","x":"x"}'
*/
static sortKeys(o: any) {
- const copy = {};
- let keys = Object.keys(o);
- keys = keys.sort();
+ const copy = {}
+ let keys = Object.keys(o)
+ keys = keys.sort()
for (const key of keys) {
- let v = o[key];
+ let v = o[key]
if (typeof v === "object") {
- v = Utils.sortKeys(v);
+ v = Utils.sortKeys(v)
}
- copy[key] = v;
+ copy[key] = v
}
- return copy;
+ return copy
}
public static async waitFor(timeMillis: number): Promise {
return new Promise((resolve) => {
- window.setTimeout(resolve, timeMillis);
- });
+ window.setTimeout(resolve, timeMillis)
+ })
}
public static toHumanTime(seconds): string {
- seconds = Math.floor(seconds);
- let minutes = Math.floor(seconds / 60);
- seconds = seconds % 60;
- let hours = Math.floor(minutes / 60);
- minutes = minutes % 60;
- const days = Math.floor(hours / 24);
- hours = hours % 24;
+ seconds = Math.floor(seconds)
+ let minutes = Math.floor(seconds / 60)
+ seconds = seconds % 60
+ let hours = Math.floor(minutes / 60)
+ minutes = minutes % 60
+ const days = Math.floor(hours / 24)
+ hours = hours % 24
if (days > 0) {
- return days + "days" + " " + hours + "h";
+ return days + "days" + " " + hours + "h"
}
- return hours + ":" + Utils.TwoDigits(minutes) + ":" + Utils.TwoDigits(seconds);
+ return hours + ":" + Utils.TwoDigits(minutes) + ":" + Utils.TwoDigits(seconds)
}
public static DisableLongPresses() {
@@ -1209,55 +1217,55 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
// Not compatible with IE < 9
if (e.target["nodeName"] === "INPUT") {
- return;
+ return
}
- e.preventDefault();
- return false;
+ e.preventDefault()
+ return false
},
false
- );
+ )
}
public static preventDefaultOnMouseEvent(event: any) {
- event?.originalEvent?.preventDefault();
- event?.originalEvent?.stopPropagation();
- event?.originalEvent?.stopImmediatePropagation();
+ event?.originalEvent?.preventDefault()
+ event?.originalEvent?.stopPropagation()
+ event?.originalEvent?.stopImmediatePropagation()
if (event?.originalEvent) {
// This is a total workaround, as 'preventDefault' and everything above seems to be not working
- event.originalEvent["dismissed"] = true;
+ event.originalEvent["dismissed"] = true
}
}
public static HomepageLink(): string {
if (typeof window === "undefined") {
- return "https://mapcomplete.org";
+ return "https://mapcomplete.org"
}
const path = (
window.location.protocol +
"//" +
window.location.host +
window.location.pathname
- ).split("/");
- path.pop();
- path.push("index.html");
- return path.join("/");
+ ).split("/")
+ path.pop()
+ path.push("index.html")
+ return path.join("/")
}
public static OsmChaLinkFor(daysInThePast, theme = undefined): string {
- const now = new Date();
- const lastWeek = new Date(now.getTime() - daysInThePast * 24 * 60 * 60 * 1000);
+ const now = new Date()
+ const lastWeek = new Date(now.getTime() - daysInThePast * 24 * 60 * 60 * 1000)
const date =
lastWeek.getFullYear() +
"-" +
Utils.TwoDigits(lastWeek.getMonth() + 1) +
"-" +
- Utils.TwoDigits(lastWeek.getDate());
- let osmcha_link = `"date__gte":[{"label":"${date}","value":"${date}"}],"editor":[{"label":"mapcomplete","value":"mapcomplete"}]`;
+ Utils.TwoDigits(lastWeek.getDate())
+ let osmcha_link = `"date__gte":[{"label":"${date}","value":"${date}"}],"editor":[{"label":"mapcomplete","value":"mapcomplete"}]`
if (theme !== undefined) {
osmcha_link =
- osmcha_link + "," + `"comment":[{"label":"#${theme}","value":"#${theme}"}]`;
+ osmcha_link + "," + `"comment":[{"label":"#${theme}","value":"#${theme}"}]`
}
- return "https://osmcha.org/?filters=" + encodeURIComponent("{" + osmcha_link + "}");
+ return "https://osmcha.org/?filters=" + encodeURIComponent("{" + osmcha_link + "}")
}
/**
@@ -1267,31 +1275,31 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
static Clone(x: T): T {
if (x === undefined) {
- return undefined;
+ return undefined
}
- return JSON.parse(JSON.stringify(x));
+ return JSON.parse(JSON.stringify(x))
}
public static ParseDate(str: string): Date {
if (str.endsWith(" UTC")) {
- str = str.replace(" UTC", "+00");
+ str = str.replace(" UTC", "+00")
}
- return new Date(str);
+ return new Date(str)
}
public static selectTextIn(node) {
if (document.body["createTextRange"]) {
- const range = document.body["createTextRange"]();
- range.moveToElementText(node);
- range.select();
+ const range = document.body["createTextRange"]()
+ range.moveToElementText(node)
+ range.select()
} else if (window.getSelection) {
- const selection = window.getSelection();
- const range = document.createRange();
- range.selectNodeContents(node);
- selection.removeAllRanges();
- selection.addRange(range);
+ const selection = window.getSelection()
+ const range = document.createRange()
+ range.selectNodeContents(node)
+ selection.removeAllRanges()
+ selection.addRange(range)
} else {
- console.warn("Could not select text in node: Unsupported browser.");
+ console.warn("Could not select text in node: Unsupported browser.")
}
}
@@ -1302,46 +1310,46 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
): T[] {
const withDistance: [T, number][] = ts.map((t) => [
t,
- Utils.levenshteinDistance(getName(t), reference)
- ]);
- withDistance.sort(([_, a], [__, b]) => a - b);
- return withDistance.map((n) => n[0]);
+ Utils.levenshteinDistance(getName(t), reference),
+ ])
+ withDistance.sort(([_, a], [__, b]) => a - b)
+ return withDistance.map((n) => n[0])
}
public static levenshteinDistance(str1: string, str2: string) {
const track = Array(str2.length + 1)
.fill(null)
- .map(() => Array(str1.length + 1).fill(null));
+ .map(() => Array(str1.length + 1).fill(null))
for (let i = 0; i <= str1.length; i += 1) {
- track[0][i] = i;
+ track[0][i] = i
}
for (let j = 0; j <= str2.length; j += 1) {
- track[j][0] = j;
+ track[j][0] = j
}
for (let j = 1; j <= str2.length; j += 1) {
for (let i = 1; i <= str1.length; i += 1) {
- const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1;
+ const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1
track[j][i] = Math.min(
track[j][i - 1] + 1, // deletion
track[j - 1][i] + 1, // insertion
track[j - 1][i - 1] + indicator // substitution
- );
+ )
}
}
- return track[str2.length][str1.length];
+ return track[str2.length][str1.length]
}
public static MapToObj(
d: Map,
onValue: (t: V, key: string) => T
): Record {
- const o = {};
- const keys = Array.from(d.keys());
- keys.sort();
+ const o = {}
+ const keys = Array.from(d.keys())
+ keys.sort()
for (const key of keys) {
- o[key] = onValue(d.get(key), key);
+ o[key] = onValue(d.get(key), key)
}
- return o;
+ return o
}
/**
@@ -1352,20 +1360,20 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
public static TransposeMap(
d: Record
): Record {
- const newD: Record = {};
+ const newD: Record = {}
for (const k in d) {
- const vs = d[k];
+ const vs = d[k]
for (const v of vs) {
- const list = newD[v];
+ const list = newD[v]
if (list === undefined) {
- newD[v] = [k]; // Left: indexing; right: list with one element
+ newD[v] = [k] // Left: indexing; right: list with one element
} else {
- list.push(k);
+ list.push(k)
}
}
}
- return newD;
+ return newD
}
/**
@@ -1374,15 +1382,15 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
public static colorAsHex(c: { r: number; g: number; b: number }) {
if (c === undefined) {
- return undefined;
+ return undefined
}
function componentToHex(n) {
- const hex = n.toString(16);
- return hex.length == 1 ? "0" + hex : hex;
+ const hex = n.toString(16)
+ return hex.length == 1 ? "0" + hex : hex
}
- return "#" + componentToHex(c.r) + componentToHex(c.g) + componentToHex(c.b);
+ return "#" + componentToHex(c.r) + componentToHex(c.g) + componentToHex(c.b)
}
/**
@@ -1394,90 +1402,90 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
public static color(hex: string): { r: number; g: number; b: number } {
if (hex === undefined) {
- return undefined;
+ return undefined
}
- hex = hex.replace(/[ \t]/g, "");
+ hex = hex.replace(/[ \t]/g, "")
if (hex.startsWith("rgba(")) {
- const match = hex.match(/rgba\(([0-9.]+),([0-9.]+),([0-9.]+)(,[0-9.]*)?\)/);
+ const match = hex.match(/rgba\(([0-9.]+),([0-9.]+),([0-9.]+)(,[0-9.]*)?\)/)
if (match == undefined) {
- return undefined;
+ return undefined
}
- return { r: Number(match[1]), g: Number(match[2]), b: Number(match[3]) };
+ return { r: Number(match[1]), g: Number(match[2]), b: Number(match[3]) }
}
if (!hex.startsWith("#")) {
- return undefined;
+ return undefined
}
if (hex.length === 4) {
return {
r: parseInt(hex.substr(1, 1), 16),
g: parseInt(hex.substr(2, 1), 16),
- b: parseInt(hex.substr(3, 1), 16)
- };
+ b: parseInt(hex.substr(3, 1), 16),
+ }
}
return {
r: parseInt(hex.substr(1, 2), 16),
g: parseInt(hex.substr(3, 2), 16),
- b: parseInt(hex.substr(5, 2), 16)
- };
+ b: parseInt(hex.substr(5, 2), 16),
+ }
}
public static asDict(
tags: { key: string; value: string | number }[]
): Map {
- const d = new Map();
+ const d = new Map()
for (const tag of tags) {
- d.set(tag.key, tag.value);
+ d.set(tag.key, tag.value)
}
- return d;
+ return d
}
static toIdRecord(ts: T[]): Record {
- const result: Record = {};
+ const result: Record = {}
for (const t of ts) {
- result[t.id] = t;
+ result[t.id] = t
}
- return result;
+ return result
}
public static SetMidnight(d: Date): void {
- d.setUTCHours(0);
- d.setUTCSeconds(0);
- d.setUTCMilliseconds(0);
- d.setUTCMinutes(0);
+ d.setUTCHours(0)
+ d.setUTCSeconds(0)
+ d.setUTCMilliseconds(0)
+ d.setUTCMinutes(0)
}
public static scrollIntoView(element: HTMLBaseElement) {
// Is the element completely in the view?
- const parentRect = Utils.findParentWithScrolling(element).getBoundingClientRect();
- const elementRect = element.getBoundingClientRect();
+ const parentRect = Utils.findParentWithScrolling(element).getBoundingClientRect()
+ const elementRect = element.getBoundingClientRect()
// Check if the element is within the vertical bounds of the parent element
- const topIsVisible = elementRect.top >= parentRect.top;
- const bottomIsVisible = elementRect.bottom <= parentRect.bottom;
- const inView = topIsVisible && bottomIsVisible;
+ const topIsVisible = elementRect.top >= parentRect.top
+ const bottomIsVisible = elementRect.bottom <= parentRect.bottom
+ const inView = topIsVisible && bottomIsVisible
if (inView) {
- return;
+ return
}
- element.scrollIntoView({ behavior: "smooth", block: "nearest" });
+ element.scrollIntoView({ behavior: "smooth", block: "nearest" })
}
public static findParentWithScrolling(element: HTMLBaseElement): HTMLBaseElement {
// Check if the element itself has scrolling
if (element.scrollHeight > element.clientHeight) {
- return element;
+ return element
}
// If the element does not have scrolling, check if it has a parent element
if (!element.parentElement) {
- return null;
+ return null
}
// If the element has a parent, repeat the process for the parent element
- return Utils.findParentWithScrolling(element.parentElement);
+ return Utils.findParentWithScrolling(element.parentElement)
}
/**
@@ -1488,55 +1496,55 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
*/
public static sameList(a: ReadonlyArray, b: ReadonlyArray) {
if (a == b) {
- return true;
+ return true
}
if (a === undefined || a === null || b === undefined || b === null) {
- return false;
+ return false
}
if (a.length !== b.length) {
- return false;
+ return false
}
for (let i = 0; i < a.length; i++) {
- const ai = a[i];
- const bi = b[i];
+ const ai = a[i]
+ const bi = b[i]
if (ai == bi) {
- continue;
+ continue
}
if (ai === bi) {
- continue;
+ continue
}
- return false;
+ return false
}
- return true;
+ return true
}
public static SameObject(a: any, b: any) {
if (a === b) {
- return true;
+ return true
}
if (a === undefined || a === null || b === null || b === undefined) {
- return false;
+ return false
}
if (typeof a === "object" && typeof b === "object") {
for (const aKey in a) {
if (!(aKey in b)) {
- return false;
+ return false
}
}
for (const bKey in b) {
if (!(bKey in a)) {
- return false;
+ return false
}
}
for (const k in a) {
if (!Utils.SameObject(a[k], b[k])) {
- return false;
+ return false
}
}
- return true;
+ return true
}
- return false;
+ return false
}
/**
@@ -1548,22 +1556,22 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
public static splitIntoSubstitutionParts(
template: string
): ({ message: string } | { subs: string })[] {
- const preparts = template.split("{");
- const spec: ({ message: string } | { subs: string })[] = [];
+ const preparts = template.split("{")
+ const spec: ({ message: string } | { subs: string })[] = []
for (const prepart of preparts) {
- const postParts = prepart.split("}");
+ const postParts = prepart.split("}")
if (postParts.length === 1) {
// This was a normal part
- spec.push({ message: postParts[0] });
+ spec.push({ message: postParts[0] })
} else {
- const [subs, message] = postParts;
- spec.push({ subs });
+ const [subs, message] = postParts
+ spec.push({ subs })
if (message !== "") {
- spec.push({ message });
+ spec.push({ message })
}
}
}
- return spec;
+ return spec
}
/**
@@ -1577,40 +1585,40 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
filename: string
functionName: string
} {
- const error = new Error("No error");
- const stack = error.stack.split("\n");
- stack.shift(); // Remove "Error: No error"
- const regex = /at (.*) \(([a-zA-Z0-9/.]+):([0-9]+):([0-9]+)\)/;
- const stackItem = stack[Math.abs(offset) + 1];
+ const error = new Error("No error")
+ const stack = error.stack.split("\n")
+ stack.shift() // Remove "Error: No error"
+ const regex = /at (.*) \(([a-zA-Z0-9/.]+):([0-9]+):([0-9]+)\)/
+ const stackItem = stack[Math.abs(offset) + 1]
- let functionName: string;
- let path: string;
- let line: string;
- let column: string;
- let _: string;
- const matchWithFuncName = stackItem.match(regex);
+ let functionName: string
+ let path: string
+ let line: string
+ let column: string
+ let _: string
+ const matchWithFuncName = stackItem.match(regex)
if (matchWithFuncName) {
- ;[_, functionName, path, line, column] = matchWithFuncName;
+ ;[_, functionName, path, line, column] = matchWithFuncName
} else {
const regexNoFuncName: RegExp = new RegExp("at ([a-zA-Z0-9/.]+):([0-9]+):([0-9]+)")
- ;[_, path, line, column] = stackItem.match(regexNoFuncName);
+ ;[_, path, line, column] = stackItem.match(regexNoFuncName)
}
- const markdownLocation = path.substring(path.indexOf("MapComplete/src") + 11) + "#L" + line;
+ const markdownLocation = path.substring(path.indexOf("MapComplete/src") + 11) + "#L" + line
return {
path,
functionName,
line: Number(line),
column: Number(column),
markdownLocation,
- filename: path.substring(path.lastIndexOf("/") + 1)
- };
+ filename: path.substring(path.lastIndexOf("/") + 1),
+ }
}
private static colorDiff(
c0: { r: number; g: number; b: number },
c1: { r: number; g: number; b: number }
) {
- return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b);
+ return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b)
}
}
diff --git a/src/assets/contributors.json b/src/assets/contributors.json
index 7aee997160..933d386956 100644
--- a/src/assets/contributors.json
+++ b/src/assets/contributors.json
@@ -1,11 +1,11 @@
{
"contributors": [
{
- "commits": 6039,
+ "commits": 6055,
"contributor": "Pieter Vander Vennet"
},
{
- "commits": 408,
+ "commits": 414,
"contributor": "Robin van der Linde"
},
{
@@ -52,6 +52,10 @@
"commits": 24,
"contributor": "Ward"
},
+ {
+ "commits": 21,
+ "contributor": "dependabot[bot]"
+ },
{
"commits": 21,
"contributor": "wjtje"
@@ -60,10 +64,6 @@
"commits": 21,
"contributor": "AlexanderRebai"
},
- {
- "commits": 20,
- "contributor": "dependabot[bot]"
- },
{
"commits": 19,
"contributor": "Niels Elgaard Larsen"
@@ -106,11 +106,11 @@
},
{
"commits": 11,
- "contributor": "RobJN"
+ "contributor": "Thibault Molleman"
},
{
- "commits": 10,
- "contributor": "Thibault Molleman"
+ "commits": 11,
+ "contributor": "RobJN"
},
{
"commits": 10,
diff --git a/src/assets/translators.json b/src/assets/translators.json
index 3637f0b3ad..d0a89d4356 100644
--- a/src/assets/translators.json
+++ b/src/assets/translators.json
@@ -1,7 +1,7 @@
{
"contributors": [
{
- "commits": 306,
+ "commits": 308,
"contributor": "kjon"
},
{
@@ -9,7 +9,7 @@
"contributor": "Pieter Vander Vennet"
},
{
- "commits": 171,
+ "commits": 176,
"contributor": "paunofu"
},
{