Add binoculars theme, auto reformat everything
|
@ -9,16 +9,14 @@
|
||||||
"VARIANT": "14"
|
"VARIANT": "14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Set *default* container specific settings.json values on container create.
|
// Set *default* container specific settings.json values on container create.
|
||||||
"settings": {},
|
"settings": {},
|
||||||
|
|
||||||
// Add the IDs of extensions you want installed when the container is created.
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
"extensions": [],
|
"extensions": [],
|
||||||
|
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
"forwardPorts": [1234],
|
"forwardPorts": [
|
||||||
|
1234
|
||||||
|
],
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
//"postCreateCommand": "npm run init",
|
//"postCreateCommand": "npm run init",
|
||||||
|
|
||||||
|
|
9
.github/pull_request_template.md
vendored
|
@ -1,9 +1,8 @@
|
||||||
|
|
||||||
Opening a pull request on MapComplete
|
Opening a pull request on MapComplete
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
Hey! Thanks for opening a pull request on Mapcomplete! This probably means you want to add a new theme - if so, please follow the checklist below.
|
Hey! Thanks for opening a pull request on Mapcomplete! This probably means you want to add a new theme - if so, please
|
||||||
If this pull request is for some other issue, please ignore the template.
|
follow the checklist below. If this pull request is for some other issue, please ignore the template.
|
||||||
|
|
||||||
Adding your new theme
|
Adding your new theme
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -14,4 +13,6 @@ To making merging smooth, please make sure that each of the following conditions
|
||||||
|
|
||||||
- [ ] The codebase is GPL-licensed. By opening a pull request, the new theme will be GPL too
|
- [ ] The codebase is GPL-licensed. By opening a pull request, the new theme will be GPL too
|
||||||
- [ ] All images are included in the pull request and no images are loaded from an external service (e.g. Wikipedia)
|
- [ ] All images are included in the pull request and no images are loaded from an external service (e.g. Wikipedia)
|
||||||
- [ ] The [guidelines on how to make your own theme](https://github.com/pietervdvn/MapComplete/blob/master/Docs/Making_Your_Own_Theme.md) are read and followed
|
- [ ]
|
||||||
|
The [guidelines on how to make your own theme](https://github.com/pietervdvn/MapComplete/blob/master/Docs/Making_Your_Own_Theme.md)
|
||||||
|
are read and followed
|
|
@ -1,7 +1,8 @@
|
||||||
Architecture
|
Architecture
|
||||||
============
|
============
|
||||||
|
|
||||||
This document aims to give an architectural overview of how MapCompelte is built. It should give some feeling on how everything fits together.
|
This document aims to give an architectural overview of how MapCompelte is built. It should give some feeling on how
|
||||||
|
everything fits together.
|
||||||
|
|
||||||
Servers?
|
Servers?
|
||||||
--------
|
--------
|
||||||
|
@ -11,24 +12,30 @@ There are no servers for MapComplete, all services are configured by third parti
|
||||||
Minimal HTML - Minimal CSS
|
Minimal HTML - Minimal CSS
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
There is quasi no HTML. Most of the components are generated by TypeScript and attached dynamically. The html is a barebones skeleton which serves every theme.
|
There is quasi no HTML. Most of the components are generated by TypeScript and attached dynamically. The html is a
|
||||||
|
barebones skeleton which serves every theme.
|
||||||
|
|
||||||
|
|
||||||
The UIEventSource
|
The UIEventSource
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Most (but not all) objects in MapComplete get all the state they need as a parameter in the constructor. However, as is the case with most graphical applications, there are quite some dynamical values.
|
Most (but not all) objects in MapComplete get all the state they need as a parameter in the constructor. However, as is
|
||||||
|
the case with most graphical applications, there are quite some dynamical values.
|
||||||
|
|
||||||
All values which change regularly are wrapped into a [UIEventSource](https://github.com/pietervdvn/MapComplete/blob/master/Logic/UIEventSource.ts).
|
All values which change regularly are wrapped into
|
||||||
An UiEventSource is a wrapper containing a value and offers the possibility to add a callback function which is called every time the value is changed (with setData)
|
a [UIEventSource](https://github.com/pietervdvn/MapComplete/blob/master/Logic/UIEventSource.ts). An UiEventSource is a
|
||||||
|
wrapper containing a value and offers the possibility to add a callback function which is called every time the value is
|
||||||
|
changed (with setData)
|
||||||
|
|
||||||
Furthermore, there are various helper functions, the most widely used one being `map` - generating a new event source with the new value applied.
|
Furthermore, there are various helper functions, the most widely used one being `map` - generating a new event source
|
||||||
Note that 'map' will also absorb some changes, e.g. `const someEventSource : UIEventSource<string[]> = ... ; someEventSource.map(list = list.length)` will only trigger when the length of the list has changed.
|
with the new value applied. Note that 'map' will also absorb some changes,
|
||||||
|
e.g. `const someEventSource : UIEventSource<string[]> = ... ; someEventSource.map(list = list.length)` will only trigger
|
||||||
|
when the length of the list has changed.
|
||||||
|
|
||||||
An object which receives an UIEventSource is responsible of responding onto changes of this object. This is especially true for UI-components
|
An object which receives an UIEventSource is responsible of responding onto changes of this object. This is especially
|
||||||
|
true for UI-components
|
||||||
|
|
||||||
UI
|
UI --```
|
||||||
--```
|
|
||||||
|
|
||||||
export default class MyComponent {
|
export default class MyComponent {
|
||||||
|
|
||||||
|
@ -37,6 +44,7 @@ export default class MyComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The Graphical User Interface is composed of various UI-elements. For every UI-element, there is a BaseUIElement which creates the actual HTMLElement when needed.
|
The Graphical User Interface is composed of various UI-elements. For every UI-element, there is a BaseUIElement which creates the actual HTMLElement when needed.
|
||||||
|
@ -55,9 +63,9 @@ For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
const src : UIEventSource<string> = ... // E.g. user input, data that will be updated...
|
const src : UIEventSource<string> = ... // E.g. user input, data that will be updated... new VariableUIElement(src)
|
||||||
new VariableUIElement(src)
|
|
||||||
.AttachTo('some-id') // attach it to the html
|
.AttachTo('some-id') // attach it to the html
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that every component offers support for `onClick( someCallBack)`
|
Note that every component offers support for `onClick( someCallBack)`
|
||||||
|
@ -109,6 +117,7 @@ This can be constructed as following:
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
// We construct the dropdown element with values and labelshttps://tailwindcss.com/
|
// We construct the dropdown element with values and labelshttps://tailwindcss.com/
|
||||||
const isOpened = new Dropdown<string>(Translations.t.is_this_shop_opened_during_holidays,
|
const isOpened = new Dropdown<string>(Translations.t.is_this_shop_opened_during_holidays,
|
||||||
[
|
[
|
||||||
|
@ -127,6 +136,7 @@ This can be constructed as following:
|
||||||
)
|
)
|
||||||
|
|
||||||
return new Combine([isOpened, extraQuestion])
|
return new Combine([isOpened, extraQuestion])
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Constructing a special class
|
### Constructing a special class
|
||||||
|
@ -144,6 +154,7 @@ export default class MyComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Construct the needed UI in the constructor
|
2. Construct the needed UI in the constructor
|
||||||
|
@ -166,6 +177,7 @@ export default class MyComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
3. You'll notice that you'll end up with one certain component (in this example the combine) to wrap it all together. Change the class to extend this type of component and use super to wrap it all up:
|
3. You'll notice that you'll end up with one certain component (in this example the combine) to wrap it all together. Change the class to extend this type of component and use super to wrap it all up:
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
Metatags
|
Metatags
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
@ -7,9 +5,11 @@
|
||||||
|
|
||||||
Metatags are extra tags available, in order to display more data or to give better questions.
|
Metatags are extra tags available, in order to display more data or to give better questions.
|
||||||
|
|
||||||
The are calculated automatically on every feature when the data arrives in the webbrowser. This document gives an overview of the available metatags.
|
The are calculated automatically on every feature when the data arrives in the webbrowser. This document gives an
|
||||||
|
overview of the available metatags.
|
||||||
|
|
||||||
**Hint:** when using metatags, add the [query parameter](URL_Parameters.md) `debug=true` to the URL. This will include a box in the popup for features which shows all the properties of the object
|
**Hint:** when using metatags, add the [query parameter](URL_Parameters.md) `debug=true` to the URL. This will include a
|
||||||
|
box in the popup for features which shows all the properties of the object
|
||||||
|
|
||||||
|
|
||||||
Metatags calculated by MapComplete
|
Metatags calculated by MapComplete
|
||||||
|
@ -17,76 +17,53 @@ The are calculated automatically on every feature when the data arrives in the w
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The following values are always calculated, by default, by MapComplete and are available automatically on all elements in every theme
|
The following values are always calculated, by default, by MapComplete and are available automatically on all elements
|
||||||
|
in every theme
|
||||||
|
|
||||||
### _lat, _lon
|
### _lat, _lon
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The latitude and longitude of the point (or centerpoint in the case of a way/area)
|
The latitude and longitude of the point (or centerpoint in the case of a way/area)
|
||||||
|
|
||||||
|
|
||||||
### _surface, _surface:ha
|
### _surface, _surface:ha
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The surface area of the feature, in square meters and in hectare. Not set on points and ways
|
The surface area of the feature, in square meters and in hectare. Not set on points and ways
|
||||||
|
|
||||||
|
|
||||||
### _length, _length:km
|
### _length, _length:km
|
||||||
|
|
||||||
|
The total length of a feature in meters (and in kilometers, rounded to one decimal for '_length:km'). For a surface, the
|
||||||
|
length of the perimeter
|
||||||
The total length of a feature in meters (and in kilometers, rounded to one decimal for '_length:km'). For a surface, the length of the perimeter
|
|
||||||
|
|
||||||
|
|
||||||
### Theme-defined keys
|
### Theme-defined keys
|
||||||
|
|
||||||
|
If 'units' is defined in the layoutConfig, then this metatagger will rewrite the specified keys to have the canonical
|
||||||
|
form (e.g. `1meter` will be rewritten to `1m`)
|
||||||
If 'units' is defined in the layoutConfig, then this metatagger will rewrite the specified keys to have the canonical form (e.g. `1meter` will be rewritten to `1m`)
|
|
||||||
|
|
||||||
|
|
||||||
### _country
|
### _country
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The country code of the property (with latlon2country)
|
The country code of the property (with latlon2country)
|
||||||
|
|
||||||
|
|
||||||
### _isOpen, _isOpen:description
|
### _isOpen, _isOpen:description
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
If 'opening_hours' is present, it will add the current state of the feature (being 'yes' or 'no')
|
If 'opening_hours' is present, it will add the current state of the feature (being 'yes' or 'no')
|
||||||
|
|
||||||
|
|
||||||
### _width:needed, _width:needed:no_pedestrians, _width:difference
|
### _width:needed, _width:needed:no_pedestrians, _width:difference
|
||||||
|
|
||||||
|
Legacy for a specific project calculating the needed width for safe traffic on a road. Only activated if 'width:
|
||||||
|
carriageway' is present
|
||||||
Legacy for a specific project calculating the needed width for safe traffic on a road. Only activated if 'width:carriageway' is present
|
|
||||||
|
|
||||||
|
|
||||||
### _direction:numerical, _direction:leftright
|
### _direction:numerical, _direction:leftright
|
||||||
|
|
||||||
|
_direction:numerical is a normalized, numerical direction based on 'camera:direction' or on 'direction'; it is only
|
||||||
|
present if a valid direction is found (e.g. 38.5 or NE). _direction:leftright is either 'left' or 'right', which is
|
||||||
_direction:numerical is a normalized, numerical direction based on 'camera:direction' or on 'direction'; it is only present if a valid direction is found (e.g. 38.5 or NE). _direction:leftright is either 'left' or 'right', which is left-looking on the map or 'right-looking' on the map
|
left-looking on the map or 'right-looking' on the map
|
||||||
|
|
||||||
|
|
||||||
### _now:date, _now:datetime, _loaded:date, _loaded:_datetime
|
### _now:date, _now:datetime, _loaded:date, _loaded:_datetime
|
||||||
|
|
||||||
|
Adds the time that the data got loaded - pretty much the time of downloading from overpass. The format is YYYY-MM-DD hh:
|
||||||
|
mm, aka 'sortable' aka ISO-8601-but-not-entirely
|
||||||
Adds the time that the data got loaded - pretty much the time of downloading from overpass. The format is YYYY-MM-DD hh:mm, aka 'sortable' aka ISO-8601-but-not-entirely
|
|
||||||
|
|
||||||
|
|
||||||
### _last_edit:contributor, _last_edit:contributor:uid, _last_edit:changeset, _last_edit:timestamp, _version_number
|
### _last_edit:contributor, _last_edit:contributor:uid, _last_edit:changeset, _last_edit:timestamp, _version_number
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Information about the last edit of this object.
|
Information about the last edit of this object.
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,20 +72,18 @@ Information about the last edit of this object.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
In some cases, it is useful to have some tags calculated based on other properties. Some useful tags are available by default (e.g. `lat`, `lon`, `_country`), as detailed above.
|
In some cases, it is useful to have some tags calculated based on other properties. Some useful tags are available by
|
||||||
|
default (e.g. `lat`, `lon`, `_country`), as detailed above.
|
||||||
|
|
||||||
It is also possible to calculate your own tags - but this requires some javascript knowledge.
|
It is also possible to calculate your own tags - but this requires some javascript knowledge.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Before proceeding, some warnings:
|
Before proceeding, some warnings:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- DO NOT DO THIS AS BEGINNER
|
- DO NOT DO THIS AS BEGINNER
|
||||||
- **Only do this if all other techniques fail** This should _not_ be done to create a rendering effect, only to calculate a specific value
|
- **Only do this if all other techniques fail** This should _not_ be done to create a rendering effect, only to
|
||||||
- **THIS MIGHT BE DISABLED WITHOUT ANY NOTICE ON UNOFFICIAL THEMES** As unofficial themes might be loaded from the internet, this is the equivalent of injecting arbitrary code into the client. It'll be disabled if abuse occurs.
|
calculate a specific value
|
||||||
|
- **THIS MIGHT BE DISABLED WITHOUT ANY NOTICE ON UNOFFICIAL THEMES** As unofficial themes might be loaded from the
|
||||||
|
internet, this is the equivalent of injecting arbitrary code into the client. It'll be disabled if abuse occurs.
|
||||||
|
|
||||||
To enable this feature, add a field `calculatedTags` in the layer object, e.g.:
|
To enable this feature, add a field `calculatedTags` in the layer object, e.g.:
|
||||||
|
|
||||||
|
@ -126,16 +101,12 @@ To enable this feature, add a field `calculatedTags` in the layer object, e.g.:
|
||||||
|
|
||||||
````
|
````
|
||||||
|
|
||||||
|
The above code will be executed for every feature in the layer. The feature is accessible as `feat` and is an amended
|
||||||
|
geojson object:
|
||||||
The above code will be executed for every feature in the layer. The feature is accessible as `feat` and is an amended geojson object:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- `area` contains the surface area (in square meters) of the object
|
- `area` contains the surface area (in square meters) of the object
|
||||||
- `lat` and `lon` contain the latitude and longitude
|
- `lat` and `lon` contain the latitude and longitude
|
||||||
|
|
||||||
|
|
||||||
Some advanced functions are available on **feat** as well:
|
Some advanced functions are available on **feat** as well:
|
||||||
|
|
||||||
- distanceTo
|
- distanceTo
|
||||||
|
@ -146,20 +117,25 @@ Some advanced functions are available on **feat** as well:
|
||||||
|
|
||||||
### distanceTo
|
### distanceTo
|
||||||
|
|
||||||
Calculates the distance between the feature and a specified point in kilometer. The input should either be a pair of coordinates, a geojson feature or the ID of an object
|
Calculates the distance between the feature and a specified point in kilometer. The input should either be a pair of
|
||||||
|
coordinates, a geojson feature or the ID of an object
|
||||||
|
|
||||||
0. longitude
|
0. longitude
|
||||||
1. latitude
|
1. latitude
|
||||||
|
|
||||||
### overlapWith
|
### overlapWith
|
||||||
|
|
||||||
Gives a list of features from the specified layer which this feature (partly) overlaps with. If the current feature is a point, all features that embed the point are given. The returned value is `{ feat: GeoJSONFeature, overlap: number}[]` where `overlap` is the overlapping surface are (in m²) for areas, the overlapping length (in meter) if the current feature is a line or `undefined` if the current feature is a point
|
Gives a list of features from the specified layer which this feature (partly) overlaps with. If the current feature is a
|
||||||
|
point, all features that embed the point are given. The returned value is `{ feat: GeoJSONFeature, overlap: number}[]`
|
||||||
|
where `overlap` is the overlapping surface are (in m²) for areas, the overlapping length (in meter) if the current
|
||||||
|
feature is a line or `undefined` if the current feature is a point
|
||||||
|
|
||||||
0. ...layerIds - one or more layer ids of the layer from which every feature is checked for overlap)
|
0. ...layerIds - one or more layer ids of the layer from which every feature is checked for overlap)
|
||||||
|
|
||||||
### closest
|
### closest
|
||||||
|
|
||||||
Given either a list of geojson features or a single layer name, gives the single object which is nearest to the feature. In the case of ways/polygons, only the centerpoint is considered.
|
Given either a list of geojson features or a single layer name, gives the single object which is nearest to the feature.
|
||||||
|
In the case of ways/polygons, only the centerpoint is considered.
|
||||||
|
|
||||||
0. list of features
|
0. list of features
|
||||||
|
|
||||||
|
@ -169,13 +145,12 @@ Some advanced functions are available on **feat** as well:
|
||||||
|
|
||||||
For example: `_part_of_walking_routes=feat.memberships().map(r => r.relation.tags.name).join(';')`
|
For example: `_part_of_walking_routes=feat.memberships().map(r => r.relation.tags.name).join(';')`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### score
|
### score
|
||||||
|
|
||||||
Given the path of an aspected routing json file, will calculate the score. This score is wrapped in a UIEventSource, so for further calculations, use `.map(score => ...)`
|
Given the path of an aspected routing json file, will calculate the score. This score is wrapped in a UIEventSource, so
|
||||||
|
for further calculations, use `.map(score => ...)`
|
||||||
|
|
||||||
For example: `_comfort_score=feat.score('https://raw.githubusercontent.com/pietervdvn/AspectedRouting/master/Examples/bicycle/aspects/bicycle.comfort.json')`
|
For
|
||||||
|
example: `_comfort_score=feat.score('https://raw.githubusercontent.com/pietervdvn/AspectedRouting/master/Examples/bicycle/aspects/bicycle.comfort.json')`
|
||||||
|
|
||||||
0. path
|
0. path Generated from SimpleMetaTagger, ExtraFunction
|
||||||
Generated from SimpleMetaTagger, ExtraFunction
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
Development and deployment
|
Development and deployment
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
@ -6,28 +5,37 @@
|
||||||
|
|
||||||
This documents attempts to shed some light on these scripts.
|
This documents attempts to shed some light on these scripts.
|
||||||
|
|
||||||
Note: these scripts change every now and then - if the documentation here is incorrect or you run into troubles, do leave a message in [the issue tracker](https://github.com/pietervdvn/MapComplete/issues)
|
Note: these scripts change every now and then - if the documentation here is incorrect or you run into troubles, do
|
||||||
|
leave a message in [the issue tracker](https://github.com/pietervdvn/MapComplete/issues)
|
||||||
|
|
||||||
Architecture overview
|
Architecture overview
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
At its core, MapComplete is a static (!) website. There are no servers to host.
|
At its core, MapComplete is a static (!) website. There are no servers to host.
|
||||||
|
|
||||||
The data is fetched from Overpass/OSM/Wikidata/Wikipedia/Mapillary/... and written there directly. This means that any static file server will do to create a self-hosted version of MapComplete.
|
The data is fetched from Overpass/OSM/Wikidata/Wikipedia/Mapillary/... and written there directly. This means that any
|
||||||
|
static file server will do to create a self-hosted version of MapComplete.
|
||||||
|
|
||||||
Development
|
Development
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
**Windows users**: All scripts are made for linux devices. Use the Ubuntu terminal for Windows (or even better - make the switch ;) ). If you are using Visual Studio Code you can use a [WSL Remote](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl) window, or use the Devcontainer (see more details later).
|
**Windows users**: All scripts are made for linux devices. Use the Ubuntu terminal for Windows (or even better - make
|
||||||
|
the switch ;) ). If you are using Visual Studio Code you can use
|
||||||
|
a [WSL Remote](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl) window, or use the
|
||||||
|
Devcontainer (see more details later).
|
||||||
|
|
||||||
To develop and build MapComplete, you
|
To develop and build MapComplete, you
|
||||||
|
|
||||||
0. Make sure you have a recent version of nodejs - at least 12.0, preferably 15
|
0. Make sure you have a recent version of nodejs - at least 12.0, preferably 15
|
||||||
0. Make a fork and clone the repository.
|
0. Make a fork and clone the repository.
|
||||||
1. Install `npm`. Linux: `sudo apt install npm` (or your favourite package manager), Windows: install nodeJS: https://nodejs.org/en/download/
|
1. Install `npm`. Linux: `sudo apt install npm` (or your favourite package manager), Windows: install
|
||||||
3. Run `npm run init` and generate some additional dependencies and generated files. Note that it'll install the dependencies too
|
nodeJS: https://nodejs.org/en/download/
|
||||||
|
3. Run `npm run init` and generate some additional dependencies and generated files. Note that it'll install the
|
||||||
|
dependencies too
|
||||||
4. Run `npm run start` to host a local testversion at http://localhost:1234/index.html
|
4. Run `npm run start` to host a local testversion at http://localhost:1234/index.html
|
||||||
5. By default, a landing page with available themes is served. In order to load a single theme, use `layout=themename` or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version.
|
5. By default, a landing page with available themes is served. In order to load a single theme, use `layout=themename`
|
||||||
|
or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (
|
||||||
|
e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version.
|
||||||
|
|
||||||
Development using Windows
|
Development using Windows
|
||||||
------------------------
|
------------------------
|
||||||
|
@ -36,12 +44,16 @@
|
||||||
|
|
||||||
To use the devcontainer in Visual Studio Code:
|
To use the devcontainer in Visual Studio Code:
|
||||||
|
|
||||||
0. Make sure you have installed the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension and it's dependencies.
|
0. Make sure you have installed
|
||||||
|
the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
|
||||||
|
extension and it's dependencies.
|
||||||
1. Make a fork and clone the repository.
|
1. Make a fork and clone the repository.
|
||||||
2. After cloning, Visual Studio Code will ask you if you want to use the devcontainer.
|
2. After cloning, Visual Studio Code will ask you if you want to use the devcontainer.
|
||||||
3. Then you can either clone it again in a volume (for better performance), or open the current folder in a container.
|
3. Then you can either clone it again in a volume (for better performance), or open the current folder in a container.
|
||||||
4. By now, you should be able to run `npm run start` to host a local testversion at http://localhost:1234/index.html
|
4. By now, you should be able to run `npm run start` to host a local testversion at http://localhost:1234/index.html
|
||||||
5. By default, a landing page with available themes is served. In order to load a single theme, use `layout=themename` or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version.
|
5. By default, a landing page with available themes is served. In order to load a single theme, use `layout=themename`
|
||||||
|
or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (
|
||||||
|
e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version.
|
||||||
|
|
||||||
To use the WSL in Visual Studio Code:
|
To use the WSL in Visual Studio Code:
|
||||||
|
|
||||||
|
@ -49,10 +61,12 @@
|
||||||
1. Open a remote WSL window using the button in the bottom left.
|
1. Open a remote WSL window using the button in the bottom left.
|
||||||
2. Make a fork and clone the repository.
|
2. Make a fork and clone the repository.
|
||||||
3. Install `npm` using `sudo apt install npm`.
|
3. Install `npm` using `sudo apt install npm`.
|
||||||
4. Run `npm run init` and generate some additional dependencies and generated files. Note that it'll install the dependencies too
|
4. Run `npm run init` and generate some additional dependencies and generated files. Note that it'll install the
|
||||||
|
dependencies too
|
||||||
5. Run `npm run start` to host a local testversion at http://localhost:1234/index.html
|
5. Run `npm run start` to host a local testversion at http://localhost:1234/index.html
|
||||||
6. By default, a landing page with available themes is served. In order to load a single theme, use `layout=themename` or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version.
|
6. By default, a landing page with available themes is served. In order to load a single theme, use `layout=themename`
|
||||||
|
or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (
|
||||||
|
e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version.
|
||||||
|
|
||||||
Automatic deployment
|
Automatic deployment
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -71,15 +85,14 @@
|
||||||
- have individual social images
|
- have individual social images
|
||||||
- have individual web manifests
|
- have individual web manifests
|
||||||
|
|
||||||
|
|
||||||
This script can be invoked with `npm run prepare-deploy`
|
This script can be invoked with `npm run prepare-deploy`
|
||||||
|
|
||||||
If you want to deploy your fork:
|
If you want to deploy your fork:
|
||||||
|
|
||||||
0. `npm run prepare-deploy`
|
0. `npm run prepare-deploy`
|
||||||
1. `npm run build`
|
1. `npm run build`
|
||||||
2. Copy the entire `dist` folder to where you host your website. Visiting `index.html` gives you the landing page, visiting `yourwebsite/<theme>` should bring you to the appropriate theme.
|
2. Copy the entire `dist` folder to where you host your website. Visiting `index.html` gives you the landing page,
|
||||||
|
visiting `yourwebsite/<theme>` should bring you to the appropriate theme.
|
||||||
|
|
||||||
Weird errors
|
Weird errors
|
||||||
------------
|
------------
|
||||||
|
@ -96,8 +109,10 @@ Try removing `node_modules`, `package-lock.json` and `.cache`
|
||||||
- `generate:editor-layer-index`: downloads the editor-layer-index-json from osmlab.github.io
|
- `generate:editor-layer-index`: downloads the editor-layer-index-json from osmlab.github.io
|
||||||
- `generate:images`: compiles the SVG's into an asset
|
- `generate:images`: compiles the SVG's into an asset
|
||||||
- `generate:translations`: compiles the translation file into a javascript file
|
- `generate:translations`: compiles the translation file into a javascript file
|
||||||
- `generate:layouts`: uses `index.html` as template to create all the theme index pages. You'll want to run `clean` when done
|
- `generate:layouts`: uses `index.html` as template to create all the theme index pages. You'll want to run `clean` when
|
||||||
- `generate:docs`: generates various documents, such as information about available metatags, information to put on the [OSM-wiki](https://wiki.openstreetmap.org/wiki/MapComplete),...
|
done
|
||||||
|
- `generate:docs`: generates various documents, such as information about available metatags, information to put on
|
||||||
|
the [OSM-wiki](https://wiki.openstreetmap.org/wiki/MapComplete),...
|
||||||
- `generate:report`: downloads statistics from OsmCha, compiles neat graphs
|
- `generate:report`: downloads statistics from OsmCha, compiles neat graphs
|
||||||
- `generate:cache:speelplekken`: creates an offline copy of all the data required for one specific (paid for) theme
|
- `generate:cache:speelplekken`: creates an offline copy of all the data required for one specific (paid for) theme
|
||||||
- `generate:layeroverview`: reads all the theme- and layerconfigurations, compiles them into a single JSON.
|
- `generate:layeroverview`: reads all the theme- and layerconfigurations, compiles them into a single JSON.
|
||||||
|
|
|
@ -1,28 +1,45 @@
|
||||||
Gebruikersgids MapComplete
|
Gebruikersgids MapComplete
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
MapComplete is een website waar geodata op basis van [OpenStreetMap](https://osm.org), [Wikidata](https://wikidata.org) en andere open bronnen wordt gevisualiseerd en aangevuld.
|
MapComplete is een website waar geodata op basis van [OpenStreetMap](https://osm.org), [Wikidata](https://wikidata.org)
|
||||||
|
en andere open bronnen wordt gevisualiseerd en aangevuld.
|
||||||
|
|
||||||
De getoonde geodata is afhankelijk van het thema - zo is er bijvoorbeeld het thema voor [boekenruilkasten](https://mapcomplete.osm.be/bookcases) [cyclofix](http://mapcomplete.osm.be/cyclofix) die focust op fietspompen, fietswinkels, ...
|
De getoonde geodata is afhankelijk van het thema - zo is er bijvoorbeeld het thema
|
||||||
|
voor [boekenruilkasten](https://mapcomplete.osm.be/bookcases) [cyclofix](http://mapcomplete.osm.be/cyclofix) die focust
|
||||||
|
op fietspompen, fietswinkels, ...
|
||||||
|
|
||||||
MapComplete mag gratis gebruikt worden. Om de data te raadplegen heb je geen account nodig - de webpagina bezoeken is voldoende.
|
MapComplete mag gratis gebruikt worden. Om de data te raadplegen heb je geen account nodig - de webpagina bezoeken is
|
||||||
|
voldoende.
|
||||||
|
|
||||||
### Data toevoegen
|
### Data toevoegen
|
||||||
|
|
||||||
OpenStreetMap is een gedeelde databank van geodata. Om die correct en up to date te houden, voegen we _enkel_ gegevens toe waarvan we zeker weten dat die op dit moment ook zo zijn in de echte wereld. Twijfel je dus over een vraag? Sla de vraag dan over en ga opnieuw ter plaatse kijken. **Beter geen informatie dan foute informatie**.
|
OpenStreetMap is een gedeelde databank van geodata. Om die correct en up to date te houden, voegen we _enkel_ gegevens
|
||||||
|
toe waarvan we zeker weten dat die op dit moment ook zo zijn in de echte wereld. Twijfel je dus over een vraag? Sla de
|
||||||
|
vraag dan over en ga opnieuw ter plaatse kijken. **Beter geen informatie dan foute informatie**.
|
||||||
|
|
||||||
Daarnaast verwachten we ook dat je op een vriendelijke en correcte manier omgaat met andere leden van de community. Je kan feedback of vragen krijgen over je aanpassingen - bijvoorbeeld wanneer andere bijdragers denken dat er een vergissing is gebeurd. Meestal is de vergissing met een paar heen- en weerberichtjes uitgeklaard. Vergissen is menselijk.
|
Daarnaast verwachten we ook dat je op een vriendelijke en correcte manier omgaat met andere leden van de community. Je
|
||||||
|
kan feedback of vragen krijgen over je aanpassingen - bijvoorbeeld wanneer andere bijdragers denken dat er een
|
||||||
|
vergissing is gebeurd. Meestal is de vergissing met een paar heen- en weerberichtjes uitgeklaard. Vergissen is
|
||||||
|
menselijk.
|
||||||
|
|
||||||
Als je bijdragen grote fouten bevatten, kunnen je wijzigingen ongedaan gemaakt worden door andere leden van OpenStreetMap. Dit is echter erg uitzonderlijk. Bij herhaaldelijke grote fouten, (vermoeden van) kwaad opzet of vandalisme kan je account geblokkeerd worden. Merk op dat MapComplete is opgezet om (grote) vergissingen te vermijden, dus dit is bijna onmogelijk.
|
Als je bijdragen grote fouten bevatten, kunnen je wijzigingen ongedaan gemaakt worden door andere leden van
|
||||||
|
OpenStreetMap. Dit is echter erg uitzonderlijk. Bij herhaaldelijke grote fouten, (vermoeden van) kwaad opzet of
|
||||||
|
vandalisme kan je account geblokkeerd worden. Merk op dat MapComplete is opgezet om (grote) vergissingen te vermijden,
|
||||||
|
dus dit is bijna onmogelijk.
|
||||||
|
|
||||||
Data hergebruiken
|
Data hergebruiken
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
De getoonde data (locaties van POI, ...) mogen vrij en gratis hergebruikt worden voor alle doeleinden (ook commercieel), mits de vermelding `Data van OpenStreetMap, vrij beschikbaar onder ODBL` of een gelijkaardige zin. Hiervoor hoef je geen toestemming te vragen.
|
De getoonde data (locaties van POI, ...) mogen vrij en gratis hergebruikt worden voor alle doeleinden (ook commercieel),
|
||||||
|
mits de vermelding `Data van OpenStreetMap, vrij beschikbaar onder ODBL` of een gelijkaardige zin. Hiervoor hoef je geen
|
||||||
|
toestemming te vragen.
|
||||||
|
|
||||||
Let op: aanpassingen aan de data worden ook als open data beschouwd. Let ook op wanneer je OpenStreetMap-data gaat mengen uit andere databronnen waar copyright op rust; vaak mag dit niet. Voor meer informatie, zie de [volledige copyrightnotice](https://osm.org/copyright).
|
Let op: aanpassingen aan de data worden ook als open data beschouwd. Let ook op wanneer je OpenStreetMap-data gaat
|
||||||
|
mengen uit andere databronnen waar copyright op rust; vaak mag dit niet. Voor meer informatie, zie
|
||||||
|
de [volledige copyrightnotice](https://osm.org/copyright).
|
||||||
|
|
||||||
Om de data als computerbestand op te vragen, bestaan er [verschillende opties](https://learnosm.org/en/osm-data/getting-data/).
|
Om de data als computerbestand op te vragen, bestaan
|
||||||
|
er [verschillende opties](https://learnosm.org/en/osm-data/getting-data/).
|
||||||
|
|
||||||
Privacy
|
Privacy
|
||||||
-------
|
-------
|
||||||
|
@ -31,17 +48,24 @@ Privacy
|
||||||
|
|
||||||
Zolang je je niet aanmeldt, worden er geen persoonsgegevens opgeslaan.
|
Zolang je je niet aanmeldt, worden er geen persoonsgegevens opgeslaan.
|
||||||
|
|
||||||
Je computer stuurt echter wel een klein berichtje naar [pietervdvn.goatcounter.com](pietervdvn.goatcounter.com), waar statistieken over de bezoekersaantallen worden bijgehouden. Dit omvat een minimum aan technische gegevens en kan niet gelinkt worden aan een OSM-gebruikersaccount of persoon door de makers van MapComplete.
|
Je computer stuurt echter wel een klein berichtje naar [pietervdvn.goatcounter.com](pietervdvn.goatcounter.com), waar
|
||||||
|
statistieken over de bezoekersaantallen worden bijgehouden. Dit omvat een minimum aan technische gegevens en kan niet
|
||||||
|
gelinkt worden aan een OSM-gebruikersaccount of persoon door de makers van MapComplete.
|
||||||
|
|
||||||
### Met account
|
### Met account
|
||||||
|
|
||||||
Wanneer je een account maakt, is dit een account op OpenStreetMap. Voor je een account maakt, gelieve hun [privacy statement](https://wiki.osmfoundation.org/wiki/Privacy_Policy) te lezen.
|
Wanneer je een account maakt, is dit een account op OpenStreetMap. Voor je een account maakt, gelieve
|
||||||
|
hun [privacy statement](https://wiki.osmfoundation.org/wiki/Privacy_Policy) te lezen.
|
||||||
|
|
||||||
Een account maken is gratis, je moet enkel een email-adres en gebruikersnaam opgeven. Je email-adres is niet publiek zichtbaar, je gebruikersnaam wel.
|
Een account maken is gratis, je moet enkel een email-adres en gebruikersnaam opgeven. Je email-adres is niet publiek
|
||||||
|
zichtbaar, je gebruikersnaam wel.
|
||||||
|
|
||||||
Je kan opteren om een _pseudoniem_ te gebruiken - je gebruikersnaam hoeft niet je echte naam te zijn. Ook de naam van je huisdier of iets zelfbedacht mag gerust.
|
Je kan opteren om een _pseudoniem_ te gebruiken - je gebruikersnaam hoeft niet je echte naam te zijn. Ook de naam van je
|
||||||
|
huisdier of iets zelfbedacht mag gerust.
|
||||||
|
|
||||||
Wanneer je gegevens aanvult via MapComplete, zal je wijziging **publiek zichtbaar** zijn voor iedereen ter wereld. Dit betekent dus dat iedereen weet dat _gebruikersnaam_ op een bepaalde plaats op een bepaald uur aanwezig was.
|
Wanneer je gegevens aanvult via MapComplete, zal je wijziging **publiek zichtbaar** zijn voor iedereen ter wereld. Dit
|
||||||
|
betekent dus dat iedereen weet dat _gebruikersnaam_ op een bepaalde plaats op een bepaald uur aanwezig was.
|
||||||
|
|
||||||
**Ben je minderjarig?** Vraag toestemming aan je ouders voordat je een account aanmaakt en kies ervoor om je echte naam _niet_ te gebruiken.
|
**Ben je minderjarig?** Vraag toestemming aan je ouders voordat je een account aanmaakt en kies ervoor om je echte
|
||||||
|
naam _niet_ te gebruiken.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
Making your own theme
|
Making your own theme
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
In MapComplete, it is relatively simple to make your own theme. This guide will give some information on how you can do this.
|
In MapComplete, it is relatively simple to make your own theme. This guide will give some information on how you can do
|
||||||
|
this.
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
@ -11,17 +12,22 @@ Before you start, you should have the following qualifications:
|
||||||
- You are a longtime contributor and do know the OpenStreetMap tagging scheme very well.
|
- You are a longtime contributor and do know the OpenStreetMap tagging scheme very well.
|
||||||
- You are not afraid of editing a .JSON-file
|
- You are not afraid of editing a .JSON-file
|
||||||
- You're theme will add well-understood tags (aka: the tags have a wiki page, are not controversial and are objective)
|
- You're theme will add well-understood tags (aka: the tags have a wiki page, are not controversial and are objective)
|
||||||
- You are in contact with your local OpenStreetMap community and do know some other members to discuss tagging and to help testing
|
- You are in contact with your local OpenStreetMap community and do know some other members to discuss tagging and to
|
||||||
|
help testing
|
||||||
|
|
||||||
If you do not have those qualifications, reach out to the MapComplete community channel on [Telegram](https://t.me/MapComplete)
|
If you do not have those qualifications, reach out to the MapComplete community channel
|
||||||
|
on [Telegram](https://t.me/MapComplete)
|
||||||
or [Matrix](https://app.element.io/#/room/#MapComplete:matrix.org).
|
or [Matrix](https://app.element.io/#/room/#MapComplete:matrix.org).
|
||||||
|
|
||||||
The custom theme generator
|
The custom theme generator
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
The custom theme generator is a special page of MapComplete, where one can create their own theme. It makes it easier to get started.
|
The custom theme generator is a special page of MapComplete, where one can create their own theme. It makes it easier to
|
||||||
|
get started.
|
||||||
|
|
||||||
However, the custom theme generator is extremely buggy and built before some updates. This means that some features are _not_ available through the custom theme generator. The custom theme generator is good to get the basics of the theme set up, but you will have to edit the raw JSON-file anyway afterwards.
|
However, the custom theme generator is extremely buggy and built before some updates. This means that some features
|
||||||
|
are _not_ available through the custom theme generator. The custom theme generator is good to get the basics of the
|
||||||
|
theme set up, but you will have to edit the raw JSON-file anyway afterwards.
|
||||||
|
|
||||||
[A quick tutorial for the custom theme generator can be found here](https://www.youtube.com/watch?v=nVbFrNVPxPw).
|
[A quick tutorial for the custom theme generator can be found here](https://www.youtube.com/watch?v=nVbFrNVPxPw).
|
||||||
|
|
||||||
|
@ -30,48 +36,67 @@ Loading your theme
|
||||||
|
|
||||||
If you have your .json file, there are three ways to distribute your theme:
|
If you have your .json file, there are three ways to distribute your theme:
|
||||||
|
|
||||||
- Take the entire JSON-file and [base64](https://www.base64encode.org/) encode it. Then open up the url `https://mapcomplete.osm.be?userlayout=true#<base64-encoded-json-here>`. Yes, this URL will be huge; and updates are difficult to distribute as you have to send a new URL to everyone. This is however excellent to have a 'quick and dirty' test version up and running as these links can be generated from the customThemeGenerator and can be quickly shared with a few other contributors.
|
- Take the entire JSON-file and [base64](https://www.base64encode.org/) encode it. Then open up the
|
||||||
- Host the JSON file on a publicly accessible webserver (e.g. github) and open up `https://mapcomplete.osm.be?userlayout=<url-to-the-raw.json>`
|
url `https://mapcomplete.osm.be?userlayout=true#<base64-encoded-json-here>`. Yes, this URL will be huge; and updates
|
||||||
|
are difficult to distribute as you have to send a new URL to everyone. This is however excellent to have a 'quick and
|
||||||
|
dirty' test version up and running as these links can be generated from the customThemeGenerator and can be quickly
|
||||||
|
shared with a few other contributors.
|
||||||
|
- Host the JSON file on a publicly accessible webserver (e.g. github) and open
|
||||||
|
up `https://mapcomplete.osm.be?userlayout=<url-to-the-raw.json>`
|
||||||
- Ask to have your theme included into the official MapComplete - requirements below
|
- Ask to have your theme included into the official MapComplete - requirements below
|
||||||
|
|
||||||
### Getting your theme included into the official mapcomplete
|
### Getting your theme included into the official mapcomplete
|
||||||
|
|
||||||
Did you make an awesome theme that you want to share with the OpenStreetMap community? Have it included in the main application, which makes it more discoverable.
|
Did you make an awesome theme that you want to share with the OpenStreetMap community? Have it included in the main
|
||||||
|
application, which makes it more discoverable.
|
||||||
|
|
||||||
Your theme has to be:
|
Your theme has to be:
|
||||||
|
|
||||||
0) Make sure the theme has an English version. This makes it easier for me to understand what is going on. The more other languages, the better of course!
|
0) Make sure the theme has an English version. This makes it easier for me to understand what is going on. The more
|
||||||
|
other languages, the better of course!
|
||||||
1) Make sure your theme has good tagging
|
1) Make sure your theme has good tagging
|
||||||
3) Make sure there are somewhat decent icons. Note that there is _no_ styleguide at the moment though.
|
3) Make sure there are somewhat decent icons. Note that there is _no_ styleguide at the moment though.
|
||||||
|
|
||||||
The preferred way to add your theme is via a Pull Request. A Pull Request is less work for the maintainer (which makes it really easy and for me to add it) and your name will be included in the git history (so you'll be listed as contributor). If that is not possible, send the .Json-file and assets, e.g. as a zip in an issue, per email, ...
|
The preferred way to add your theme is via a Pull Request. A Pull Request is less work for the maintainer (which makes
|
||||||
|
it really easy and for me to add it) and your name will be included in the git history (so you'll be listed as
|
||||||
|
contributor). If that is not possible, send the .Json-file and assets, e.g. as a zip in an issue, per email, ...
|
||||||
|
|
||||||
*Via a pull request:*
|
*Via a pull request:*
|
||||||
|
|
||||||
1) Fork this repository
|
1) Fork this repository
|
||||||
2) Go to `assets/themes` and create a new directory `yourtheme`
|
2) Go to `assets/themes` and create a new directory `yourtheme`
|
||||||
3) Create a new file `yourtheme.json`, paste the theme configuration in there. You can find your theme configuration in the customThemeBuilder (the tab with the *Floppy disk* icon)
|
3) Create a new file `yourtheme.json`, paste the theme configuration in there. You can find your theme configuration in
|
||||||
4) Copy all the images into this new directory. **No external sources are allowed!** External image sources leak privacy or can break.
|
the customThemeBuilder (the tab with the *Floppy disk* icon)
|
||||||
|
4) Copy all the images into this new directory. **No external sources are allowed!** External image sources leak privacy
|
||||||
|
or can break.
|
||||||
- Make sure the license is suitable, preferable a Creative Commons license or CC0-license.
|
- Make sure the license is suitable, preferable a Creative Commons license or CC0-license.
|
||||||
- If an SVG version is available, use the SVG version
|
- If an SVG version is available, use the SVG version
|
||||||
- Make sure all the links in `yourtheme.json` are updated. You can use `./assets/themes/yourtheme/yourimage.svg` instead of the HTML link
|
- Make sure all the links in `yourtheme.json` are updated. You can use `./assets/themes/yourtheme/yourimage.svg`
|
||||||
|
instead of the HTML link
|
||||||
- Create a file `license_info.json` in the theme directory, which contains metadata on every artwork source
|
- Create a file `license_info.json` in the theme directory, which contains metadata on every artwork source
|
||||||
5) Add your theme to the code base: add it into "assets/themes" and make sure all the images are there too. Running 'ts-node scripts/fixTheme <path to your theme>' will help downloading the images and attempts to get the licenses if on wikimedia.
|
5) Add your theme to the code base: add it into "assets/themes" and make sure all the images are there too. Running '
|
||||||
6) Add some finishing touches, such as a social image. See [this blog post](https://www.h3xed.com/web-and-internet/how-to-use-og-image-meta-tag-facebook-reddit) for some hints
|
ts-node scripts/fixTheme <path to your theme>' will help downloading the images and attempts to get the licenses if
|
||||||
|
on wikimedia.
|
||||||
|
6) Add some finishing touches, such as a social image.
|
||||||
|
See [this blog post](https://www.h3xed.com/web-and-internet/how-to-use-og-image-meta-tag-facebook-reddit) for some
|
||||||
|
hints
|
||||||
7) Test your theme: run the project as described in [development_deployment](Development_deployment.md)
|
7) Test your theme: run the project as described in [development_deployment](Development_deployment.md)
|
||||||
8) Happy with your theme? Time to open a Pull Request!
|
8) Happy with your theme? Time to open a Pull Request!
|
||||||
9) Thanks a lot for improving MapComplete!
|
9) Thanks a lot for improving MapComplete!
|
||||||
|
|
||||||
|
|
||||||
The .JSON-format
|
The .JSON-format
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
There are three important levels in the .JSON-file:
|
There are three important levels in the .JSON-file:
|
||||||
|
|
||||||
- The toplevel describes the metadata of the entire theme. It contains the `title`, `description`, `icon`... of the theme. The most important object is `layers`, which is a list of objects describing layers.
|
- The toplevel describes the metadata of the entire theme. It contains the `title`, `description`, `icon`... of the
|
||||||
- A `layer` describes a layer. It contains the `name`, `icon`, `tags of objects to download from overpass`, and especially the `icon` and a way to ask dynamically render tags and ask questions. A lot of those fields (`icon`, `title`, ...) are actually a `TagRendering`
|
theme. The most important object is `layers`, which is a list of objects describing layers.
|
||||||
- A `TagRendering` is an object describing a relationship between what should be shown on screen and the OSM-tagging. It works in two ways: if the correct tag is known, the appropriate text will be shown. If the tag is missing (and a question is defined), the question will be shown.
|
- A `layer` describes a layer. It contains the `name`, `icon`, `tags of objects to download from overpass`, and
|
||||||
|
especially the `icon` and a way to ask dynamically render tags and ask questions. A lot of those fields (`icon`
|
||||||
|
, `title`, ...) are actually a `TagRendering`
|
||||||
|
- A `TagRendering` is an object describing a relationship between what should be shown on screen and the OSM-tagging. It
|
||||||
|
works in two ways: if the correct tag is known, the appropriate text will be shown. If the tag is missing (and a
|
||||||
|
question is defined), the question will be shown.
|
||||||
|
|
||||||
Every field is documented in the source code itself - you can find them here:
|
Every field is documented in the source code itself - you can find them here:
|
||||||
|
|
||||||
|
@ -82,50 +107,65 @@ Every field is documented in the source code itself - you can find them here:
|
||||||
|
|
||||||
### MetaTags
|
### MetaTags
|
||||||
|
|
||||||
There are few tags available that are calculated for convenience - e.g. the country an object is located at. [An overview of all these metatags is available here](Docs/CalculatedTags.md)
|
There are few tags available that are calculated for convenience - e.g. the country an object is located
|
||||||
|
at. [An overview of all these metatags is available here](Docs/CalculatedTags.md)
|
||||||
|
|
||||||
Some hints
|
Some hints
|
||||||
------------
|
------------
|
||||||
|
|
||||||
### Everything is HTML
|
### Everything is HTML
|
||||||
|
|
||||||
All the texts are actually *HTML*-snippets, so you can use `<b>` to add bold, or `<img src=...>` to add images to mappings or tagrenderings.
|
All the texts are actually *HTML*-snippets, so you can use `<b>` to add bold, or `<img src=...>` to add images to
|
||||||
|
mappings or tagrenderings.
|
||||||
|
|
||||||
Some remarks:
|
Some remarks:
|
||||||
|
|
||||||
- links are disabled when answering a question (e.g. a link in a mapping) as it should trigger the answer - not trigger to open the link.
|
- links are disabled when answering a question (e.g. a link in a mapping) as it should trigger the answer - not trigger
|
||||||
- If you include images, e.g. to clarify a type, make sure these are _icons_ or _diagrams_ - not actual pictures! If users see a picture, they think it is a picture of _that actual object_, not a type to clarify the type. An icon is however perceived as something more abstract.
|
to open the link.
|
||||||
|
- If you include images, e.g. to clarify a type, make sure these are _icons_ or _diagrams_ - not actual pictures! If
|
||||||
|
users see a picture, they think it is a picture of _that actual object_, not a type to clarify the type. An icon is
|
||||||
|
however perceived as something more abstract.
|
||||||
|
|
||||||
Some pitfalls
|
Some pitfalls
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
### Not publishing
|
### Not publishing
|
||||||
|
|
||||||
Not publishing because 'it is not good enough'. _Share your theme, even if it is still not great, let the community help it improve_
|
Not publishing because 'it is not good enough'. _Share your theme, even if it is still not great, let the community help
|
||||||
|
it improve_
|
||||||
|
|
||||||
### Thinking in terms of a question
|
### Thinking in terms of a question
|
||||||
|
|
||||||
Making a tagrendering as if it were a question only. If you have a question such as: _Does this bench have a backrest?_, it is very tempting to have as options _yes_ for `backrest=yes` and _no_ for `backrest=no`. However, when this data is known, it will simply show a lone _yes_ or _no_ which is very unclear.
|
Making a tagrendering as if it were a question only. If you have a question such as: _Does this bench have a backrest?_,
|
||||||
|
it is very tempting to have as options _yes_ for `backrest=yes` and _no_ for `backrest=no`. However, when this data is
|
||||||
|
known, it will simply show a lone _yes_ or _no_ which is very unclear.
|
||||||
|
|
||||||
The correct way to handle this is to use _This bench does have a backrest_ and _This bench does not have a backrest_ as answers.
|
The correct way to handle this is to use _This bench does have a backrest_ and _This bench does not have a backrest_ as
|
||||||
|
answers.
|
||||||
|
|
||||||
One has to think first in terms of _what is shown to the user if it is known_, only then in terms of _what is the question I want to ask_
|
One has to think first in terms of _what is shown to the user if it is known_, only then in terms of _what is the
|
||||||
|
question I want to ask_
|
||||||
|
|
||||||
### Forgetting the casual/noob mapper
|
### Forgetting the casual/noob mapper
|
||||||
|
|
||||||
MapComplete is in the first place a tool to help *non-technical* people visualize their interest and contribute to it. In order to maximize contribution:
|
MapComplete is in the first place a tool to help *non-technical* people visualize their interest and contribute to it.
|
||||||
|
In order to maximize contribution:
|
||||||
|
|
||||||
1. Use simple language. Avoid difficult words and explain jargon
|
1. Use simple language. Avoid difficult words and explain jargon
|
||||||
2. Put the simple questions first and the difficult ones on the back. The contributor can then stop at a difficult point and go to the next POI
|
2. Put the simple questions first and the difficult ones on the back. The contributor can then stop at a difficult point
|
||||||
|
and go to the next POI
|
||||||
3. Use symbols and images, also in the mappings on questions
|
3. Use symbols and images, also in the mappings on questions
|
||||||
4. Make sure the icons (on the map and in the questions) are big enough, clear enough and contrast enough with the background map
|
4. Make sure the icons (on the map and in the questions) are big enough, clear enough and contrast enough with the
|
||||||
|
background map
|
||||||
|
|
||||||
### Using layers to distinguish on attributes
|
### Using layers to distinguish on attributes
|
||||||
|
|
||||||
One layer should portray one kind of physical object, e.g. "benches" or "restaurants". It should contain all of them, disregarding other properties.
|
One layer should portray one kind of physical object, e.g. "benches" or "restaurants". It should contain all of them,
|
||||||
|
disregarding other properties.
|
||||||
|
|
||||||
One should not make one layer for benches with a backrest and one layer for benches without. This is confusing for users and poses problems: what if the backrest status is unknown? What if it is some weird value?
|
One should not make one layer for benches with a backrest and one layer for benches without. This is confusing for users
|
||||||
Also, it isn't possible to 'move' an attribute to another layer.
|
and poses problems: what if the backrest status is unknown? What if it is some weird value? Also, it isn't possible to '
|
||||||
|
move' an attribute to another layer.
|
||||||
|
|
||||||
Instead, make one layer for one kind of object and change the icon based on attributes.
|
Instead, make one layer for one kind of object and change the icon based on attributes.
|
||||||
|
|
||||||
|
@ -133,12 +173,19 @@ Instead, make one layer for one kind of object and change the icon based on attr
|
||||||
|
|
||||||
Using layers as filters - this doesn't work!
|
Using layers as filters - this doesn't work!
|
||||||
|
|
||||||
_All_ data is downloaded in one go and cached locally first. The layer selection (bottom left of the live app) then selects _anything_ that matches the criteria. This match is then passed of to the rendering layer, which selects the layer independently. This means that a feature can show up, even if it's layer is unselected!
|
_All_ data is downloaded in one go and cached locally first. The layer selection (bottom left of the live app) then
|
||||||
|
selects _anything_ that matches the criteria. This match is then passed of to the rendering layer, which selects the
|
||||||
|
layer independently. This means that a feature can show up, even if it's layer is unselected!
|
||||||
|
|
||||||
For example, in the [cyclofix-theme](https://mapcomplete.osm.org/cyclofix), there is the layer with _bike-wash_ for do it yourself bikecleaning - points marked with `service:bicycle:cleaning`. However, a bicycle repair shop can offer this service too!
|
For example, in the [cyclofix-theme](https://mapcomplete.osm.org/cyclofix), there is the layer with _bike-wash_ for do
|
||||||
|
it yourself bikecleaning - points marked with `service:bicycle:cleaning`. However, a bicycle repair shop can offer this
|
||||||
|
service too!
|
||||||
|
|
||||||
If all the layers are deselected except the bike wash layer, a shop having this tag will still match and will still show up as shop.
|
If all the layers are deselected except the bike wash layer, a shop having this tag will still match and will still show
|
||||||
|
up as shop.
|
||||||
|
|
||||||
### Not reading the .JSON-specs
|
### Not reading the .JSON-specs
|
||||||
|
|
||||||
There are a few advanced features to do fancy stuff available, which are documented only in the spec above - for example, reusing background images and substituting the colours or HTML-rendering. If you need advanced stuff, read it through!
|
There are a few advanced features to do fancy stuff available, which are documented only in the spec above - for
|
||||||
|
example, reusing background images and substituting the colours or HTML-rendering. If you need advanced stuff, read it
|
||||||
|
through!
|
||||||
|
|
|
@ -4,15 +4,18 @@
|
||||||
|
|
||||||
## StreetComplete
|
## StreetComplete
|
||||||
|
|
||||||
StreetComplete might look pretty similar to MapComplete at first glance - especially as it was a huge inspiration. However, there are a few huge differences between the two, especially in vision.
|
StreetComplete might look pretty similar to MapComplete at first glance - especially as it was a huge inspiration.
|
||||||
|
However, there are a few huge differences between the two, especially in vision.
|
||||||
|
|
||||||
### Vision
|
### Vision
|
||||||
|
|
||||||
The core philosophy of StreetComplete is **OpenStreetMap is cool! Help to improve it by answering these questions**
|
The core philosophy of StreetComplete is **OpenStreetMap is cool! Help to improve it by answering these questions**
|
||||||
The core philosophy of MapComplete is **Here is a map of topic XYZ - enjoy it and update it if there is still some info missing**
|
The core philosophy of MapComplete is **Here is a map of topic XYZ - enjoy it and update it if there is still some info
|
||||||
|
missing**
|
||||||
|
|
||||||
This means that StreetComplete is mainly aimed towards people who are already OpenStreetMap-enthusiasts, whereas MapComplete is aimed to an audience interested in a certain topic.
|
This means that StreetComplete is mainly aimed towards people who are already OpenStreetMap-enthusiasts, whereas
|
||||||
Of course, the next step is to attempt to inform that audience why having an open map is so cool and that they can contribute as well.
|
MapComplete is aimed to an audience interested in a certain topic. Of course, the next step is to attempt to inform that
|
||||||
|
audience why having an open map is so cool and that they can contribute as well.
|
||||||
|
|
||||||
### Use cases
|
### Use cases
|
||||||
|
|
||||||
|
@ -29,7 +32,9 @@ MapComplete is made to
|
||||||
|
|
||||||
StreetComplete is an android app, so can only be used on Android Phones.
|
StreetComplete is an android app, so can only be used on Android Phones.
|
||||||
|
|
||||||
MapComplete is a web-app, and thus works on all devices. It can be installed as PWA to give an 'app-like'-experience, but can just as well be embedded in other websites. On the other hand PWA are a bit of a second class citizen compared to native apps.
|
MapComplete is a web-app, and thus works on all devices. It can be installed as PWA to give an 'app-like'-experience,
|
||||||
|
but can just as well be embedded in other websites. On the other hand PWA are a bit of a second class citizen compared
|
||||||
|
to native apps.
|
||||||
|
|
||||||
### Feature comparison
|
### Feature comparison
|
||||||
|
|
||||||
|
@ -37,22 +42,26 @@ MapComplete is also an OpenStreetMap-viewer, while StreetComplete hides known va
|
||||||
|
|
||||||
MapComplete will not work offline.
|
MapComplete will not work offline.
|
||||||
|
|
||||||
In MapComplete it is easier to add more experimental, extremely detailed and more personal styles, as each topic is separated with its own part.
|
In MapComplete it is easier to add more experimental, extremely detailed and more personal styles, as each topic is
|
||||||
|
separated with its own part.
|
||||||
|
|
||||||
MapComplete is a bit more complex to use. One needs to go hunting for a specific map style rather than getting bunch of quests by default. And is likely to ask far more detailed question (email address and phone number of bicycle shop etc).
|
MapComplete is a bit more complex to use. One needs to go hunting for a specific map style rather than getting bunch of
|
||||||
After all if it would duplicate StreetComplete it would be a bit pointless and it is pretty hard to compete with SC by being easier to use and more newbie friendly, while there is space for "more complicated/detailed/involved editor working like SC".
|
quests by default. And is likely to ask far more detailed question (email address and phone number of bicycle shop etc).
|
||||||
|
After all if it would duplicate StreetComplete it would be a bit pointless and it is pretty hard to compete with SC by
|
||||||
|
being easier to use and more newbie friendly, while there is space for "more complicated/detailed/involved editor
|
||||||
|
working like SC".
|
||||||
|
|
||||||
Also, MapComplete has no requirement to make question easy to answer, making both possible to ask more questions than StreetComplete but making it more complicated to use.
|
Also, MapComplete has no requirement to make question easy to answer, making both possible to ask more questions than
|
||||||
|
StreetComplete but making it more complicated to use.
|
||||||
|
|
||||||
No support for splitting ways in MapComplete (as of now - hopefully it'll get added one day).
|
No support for splitting ways in MapComplete (as of now - hopefully it'll get added one day).
|
||||||
|
|
||||||
MapComplete allows the addition of new points, whereas StreetComplete does not.
|
MapComplete allows the addition of new points, whereas StreetComplete does not.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## MapContrib
|
## MapContrib
|
||||||
|
|
||||||
MapContrib is another very similar editor which served as inspiration. MapContrib offers - just like MapComplete - an extensible, thematic map view. However, I never understood the MapContrib user interface.
|
MapContrib is another very similar editor which served as inspiration. MapContrib offers - just like MapComplete - an
|
||||||
|
extensible, thematic map view. However, I never understood the MapContrib user interface.
|
||||||
|
|
||||||
MapContrib also allows to add new points and to edit tags - but it is very cumbersome.
|
MapContrib also allows to add new points and to edit tags - but it is very cumbersome.
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,19 @@
|
||||||
|
|
||||||
In this document, you'll find a short overview of which (paid) projects have been completed with MapComplete
|
In this document, you'll find a short overview of which (paid) projects have been completed with MapComplete
|
||||||
|
|
||||||
|
|
||||||
## Buurtnatuur
|
## Buurtnatuur
|
||||||
|
|
||||||
Commisioned by Groen (the Belgian Green Party): "a project to crowdsource data about parks, nature reserve and forests"
|
Commisioned by Groen (the Belgian Green Party): "a project to crowdsource data about parks, nature reserve and forests"
|
||||||
|
|
||||||
## Cyclofix
|
## Cyclofix
|
||||||
|
|
||||||
Cycle-related Points of interest (pumps, shops, drinking water, ...). Commissioned by "Brussels Mobility", executed during OSOC
|
Cycle-related Points of interest (pumps, shops, drinking water, ...). Commissioned by "Brussels Mobility", executed
|
||||||
|
during OSOC
|
||||||
|
|
||||||
## Speelplekken in de Antwerpse Zuidrand
|
## Speelplekken in de Antwerpse Zuidrand
|
||||||
|
|
||||||
Playgrounds, play forests and village green in the southern part of the Province of Antwerp; commisioned by Province of Antwerp
|
Playgrounds, play forests and village green in the southern part of the Province of Antwerp; commisioned by Province of
|
||||||
|
Antwerp
|
||||||
|
|
||||||
## Natuurpunt Map (planned)
|
## Natuurpunt Map (planned)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
# Available types for text fields
|
# Available types for text fields
|
||||||
|
|
||||||
The listed types here trigger a special input element. Use them in `tagrendering.freeform.type` of your tagrendering to activate them
|
The listed types here trigger a special input element. Use them in `tagrendering.freeform.type` of your tagrendering to
|
||||||
|
activate them
|
||||||
|
|
||||||
## string
|
## string
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ A geographical direction, in degrees. 0° is north, 90° is east, ... Will retur
|
||||||
|
|
||||||
## length
|
## length
|
||||||
|
|
||||||
A geographical length in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `["21", "map,photo"]
|
A geographical length in meters (rounded at two points). Will give an extra minimap with a measurement tool.
|
||||||
|
Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `["21", "map,photo"]
|
||||||
|
|
||||||
## wikidata
|
## wikidata
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
|
||||||
### Special tag renderings
|
### Special tag renderings
|
||||||
|
|
||||||
In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's. General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_name(args):cssStyle}`. Note that you _do not_fcs need to use quotes around your arguments, the comma is enough to separate them. This also implies you cannot use a comma in your args
|
In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and
|
||||||
|
visualizations to be reused by custom themes or even to query third-party API's. General usage is `{func_name()}`
|
||||||
|
, `{func_name(arg, someotherarg)}` or `{func_name(args):cssStyle}`. Note that you _do not_fcs need to use quotes around
|
||||||
|
your arguments, the comma is enough to separate them. This also implies you cannot use a comma in your args
|
||||||
|
|
||||||
### all_tags
|
### all_tags
|
||||||
|
|
||||||
Prints all key-value pairs of the object - used for debugging
|
Prints all key-value pairs of the object - used for debugging
|
||||||
|
@ -9,13 +12,14 @@
|
||||||
name | default | description
|
name | default | description
|
||||||
------ | --------- | -------------
|
------ | --------- | -------------
|
||||||
|
|
||||||
|
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
{all_tags()}
|
{all_tags()}
|
||||||
|
|
||||||
### image_carousel
|
### image_carousel
|
||||||
|
|
||||||
Creates an image carousel for the given sources. An attempt will be made to guess what source is used. Supported: Wikidata identifiers, Wikipedia pages, Wikimedia categories, IMGUR (with attribution, direct links)
|
Creates an image carousel for the given sources. An attempt will be made to guess what source is used. Supported:
|
||||||
|
Wikidata identifiers, Wikipedia pages, Wikimedia categories, IMGUR (with attribution, direct links)
|
||||||
|
|
||||||
name | default | description
|
name | default | description
|
||||||
------ | --------- | -------------
|
------ | --------- | -------------
|
||||||
|
@ -25,6 +29,7 @@ smart search | true | Also include images given via 'Wikidata', 'wikimedia_commo
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
{image_carousel(image,true)}
|
{image_carousel(image,true)}
|
||||||
|
|
||||||
### image_upload
|
### image_upload
|
||||||
|
|
||||||
Creates a button where a user can upload an image to IMGUR
|
Creates a button where a user can upload an image to IMGUR
|
||||||
|
@ -36,6 +41,7 @@ image-key | image | Image tag to add the URL to (or image-tag:0, image-tag:1 whe
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
{image_upload(image)}
|
{image_upload(image)}
|
||||||
|
|
||||||
### minimap
|
### minimap
|
||||||
|
|
||||||
A small map showing the selected feature. Note that no styling is applied, wrap this in a div
|
A small map showing the selected feature. Note that no styling is applied, wrap this in a div
|
||||||
|
@ -47,10 +53,13 @@ idKey | id | (Matches all resting arguments) This argument should be the key of
|
||||||
|
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
`{minimap()}`, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`
|
`{minimap()}`
|
||||||
|
, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`
|
||||||
|
|
||||||
### reviews
|
### reviews
|
||||||
|
|
||||||
Adds an overview of the mangrove-reviews of this object. Mangrove.Reviews needs - in order to identify the reviewed object - a coordinate and a name. By default, the name of the object is given, but this can be overwritten
|
Adds an overview of the mangrove-reviews of this object. Mangrove.Reviews needs - in order to identify the reviewed
|
||||||
|
object - a coordinate and a name. By default, the name of the object is given, but this can be overwritten
|
||||||
|
|
||||||
name | default | description
|
name | default | description
|
||||||
------ | --------- | -------------
|
------ | --------- | -------------
|
||||||
|
@ -59,10 +68,13 @@ fallback | undefined | The identifier to use, if <i>tags[subjectKey]</i> as spec
|
||||||
|
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
<b>{reviews()}<b> for a vanilla review, <b>{reviews(name, play_forest)}</b> to review a play forest. If a name is known, the name will be used as identifier, otherwise 'play_forest' is used
|
<b>{reviews()}<b> for a vanilla review, <b>{reviews(name, play_forest)}</b> to review a play forest. If a name is known,
|
||||||
|
the name will be used as identifier, otherwise 'play_forest' is used
|
||||||
|
|
||||||
### opening_hours_table
|
### opening_hours_table
|
||||||
|
|
||||||
Creates an opening-hours table. Usage: {opening_hours_table(opening_hours)} to create a table of the tag 'opening_hours'.
|
Creates an opening-hours table. Usage: {opening_hours_table(opening_hours)} to create a table of the tag '
|
||||||
|
opening_hours'.
|
||||||
|
|
||||||
name | default | description
|
name | default | description
|
||||||
------ | --------- | -------------
|
------ | --------- | -------------
|
||||||
|
@ -71,9 +83,13 @@ key | opening_hours | The tagkey from which the table is constructed.
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
{opening_hours_table(opening_hours)}
|
{opening_hours_table(opening_hours)}
|
||||||
|
|
||||||
### live
|
### live
|
||||||
|
|
||||||
Downloads a JSON from the given URL, e.g. '{live(example.org/data.json, shorthand:x.y.z, other:a.b.c, shorthand)}' will download the given file, will create an object {shorthand: json[x][y][z], other: json[a][b][c] out of it and will return 'other' or 'json[a][b][c]. This is made to use in combination with tags, e.g. {live({url}, {url:format}, needed_value)}
|
Downloads a JSON from the given URL, e.g. '{live(example.org/data.json, shorthand:x.y.z, other:a.b.c, shorthand)}' will
|
||||||
|
download the given file, will create an object {shorthand: json[x][y][z], other: json[a][b][c] out of it and will
|
||||||
|
return 'other' or 'json[a][b][c]. This is made to use in combination with tags, e.g. {live({url}, {url:format},
|
||||||
|
needed_value)}
|
||||||
|
|
||||||
name | default | description
|
name | default | description
|
||||||
------ | --------- | -------------
|
------ | --------- | -------------
|
||||||
|
@ -83,7 +99,9 @@ path | undefined | The path (or shorthand) that should be returned
|
||||||
|
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
{live({url},{url:format},hour)} {live(https://data.mobility.brussels/bike/api/counts/?request=live&featureID=CB2105,hour:data.hour_cnt;day:data.day_cnt;year:data.year_cnt,hour)}
|
{live({url},{url:format},hour)}
|
||||||
|
{live(https://data.mobility.brussels/bike/api/counts/?request=live&featureID=CB2105,hour:data.hour_cnt;day:data.day_cnt;year:data.year_cnt,hour)}
|
||||||
|
|
||||||
### histogram
|
### histogram
|
||||||
|
|
||||||
Create a histogram for a list of given values, read from the properties.
|
Create a histogram for a list of given values, read from the properties.
|
||||||
|
@ -98,6 +116,7 @@ colors* | undefined | (Matches all resting arguments - optional) Matches a regex
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
`{histogram('some_key')}` with properties being `{some_key: ['a','b','a','c']} to create a histogram
|
`{histogram('some_key')}` with properties being `{some_key: ['a','b','a','c']} to create a histogram
|
||||||
|
|
||||||
### share_link
|
### share_link
|
||||||
|
|
||||||
Creates a link that (attempts to) open the native 'share'-screen
|
Creates a link that (attempts to) open the native 'share'-screen
|
||||||
|
@ -109,6 +128,7 @@ url | undefined | The url to share (default: current URL)
|
||||||
#### Example usage
|
#### Example usage
|
||||||
|
|
||||||
{share_link()} to share the current page, {share_link(<some_url>)} to share the given url
|
{share_link()} to share the current page, {share_link(<some_url>)} to share the given url
|
||||||
|
|
||||||
### canonical
|
### canonical
|
||||||
|
|
||||||
Converts a short, canonical value into the long, translated text
|
Converts a short, canonical value into the long, translated text
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
Statistics
|
Statistics
|
||||||
==========
|
==========
|
||||||
|
|
||||||
There are some fancy statistics available about MapComplete use. The most important once are listed below, some more graphs (and the scripts to generate them) are [in the tools directory](Tools/)
|
There are some fancy statistics available about MapComplete use. The most important once are listed below, some more
|
||||||
|
graphs (and the scripts to generate them) are [in the tools directory](Tools/)
|
||||||
|
|
||||||
All Time usage
|
All Time usage
|
||||||
--------------
|
--------------
|
||||||
|
@ -9,7 +10,8 @@ All Time usage
|
||||||
![](Tools/CumulativeContributors.png)
|
![](Tools/CumulativeContributors.png)
|
||||||
![](Tools/Cumulative%20changesets%20per%20contributor.png)
|
![](Tools/Cumulative%20changesets%20per%20contributor.png)
|
||||||
|
|
||||||
Note: in 2020, MapComplete would still make one changeset per answered question. This heavily skews the below graphs towards `buurtnatuur` and `cyclofìx`, two heavily used themes at the beginning.
|
Note: in 2020, MapComplete would still make one changeset per answered question. This heavily skews the below graphs
|
||||||
|
towards `buurtnatuur` and `cyclofìx`, two heavily used themes at the beginning.
|
||||||
|
|
||||||
![](Tools/Cumulative%20changesets%20per%20theme.png)
|
![](Tools/Cumulative%20changesets%20per%20theme.png)
|
||||||
![](Tools/Theme%20distribution.png)
|
![](Tools/Theme%20distribution.png)
|
||||||
|
|
|
@ -1,48 +1,59 @@
|
||||||
Tags format
|
Tags format
|
||||||
=============
|
=============
|
||||||
|
|
||||||
When creating the `json` file describing your layer or theme, you'll have to add a few tags to describe what you want. This document gives an overview of what every expression means and how it behaves in edge cases.
|
When creating the `json` file describing your layer or theme, you'll have to add a few tags to describe what you want.
|
||||||
|
This document gives an overview of what every expression means and how it behaves in edge cases.
|
||||||
|
|
||||||
Strict equality
|
Strict equality
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Strict equality is denoted by `key=value`. This key matches __only if__ the keypair is present exactly as stated.
|
Strict equality is denoted by `key=value`. This key matches __only if__ the keypair is present exactly as stated.
|
||||||
|
|
||||||
**Only normal tags (eventually in an `and`) can be used in places where they are uploaded**. Normal tags are used in the `mappings` of a [TagRendering] (unless `hideInAnswer` is specified), they are used in `addExtraTags` of [Freeform] and are used in the `tags`-list of a preset.
|
**Only normal tags (eventually in an `and`) can be used in places where they are uploaded**. Normal tags are used in
|
||||||
|
the `mappings` of a [TagRendering] (unless `hideInAnswer` is specified), they are used in `addExtraTags` of [Freeform]
|
||||||
|
and are used in the `tags`-list of a preset.
|
||||||
|
|
||||||
If a different kind of tag specification is given, your theme will fail to parse.
|
If a different kind of tag specification is given, your theme will fail to parse.
|
||||||
|
|
||||||
### If key is not present
|
### If key is not present
|
||||||
|
|
||||||
If you want to check if a key is not present, use `key=` (pronounce as *key is empty*). A tag collection will match this if `key` is missing or if `key` is a literal empty value.
|
If you want to check if a key is not present, use `key=` (pronounce as *key is empty*). A tag collection will match this
|
||||||
|
if `key` is missing or if `key` is a literal empty value.
|
||||||
|
|
||||||
### Removing a key
|
### Removing a key
|
||||||
|
|
||||||
If a key should be deleted in the OpenStreetMap-database, specify `key=` as well. This can be used e.g. to remove a fixme or value from another mapping if another field is filled out.
|
If a key should be deleted in the OpenStreetMap-database, specify `key=` as well. This can be used e.g. to remove a
|
||||||
|
fixme or value from another mapping if another field is filled out.
|
||||||
|
|
||||||
Strict not equals
|
Strict not equals
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
To check if a key does _not_ equal a certain value, use `key!=value`. This is converted behind the scenes to `key!~^value$`
|
To check if a key does _not_ equal a certain value, use `key!=value`. This is converted behind the scenes
|
||||||
|
to `key!~^value$`
|
||||||
|
|
||||||
### If key is present
|
### If key is present
|
||||||
|
|
||||||
This implies that, to check if a key is present, `key!=` can be used. This will only match if the key is present and not empty.
|
This implies that, to check if a key is present, `key!=` can be used. This will only match if the key is present and not
|
||||||
|
empty.
|
||||||
|
|
||||||
Number comparison
|
Number comparison
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
If the value of a tag is a number (e.g. `key=42`), one can use a filter `key<=42`, `key>=35`, `key>40` or `key<50` to match this, e.g. in conditions for renderings.
|
If the value of a tag is a number (e.g. `key=42`), one can use a filter `key<=42`, `key>=35`, `key>40` or `key<50` to
|
||||||
These tags cannot be used to generate an answer nor can they be used to request data upstream from overpass.
|
match this, e.g. in conditions for renderings. These tags cannot be used to generate an answer nor can they be used to
|
||||||
|
request data upstream from overpass.
|
||||||
|
|
||||||
Note that the value coming from OSM will first be stripped by removing all non-numeric characters. For example, `length=42 meter` will be interpreted as `length=42` and will thus match `length<=42` and `length>=42`.
|
Note that the value coming from OSM will first be stripped by removing all non-numeric characters. For
|
||||||
In special circumstances (e.g. `surface_area=42 m2` or `length=100 feet`), this will result in erronous values (`surface=422` or if a length in meters is compared to).
|
example, `length=42 meter` will be interpreted as `length=42` and will thus match `length<=42` and `length>=42`. In
|
||||||
However, this can be partially alleviated by using 'Units' to rewrite to a default format.
|
special circumstances (e.g. `surface_area=42 m2` or `length=100 feet`), this will result in erronous
|
||||||
|
values (`surface=422` or if a length in meters is compared to). However, this can be partially alleviated by using '
|
||||||
|
Units' to rewrite to a default format.
|
||||||
|
|
||||||
Regex equals
|
Regex equals
|
||||||
------------
|
------------
|
||||||
|
|
||||||
A tag can also be tested against a regex with `key~regex`. Note that this regex __must match__ the entire value. If the value is allowed to appear anywhere as substring, use `key~.*regex.*`
|
A tag can also be tested against a regex with `key~regex`. Note that this regex __must match__ the entire value. If the
|
||||||
|
value is allowed to appear anywhere as substring, use `key~.*regex.*`
|
||||||
|
|
||||||
Equivalently, `key!~regex` can be used if you _don't_ want to match the regex in order to appear.
|
Equivalently, `key!~regex` can be used if you _don't_ want to match the regex in order to appear.
|
||||||
|
|
||||||
|
@ -52,16 +63,18 @@ Using other tags as variables
|
||||||
|
|
||||||
**This is an advanced feature - use with caution**
|
**This is an advanced feature - use with caution**
|
||||||
|
|
||||||
Some tags are automatically set or calculated - see [CalculatedTags](CalculatedTags.md) for an entire overview.
|
Some tags are automatically set or calculated - see [CalculatedTags](CalculatedTags.md) for an entire overview. If one
|
||||||
If one wants to apply such a value as tag, use a substituting-tag such, for example`survey:date:={_date:now}`. Note that the separator between key and value here is `:=`.
|
wants to apply such a value as tag, use a substituting-tag such, for example`survey:date:={_date:now}`. Note that the
|
||||||
The text between `{` and `}` is interpreted as a key, and the respective value is substituted into the string.
|
separator between key and value here is `:=`. The text between `{` and `}` is interpreted as a key, and the respective
|
||||||
|
value is substituted into the string.
|
||||||
|
|
||||||
One can also append, e.g. `key:={some_key} fixed text {some_other_key}`.
|
One can also append, e.g. `key:={some_key} fixed text {some_other_key}`.
|
||||||
|
|
||||||
An assigning tag _cannot_ be used to query OpenStreetMap/Overpass.
|
An assigning tag _cannot_ be used to query OpenStreetMap/Overpass.
|
||||||
|
|
||||||
If using a key or variable which might not be defined, add a condition in the mapping to hide the option.
|
If using a key or variable which might not be defined, add a condition in the mapping to hide the option. This is
|
||||||
This is because, if `some_other_key` is not defined, one might actually upload the literal text `key={some_other_key}` to OSM - which we do not want.
|
because, if `some_other_key` is not defined, one might actually upload the literal text `key={some_other_key}` to OSM -
|
||||||
|
which we do not want.
|
||||||
|
|
||||||
To mitigate this, use:
|
To mitigate this, use:
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
Talk at State of the Map
|
Talk at State of the Map
|
||||||
========================
|
========================
|
||||||
|
|
||||||
I'm planning to do a talk/video on MapComplete on _State of the Map 2021_. This document outlines the structure of the talk and serves as my speaker notes.
|
I'm planning to do a talk/video on MapComplete on _State of the Map 2021_. This document outlines the structure of the
|
||||||
|
talk and serves as my speaker notes.
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
--------
|
--------
|
||||||
|
@ -12,15 +12,12 @@ I'm planning to do a talk/video on MapComplete on _State of the Map 2021_. This
|
||||||
a. Where and how did it start? "This project isn't going anywhere"
|
a. Where and how did it start? "This project isn't going anywhere"
|
||||||
(buurtnatuur, cyclofix, Antwerpen, Natuurpunt, Oost-Vlaanderen?, Toerisme Vlaanderen?)
|
(buurtnatuur, cyclofix, Antwerpen, Natuurpunt, Oost-Vlaanderen?, Toerisme Vlaanderen?)
|
||||||
b. Where are we now? Some cool statistics
|
b. Where are we now? Some cool statistics
|
||||||
3. The vision
|
3. The vision a. Your granny can use it a. pragmatism - somewhat working today is better then something perfect tomorrow
|
||||||
a. Your granny can use it
|
a. It's a trap! Cool thematic map (as iframe on website) -> the OSM rabbit hole -> easy start -> more features when
|
||||||
a. pragmatism - somewhat working today is better then something perfect tomorrow
|
mapping more -> oh, I can make a theme too!
|
||||||
a. It's a trap! Cool thematic map (as iframe on website) -> the OSM rabbit hole -> easy start -> more features when mapping more -> oh, I can make a theme too!
|
b. The pareto frontier of 'easy to use' vs 'number of features' c. The thematic approach (+ disabling/enabling
|
||||||
b. The pareto frontier of 'easy to use' vs 'number of features'
|
features per theme/view)
|
||||||
c. The thematic approach (+ disabling/enabling features per theme/view)
|
|
||||||
|
|
||||||
|
|
||||||
4. The future
|
4. The future a. paid projects? Microgrant for a better theme creator? b. user contributed themes (see you next talk!)
|
||||||
a. paid projects? Microgrant for a better theme creator?
|
|
||||||
b. user contributed themes (see you next talk!)
|
|
||||||
5. OpenStreetMap is Cool!
|
5. OpenStreetMap is Cool!
|
||||||
|
|
|
@ -216,12 +216,6 @@ function createGraph(
|
||||||
}
|
}
|
||||||
|
|
||||||
class Histogram<K> {
|
class Histogram<K> {
|
||||||
total(): number {
|
|
||||||
let total = 0
|
|
||||||
Array.from(this.counts.values()).forEach(i => total = total + i)
|
|
||||||
return total
|
|
||||||
}
|
|
||||||
|
|
||||||
public counts: Map<K, number> = new Map<K, number>()
|
public counts: Map<K, number> = new Map<K, number>()
|
||||||
private sortAtEnd: K[] = []
|
private sortAtEnd: K[] = []
|
||||||
|
|
||||||
|
@ -230,6 +224,11 @@ class Histogram<K> {
|
||||||
keys?.forEach(key => self.bump(key))
|
keys?.forEach(key => self.bump(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
total(): number {
|
||||||
|
let total = 0
|
||||||
|
Array.from(this.counts.values()).forEach(i => total = total + i)
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
public bump(key: K, increase = 1) {
|
public bump(key: K, increase = 1) {
|
||||||
if (this.counts.has(key)) {
|
if (this.counts.has(key)) {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
URL-parameters and URL-hash
|
URL-parameters and URL-hash
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
@ -9,8 +8,8 @@ What is a URL parameter?
|
||||||
|
|
||||||
URL-parameters are extra parts of the URL used to set the state.
|
URL-parameters are extra parts of the URL used to set the state.
|
||||||
|
|
||||||
For example, if the url is `https://mapcomplete.osm.be/cyclofix?lat=51.0&lon=4.3&z=5&test=true#node/1234`,
|
For example, if the url is `https://mapcomplete.osm.be/cyclofix?lat=51.0&lon=4.3&z=5&test=true#node/1234`, the
|
||||||
the URL-parameters are stated in the part between the `?` and the `#`. There are multiple, all separated by `&`, namely:
|
URL-parameters are stated in the part between the `?` and the `#`. There are multiple, all separated by `&`, namely:
|
||||||
|
|
||||||
- The url-parameter `lat` is `51.0` in this instance
|
- The url-parameter `lat` is `51.0` in this instance
|
||||||
- The url-parameter `lon` is `4.3` in this instance
|
- The url-parameter `lon` is `4.3` in this instance
|
||||||
|
@ -22,7 +21,8 @@ Finally, the URL-hash is the part after the `#`. It is `node/1234` in this case.
|
||||||
language
|
language
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The language to display mapcomplete in. Will be ignored in case a logged-in-user did set their language before. If the specified language does not exist, it will default to the first language in the theme.
|
The language to display mapcomplete in. Will be ignored in case a logged-in-user did set their language before. If the
|
||||||
|
specified language does not exist, it will default to the first language in the theme.
|
||||||
|
|
||||||
download-control-toggle
|
download-control-toggle
|
||||||
-------------------------
|
-------------------------
|
||||||
|
@ -39,7 +39,8 @@ The language to display mapcomplete in. Will be ignored in case a logged-in-user
|
||||||
tab
|
tab
|
||||||
-----
|
-----
|
||||||
|
|
||||||
The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >50 changesets) The default value is _0_
|
The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 =
|
||||||
|
more themes, 4 = about mapcomplete (user must be logged in and have >50 changesets) The default value is _0_
|
||||||
|
|
||||||
|
|
||||||
z
|
z
|
||||||
|
@ -63,7 +64,8 @@ The language to display mapcomplete in. Will be ignored in case a logged-in-user
|
||||||
fs-userbadge
|
fs-userbadge
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Disables/Enables the user information pill (userbadge) at the top left. Disabling this disables logging in and thus disables editing all together, effectively putting MapComplete into read-only mode. The default value is _true_
|
Disables/Enables the user information pill (userbadge) at the top left. Disabling this disables logging in and thus
|
||||||
|
disables editing all together, effectively putting MapComplete into read-only mode. The default value is _true_
|
||||||
|
|
||||||
|
|
||||||
fs-search
|
fs-search
|
||||||
|
@ -87,7 +89,8 @@ The language to display mapcomplete in. Will be ignored in case a logged-in-user
|
||||||
fs-add-new
|
fs-add-new
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Disables/Enables the 'add new feature'-popup. (A theme without presets might not have it in the first place) The default value is _true_
|
Disables/Enables the 'add new feature'-popup. (A theme without presets might not have it in the first place) The default
|
||||||
|
value is _true_
|
||||||
|
|
||||||
|
|
||||||
fs-welcome-message
|
fs-welcome-message
|
||||||
|
@ -141,7 +144,8 @@ The language to display mapcomplete in. Will be ignored in case a logged-in-user
|
||||||
test
|
test
|
||||||
------
|
------
|
||||||
|
|
||||||
If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org The default value is _false_
|
If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the
|
||||||
|
console instead of actually uploaded to osm.org The default value is _false_
|
||||||
|
|
||||||
|
|
||||||
debug
|
debug
|
||||||
|
@ -153,7 +157,8 @@ The language to display mapcomplete in. Will be ignored in case a logged-in-user
|
||||||
overpassUrl
|
overpassUrl
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter The default value is _https://overpass.kumi.de/api/interpreter_
|
Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter The default value
|
||||||
|
is _https://overpass.kumi.de/api/interpreter_
|
||||||
|
|
||||||
|
|
||||||
overpassTimeout
|
overpassTimeout
|
||||||
|
@ -170,7 +175,8 @@ Set a different timeout (in seconds) for queries in overpass The default value i
|
||||||
backend
|
backend
|
||||||
---------
|
---------
|
||||||
|
|
||||||
The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test' The default value is _osm_
|
The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test' The default
|
||||||
|
value is _osm_
|
||||||
|
|
||||||
|
|
||||||
custom-css
|
custom-css
|
||||||
|
|
|
@ -3,6 +3,8 @@ What is MapComplete?
|
||||||
|
|
||||||
MapComplete is a website where people can see a map of Points of Interest (POI) on a specific subject or theme.
|
MapComplete is a website where people can see a map of Points of Interest (POI) on a specific subject or theme.
|
||||||
|
|
||||||
If the visitor is logged in with their OpenStreetMap account, information about a selected POI can be enriched by answering questions in the respective popups; this data is sent back directly to OpenStreetMap.
|
If the visitor is logged in with their OpenStreetMap account, information about a selected POI can be enriched by
|
||||||
|
answering questions in the respective popups; this data is sent back directly to OpenStreetMap.
|
||||||
|
|
||||||
While there are some predefined themes available, it is also possible to create your own theme. Have a look on [the OpenStreetMap-wiki](https://wiki.openstreetmap.org/wiki/MapComplete) for a list of (un)official themes.
|
While there are some predefined themes available, it is also possible to create your own theme. Have a look
|
||||||
|
on [the OpenStreetMap-wiki](https://wiki.openstreetmap.org/wiki/MapComplete) for a list of (un)official themes.
|
|
@ -4,7 +4,6 @@ import Svg from "../../Svg";
|
||||||
import Img from "../../UI/Base/Img";
|
import Img from "../../UI/Base/Img";
|
||||||
import {LocalStorageSource} from "../Web/LocalStorageSource";
|
import {LocalStorageSource} from "../Web/LocalStorageSource";
|
||||||
import {VariableUiElement} from "../../UI/Base/VariableUIElement";
|
import {VariableUiElement} from "../../UI/Base/VariableUIElement";
|
||||||
import BaseUIElement from "../../UI/BaseUIElement";
|
|
||||||
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
||||||
import {QueryParameters} from "../Web/QueryParameters";
|
import {QueryParameters} from "../Web/QueryParameters";
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ Actors
|
||||||
|
|
||||||
An **actor** is a module which converts one UIEventSource into another while performing logic.
|
An **actor** is a module which converts one UIEventSource into another while performing logic.
|
||||||
|
|
||||||
Typically, it will only expose the constructor taking some UIEventSources (and configuration) and a few fields which are UIEVentSources.
|
Typically, it will only expose the constructor taking some UIEventSources (and configuration) and a few fields which are
|
||||||
|
UIEVentSources.
|
||||||
|
|
||||||
An actor should _never_ have a dependency on 'State' and should _never_ import it
|
An actor should _never_ have a dependency on 'State' and should _never_ import it
|
|
@ -9,11 +9,10 @@ import OsmApiFeatureSource from "../FeatureSource/OsmApiFeatureSource";
|
||||||
* Makes sure the hash shows the selected element and vice-versa.
|
* Makes sure the hash shows the selected element and vice-versa.
|
||||||
*/
|
*/
|
||||||
export default class SelectedFeatureHandler {
|
export default class SelectedFeatureHandler {
|
||||||
|
private static readonly _no_trigger_on = ["welcome", "copyright", "layers", "new"]
|
||||||
private readonly _featureSource: FeatureSource;
|
private readonly _featureSource: FeatureSource;
|
||||||
private readonly _hash: UIEventSource<string>;
|
private readonly _hash: UIEventSource<string>;
|
||||||
private readonly _selectedFeature: UIEventSource<any>;
|
private readonly _selectedFeature: UIEventSource<any>;
|
||||||
|
|
||||||
private static readonly _no_trigger_on = ["welcome", "copyright", "layers", "new"]
|
|
||||||
private readonly _osmApiSource: OsmApiFeatureSource;
|
private readonly _osmApiSource: OsmApiFeatureSource;
|
||||||
|
|
||||||
constructor(hash: UIEventSource<string>,
|
constructor(hash: UIEventSource<string>,
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import * as L from "leaflet";
|
import * as L from "leaflet";
|
||||||
import Svg from "../../Svg";
|
|
||||||
import {UIEventSource} from "../UIEventSource";
|
import {UIEventSource} from "../UIEventSource";
|
||||||
import Img from "../../UI/Base/Img";
|
|
||||||
import ScrollableFullScreen from "../../UI/Base/ScrollableFullScreen";
|
import ScrollableFullScreen from "../../UI/Base/ScrollableFullScreen";
|
||||||
import AddNewMarker from "../../UI/BigComponents/AddNewMarker";
|
import AddNewMarker from "../../UI/BigComponents/AddNewMarker";
|
||||||
import FilteredLayer from "../../Models/FilteredLayer";
|
import FilteredLayer from "../../Models/FilteredLayer";
|
||||||
|
|
|
@ -49,7 +49,6 @@ class TitleElement extends UIEventSource<string> {
|
||||||
}
|
}
|
||||||
, [Locale.language, layoutToUse]
|
, [Locale.language, layoutToUse]
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ import {UIEventSource} from "./UIEventSource";
|
||||||
|
|
||||||
export class ElementStorage {
|
export class ElementStorage {
|
||||||
|
|
||||||
private _elements = new Map<string, UIEventSource<any>>();
|
|
||||||
public ContainingFeatures = new Map<string, any>();
|
public ContainingFeatures = new Map<string, any>();
|
||||||
|
private _elements = new Map<string, UIEventSource<any>>();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@ export default class GeoJsonSource implements FeatureSource {
|
||||||
|
|
||||||
public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>;
|
public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>;
|
||||||
public readonly name;
|
public readonly name;
|
||||||
|
public readonly isOsmCache: boolean
|
||||||
private onFail: ((errorMsg: any, url: string) => void) = undefined;
|
private onFail: ((errorMsg: any, url: string) => void) = undefined;
|
||||||
private readonly layerId: string;
|
private readonly layerId: string;
|
||||||
private readonly seenids: Set<string> = new Set<string>()
|
private readonly seenids: Set<string> = new Set<string>()
|
||||||
public readonly isOsmCache: boolean
|
|
||||||
|
|
||||||
private constructor(locationControl: UIEventSource<Loc>,
|
private constructor(locationControl: UIEventSource<Loc>,
|
||||||
flayer: { isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig },
|
flayer: { isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig },
|
||||||
|
|
|
@ -185,6 +185,60 @@ export class GeoOperations {
|
||||||
return turf.length(feature) * 1000
|
return turf.length(feature) * 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the closest point on a way from a given point
|
||||||
|
* @param way The road on which you want to find a point
|
||||||
|
* @param point Point defined as [lon, lat]
|
||||||
|
*/
|
||||||
|
public static nearestPoint(way, point: [number, number]) {
|
||||||
|
return turf.nearestPointOnLine(way, point, {units: "kilometers"});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static toCSV(features: any[]): string {
|
||||||
|
|
||||||
|
const headerValuesSeen = new Set<string>();
|
||||||
|
const headerValuesOrdered: string[] = []
|
||||||
|
|
||||||
|
function addH(key) {
|
||||||
|
if (!headerValuesSeen.has(key)) {
|
||||||
|
headerValuesSeen.add(key)
|
||||||
|
headerValuesOrdered.push(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addH("_lat")
|
||||||
|
addH("_lon")
|
||||||
|
|
||||||
|
const lines: string[] = []
|
||||||
|
|
||||||
|
for (const feature of features) {
|
||||||
|
const properties = feature.properties;
|
||||||
|
for (const key in properties) {
|
||||||
|
if (!properties.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
addH(key)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
headerValuesOrdered.sort()
|
||||||
|
for (const feature of features) {
|
||||||
|
const properties = feature.properties;
|
||||||
|
let line = ""
|
||||||
|
for (const key of headerValuesOrdered) {
|
||||||
|
const value = properties[key]
|
||||||
|
if (value === undefined) {
|
||||||
|
line += ","
|
||||||
|
} else {
|
||||||
|
line += JSON.stringify(value) + ","
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lines.push(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
return headerValuesOrdered.map(v => JSON.stringify(v)).join(",") + "\n" + lines.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the intersection between two features.
|
* Calculates the intersection between two features.
|
||||||
* Returns the length if intersecting a linestring and a (multi)polygon (in meters), returns a surface area (in m²) if intersecting two (multi)polygons
|
* Returns the length if intersecting a linestring and a (multi)polygon (in meters), returns a surface area (in m²) if intersecting two (multi)polygons
|
||||||
|
@ -277,60 +331,6 @@ export class GeoOperations {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the closest point on a way from a given point
|
|
||||||
* @param way The road on which you want to find a point
|
|
||||||
* @param point Point defined as [lon, lat]
|
|
||||||
*/
|
|
||||||
public static nearestPoint(way, point: [number, number]) {
|
|
||||||
return turf.nearestPointOnLine(way, point, {units: "kilometers"});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static toCSV(features: any[]): string {
|
|
||||||
|
|
||||||
const headerValuesSeen = new Set<string>();
|
|
||||||
const headerValuesOrdered: string[] = []
|
|
||||||
|
|
||||||
function addH(key) {
|
|
||||||
if (!headerValuesSeen.has(key)) {
|
|
||||||
headerValuesSeen.add(key)
|
|
||||||
headerValuesOrdered.push(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addH("_lat")
|
|
||||||
addH("_lon")
|
|
||||||
|
|
||||||
const lines: string[] = []
|
|
||||||
|
|
||||||
for (const feature of features) {
|
|
||||||
const properties = feature.properties;
|
|
||||||
for (const key in properties) {
|
|
||||||
if (!properties.hasOwnProperty(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
addH(key)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
headerValuesOrdered.sort()
|
|
||||||
for (const feature of features) {
|
|
||||||
const properties = feature.properties;
|
|
||||||
let line = ""
|
|
||||||
for (const key of headerValuesOrdered) {
|
|
||||||
const value = properties[key]
|
|
||||||
if (value === undefined) {
|
|
||||||
line += ","
|
|
||||||
} else {
|
|
||||||
line += JSON.stringify(value) + ","
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lines.push(line)
|
|
||||||
}
|
|
||||||
|
|
||||||
return headerValuesOrdered.map(v => JSON.stringify(v)).join(",") + "\n" + lines.join("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,13 @@ export default abstract class ImageAttributionSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public abstract SourceIcon(backlinkSource?: string): BaseUIElement;
|
public abstract SourceIcon(backlinkSource?: string): BaseUIElement;
|
||||||
protected abstract DownloadAttribution(url: string): UIEventSource<LicenseInfo>;
|
|
||||||
/*Converts a value to a URL. Can return null if not applicable*/
|
/*Converts a value to a URL. Can return null if not applicable*/
|
||||||
public PrepareUrl(value: string): string {
|
public PrepareUrl(value: string): string {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract DownloadAttribution(url: string): UIEventSource<LicenseInfo>;
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import $ from "jquery"
|
|
||||||
import {LicenseInfo} from "./Wikimedia";
|
import {LicenseInfo} from "./Wikimedia";
|
||||||
import ImageAttributionSource from "./ImageAttributionSource";
|
import ImageAttributionSource from "./ImageAttributionSource";
|
||||||
import BaseUIElement from "../../UI/BaseUIElement";
|
import BaseUIElement from "../../UI/BaseUIElement";
|
||||||
|
|
|
@ -18,6 +18,9 @@ interface Params {
|
||||||
export default class MetaTagging {
|
export default class MetaTagging {
|
||||||
|
|
||||||
|
|
||||||
|
private static errorPrintCount = 0;
|
||||||
|
private static readonly stopErrorOutputAt = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An actor which adds metatags on every feature in the given object
|
* An actor which adds metatags on every feature in the given object
|
||||||
* The features are a list of geojson-features, with a "properties"-field and geometry
|
* The features are a list of geojson-features, with a "properties"-field and geometry
|
||||||
|
@ -86,9 +89,6 @@ export default class MetaTagging {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static errorPrintCount = 0;
|
|
||||||
private static readonly stopErrorOutputAt = 10;
|
|
||||||
|
|
||||||
private static createRetaggingFunc(layer: LayerConfig):
|
private static createRetaggingFunc(layer: LayerConfig):
|
||||||
((params: Params, feature: any) => void) {
|
((params: Params, feature: any) => void) {
|
||||||
const calculatedTags: [string, string][] = layer.calculatedTags;
|
const calculatedTags: [string, string][] = layer.calculatedTags;
|
||||||
|
|
|
@ -8,11 +8,10 @@ import {GeoOperations} from "../../GeoOperations";
|
||||||
|
|
||||||
export default class CreateNewNodeAction extends OsmChangeAction {
|
export default class CreateNewNodeAction extends OsmChangeAction {
|
||||||
|
|
||||||
|
public newElementId: string = undefined
|
||||||
private readonly _basicTags: Tag[];
|
private readonly _basicTags: Tag[];
|
||||||
private readonly _lat: number;
|
private readonly _lat: number;
|
||||||
private readonly _lon: number;
|
private readonly _lon: number;
|
||||||
|
|
||||||
public newElementId: string = undefined
|
|
||||||
private readonly _snapOnto: OsmWay;
|
private readonly _snapOnto: OsmWay;
|
||||||
private readonly _reusePointDistance: number;
|
private readonly _reusePointDistance: number;
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,6 @@ export default class DeleteAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
deletionStarted = true;
|
deletionStarted = true;
|
||||||
OsmObject.DownloadObject(self._id).addCallbackAndRun(obj => {
|
OsmObject.DownloadObject(self._id).addCallbackAndRun(obj => {
|
||||||
if (obj === undefined) {
|
if (obj === undefined) {
|
||||||
|
@ -216,7 +214,6 @@ export default class DeleteAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import OsmChangeAction from "./OsmChangeAction";
|
import OsmChangeAction from "./OsmChangeAction";
|
||||||
import {Changes} from "../Changes";
|
import {Changes} from "../Changes";
|
||||||
import {ChangeDescription} from "./ChangeDescription";
|
import {ChangeDescription} from "./ChangeDescription";
|
||||||
import {OsmRelation, OsmWay} from "../OsmObject";
|
import {OsmRelation} from "../OsmObject";
|
||||||
|
|
||||||
export default class RelationSplitlHandler extends OsmChangeAction {
|
export default class RelationSplitlHandler extends OsmChangeAction {
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,88 @@ export class Changes {
|
||||||
.map(c => c.type + "/" + c.id))
|
.map(c => c.type + "/" + c.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new ID and updates the value for the next ID
|
||||||
|
*/
|
||||||
|
public getNewID() {
|
||||||
|
return Changes._nextId--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads all the pending changes in one go.
|
||||||
|
* Triggered by the 'PendingChangeUploader'-actor in Actors
|
||||||
|
*/
|
||||||
|
public flushChanges(flushreason: string = undefined) {
|
||||||
|
if (this.pendingChanges.data.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isUploading.data) {
|
||||||
|
console.log("Is already uploading... Abort")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.isUploading.setData(true)
|
||||||
|
|
||||||
|
console.log("Beginning upload... " + flushreason ?? "");
|
||||||
|
// At last, we build the changeset and upload
|
||||||
|
const self = this;
|
||||||
|
const pending = self.pendingChanges.data;
|
||||||
|
const neededIds = Changes.GetNeededIds(pending)
|
||||||
|
console.log("Needed ids", neededIds)
|
||||||
|
OsmObject.DownloadAll(neededIds, true).addCallbackAndRunD(osmObjects => {
|
||||||
|
console.log("Got the fresh objects!", osmObjects, "pending: ", pending)
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
const changes: {
|
||||||
|
newObjects: OsmObject[],
|
||||||
|
modifiedObjects: OsmObject[]
|
||||||
|
deletedObjects: OsmObject[]
|
||||||
|
|
||||||
|
} = self.CreateChangesetObjects(pending, osmObjects)
|
||||||
|
if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) {
|
||||||
|
console.log("No changes to be made")
|
||||||
|
self.pendingChanges.setData([])
|
||||||
|
self.isUploading.setData(false)
|
||||||
|
return true; // Unregister the callback
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
State.state.osmConnection.UploadChangeset(
|
||||||
|
State.state.layoutToUse.data,
|
||||||
|
State.state.allElements,
|
||||||
|
(csId) => Changes.createChangesetFor(csId, changes),
|
||||||
|
() => {
|
||||||
|
console.log("Upload successfull!")
|
||||||
|
self.pendingChanges.setData([]);
|
||||||
|
self.isUploading.setData(false)
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
console.log("Upload failed - trying again later")
|
||||||
|
return self.isUploading.setData(false);
|
||||||
|
} // Failed - mark to try again
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e)
|
||||||
|
self.pendingChanges.setData([])
|
||||||
|
self.isUploading.setData(false)
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public applyAction(action: OsmChangeAction) {
|
||||||
|
const changes = action.Perform(this)
|
||||||
|
console.log("Received changes:", changes)
|
||||||
|
this.pendingChanges.data.push(...changes);
|
||||||
|
this.pendingChanges.ping();
|
||||||
|
}
|
||||||
|
|
||||||
private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
||||||
newObjects: OsmObject[],
|
newObjects: OsmObject[],
|
||||||
modifiedObjects: OsmObject[]
|
modifiedObjects: OsmObject[]
|
||||||
|
@ -221,86 +303,4 @@ export class Changes {
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new ID and updates the value for the next ID
|
|
||||||
*/
|
|
||||||
public getNewID() {
|
|
||||||
return Changes._nextId--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uploads all the pending changes in one go.
|
|
||||||
* Triggered by the 'PendingChangeUploader'-actor in Actors
|
|
||||||
*/
|
|
||||||
public flushChanges(flushreason: string = undefined) {
|
|
||||||
if (this.pendingChanges.data.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isUploading.data) {
|
|
||||||
console.log("Is already uploading... Abort")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.isUploading.setData(true)
|
|
||||||
|
|
||||||
console.log("Beginning upload... "+flushreason ?? "");
|
|
||||||
// At last, we build the changeset and upload
|
|
||||||
const self = this;
|
|
||||||
const pending = self.pendingChanges.data;
|
|
||||||
const neededIds = Changes.GetNeededIds(pending)
|
|
||||||
console.log("Needed ids", neededIds)
|
|
||||||
OsmObject.DownloadAll(neededIds, true).addCallbackAndRunD(osmObjects => {
|
|
||||||
console.log("Got the fresh objects!", osmObjects, "pending: ", pending)
|
|
||||||
try{
|
|
||||||
|
|
||||||
|
|
||||||
const changes: {
|
|
||||||
newObjects: OsmObject[],
|
|
||||||
modifiedObjects: OsmObject[]
|
|
||||||
deletedObjects: OsmObject[]
|
|
||||||
|
|
||||||
} = self.CreateChangesetObjects(pending, osmObjects)
|
|
||||||
if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) {
|
|
||||||
console.log("No changes to be made")
|
|
||||||
self.pendingChanges.setData([])
|
|
||||||
self.isUploading.setData(false)
|
|
||||||
return true; // Unregister the callback
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
State.state.osmConnection.UploadChangeset(
|
|
||||||
State.state.layoutToUse.data,
|
|
||||||
State.state.allElements,
|
|
||||||
(csId) => Changes.createChangesetFor(csId, changes),
|
|
||||||
() => {
|
|
||||||
console.log("Upload successfull!")
|
|
||||||
self.pendingChanges.setData([]);
|
|
||||||
self.isUploading.setData(false)
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
console.log("Upload failed - trying again later")
|
|
||||||
return self.isUploading.setData(false);
|
|
||||||
} // Failed - mark to try again
|
|
||||||
)
|
|
||||||
}catch(e){
|
|
||||||
console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e)
|
|
||||||
self.pendingChanges.setData([])
|
|
||||||
self.isUploading.setData(false)
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public applyAction(action: OsmChangeAction) {
|
|
||||||
const changes = action.Perform(this)
|
|
||||||
console.log("Received changes:", changes)
|
|
||||||
this.pendingChanges.data.push(...changes);
|
|
||||||
this.pendingChanges.ping();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -6,8 +6,10 @@ export class Geocoding {
|
||||||
private static readonly host = "https://nominatim.openstreetmap.org/search?";
|
private static readonly host = "https://nominatim.openstreetmap.org/search?";
|
||||||
|
|
||||||
static Search(query: string,
|
static Search(query: string,
|
||||||
handleResult: ((places: { display_name: string, lat: number, lon: number, boundingbox: number[],
|
handleResult: ((places: {
|
||||||
osm_type: string, osm_id: string}[]) => void),
|
display_name: string, lat: number, lon: number, boundingbox: number[],
|
||||||
|
osm_type: string, osm_id: string
|
||||||
|
}[]) => void),
|
||||||
onFail: (() => void)) {
|
onFail: (() => void)) {
|
||||||
const b = State.state.leafletMap.data.getBounds();
|
const b = State.state.leafletMap.data.getBounds();
|
||||||
const url = Geocoding.host + "format=json&limit=1&viewbox=" +
|
const url = Geocoding.host + "format=json&limit=1&viewbox=" +
|
||||||
|
|
|
@ -47,10 +47,10 @@ export class OsmConnection {
|
||||||
public auth;
|
public auth;
|
||||||
public userDetails: UIEventSource<UserDetails>;
|
public userDetails: UIEventSource<UserDetails>;
|
||||||
public isLoggedIn: UIEventSource<boolean>
|
public isLoggedIn: UIEventSource<boolean>
|
||||||
private fakeUser: boolean;
|
|
||||||
_dryRun: boolean;
|
_dryRun: boolean;
|
||||||
public preferencesHandler: OsmPreferences;
|
public preferencesHandler: OsmPreferences;
|
||||||
public changesetHandler: ChangesetHandler;
|
public changesetHandler: ChangesetHandler;
|
||||||
|
private fakeUser: boolean;
|
||||||
private _onLoggedIn: ((userDetails: UserDetails) => void)[] = [];
|
private _onLoggedIn: ((userDetails: UserDetails) => void)[] = [];
|
||||||
private readonly _iframeMode: Boolean | boolean;
|
private readonly _iframeMode: Boolean | boolean;
|
||||||
private readonly _singlePage: boolean;
|
private readonly _singlePage: boolean;
|
||||||
|
@ -59,6 +59,7 @@ export class OsmConnection {
|
||||||
oauth_secret: string,
|
oauth_secret: string,
|
||||||
url: string
|
url: string
|
||||||
};
|
};
|
||||||
|
private isChecking = false;
|
||||||
|
|
||||||
constructor(dryRun: boolean,
|
constructor(dryRun: boolean,
|
||||||
fakeUser: boolean,
|
fakeUser: boolean,
|
||||||
|
@ -249,7 +250,6 @@ export class OsmConnection {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private isChecking = false;
|
|
||||||
private CheckForMessagesContinuously() {
|
private CheckForMessagesContinuously() {
|
||||||
const self = this;
|
const self = this;
|
||||||
if (this.isChecking) {
|
if (this.isChecking) {
|
||||||
|
|
|
@ -15,9 +15,6 @@ export default class AspectedRouting {
|
||||||
delete this.program.unit
|
delete this.program.unit
|
||||||
}
|
}
|
||||||
|
|
||||||
public evaluate(properties){
|
|
||||||
return AspectedRouting.interpret(this.program, properties)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Interprets the given Aspected-routing program for the given properties
|
* Interprets the given Aspected-routing program for the given properties
|
||||||
*/
|
*/
|
||||||
|
@ -191,4 +188,8 @@ export default class AspectedRouting {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public evaluate(properties) {
|
||||||
|
return AspectedRouting.interpret(this.program, properties)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -8,6 +8,14 @@ export class And extends TagsFilter {
|
||||||
this.and = and
|
this.and = and
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static combine(filter: string, choices: string[]): string[] {
|
||||||
|
const values = [];
|
||||||
|
for (const or of choices) {
|
||||||
|
values.push(filter + or);
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
normalize() {
|
normalize() {
|
||||||
const ands = []
|
const ands = []
|
||||||
for (const c of this.and) {
|
for (const c of this.and) {
|
||||||
|
@ -20,14 +28,6 @@ export class And extends TagsFilter {
|
||||||
return new And(ands)
|
return new And(ands)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static combine(filter: string, choices: string[]): string[] {
|
|
||||||
const values = [];
|
|
||||||
for (const or of choices) {
|
|
||||||
values.push(filter + or);
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
matchesProperties(tags: any): boolean {
|
matchesProperties(tags: any): boolean {
|
||||||
for (const tagsFilter of this.and) {
|
for (const tagsFilter of this.and) {
|
||||||
if (!tagsFilter.matchesProperties(tags)) {
|
if (!tagsFilter.matchesProperties(tags)) {
|
||||||
|
|
|
@ -52,6 +52,7 @@ export class Tag extends TagsFilter {
|
||||||
}
|
}
|
||||||
return [`["${this.key}"="${this.value}"]`];
|
return [`["${this.key}"="${this.value}"]`];
|
||||||
}
|
}
|
||||||
|
|
||||||
asHumanString(linkToWiki?: boolean, shorten?: boolean) {
|
asHumanString(linkToWiki?: boolean, shorten?: boolean) {
|
||||||
let v = this.value;
|
let v = this.value;
|
||||||
if (shorten) {
|
if (shorten) {
|
||||||
|
|
|
@ -10,6 +10,15 @@ import {AndOrTagConfigJson} from "../../Models/ThemeConfig/Json/TagConfigJson";
|
||||||
import {isRegExp} from "util";
|
import {isRegExp} from "util";
|
||||||
|
|
||||||
export class TagUtils {
|
export class TagUtils {
|
||||||
|
private static comparators
|
||||||
|
: [string, (a: number, b: number) => boolean][]
|
||||||
|
= [
|
||||||
|
["<=", (a, b) => a <= b],
|
||||||
|
[">=", (a, b) => a >= b],
|
||||||
|
["<", (a, b) => a < b],
|
||||||
|
[">", (a, b) => a > b],
|
||||||
|
]
|
||||||
|
|
||||||
static ApplyTemplate(template: string, tags: any): string {
|
static ApplyTemplate(template: string, tags: any): string {
|
||||||
for (const k in tags) {
|
for (const k in tags) {
|
||||||
while (template.indexOf("{" + k + "}") >= 0) {
|
while (template.indexOf("{" + k + "}") >= 0) {
|
||||||
|
@ -170,15 +179,6 @@ export class TagUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static comparators
|
|
||||||
: [string, (a: number, b: number) => boolean][]
|
|
||||||
= [
|
|
||||||
["<=", (a, b) => a <= b],
|
|
||||||
[">=", (a, b) => a >= b],
|
|
||||||
["<", (a, b) => a < b],
|
|
||||||
[">", (a, b) => a > b],
|
|
||||||
]
|
|
||||||
|
|
||||||
private static TagUnsafe(json: AndOrTagConfigJson | string, context: string = ""): TagsFilter {
|
private static TagUnsafe(json: AndOrTagConfigJson | string, context: string = ""): TagsFilter {
|
||||||
|
|
||||||
if (json === undefined) {
|
if (json === undefined) {
|
||||||
|
|
|
@ -69,6 +69,10 @@ export class QueryParameters {
|
||||||
return docs.join("\n\n");
|
return docs.join("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static wasInitialized(key: string): boolean {
|
||||||
|
return QueryParameters._wasInitialized.has(key)
|
||||||
|
}
|
||||||
|
|
||||||
private static addOrder(key) {
|
private static addOrder(key) {
|
||||||
if (this.order.indexOf(key) < 0) {
|
if (this.order.indexOf(key) < 0) {
|
||||||
this.order.push(key)
|
this.order.push(key)
|
||||||
|
@ -105,10 +109,6 @@ export class QueryParameters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static wasInitialized(key: string) : boolean{
|
|
||||||
return QueryParameters._wasInitialized.has(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Serialize() {
|
private static Serialize() {
|
||||||
const parts = []
|
const parts = []
|
||||||
for (const key of QueryParameters.order) {
|
for (const key of QueryParameters.order) {
|
||||||
|
|
|
@ -6,8 +6,8 @@ export class Denomination {
|
||||||
public readonly canonical: string;
|
public readonly canonical: string;
|
||||||
readonly default: boolean;
|
readonly default: boolean;
|
||||||
readonly prefix: boolean;
|
readonly prefix: boolean;
|
||||||
private readonly _human: Translation;
|
|
||||||
public readonly alternativeDenominations: string [];
|
public readonly alternativeDenominations: string [];
|
||||||
|
private readonly _human: Translation;
|
||||||
|
|
||||||
constructor(json: UnitConfigJson, context: string) {
|
constructor(json: UnitConfigJson, context: string) {
|
||||||
context = `${context}.unit(${json.canonicalDenomination})`
|
context = `${context}.unit(${json.canonicalDenomination})`
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {UIEventSource} from "../Logic/UIEventSource";
|
import {UIEventSource} from "../Logic/UIEventSource";
|
||||||
import {TagsFilter} from "../Logic/Tags/TagsFilter";
|
|
||||||
import LayerConfig from "./ThemeConfig/LayerConfig";
|
import LayerConfig from "./ThemeConfig/LayerConfig";
|
||||||
import {And} from "../Logic/Tags/And";
|
import {And} from "../Logic/Tags/And";
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,9 @@ export default class LayoutConfig {
|
||||||
*/
|
*/
|
||||||
public readonly cacheTimeout?: number;
|
public readonly cacheTimeout?: number;
|
||||||
public readonly units: Unit[] = []
|
public readonly units: Unit[] = []
|
||||||
private readonly _official: boolean;
|
|
||||||
|
|
||||||
public readonly overpassUrl: string;
|
public readonly overpassUrl: string;
|
||||||
public readonly overpassTimeout: number;
|
public readonly overpassTimeout: number;
|
||||||
|
private readonly _official: boolean;
|
||||||
|
|
||||||
constructor(json: LayoutConfigJson, official = true, context?: string) {
|
constructor(json: LayoutConfigJson, official = true, context?: string) {
|
||||||
this._official = official;
|
this._official = official;
|
||||||
|
|
|
@ -6,7 +6,6 @@ import {TagUtils} from "../../Logic/Tags/TagUtils";
|
||||||
import {And} from "../../Logic/Tags/And";
|
import {And} from "../../Logic/Tags/And";
|
||||||
import ValidatedTextField from "../../UI/Input/ValidatedTextField";
|
import ValidatedTextField from "../../UI/Input/ValidatedTextField";
|
||||||
import {Utils} from "../../Utils";
|
import {Utils} from "../../Utils";
|
||||||
import {SubstitutedTranslation} from "../../UI/SubstitutedTranslation";
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* The parsed version of TagRenderingConfigJSON
|
* The parsed version of TagRenderingConfigJSON
|
||||||
|
|
97
README.md
|
@ -1,10 +1,12 @@
|
||||||
|
|
||||||
# MapComplete
|
# MapComplete
|
||||||
|
|
||||||
> Let a thousand flowers bloom
|
> Let a thousand flowers bloom
|
||||||
|
|
||||||
MapComplete is an OpenStreetMap viewer and editor. It shows map features on a certain topic, and allows to see, edit and add new features to the map.
|
MapComplete is an OpenStreetMap viewer and editor. It shows map features on a certain topic, and allows to see, edit and
|
||||||
It can be seen as a webversion [crossover of StreetComplete and MapContrib](Docs/MapComplete_vs_other_editors.md). It tries to be just as easy to use as StreetComplete, but it allows to focus on one single theme per instance (e.g. nature, bicycle infrastructure, ...)
|
add new features to the map. It can be seen as a
|
||||||
|
webversion [crossover of StreetComplete and MapContrib](Docs/MapComplete_vs_other_editors.md). It tries to be just as
|
||||||
|
easy to use as StreetComplete, but it allows to focus on one single theme per instance (e.g. nature, bicycle
|
||||||
|
infrastructure, ...)
|
||||||
|
|
||||||
The design goals of MapComplete are to be:
|
The design goals of MapComplete are to be:
|
||||||
|
|
||||||
|
@ -13,29 +15,39 @@ The design goals of MapComplete are to be:
|
||||||
- Easy to set up a custom theme
|
- Easy to set up a custom theme
|
||||||
- Easy to fall down the rabbit hole of OSM
|
- Easy to fall down the rabbit hole of OSM
|
||||||
|
|
||||||
The basic functionality is to download some map features from Overpass and then ask certain questions. An answer is sent back to directly to OpenStreetMap.
|
The basic functionality is to download some map features from Overpass and then ask certain questions. An answer is sent
|
||||||
|
back to directly to OpenStreetMap.
|
||||||
|
|
||||||
Furthermore, it shows images present in the `image` tag or, if a `wikidata` or `wikimedia_commons`-tag is present, it follows those to get these images too.
|
Furthermore, it shows images present in the `image` tag or, if a `wikidata` or `wikimedia_commons`-tag is present, it
|
||||||
|
follows those to get these images too.
|
||||||
An explicit non-goal of MapComplete is to modify geometries of ways. Although adding a point to a way or splitting a way in two parts might be added one day.
|
|
||||||
|
|
||||||
|
An explicit non-goal of MapComplete is to modify geometries of ways. Although adding a point to a way or splitting a way
|
||||||
|
in two parts might be added one day.
|
||||||
|
|
||||||
# Creating your own theme
|
# Creating your own theme
|
||||||
|
|
||||||
It is possible to quickly make and distribute your own theme - [please read the documentation on how to do this](Docs/Making_Your_Own_Theme.md).
|
It is possible to quickly make and distribute your own theme
|
||||||
|
- [please read the documentation on how to do this](Docs/Making_Your_Own_Theme.md).
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
- [Buurtnatuur.be](http://buurtnatuur.be), developed for the Belgian [Green party](https://www.groen.be/). They also funded the initial development!
|
- [Buurtnatuur.be](http://buurtnatuur.be), developed for the Belgian [Green party](https://www.groen.be/). They also
|
||||||
- [Cyclofix](https://pietervdvn.github.io/MapComplete/index.html?layout=cyclofix), further development on [Open Summer of Code](https://summerofcode.be/) funded by [Brussels Mobility](https://mobilite-mobiliteit.brussels/en). Landing page at https://cyclofix.osm.be/
|
funded the initial development!
|
||||||
- [Bookcases](https://pietervdvn.github.io/MapComplete/index.html?quests=bookcases#element) cause I like to collect them.
|
- [Cyclofix](https://pietervdvn.github.io/MapComplete/index.html?layout=cyclofix), further development
|
||||||
- [Map of Maps](https://pietervdvn.github.io/MapComplete/index.html?layout=maps&z=14&lat=50.650&lon=4.2668#element), after a tweet
|
on [Open Summer of Code](https://summerofcode.be/) funded
|
||||||
|
by [Brussels Mobility](https://mobilite-mobiliteit.brussels/en). Landing page at https://cyclofix.osm.be/
|
||||||
|
- [Bookcases](https://pietervdvn.github.io/MapComplete/index.html?quests=bookcases#element) cause I like to collect
|
||||||
|
them.
|
||||||
|
- [Map of Maps](https://pietervdvn.github.io/MapComplete/index.html?layout=maps&z=14&lat=50.650&lon=4.2668#element),
|
||||||
|
after a tweet
|
||||||
|
|
||||||
There are plenty more. Discover them in the app.
|
There are plenty more. Discover them in the app.
|
||||||
|
|
||||||
### Statistics
|
### Statistics
|
||||||
|
|
||||||
To see statistics, consult [OsmCha](https://osmcha.org/?filters=%7B%22comment%22%3A%5B%7B%22label%22%3A%22%23mapcomplete%22%2C%22value%22%3A%22%23mapcomplete%22%7D%5D%2C%22date__gte%22%3A%5B%7B%22label%22%3A%222020-07-05%22%2C%22value%22%3A%222020-07-05%22%7D%5D%7D) or the [analytics page](https://pietervdvn.goatcounter.com/)
|
To see statistics,
|
||||||
|
consult [OsmCha](https://osmcha.org/?filters=%7B%22comment%22%3A%5B%7B%22label%22%3A%22%23mapcomplete%22%2C%22value%22%3A%22%23mapcomplete%22%7D%5D%2C%22date__gte%22%3A%5B%7B%22label%22%3A%222020-07-05%22%2C%22value%22%3A%222020-07-05%22%7D%5D%7D)
|
||||||
|
or the [analytics page](https://pietervdvn.goatcounter.com/)
|
||||||
|
|
||||||
## User journey
|
## User journey
|
||||||
|
|
||||||
|
@ -49,7 +61,8 @@ A typical user journey would be:
|
||||||
* The user might share the map and/or embed it in the third tab
|
* The user might share the map and/or embed it in the third tab
|
||||||
* The user might discover the other themes in the last tab
|
* The user might discover the other themes in the last tab
|
||||||
|
|
||||||
1. The user clicks that big tempting button 'login' in order to answer questions - there's enough of these login buttons... The user creates an account.
|
1. The user clicks that big tempting button 'login' in order to answer questions - there's enough of these login
|
||||||
|
buttons... The user creates an account.
|
||||||
|
|
||||||
2. The user answers a question! Hooray! The user transformed into a __contributor__ now.
|
2. The user answers a question! Hooray! The user transformed into a __contributor__ now.
|
||||||
|
|
||||||
|
@ -58,49 +71,57 @@ A typical user journey would be:
|
||||||
3. The user adds a new POI somewhere
|
3. The user adds a new POI somewhere
|
||||||
|
|
||||||
* Note that _all messages_ must be read before being able to add a point.
|
* Note that _all messages_ must be read before being able to add a point.
|
||||||
* In other words, sending a message to a misbehaving MapComplete user acts as having a **zero-day-block**. This is added deliberately to make sure new users _have_ to read feedback from the community.
|
* In other words, sending a message to a misbehaving MapComplete user acts as having a **zero-day-block**. This is
|
||||||
|
added deliberately to make sure new users _have_ to read feedback from the community.
|
||||||
|
|
||||||
4. At 50 changesets, the [personal layout](https://pietervdvn.github.io/MapComplete/personal.html) is advertised. The personal theme is a theme where contributors can pick layers from all the official themes. Note that the personal theme is always available.
|
4. At 50 changesets, the [personal layout](https://pietervdvn.github.io/MapComplete/personal.html) is advertised. The
|
||||||
|
personal theme is a theme where contributors can pick layers from all the official themes. Note that the personal
|
||||||
|
theme is always available.
|
||||||
|
|
||||||
5. At 200 changesets, the tags become visible when answering questions and when adding a new point from a preset. This is to give more control to power users and to teach new users the tagging scheme
|
5. At 200 changesets, the tags become visible when answering questions and when adding a new point from a preset. This
|
||||||
|
is to give more control to power users and to teach new users the tagging scheme
|
||||||
|
|
||||||
6. At 250 changesets, the tags get linked to the wiki
|
6. At 250 changesets, the tags get linked to the wiki
|
||||||
|
|
||||||
7. At 500 changesets, I expect contributors to be power users and to be comfortable with tagging scheme and such. The custom theme generator is unlocked.
|
7. At 500 changesets, I expect contributors to be power users and to be comfortable with tagging scheme and such. The
|
||||||
|
custom theme generator is unlocked.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
GPLv3.0 + recommended pingback.
|
GPLv3.0 + recommended pingback.
|
||||||
|
|
||||||
I love it to see where the project ends up. You are free to reuse the software (under GPL) but, when you have made your own change and are using it, I would like to know about it. Drop me a line, give a pingback in the issues,...
|
I love it to see where the project ends up. You are free to reuse the software (under GPL) but, when you have made your
|
||||||
|
own change and are using it, I would like to know about it. Drop me a line, give a pingback in the issues,...
|
||||||
|
|
||||||
## Dev
|
## Dev
|
||||||
|
|
||||||
To develop or deploy a version of MapComplete, have a look [to the guide](Docs/Development_deployment.md).
|
To develop or deploy a version of MapComplete, have a look [to the guide](Docs/Development_deployment.md).
|
||||||
|
|
||||||
|
|
||||||
## Translating MapComplete
|
## Translating MapComplete
|
||||||
|
|
||||||
The core strings and builtin themes of MapComplete are translated on [Hosted Weblate](https://hosted.weblate.org/projects/mapcomplete/core/).
|
The core strings and builtin themes of MapComplete are translated
|
||||||
You can easily make an account and start translating in their web-environment - no installation required.
|
on [Hosted Weblate](https://hosted.weblate.org/projects/mapcomplete/core/). You can easily make an account and start
|
||||||
|
translating in their web-environment - no installation required.
|
||||||
|
|
||||||
[![Translation status](https://hosted.weblate.org/widgets/mapcomplete/-/multi-blue.svg)](https://hosted.weblate.org/engage/mapcomplete/)
|
[![Translation status](https://hosted.weblate.org/widgets/mapcomplete/-/multi-blue.svg)](https://hosted.weblate.org/engage/mapcomplete/)
|
||||||
|
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### High-level overview
|
### High-level overview
|
||||||
|
|
||||||
The website is purely static. This means that there is no database here, nor one is needed as all the data is kept in OpenStreetMap, Wikimedia (for images), Imgur. Settings are saved in the preferences-space of the OSM-website, amended by some local-storage if the user is not logged-in.
|
The website is purely static. This means that there is no database here, nor one is needed as all the data is kept in
|
||||||
|
OpenStreetMap, Wikimedia (for images), Imgur. Settings are saved in the preferences-space of the OSM-website, amended by
|
||||||
|
some local-storage if the user is not logged-in.
|
||||||
|
|
||||||
When viewing, the data is loaded from overpass. The data is then converted (in the browser) to geojson, which is rendered by Leaflet.
|
When viewing, the data is loaded from overpass. The data is then converted (in the browser) to geojson, which is
|
||||||
|
rendered by Leaflet.
|
||||||
|
|
||||||
When a map feature is clicked, a popup shows the information, images and questions that are relevant for that object.
|
When a map feature is clicked, a popup shows the information, images and questions that are relevant for that object.
|
||||||
The answers given by the user are sent (after a few seconds) to OpenStreetMap directly - if the user is logged in. If not logged in, the user is prompted to do so.
|
The answers given by the user are sent (after a few seconds) to OpenStreetMap directly - if the user is logged in. If
|
||||||
|
not logged in, the user is prompted to do so.
|
||||||
The UI-event-source is a class where the entire system is built upon, it acts as an observable object: another object can register for changes to update when needed.
|
|
||||||
|
|
||||||
|
The UI-event-source is a class where the entire system is built upon, it acts as an observable object: another object
|
||||||
|
can register for changes to update when needed.
|
||||||
|
|
||||||
### Searching images
|
### Searching images
|
||||||
|
|
||||||
|
@ -114,15 +135,19 @@ Images are fetched from:
|
||||||
|
|
||||||
Images are uploaded to Imgur, as their API was way easier to handle. The URL is written into the changes.
|
Images are uploaded to Imgur, as their API was way easier to handle. The URL is written into the changes.
|
||||||
|
|
||||||
The idea is that once in a while, the images are transferred to wikipedia or that we hook up wikimedia directly (but I need some help in getting their API working).
|
The idea is that once in a while, the images are transferred to wikipedia or that we hook up wikimedia directly (but I
|
||||||
|
need some help in getting their API working).
|
||||||
|
|
||||||
### Uploading changes
|
### Uploading changes
|
||||||
|
|
||||||
In order to avoid lots of small changesets, a changeset is opened and kept open. The changeset number is saved into the users preferences on OSM.
|
In order to avoid lots of small changesets, a changeset is opened and kept open. The changeset number is saved into the
|
||||||
|
users preferences on OSM.
|
||||||
|
|
||||||
Whenever a change is made -even adding a single tag - the change is uploaded into this changeset. If that fails, the changeset is probably closed and we open a new changeset.
|
Whenever a change is made -even adding a single tag - the change is uploaded into this changeset. If that fails, the
|
||||||
|
changeset is probably closed and we open a new changeset.
|
||||||
|
|
||||||
Note that changesets are closed automatically after one hour of inactivity, so we don't have to worry about closing them.
|
Note that changesets are closed automatically after one hour of inactivity, so we don't have to worry about closing
|
||||||
|
them.
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
|
@ -130,13 +155,11 @@ All documentation can be found in [here](Docs/)
|
||||||
|
|
||||||
# Privacy
|
# Privacy
|
||||||
|
|
||||||
Privacy is important, we try to leak as little information as possible.
|
Privacy is important, we try to leak as little information as possible. All major personal information is handled by
|
||||||
All major personal information is handled by OSM.
|
OSM. Geolocation is available on mobile only through the device's GPS location (so no geolocation is sent of to Google).
|
||||||
Geolocation is available on mobile only through the device's GPS location (so no geolocation is sent of to Google).
|
|
||||||
|
|
||||||
TODO: erase cookies of third party websites and API's
|
TODO: erase cookies of third party websites and API's
|
||||||
|
|
||||||
|
|
||||||
# Attribution and Copyright
|
# Attribution and Copyright
|
||||||
|
|
||||||
The code is available under GPL; all map data comes from OpenStreetMap (both foreground and background maps).
|
The code is available under GPL; all map data comes from OpenStreetMap (both foreground and background maps).
|
||||||
|
|
|
@ -12,6 +12,10 @@ export class CenterFlexedElement extends BaseUIElement {
|
||||||
return this._html;
|
return this._html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsMarkdown(): string {
|
||||||
|
return this._html;
|
||||||
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
protected InnerConstructElement(): HTMLElement {
|
||||||
const e = document.createElement("div");
|
const e = document.createElement("div");
|
||||||
e.innerHTML = this._html;
|
e.innerHTML = this._html;
|
||||||
|
@ -25,8 +29,4 @@ export class CenterFlexedElement extends BaseUIElement {
|
||||||
e.style.alignItems = "center";
|
e.style.alignItems = "center";
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsMarkdown(): string {
|
|
||||||
return this._html;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,10 @@ export default class Combine extends BaseUIElement {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsMarkdown(): string {
|
||||||
|
return this.uiElements.map(el => el.AsMarkdown()).join(this.HasClass("flex-col") ? "\n\n" : " ");
|
||||||
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
protected InnerConstructElement(): HTMLElement {
|
||||||
const el = document.createElement("span")
|
const el = document.createElement("span")
|
||||||
|
|
||||||
|
@ -40,8 +44,4 @@ export default class Combine extends BaseUIElement {
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsMarkdown(): string {
|
|
||||||
return this.uiElements.map(el => el.AsMarkdown()).join(this.HasClass("flex-col") ? "\n\n" : " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -12,14 +12,14 @@ export class FixedUiElement extends BaseUIElement {
|
||||||
return this._html;
|
return this._html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsMarkdown(): string {
|
||||||
|
return this._html;
|
||||||
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
protected InnerConstructElement(): HTMLElement {
|
||||||
const e = document.createElement("span")
|
const e = document.createElement("span")
|
||||||
e.innerHTML = this._html
|
e.innerHTML = this._html
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsMarkdown(): string {
|
|
||||||
return this._html;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,6 +16,11 @@ export default class Link extends BaseUIElement {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsMarkdown(): string {
|
||||||
|
// @ts-ignore
|
||||||
|
return `[${this._embeddedShow.AsMarkdown()}](${this._href.data ?? this._href})`;
|
||||||
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
protected InnerConstructElement(): HTMLElement {
|
||||||
const embeddedShow = this._embeddedShow?.ConstructElement();
|
const embeddedShow = this._embeddedShow?.ConstructElement();
|
||||||
if (embeddedShow === undefined) {
|
if (embeddedShow === undefined) {
|
||||||
|
@ -36,9 +41,4 @@ export default class Link extends BaseUIElement {
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsMarkdown(): string {
|
|
||||||
// @ts-ignore
|
|
||||||
return `[${this._embeddedShow.AsMarkdown()}](${this._href.data ?? this._href})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -13,6 +13,15 @@ export default class List extends BaseUIElement {
|
||||||
.map(Translations.W);
|
.map(Translations.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsMarkdown(): string {
|
||||||
|
if (this._ordered) {
|
||||||
|
return "\n\n" + this.uiElements.map((el, i) => " " + i + ". " + el.AsMarkdown().replace(/\n/g, ' \n')).join("\n") + "\n"
|
||||||
|
} else {
|
||||||
|
return "\n\n" + this.uiElements.map(el => " - " + el.AsMarkdown().replace(/\n/g, ' \n')).join("\n") + "\n"
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
protected InnerConstructElement(): HTMLElement {
|
||||||
const el = document.createElement(this._ordered ? "ol" : "ul")
|
const el = document.createElement(this._ordered ? "ol" : "ul")
|
||||||
|
|
||||||
|
@ -31,13 +40,4 @@ export default class List extends BaseUIElement {
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsMarkdown(): string {
|
|
||||||
if(this._ordered){
|
|
||||||
return "\n\n"+this.uiElements.map((el, i) => " "+i+". "+el.AsMarkdown().replace(/\n/g, ' \n') ).join("\n") + "\n"
|
|
||||||
}else{
|
|
||||||
return "\n\n"+this.uiElements.map(el => " - "+el.AsMarkdown().replace(/\n/g, ' \n') ).join("\n")+"\n"
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,12 +18,12 @@ import BaseUIElement from "../BaseUIElement";
|
||||||
*/
|
*/
|
||||||
export default class ScrollableFullScreen extends UIElement {
|
export default class ScrollableFullScreen extends UIElement {
|
||||||
private static readonly empty = new FixedUiElement("");
|
private static readonly empty = new FixedUiElement("");
|
||||||
|
private static readonly _actor = ScrollableFullScreen.InitActor();
|
||||||
|
private static _currentlyOpen: ScrollableFullScreen;
|
||||||
public isShown: UIEventSource<boolean>;
|
public isShown: UIEventSource<boolean>;
|
||||||
private _component: BaseUIElement;
|
private _component: BaseUIElement;
|
||||||
private _fullscreencomponent: BaseUIElement;
|
private _fullscreencomponent: BaseUIElement;
|
||||||
private static readonly _actor = ScrollableFullScreen.InitActor();
|
|
||||||
private _hashToSet: string;
|
private _hashToSet: string;
|
||||||
private static _currentlyOpen : ScrollableFullScreen;
|
|
||||||
|
|
||||||
constructor(title: ((mode: string) => BaseUIElement), content: ((mode: string) => BaseUIElement),
|
constructor(title: ((mode: string) => BaseUIElement), content: ((mode: string) => BaseUIElement),
|
||||||
hashToSet: string,
|
hashToSet: string,
|
||||||
|
@ -46,6 +46,23 @@ export default class ScrollableFullScreen extends UIElement {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static clear() {
|
||||||
|
ScrollableFullScreen.empty.AttachTo("fullscreen")
|
||||||
|
const fs = document.getElementById("fullscreen");
|
||||||
|
ScrollableFullScreen._currentlyOpen?.isShown?.setData(false);
|
||||||
|
fs.classList.add("hidden")
|
||||||
|
Hash.hash.setData(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InitActor() {
|
||||||
|
Hash.hash.addCallback(hash => {
|
||||||
|
if (hash === undefined || hash === "") {
|
||||||
|
ScrollableFullScreen.clear()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
InnerRender(): BaseUIElement {
|
InnerRender(): BaseUIElement {
|
||||||
return this._component;
|
return this._component;
|
||||||
}
|
}
|
||||||
|
@ -86,21 +103,4 @@ export default class ScrollableFullScreen extends UIElement {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static clear() {
|
|
||||||
ScrollableFullScreen.empty.AttachTo("fullscreen")
|
|
||||||
const fs = document.getElementById("fullscreen");
|
|
||||||
ScrollableFullScreen._currentlyOpen?.isShown?.setData(false);
|
|
||||||
fs.classList.add("hidden")
|
|
||||||
Hash.hash.setData(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static InitActor(){
|
|
||||||
Hash.hash.addCallback(hash => {
|
|
||||||
if(hash === undefined || hash === ""){
|
|
||||||
ScrollableFullScreen.clear()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,22 +4,13 @@ import Translations from "../i18n/Translations";
|
||||||
export default class Title extends BaseUIElement {
|
export default class Title extends BaseUIElement {
|
||||||
private readonly _embedded: BaseUIElement;
|
private readonly _embedded: BaseUIElement;
|
||||||
private readonly _level: number;
|
private readonly _level: number;
|
||||||
|
|
||||||
constructor(embedded: string | BaseUIElement, level: number = 3) {
|
constructor(embedded: string | BaseUIElement, level: number = 3) {
|
||||||
super()
|
super()
|
||||||
this._embedded = Translations.W(embedded);
|
this._embedded = Translations.W(embedded);
|
||||||
this._level = level;
|
this._level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
|
||||||
const el = this._embedded.ConstructElement()
|
|
||||||
if(el === undefined){
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const h = document.createElement("h"+this._level)
|
|
||||||
h.appendChild(el)
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
AsMarkdown(): string {
|
AsMarkdown(): string {
|
||||||
const embedded = " " + this._embedded.AsMarkdown() + " ";
|
const embedded = " " + this._embedded.AsMarkdown() + " ";
|
||||||
|
|
||||||
|
@ -33,4 +24,14 @@ export default class Title extends BaseUIElement{
|
||||||
|
|
||||||
return "\n" + "#".repeat(this._level) + embedded + "\n\n";
|
return "\n" + "#".repeat(this._level) + embedded + "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected InnerConstructElement(): HTMLElement {
|
||||||
|
const el = this._embedded.ConstructElement()
|
||||||
|
if (el === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const h = document.createElement("h" + this._level)
|
||||||
|
h.appendChild(el)
|
||||||
|
return h;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,8 +9,6 @@ import {DownloadPanel} from "./DownloadPanel";
|
||||||
import {SubtleButton} from "../Base/SubtleButton";
|
import {SubtleButton} from "../Base/SubtleButton";
|
||||||
import Svg from "../../Svg";
|
import Svg from "../../Svg";
|
||||||
import ExportPDF from "../ExportPDF";
|
import ExportPDF from "../ExportPDF";
|
||||||
import {Browser} from "leaflet";
|
|
||||||
import ie = Browser.ie;
|
|
||||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||||
|
|
||||||
export default class AllDownloads extends ScrollableFullScreen {
|
export default class AllDownloads extends ScrollableFullScreen {
|
||||||
|
|
|
@ -37,7 +37,6 @@ export default class Attribution extends Combine {
|
||||||
const mapillary = new Link(Svg.mapillary_black_ui().SetClass("small-image"), mapillaryLink, true);
|
const mapillary = new Link(Svg.mapillary_black_ui().SetClass("small-image"), mapillaryLink, true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let editWithJosm = new VariableUiElement(
|
let editWithJosm = new VariableUiElement(
|
||||||
userDetails.map(userDetails => {
|
userDetails.map(userDetails => {
|
||||||
|
|
||||||
|
|
|
@ -163,8 +163,6 @@ export default class MoreScreen extends Combine {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let description = Translations.WT(layout.shortDescription).Clone();
|
let description = Translations.WT(layout.shortDescription).Clone();
|
||||||
return new SubtleButton(layout.icon,
|
return new SubtleButton(layout.icon,
|
||||||
new Combine([
|
new Combine([
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {SubtleButton} from "../Base/SubtleButton";
|
||||||
import Translations from "../i18n/Translations";
|
import Translations from "../i18n/Translations";
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement";
|
||||||
import {VariableUiElement} from "../Base/VariableUIElement";
|
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||||
import Img from "../Base/Img";
|
|
||||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import Locale from "../i18n/Locale";
|
|
||||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
import {Translation} from "../i18n/Translation";
|
import {Translation} from "../i18n/Translation";
|
||||||
import {VariableUiElement} from "../Base/VariableUIElement";
|
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||||
|
|
|
@ -178,8 +178,6 @@ export default class ShareScreen extends Combine {
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let editLayout: BaseUIElement = new FixedUiElement("");
|
let editLayout: BaseUIElement = new FixedUiElement("");
|
||||||
if ((layoutDefinition !== undefined && State.state?.osmConnection !== undefined)) {
|
if ((layoutDefinition !== undefined && State.state?.osmConnection !== undefined)) {
|
||||||
editLayout =
|
editLayout =
|
||||||
|
|
|
@ -222,7 +222,6 @@ export default class SimpleAddUI extends Toggle {
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const tagInfo = SimpleAddUI.CreateTagInfoFor(preset);
|
const tagInfo = SimpleAddUI.CreateTagInfoFor(preset);
|
||||||
|
|
||||||
const cancelButton = new SubtleButton(Svg.close_ui(),
|
const cancelButton = new SubtleButton(Svg.close_ui(),
|
||||||
|
|
|
@ -42,7 +42,6 @@ export default class ThemeIntroductionPanel extends VariableUiElement {
|
||||||
const welcomeBack = Translations.t.general.welcomeBack.Clone();
|
const welcomeBack = Translations.t.general.welcomeBack.Clone();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const loginStatus =
|
const loginStatus =
|
||||||
new Toggle(
|
new Toggle(
|
||||||
new Toggle(
|
new Toggle(
|
||||||
|
|
|
@ -13,7 +13,6 @@ export default class UploadFlowStateUI extends VariableUiElement{
|
||||||
const t = Translations.t.image;
|
const t = Translations.t.image;
|
||||||
|
|
||||||
super(
|
super(
|
||||||
|
|
||||||
queue.map(queue => {
|
queue.map(queue => {
|
||||||
const failedReasons = failed.data
|
const failedReasons = failed.data
|
||||||
const successCount = success.data.length
|
const successCount = success.data.length
|
||||||
|
@ -38,8 +37,6 @@ export default class UploadFlowStateUI extends VariableUiElement{
|
||||||
|
|
||||||
return stateMessages
|
return stateMessages
|
||||||
}, [failed, success])
|
}, [failed, success])
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
|
||||||
|
|
||||||
export default class ExportPDF {
|
export default class ExportPDF {
|
||||||
// dimensions of the map in milimeter
|
// dimensions of the map in milimeter
|
||||||
|
public isRunning = new UIEventSource(true)
|
||||||
// A4: 297 * 210mm
|
// A4: 297 * 210mm
|
||||||
private readonly mapW = 297;
|
private readonly mapW = 297;
|
||||||
private readonly mapH = 210;
|
private readonly mapH = 210;
|
||||||
|
@ -33,8 +34,6 @@ export default class ExportPDF {
|
||||||
private readonly _layout: UIEventSource<LayoutConfig>;
|
private readonly _layout: UIEventSource<LayoutConfig>;
|
||||||
private _screenhotTaken = false;
|
private _screenhotTaken = false;
|
||||||
|
|
||||||
public isRunning = new UIEventSource(true)
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
options: {
|
options: {
|
||||||
freeDivId: string,
|
freeDivId: string,
|
||||||
|
|
|
@ -16,8 +16,7 @@ export default class DeleteImage extends Toggle {
|
||||||
.SetClass("rounded-full p-1")
|
.SetClass("rounded-full p-1")
|
||||||
.SetStyle("color:white;background:#ff8c8c")
|
.SetStyle("color:white;background:#ff8c8c")
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
State.state?.changes?.
|
State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data))
|
||||||
applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data))
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const deleteButton = Translations.t.image.doDelete.Clone()
|
const deleteButton = Translations.t.image.doDelete.Clone()
|
||||||
|
|
|
@ -3,8 +3,10 @@ import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
|
|
||||||
export default class ColorPicker extends InputElement<string> {
|
export default class ColorPicker extends InputElement<string> {
|
||||||
|
|
||||||
|
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||||
private readonly value: UIEventSource<string>
|
private readonly value: UIEventSource<string>
|
||||||
private readonly _element: HTMLElement
|
private readonly _element: HTMLElement
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
value: UIEventSource<string> = new UIEventSource<string>(undefined)
|
value: UIEventSource<string> = new UIEventSource<string>(undefined)
|
||||||
) {
|
) {
|
||||||
|
@ -26,18 +28,16 @@ private readonly _element : HTMLElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
|
||||||
return this._element;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetValue(): UIEventSource<string> {
|
GetValue(): UIEventSource<string> {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
|
||||||
|
|
||||||
IsValid(t: string): boolean {
|
IsValid(t: string): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected InnerConstructElement(): HTMLElement {
|
||||||
|
return this._element;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -13,9 +13,8 @@ import Loc from "../../Models/Loc";
|
||||||
*/
|
*/
|
||||||
export default class DirectionInput extends InputElement<string> {
|
export default class DirectionInput extends InputElement<string> {
|
||||||
public static constructMinimap: ((any) => BaseUIElement);
|
public static constructMinimap: ((any) => BaseUIElement);
|
||||||
private readonly _location: UIEventSource<Loc>;
|
|
||||||
|
|
||||||
public readonly IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
public readonly IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||||
|
private readonly _location: UIEventSource<Loc>;
|
||||||
private readonly value: UIEventSource<string>;
|
private readonly value: UIEventSource<string>;
|
||||||
private background;
|
private background;
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import Translations from "../i18n/Translations";
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement";
|
||||||
|
|
||||||
export class FixedInputElement<T> extends InputElement<T> {
|
export class FixedInputElement<T> extends InputElement<T> {
|
||||||
private readonly value: UIEventSource<T>;
|
|
||||||
public readonly IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
public readonly IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||||
|
private readonly value: UIEventSource<T>;
|
||||||
private readonly _comparator: (t0: T, t1: T) => boolean;
|
private readonly _comparator: (t0: T, t1: T) => boolean;
|
||||||
|
|
||||||
private readonly _el: HTMLElement;
|
private readonly _el: HTMLElement;
|
||||||
|
@ -30,10 +30,6 @@ export class FixedInputElement<T> extends InputElement<T> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
|
||||||
return this._el;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetValue(): UIEventSource<T> {
|
GetValue(): UIEventSource<T> {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
@ -42,5 +38,9 @@ export class FixedInputElement<T> extends InputElement<T> {
|
||||||
return this._comparator(t, this.value.data);
|
return this._comparator(t, this.value.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected InnerConstructElement(): HTMLElement {
|
||||||
|
return this._el;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,8 +3,10 @@ import BaseUIElement from "../BaseUIElement";
|
||||||
|
|
||||||
export abstract class InputElement<T> extends BaseUIElement {
|
export abstract class InputElement<T> extends BaseUIElement {
|
||||||
|
|
||||||
abstract GetValue() : UIEventSource<T>;
|
|
||||||
abstract IsSelected: UIEventSource<boolean>;
|
abstract IsSelected: UIEventSource<boolean>;
|
||||||
|
|
||||||
|
abstract GetValue(): UIEventSource<T>;
|
||||||
|
|
||||||
abstract IsValid(t: T): boolean;
|
abstract IsValid(t: T): boolean;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,14 @@ import {Utils} from "../../Utils";
|
||||||
import Loc from "../../Models/Loc";
|
import Loc from "../../Models/Loc";
|
||||||
import {GeoOperations} from "../../Logic/GeoOperations";
|
import {GeoOperations} from "../../Logic/GeoOperations";
|
||||||
import DirectionInput from "./DirectionInput";
|
import DirectionInput from "./DirectionInput";
|
||||||
import {RadioButton} from "./RadioButton";
|
|
||||||
import {FixedInputElement} from "./FixedInputElement";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects a length after clicking on the minimap, in meters
|
* Selects a length after clicking on the minimap, in meters
|
||||||
*/
|
*/
|
||||||
export default class LengthInput extends InputElement<string> {
|
export default class LengthInput extends InputElement<string> {
|
||||||
private readonly _location: UIEventSource<Loc>;
|
|
||||||
|
|
||||||
public readonly IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
public readonly IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||||
|
private readonly _location: UIEventSource<Loc>;
|
||||||
private readonly value: UIEventSource<string>;
|
private readonly value: UIEventSource<string>;
|
||||||
private background;
|
private background;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,27 @@ import * as L from "leaflet";
|
||||||
|
|
||||||
export default class LocationInput extends InputElement<Loc> {
|
export default class LocationInput extends InputElement<Loc> {
|
||||||
|
|
||||||
|
private static readonly matchLayout = new UIEventSource(new LayoutConfig({
|
||||||
|
description: "Matchpoint style",
|
||||||
|
icon: "./assets/svg/crosshair-empty.svg",
|
||||||
|
id: "matchpoint",
|
||||||
|
language: ["en"],
|
||||||
|
layers: [{
|
||||||
|
id: "matchpoint", source: {
|
||||||
|
osmTags: {and: []}
|
||||||
|
},
|
||||||
|
icon: "./assets/svg/crosshair-empty.svg"
|
||||||
|
}],
|
||||||
|
maintainer: "MapComplete",
|
||||||
|
startLat: 0,
|
||||||
|
startLon: 0,
|
||||||
|
startZoom: 0,
|
||||||
|
title: "Location input",
|
||||||
|
version: "0"
|
||||||
|
|
||||||
|
}));
|
||||||
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||||
|
public readonly snappedOnto: UIEventSource<any> = new UIEventSource<any>(undefined)
|
||||||
private _centerLocation: UIEventSource<Loc>;
|
private _centerLocation: UIEventSource<Loc>;
|
||||||
private readonly mapBackground: UIEventSource<BaseLayer>;
|
private readonly mapBackground: UIEventSource<BaseLayer>;
|
||||||
private readonly _snapTo: UIEventSource<{ feature: any }[]>
|
private readonly _snapTo: UIEventSource<{ feature: any }[]>
|
||||||
|
@ -22,7 +42,6 @@ export default class LocationInput extends InputElement<Loc> {
|
||||||
private readonly _snappedPoint: UIEventSource<any>
|
private readonly _snappedPoint: UIEventSource<any>
|
||||||
private readonly _maxSnapDistance: number
|
private readonly _maxSnapDistance: number
|
||||||
private readonly _snappedPointTags: any;
|
private readonly _snappedPointTags: any;
|
||||||
public readonly snappedOnto: UIEventSource<any> = new UIEventSource<any>(undefined)
|
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
mapBackground?: UIEventSource<BaseLayer>,
|
mapBackground?: UIEventSource<BaseLayer>,
|
||||||
|
@ -229,24 +248,4 @@ export default class LocationInput extends InputElement<Loc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly matchLayout = new UIEventSource(new LayoutConfig({
|
|
||||||
description: "Matchpoint style",
|
|
||||||
icon: "./assets/svg/crosshair-empty.svg",
|
|
||||||
id: "matchpoint",
|
|
||||||
language: ["en"],
|
|
||||||
layers: [{
|
|
||||||
id: "matchpoint", source: {
|
|
||||||
osmTags: {and: []}
|
|
||||||
},
|
|
||||||
icon: "./assets/svg/crosshair-empty.svg"
|
|
||||||
}],
|
|
||||||
maintainer: "MapComplete",
|
|
||||||
startLat: 0,
|
|
||||||
startLon: 0,
|
|
||||||
startZoom: 0,
|
|
||||||
title: "Location input",
|
|
||||||
version: "0"
|
|
||||||
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -25,6 +25,19 @@ export class RadioButton<T> extends InputElement<T> {
|
||||||
this._dontStyle = options.dontStyle ?? false
|
this._dontStyle = options.dontStyle ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IsValid(t: T): boolean {
|
||||||
|
for (const inputElement of this._elements) {
|
||||||
|
if (inputElement.IsValid(t)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetValue(): UIEventSource<T> {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
protected InnerConstructElement(): HTMLElement {
|
||||||
const elements = this._elements;
|
const elements = this._elements;
|
||||||
const selectFirstAsDefault = this._selectFirstAsDefault;
|
const selectFirstAsDefault = this._selectFirstAsDefault;
|
||||||
|
@ -166,19 +179,6 @@ export class RadioButton<T> extends InputElement<T> {
|
||||||
return form;
|
return form;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsValid(t: T): boolean {
|
|
||||||
for (const inputElement of this._elements) {
|
|
||||||
if (inputElement.IsValid(t)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetValue(): UIEventSource<T> {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public ShowValue(t: T): boolean {
|
public ShowValue(t: T): boolean {
|
||||||
if (t === undefined) {
|
if (t === undefined) {
|
||||||
|
|
|
@ -3,8 +3,8 @@ import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
|
|
||||||
export default class SimpleDatePicker extends InputElement<string> {
|
export default class SimpleDatePicker extends InputElement<string> {
|
||||||
|
|
||||||
|
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||||
private readonly value: UIEventSource<string>
|
private readonly value: UIEventSource<string>
|
||||||
|
|
||||||
private readonly _element: HTMLElement;
|
private readonly _element: HTMLElement;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -30,17 +30,16 @@ export default class SimpleDatePicker extends InputElement<string> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
|
||||||
return this._element
|
|
||||||
}
|
|
||||||
GetValue(): UIEventSource<string> {
|
GetValue(): UIEventSource<string> {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
|
||||||
|
|
||||||
IsValid(t: string): boolean {
|
IsValid(t: string): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected InnerConstructElement(): HTMLElement {
|
||||||
|
return this._element
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -95,10 +95,6 @@ export default class OpeningHoursInput extends InputElement<string> {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
|
||||||
return this._element.ConstructElement()
|
|
||||||
}
|
|
||||||
|
|
||||||
GetValue(): UIEventSource<string> {
|
GetValue(): UIEventSource<string> {
|
||||||
return this._value;
|
return this._value;
|
||||||
}
|
}
|
||||||
|
@ -107,4 +103,8 @@ export default class OpeningHoursInput extends InputElement<string> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected InnerConstructElement(): HTMLElement {
|
||||||
|
return this._element.ConstructElement()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -25,12 +25,11 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
||||||
Translations.t.general.weekdays.abbreviations.sunday
|
Translations.t.general.weekdays.abbreviations.sunday
|
||||||
]
|
]
|
||||||
public readonly IsSelected: UIEventSource<boolean>;
|
public readonly IsSelected: UIEventSource<boolean>;
|
||||||
private readonly source: UIEventSource<OpeningHour[]>;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These html-elements are an overlay over the table columns and act as a host for the ranges in the weekdays
|
These html-elements are an overlay over the table columns and act as a host for the ranges in the weekdays
|
||||||
*/
|
*/
|
||||||
public readonly weekdayElements: HTMLElement[] = Utils.TimesT(7, () => document.createElement("div"))
|
public readonly weekdayElements: HTMLElement[] = Utils.TimesT(7, () => document.createElement("div"))
|
||||||
|
private readonly source: UIEventSource<OpeningHour[]>;
|
||||||
|
|
||||||
constructor(source?: UIEventSource<OpeningHour[]>) {
|
constructor(source?: UIEventSource<OpeningHour[]>) {
|
||||||
super();
|
super();
|
||||||
|
@ -82,8 +81,6 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
||||||
fullColumnSpan.appendChild(ranges.ConstructElement())
|
fullColumnSpan.appendChild(ranges.ConstructElement())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const fullColumnSpanWrapper = document.createElement("div")
|
const fullColumnSpanWrapper = document.createElement("div")
|
||||||
fullColumnSpanWrapper.classList.add("absolute")
|
fullColumnSpanWrapper.classList.add("absolute")
|
||||||
fullColumnSpanWrapper.style.zIndex = "10"
|
fullColumnSpanWrapper.style.zIndex = "10"
|
||||||
|
|
|
@ -30,7 +30,6 @@ export default class EditableTagRendering extends Toggle {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const answerWithEditButton = new Combine([answer,
|
const answerWithEditButton = new Combine([answer,
|
||||||
new Toggle(editButton, undefined, State.state.osmConnection.isLoggedIn)])
|
new Toggle(editButton, undefined, State.state.osmConnection.isLoggedIn)])
|
||||||
.SetClass("flex justify-between w-full")
|
.SetClass("flex justify-between w-full")
|
||||||
|
|
|
@ -138,6 +138,7 @@ export default class TagRenderingQuestion extends Combine {
|
||||||
}
|
}
|
||||||
return Utils.NoNull(configuration.mappings?.map((m, i) => excludeIndex === i ? undefined : m.ifnot))
|
return Utils.NoNull(configuration.mappings?.map((m, i) => excludeIndex === i ? undefined : m.ifnot))
|
||||||
}
|
}
|
||||||
|
|
||||||
const ff = TagRenderingQuestion.GenerateFreeform(configuration, applicableUnit, tagsSource);
|
const ff = TagRenderingQuestion.GenerateFreeform(configuration, applicableUnit, tagsSource);
|
||||||
const hasImages = mappings.filter(mapping => mapping.then.ExtractImages().length > 0).length > 0
|
const hasImages = mappings.filter(mapping => mapping.then.ExtractImages().length > 0).length > 0
|
||||||
|
|
||||||
|
|
|
@ -385,6 +385,7 @@ export default class SpecialVisualizations {
|
||||||
]
|
]
|
||||||
|
|
||||||
static HelpMessage: BaseUIElement = SpecialVisualizations.GenHelpMessage();
|
static HelpMessage: BaseUIElement = SpecialVisualizations.GenHelpMessage();
|
||||||
|
|
||||||
private static GenHelpMessage() {
|
private static GenHelpMessage() {
|
||||||
|
|
||||||
const helpTexts =
|
const helpTexts =
|
||||||
|
|
|
@ -5,11 +5,13 @@ import BaseUIElement from "../BaseUIElement";
|
||||||
|
|
||||||
export default class Translations {
|
export default class Translations {
|
||||||
|
|
||||||
|
static t = AllTranslationAssets.t;
|
||||||
|
private static wtcache = {}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
throw "Translations is static. If you want to intitialize a new translation, use the singular form"
|
throw "Translations is static. If you want to intitialize a new translation, use the singular form"
|
||||||
}
|
}
|
||||||
|
|
||||||
static t = AllTranslationAssets.t;
|
|
||||||
public static W(s: string | BaseUIElement): BaseUIElement {
|
public static W(s: string | BaseUIElement): BaseUIElement {
|
||||||
if (typeof (s) === "string") {
|
if (typeof (s) === "string") {
|
||||||
return new FixedUiElement(s);
|
return new FixedUiElement(s);
|
||||||
|
@ -20,7 +22,6 @@ export default class Translations {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static T(t: string | any, context = undefined): Translation {
|
static T(t: string | any, context = undefined): Translation {
|
||||||
if (t === undefined || t === null) {
|
if (t === undefined || t === null) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -39,7 +40,6 @@ export default class Translations {
|
||||||
return new Translation(t, context);
|
return new Translation(t, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static wtcache = {}
|
|
||||||
public static WT(s: string | Translation): Translation {
|
public static WT(s: string | Translation): Translation {
|
||||||
if (s === undefined || s === null) {
|
if (s === undefined || s === null) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
13
Utils.ts
|
@ -422,6 +422,12 @@ export class Utils {
|
||||||
return bestColor ?? hex;
|
return bestColor ?? hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static setDefaults(options, defaults) {
|
||||||
|
for (let key in defaults) {
|
||||||
|
if (!(key in options)) options[key] = defaults[key];
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
private static tile2long(x, z) {
|
private static tile2long(x, z) {
|
||||||
return (x / Math.pow(2, z) * 360 - 180);
|
return (x / Math.pow(2, z) * 360 - 180);
|
||||||
|
@ -466,12 +472,5 @@ export class Utils {
|
||||||
b: parseInt(hex.substr(5, 2), 16),
|
b: parseInt(hex.substr(5, 2), 16),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static setDefaults(options, defaults) {
|
|
||||||
for (let key in defaults) {
|
|
||||||
if (!(key in options)) options[key] = defaults[key];
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<svg version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
|
<svg version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path class="st0" d="m128 64a64 64 0 0 1-64 64 64 64 0 0 1-64-64 64 64 0 0 1 64-64 64 64 0 0 1 64 64" fill="#529add"/>
|
<path class="st0" d="m128 64a64 64 0 0 1-64 64 64 64 0 0 1-64-64 64 64 0 0 1 64-64 64 64 0 0 1 64 64"
|
||||||
|
fill="#529add"/>
|
||||||
<path d="m31.992 32.08v87.273a64 64 0 0 0 16 6.5293v-93.803z" fill="#666"/>
|
<path d="m31.992 32.08v87.273a64 64 0 0 0 16 6.5293v-93.803z" fill="#666"/>
|
||||||
<path d="m79.992 32.08v93.84a64 64 0 0 0 16-6.582v-87.258z" fill="#666"/>
|
<path d="m79.992 32.08v93.84a64 64 0 0 0 16-6.582v-87.258z" fill="#666"/>
|
||||||
<path d="m23.992 44.08c-4.456 0-8.0429 3.587-8.0429 8.043v31.914c0 4.456 3.5869 8.043 8.0429 8.043h79.914c4.456 0 8.043-3.587 8.043-8.043v-31.914c0-4.456-3.587-8.043-8.043-8.043z" fill-opacity=".2"/>
|
<path d="m23.992 44.08c-4.456 0-8.0429 3.587-8.0429 8.043v31.914c0 4.456 3.5869 8.043 8.0429 8.043h79.914c4.456 0 8.043-3.587 8.043-8.043v-31.914c0-4.456-3.587-8.043-8.043-8.043z"
|
||||||
<path d="m24.036 40.08h79.913c4.456 0 8.0433 3.5873 8.0433 8.0433v31.913c0 4.456-3.5873 8.0433-8.0433 8.0433h-79.913c-4.456 0-8.0433-3.5873-8.0433-8.0433v-31.913c0-4.456 3.5873-8.0433 8.0433-8.0433z" fill="#fff" style="paint-order:normal"/>
|
fill-opacity=".2"/>
|
||||||
<path d="m23.992 40.08c-3.8167 0-6.9867 2.6476-7.7949 6.2129l28.746 41.787h14.143l-32.332-48zm16.619 0 32.332 48h14.143l-32.332-48zm28 0 32.332 48h3.0488c3.6926 0 6.7759-2.4795 7.7051-5.8691l-28.943-42.131zm28 0 15.381 22v-14c0-4.432-3.568-8-8-8zm-80.619 26v14c0 4.432 3.568 8 8 8h7.0938z" fill="#dd2e44" style="paint-order:normal"/>
|
<path d="m24.036 40.08h79.913c4.456 0 8.0433 3.5873 8.0433 8.0433v31.913c0 4.456-3.5873 8.0433-8.0433 8.0433h-79.913c-4.456 0-8.0433-3.5873-8.0433-8.0433v-31.913c0-4.456 3.5873-8.0433 8.0433-8.0433z"
|
||||||
<path d="m24.03 40.08h79.924c4.4531 0 8.038 3.5849 8.038 8.038v31.924c0 4.453-3.5849 8.038-8.038 8.038h-79.924c-4.4531 0-8.038-3.5849-8.038-8.038v-31.924c0-4.453 3.5849-8.038 8.038-8.038z" fill="none" stroke="#555" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" style="paint-order:stroke markers fill"/>
|
fill="#fff" style="paint-order:normal"/>
|
||||||
|
<path d="m23.992 40.08c-3.8167 0-6.9867 2.6476-7.7949 6.2129l28.746 41.787h14.143l-32.332-48zm16.619 0 32.332 48h14.143l-32.332-48zm28 0 32.332 48h3.0488c3.6926 0 6.7759-2.4795 7.7051-5.8691l-28.943-42.131zm28 0 15.381 22v-14c0-4.432-3.568-8-8-8zm-80.619 26v14c0 4.432 3.568 8 8 8h7.0938z"
|
||||||
|
fill="#dd2e44" style="paint-order:normal"/>
|
||||||
|
<path d="m24.03 40.08h79.924c4.4531 0 8.038 3.5849 8.038 8.038v31.924c0 4.453-3.5849 8.038-8.038 8.038h-79.924c-4.4531 0-8.038-3.5849-8.038-8.038v-31.924c0-4.453 3.5849-8.038 8.038-8.038z"
|
||||||
|
fill="none" stroke="#555" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"
|
||||||
|
style="paint-order:stroke markers fill"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -1,16 +1,21 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<svg version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
|
<svg version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="m128 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64 35.346 0 64 28.654 64 64" fill="#9bbe55" stroke-width=".2"/>
|
<path d="m128 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64 35.346 0 64 28.654 64 64"
|
||||||
<path d="m20.021 39.998c-2.2408 0-4.0449 1.8041-4.0449 4.0449v15.91c0 2.2408 1.8042 4.045 4.0449 4.045h11.955v8h-16v8h16v16h8v-16h48v16h8v-16h16v-8h-16v-8h11.955c2.2408 0 4.0449-1.8042 4.0449-4.045v-15.91c0-2.2408-1.8041-4.0449-4.0449-4.0449zm19.955 24h48v8h-48z" fill-opacity=".2" style="paint-order:normal"/>
|
fill="#9bbe55" stroke-width=".2"/>
|
||||||
|
<path d="m20.021 39.998c-2.2408 0-4.0449 1.8041-4.0449 4.0449v15.91c0 2.2408 1.8042 4.045 4.0449 4.045h11.955v8h-16v8h16v16h8v-16h48v16h8v-16h16v-8h-16v-8h11.955c2.2408 0 4.0449-1.8042 4.0449-4.045v-15.91c0-2.2408-1.8041-4.0449-4.0449-4.0449zm19.955 24h48v8h-48z"
|
||||||
|
fill-opacity=".2" style="paint-order:normal"/>
|
||||||
<g transform="translate(717 144)">
|
<g transform="translate(717 144)">
|
||||||
<path d="m-685.02-84.002h8v32h-8z" fill="#666" style="paint-order:normal"/>
|
<path d="m-685.02-84.002h8v32h-8z" fill="#666" style="paint-order:normal"/>
|
||||||
<path d="m-629.02-84.002h8v32h-8z" fill="#666" style="paint-order:normal"/>
|
<path d="m-629.02-84.002h8v32h-8z" fill="#666" style="paint-order:normal"/>
|
||||||
<path d="m-696.98-108h87.911c2.2408 0 4.0447 1.804 4.0447 4.0447v15.911c0 2.2408-1.804 4.0447-4.0447 4.0447h-87.911c-2.2408 0-4.0447-1.8039-4.0447-4.0447v-15.911c0-2.2408 1.804-4.0447 4.0447-4.0447z" fill="#ae8862" style="paint-order:normal"/>
|
<path d="m-696.98-108h87.911c2.2408 0 4.0447 1.804 4.0447 4.0447v15.911c0 2.2408-1.804 4.0447-4.0447 4.0447h-87.911c-2.2408 0-4.0447-1.8039-4.0447-4.0447v-15.911c0-2.2408 1.804-4.0447 4.0447-4.0447z"
|
||||||
|
fill="#ae8862" style="paint-order:normal"/>
|
||||||
<path d="m-693.02-104h80v4h-80z" fill="#896847" style="paint-order:normal"/>
|
<path d="m-693.02-104h80v4h-80z" fill="#896847" style="paint-order:normal"/>
|
||||||
<path d="m-701.02-72.002h96v4h-96z" fill="#896847" style="paint-order:normal"/>
|
<path d="m-701.02-72.002h96v4h-96z" fill="#896847" style="paint-order:normal"/>
|
||||||
<path d="m-693.02-92.002h80v4h-80z" fill="#896847" style="paint-order:normal"/>
|
<path d="m-693.02-92.002h80v4h-80z" fill="#896847" style="paint-order:normal"/>
|
||||||
<path d="m-677.02-96.002a4 4 0 0 1-4 4 4 4 0 0 1-4-4 4 4 0 0 1 4-4 4 4 0 0 1 4 4" fill="#666" style="paint-order:normal"/>
|
<path d="m-677.02-96.002a4 4 0 0 1-4 4 4 4 0 0 1-4-4 4 4 0 0 1 4-4 4 4 0 0 1 4 4" fill="#666"
|
||||||
<path d="m-621.02-96.002a4 4 0 0 1-4 4 4 4 0 0 1-4-4 4 4 0 0 1 4-4 4 4 0 0 1 4 4" fill="#666" style="paint-order:normal"/>
|
style="paint-order:normal"/>
|
||||||
|
<path d="m-621.02-96.002a4 4 0 0 1-4 4 4 4 0 0 1-4-4 4 4 0 0 1 4-4 4 4 0 0 1 4 4" fill="#666"
|
||||||
|
style="paint-order:normal"/>
|
||||||
<path d="m-701.02-76.002h96v4h-96z" fill="#ae8862" style="paint-order:normal"/>
|
<path d="m-701.02-76.002h96v4h-96z" fill="#ae8862" style="paint-order:normal"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.7 KiB |
|
@ -3,10 +3,9 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg4"
|
id="svg4"
|
||||||
sodipodi:docname="bicycle_library.svg"
|
sodipodi:docname="bicycle_library.svg"
|
||||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
|
@ -5,10 +5,9 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="25.929167mm"
|
width="25.929167mm"
|
||||||
height="30.958698mm"
|
height="30.958698mm"
|
||||||
viewBox="0 0 25.929167 30.958698"
|
viewBox="0 0 25.929167 30.958698"
|
||||||
|
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 8.3 KiB |
|
@ -5,10 +5,9 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="51.841461mm"
|
width="51.841461mm"
|
||||||
height="36.68618mm"
|
height="36.68618mm"
|
||||||
viewBox="0 0 51.841461 36.68618"
|
viewBox="0 0 51.841461 36.68618"
|
||||||
|
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 6.2 KiB |
|
@ -1,16 +1,23 @@
|
||||||
<svg width="98" height="124" viewBox="0 0 98 124" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="98" height="124" viewBox="0 0 98 124" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M55.0445 114.094C53.2614 117.981 47.7386 117.981 45.9555 114.094L15.2124 47.085C13.6928 43.7729 16.1129 40 19.7569 40L81.2431 40C84.8871 40 87.3072 43.7729 85.7876 47.085L55.0445 114.094Z" fill="#694E2D"/>
|
<path d="M55.0445 114.094C53.2614 117.981 47.7386 117.981 45.9555 114.094L15.2124 47.085C13.6928 43.7729 16.1129 40 19.7569 40L81.2431 40C84.8871 40 87.3072 43.7729 85.7876 47.085L55.0445 114.094Z"
|
||||||
|
fill="#694E2D"/>
|
||||||
<circle cx="49" cy="49" r="49" fill="#694E2D"/>
|
<circle cx="49" cy="49" r="49" fill="#694E2D"/>
|
||||||
<path d="M67.5 76.3395H62.0436C65.206 74.0913 67.7862 70.9283 69.476 67.1884H74.8929C79.4101 67.1884 83.0851 63.1243 83.0851 58.1289C83.0851 53.1335 79.4101 49.0695 74.8929 49.0695H71.6699V44.494C71.6699 43.483 70.9288 42.6637 70.0149 42.6637H25.655C24.7411 42.6637 24 43.4829 24 44.494V56.9003C24 65.0531 27.8426 72.2276 33.6265 76.3396H27.3352C26.4212 76.3395 25.6551 77.1588 25.6551 78.1698C25.6551 79.1807 26.4212 80 27.3351 80H44.8888H50.7817H67.5C68.4139 80 69 79.0111 69 78C69 76.9889 68.4139 76.3395 67.5 76.3395ZM74.8931 52.7298C77.5852 52.7298 79.7754 55.1519 79.7754 58.1289C79.7754 61.106 77.5852 63.5281 74.8931 63.5281H70.7897C71.3601 61.4274 71.6702 59.2033 71.6702 56.9001V52.7298H74.8931ZM37.1501 22.8301C39.7848 19.9164 39.7848 15.1754 37.1501 12.2614L37.0263 12.1245C36.3799 11.41 36.3799 10.2511 37.0263 9.53653C37.6727 8.82167 38.7203 8.82167 39.3668 9.53653L39.4906 9.67342C43.4157 14.014 43.4157 21.0775 39.4906 25.4183C38.2143 26.8298 37.5116 28.7061 37.5116 30.7025C37.5116 32.6989 38.2146 34.5752 39.4906 35.987C40.137 36.7015 40.137 37.8604 39.4906 38.575C39.1675 38.9327 38.7438 39.1113 38.3202 39.1113C37.8965 39.1113 37.4732 38.9327 37.1497 38.575C35.2481 36.4725 34.2011 33.6766 34.2011 30.7025C34.2015 27.7285 35.2487 24.9326 37.1501 22.8301ZM46.7302 22.8301C48.0065 21.4186 48.7096 19.5419 48.7096 17.5455C48.7096 15.5492 48.0065 13.6729 46.7302 12.261L46.6064 12.1241C45.96 11.4096 45.96 10.2507 46.6064 9.53614C47.2528 8.82129 48.3004 8.82129 48.9469 9.53614L49.0707 9.67303C50.9723 11.7755 52.0197 14.5718 52.0197 17.5455C52.0197 20.5193 50.9724 23.3154 49.0707 25.4181C47.7944 26.8295 47.0917 28.7058 47.0917 30.7022C47.0917 32.6986 47.7947 34.5749 49.0707 35.9868C49.7172 36.7013 49.7172 37.8601 49.0707 38.5747C48.7476 38.9324 48.324 39.111 47.9003 39.111C47.4766 39.111 47.0533 38.9324 46.7298 38.5747C44.8283 36.4723 43.7812 33.6763 43.7812 30.7022C43.7812 27.7285 44.8286 24.9326 46.7302 22.8301ZM56.3104 22.8297C58.9448 19.9164 58.9448 15.1754 56.3104 12.2614L56.1866 12.1245C55.5402 11.41 55.5402 10.2511 56.1866 9.53653C56.833 8.82167 57.8806 8.82167 58.5272 9.53653L58.651 9.67342C62.576 14.014 62.576 21.0775 58.651 25.4183C57.3746 26.8298 56.6715 28.7061 56.6715 30.7025C56.6715 32.6989 57.3746 34.5752 58.6506 35.9867C59.297 36.7015 59.297 37.8604 58.6506 38.575C58.3275 38.9327 57.9038 39.1113 57.4802 39.1113C57.0565 39.1113 56.6331 38.9327 56.3101 38.5754C54.4085 36.4725 53.3611 33.6766 53.3611 30.7026C53.3615 27.7285 54.4087 24.9326 56.3104 22.8297Z" fill="white"/>
|
<path d="M67.5 76.3395H62.0436C65.206 74.0913 67.7862 70.9283 69.476 67.1884H74.8929C79.4101 67.1884 83.0851 63.1243 83.0851 58.1289C83.0851 53.1335 79.4101 49.0695 74.8929 49.0695H71.6699V44.494C71.6699 43.483 70.9288 42.6637 70.0149 42.6637H25.655C24.7411 42.6637 24 43.4829 24 44.494V56.9003C24 65.0531 27.8426 72.2276 33.6265 76.3396H27.3352C26.4212 76.3395 25.6551 77.1588 25.6551 78.1698C25.6551 79.1807 26.4212 80 27.3351 80H44.8888H50.7817H67.5C68.4139 80 69 79.0111 69 78C69 76.9889 68.4139 76.3395 67.5 76.3395ZM74.8931 52.7298C77.5852 52.7298 79.7754 55.1519 79.7754 58.1289C79.7754 61.106 77.5852 63.5281 74.8931 63.5281H70.7897C71.3601 61.4274 71.6702 59.2033 71.6702 56.9001V52.7298H74.8931ZM37.1501 22.8301C39.7848 19.9164 39.7848 15.1754 37.1501 12.2614L37.0263 12.1245C36.3799 11.41 36.3799 10.2511 37.0263 9.53653C37.6727 8.82167 38.7203 8.82167 39.3668 9.53653L39.4906 9.67342C43.4157 14.014 43.4157 21.0775 39.4906 25.4183C38.2143 26.8298 37.5116 28.7061 37.5116 30.7025C37.5116 32.6989 38.2146 34.5752 39.4906 35.987C40.137 36.7015 40.137 37.8604 39.4906 38.575C39.1675 38.9327 38.7438 39.1113 38.3202 39.1113C37.8965 39.1113 37.4732 38.9327 37.1497 38.575C35.2481 36.4725 34.2011 33.6766 34.2011 30.7025C34.2015 27.7285 35.2487 24.9326 37.1501 22.8301ZM46.7302 22.8301C48.0065 21.4186 48.7096 19.5419 48.7096 17.5455C48.7096 15.5492 48.0065 13.6729 46.7302 12.261L46.6064 12.1241C45.96 11.4096 45.96 10.2507 46.6064 9.53614C47.2528 8.82129 48.3004 8.82129 48.9469 9.53614L49.0707 9.67303C50.9723 11.7755 52.0197 14.5718 52.0197 17.5455C52.0197 20.5193 50.9724 23.3154 49.0707 25.4181C47.7944 26.8295 47.0917 28.7058 47.0917 30.7022C47.0917 32.6986 47.7947 34.5749 49.0707 35.9868C49.7172 36.7013 49.7172 37.8601 49.0707 38.5747C48.7476 38.9324 48.324 39.111 47.9003 39.111C47.4766 39.111 47.0533 38.9324 46.7298 38.5747C44.8283 36.4723 43.7812 33.6763 43.7812 30.7022C43.7812 27.7285 44.8286 24.9326 46.7302 22.8301ZM56.3104 22.8297C58.9448 19.9164 58.9448 15.1754 56.3104 12.2614L56.1866 12.1245C55.5402 11.41 55.5402 10.2511 56.1866 9.53653C56.833 8.82167 57.8806 8.82167 58.5272 9.53653L58.651 9.67342C62.576 14.014 62.576 21.0775 58.651 25.4183C57.3746 26.8298 56.6715 28.7061 56.6715 30.7025C56.6715 32.6989 57.3746 34.5752 58.6506 35.9867C59.297 36.7015 59.297 37.8604 58.6506 38.575C58.3275 38.9327 57.9038 39.1113 57.4802 39.1113C57.0565 39.1113 56.6331 38.9327 56.3101 38.5754C54.4085 36.4725 53.3611 33.6766 53.3611 30.7026C53.3615 27.7285 54.4087 24.9326 56.3104 22.8297Z"
|
||||||
|
fill="white"/>
|
||||||
<g filter="url(#filter0_d)">
|
<g filter="url(#filter0_d)">
|
||||||
<path d="M45.4541 63.4281H35.5495L40.952 51.3942H46.3545H50.2563H54.4583M54.4583 51.3942L52.9576 48H55.0586H57.1595M54.4583 51.3942L55.0586 52.937L56.2591 55.4055L59.5607 63.4281M54.4583 51.3942L51.607 56.0226L49.8962 58.7996M48.7556 60.651L49.8962 58.7996M43.053 54.7883L46.0544 61.5767L40.0516 48L41.8524 51.7027M47.8552 62.1938L49.8962 58.7996" stroke="#694E2D" stroke-width="2"/>
|
<path d="M45.4541 63.4281H35.5495L40.952 51.3942H46.3545H50.2563H54.4583M54.4583 51.3942L52.9576 48H55.0586H57.1595M54.4583 51.3942L55.0586 52.937L56.2591 55.4055L59.5607 63.4281M54.4583 51.3942L51.607 56.0226L49.8962 58.7996M48.7556 60.651L49.8962 58.7996M43.053 54.7883L46.0544 61.5767L40.0516 48L41.8524 51.7027M47.8552 62.1938L49.8962 58.7996"
|
||||||
<path d="M48.5098 62.9031C48.5098 63.833 47.78 64.563 46.9088 64.563C46.0375 64.563 45.3078 63.833 45.3078 62.9031C45.3078 61.9732 46.0375 61.2432 46.9088 61.2432C47.78 61.2432 48.5098 61.9732 48.5098 62.9031Z" stroke="#694E2D"/>
|
stroke="#694E2D" stroke-width="2"/>
|
||||||
<path d="M42.007 62.286C42.007 66.0203 39.0694 69 35.5035 69C31.9376 69 29 66.0203 29 62.286C29 58.5517 31.9376 55.572 35.5035 55.572C39.0694 55.572 42.007 58.5517 42.007 62.286Z" stroke="#694E2D" stroke-width="2"/>
|
<path d="M48.5098 62.9031C48.5098 63.833 47.78 64.563 46.9088 64.563C46.0375 64.563 45.3078 63.833 45.3078 62.9031C45.3078 61.9732 46.0375 61.2432 46.9088 61.2432C47.78 61.2432 48.5098 61.9732 48.5098 62.9031Z"
|
||||||
|
stroke="#694E2D"/>
|
||||||
|
<path d="M42.007 62.286C42.007 66.0203 39.0694 69 35.5035 69C31.9376 69 29 66.0203 29 62.286C29 58.5517 31.9376 55.572 35.5035 55.572C39.0694 55.572 42.007 58.5517 42.007 62.286Z"
|
||||||
|
stroke="#694E2D" stroke-width="2"/>
|
||||||
<ellipse cx="63.1725" cy="56.7207" rx="0.217504" ry="0.223607" fill="black" fill-opacity="0.49"/>
|
<ellipse cx="63.1725" cy="56.7207" rx="0.217504" ry="0.223607" fill="black" fill-opacity="0.49"/>
|
||||||
</g>
|
</g>
|
||||||
<path d="M66.007 62.714C66.007 66.4483 63.0694 69.4281 59.5035 69.4281C55.9376 69.4281 53 66.4483 53 62.714C53 58.9797 55.9376 56 59.5035 56C63.0694 56 66.007 58.9797 66.007 62.714Z" stroke="#694E2D" stroke-width="2"/>
|
<path d="M66.007 62.714C66.007 66.4483 63.0694 69.4281 59.5035 69.4281C55.9376 69.4281 53 66.4483 53 62.714C53 58.9797 55.9376 56 59.5035 56C63.0694 56 66.007 58.9797 66.007 62.714Z"
|
||||||
|
stroke="#694E2D" stroke-width="2"/>
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="filter0_d" x="24" y="47" width="43.39" height="31" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter0_d" x="24" y="47" width="43.39" height="31" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.8 KiB |
|
@ -3,10 +3,9 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="98"
|
width="98"
|
||||||
height="124"
|
height="124"
|
||||||
viewBox="0 0 98 124"
|
viewBox="0 0 98 124"
|
||||||
|
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 10 KiB |
|
@ -3,10 +3,9 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="98"
|
width="98"
|
||||||
height="98"
|
height="98"
|
||||||
viewBox="0 0 98 98"
|
viewBox="0 0 98 98"
|
||||||
|
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 10 KiB |
|
@ -3,7 +3,6 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
id="svg27"
|
id="svg27"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
|
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 5.2 KiB |
|
@ -5,10 +5,9 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
x="0px"
|
x="0px"
|
||||||
y="0px"
|
y="0px"
|
||||||
|
@ -20,8 +19,10 @@
|
||||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
|
||||||
id="metadata19"><rdf:RDF><cc:Work
|
id="metadata19"><rdf:RDF><cc:Work
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata>
|
||||||
id="defs17" /><sodipodi:namedview
|
<defs
|
||||||
|
id="defs17"/>
|
||||||
|
<sodipodi:namedview
|
||||||
pagecolor="#ffffff"
|
pagecolor="#ffffff"
|
||||||
bordercolor="#666666"
|
bordercolor="#666666"
|
||||||
borderopacity="1"
|
borderopacity="1"
|
||||||
|
@ -72,7 +73,8 @@
|
||||||
d="M 150,20 V 285"
|
d="M 150,20 V 285"
|
||||||
id="path828"
|
id="path828"
|
||||||
inkscape:connector-curvature="0"
|
inkscape:connector-curvature="0"
|
||||||
sodipodi:nodetypes="cc" /><circle
|
sodipodi:nodetypes="cc"/>
|
||||||
|
<circle
|
||||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:15;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:15;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
id="path830"
|
id="path830"
|
||||||
cx="150"
|
cx="150"
|
||||||
|
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.1 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||||
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.st0{fill:#0181C2;}
|
.st0{fill:#0181C2;}
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -1,11 +1,14 @@
|
||||||
<svg width="97" height="123" viewBox="0 0 97 123" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="97" height="123" viewBox="0 0 97 123" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M52.1412 111.419C50.4633 115.605 44.5366 115.605 42.8588 111.419L24.7014 66.1099C23.385 62.8252 25.8039 59.25 29.3426 59.25L65.6574 59.25C69.1962 59.25 71.615 62.8252 70.2986 66.11L52.1412 111.419Z" fill="#5675DF"/>
|
<path d="M52.1412 111.419C50.4633 115.605 44.5366 115.605 42.8588 111.419L24.7014 66.1099C23.385 62.8252 25.8039 59.25 29.3426 59.25L65.6574 59.25C69.1962 59.25 71.615 62.8252 70.2986 66.11L52.1412 111.419Z"
|
||||||
|
fill="#5675DF"/>
|
||||||
<ellipse cx="48.5" cy="47.5" rx="48.5" ry="47.5" fill="#5675DF"/>
|
<ellipse cx="48.5" cy="47.5" rx="48.5" ry="47.5" fill="#5675DF"/>
|
||||||
<g filter="url(#filter0_d)">
|
<g filter="url(#filter0_d)">
|
||||||
<path d="M42.2812 53.1875V71H36.2812V25.5H53.0625C58.0417 25.5 61.9375 26.7708 64.75 29.3125C67.5833 31.8542 69 35.2188 69 39.4062C69 43.8229 67.6146 47.2292 64.8438 49.625C62.0938 52 58.1458 53.1875 53 53.1875H42.2812ZM42.2812 48.2812H53.0625C56.2708 48.2812 58.7292 47.5312 60.4375 46.0312C62.1458 44.5104 63 42.3229 63 39.4688C63 36.7604 62.1458 34.5938 60.4375 32.9688C58.7292 31.3438 56.3854 30.5 53.4062 30.4375H42.2812V48.2812Z" fill="white"/>
|
<path d="M42.2812 53.1875V71H36.2812V25.5H53.0625C58.0417 25.5 61.9375 26.7708 64.75 29.3125C67.5833 31.8542 69 35.2188 69 39.4062C69 43.8229 67.6146 47.2292 64.8438 49.625C62.0938 52 58.1458 53.1875 53 53.1875H42.2812ZM42.2812 48.2812H53.0625C56.2708 48.2812 58.7292 47.5312 60.4375 46.0312C62.1458 44.5104 63 42.3229 63 39.4688C63 36.7604 62.1458 34.5938 60.4375 32.9688C58.7292 31.3438 56.3854 30.5 53.4062 30.4375H42.2812V48.2812Z"
|
||||||
|
fill="white"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="filter0_d" x="32.2812" y="25.5" width="40.7188" height="53.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter0_d" x="32.2812" y="25.5" width="40.7188" height="53.5" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -1,11 +1,13 @@
|
||||||
<svg width="97" height="123" viewBox="0 0 97 123" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="97" height="123" viewBox="0 0 97 123" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M52.1412 111.419C50.4633 115.605 44.5366 115.605 42.8588 111.419L24.7014 66.1099C23.385 62.8252 25.8039 59.25 29.3426 59.25L65.6574 59.25C69.1962 59.25 71.615 62.8252 70.2986 66.11L52.1412 111.419Z" fill="#5675DF"/>
|
<path d="M52.1412 111.419C50.4633 115.605 44.5366 115.605 42.8588 111.419L24.7014 66.1099C23.385 62.8252 25.8039 59.25 29.3426 59.25L65.6574 59.25C69.1962 59.25 71.615 62.8252 70.2986 66.11L52.1412 111.419Z"
|
||||||
|
fill="#5675DF"/>
|
||||||
<ellipse cx="48.5" cy="47.5" rx="48.5" ry="47.5" fill="#5675DF"/>
|
<ellipse cx="48.5" cy="47.5" rx="48.5" ry="47.5" fill="#5675DF"/>
|
||||||
<g filter="url(#filter0_d)">
|
<g filter="url(#filter0_d)">
|
||||||
<circle cx="39" cy="66" r="2" stroke="white" stroke-width="2"/>
|
<circle cx="39" cy="66" r="2" stroke="white" stroke-width="2"/>
|
||||||
</g>
|
</g>
|
||||||
<g filter="url(#filter1_d)">
|
<g filter="url(#filter1_d)">
|
||||||
<path d="M37.375 67H25L31.75 51.4H38.5H43.375H48.625M48.625 51.4L46.75 47H49.375H52M48.625 51.4L49.375 53.4L50.875 56.6L55 67M48.625 51.4L45.0625 57.4L42.925 61M41.5 63.4L42.925 61M34.375 55.8L38.125 64.6L30.625 47L32.875 51.8M40.375 65.4L42.925 61" stroke="white" stroke-width="2"/>
|
<path d="M37.375 67H25L31.75 51.4H38.5H43.375H48.625M48.625 51.4L46.75 47H49.375H52M48.625 51.4L49.375 53.4L50.875 56.6L55 67M48.625 51.4L45.0625 57.4L42.925 61M41.5 63.4L42.925 61M34.375 55.8L38.125 64.6L30.625 47L32.875 51.8M40.375 65.4L42.925 61"
|
||||||
|
stroke="white" stroke-width="2"/>
|
||||||
</g>
|
</g>
|
||||||
<g filter="url(#filter2_d)">
|
<g filter="url(#filter2_d)">
|
||||||
<circle cx="23" cy="67" r="9" stroke="white" stroke-width="2"/>
|
<circle cx="23" cy="67" r="9" stroke="white" stroke-width="2"/>
|
||||||
|
@ -13,7 +15,8 @@
|
||||||
<g filter="url(#filter3_d)">
|
<g filter="url(#filter3_d)">
|
||||||
<circle cx="55" cy="67" r="9" stroke="white" stroke-width="2"/>
|
<circle cx="55" cy="67" r="9" stroke="white" stroke-width="2"/>
|
||||||
</g>
|
</g>
|
||||||
<path d="M61 77V59.0476V55.9524L62.4814 54.4851C64.4301 52.5549 67.5699 52.5549 69.5186 54.4851L71 55.9524V58.4286V77" stroke="white" stroke-width="2"/>
|
<path d="M61 77V59.0476V55.9524L62.4814 54.4851C64.4301 52.5549 67.5699 52.5549 69.5186 54.4851L71 55.9524V58.4286V77"
|
||||||
|
stroke="white" stroke-width="2"/>
|
||||||
<line x1="66" y1="53" x2="66" y2="16" stroke="white" stroke-width="2"/>
|
<line x1="66" y1="53" x2="66" y2="16" stroke="white" stroke-width="2"/>
|
||||||
<g filter="url(#filter4_d)">
|
<g filter="url(#filter4_d)">
|
||||||
<circle cx="66" cy="23" r="13" fill="white"/>
|
<circle cx="66" cy="23" r="13" fill="white"/>
|
||||||
|
@ -22,11 +25,13 @@
|
||||||
<circle cx="66" cy="23" r="11" fill="#496DEB"/>
|
<circle cx="66" cy="23" r="11" fill="#496DEB"/>
|
||||||
</g>
|
</g>
|
||||||
<g filter="url(#filter6_d)">
|
<g filter="url(#filter6_d)">
|
||||||
<path d="M64.1729 24.9902V30H62.4854V17.2031H67.2051C68.6055 17.2031 69.7012 17.5605 70.4922 18.2754C71.2891 18.9902 71.6875 19.9365 71.6875 21.1143C71.6875 22.3564 71.2979 23.3145 70.5186 23.9883C69.7451 24.6562 68.6348 24.9902 67.1875 24.9902H64.1729ZM64.1729 23.6104H67.2051C68.1074 23.6104 68.7988 23.3994 69.2793 22.9775C69.7598 22.5498 70 21.9346 70 21.1318C70 20.3701 69.7598 19.7607 69.2793 19.3037C68.7988 18.8467 68.1396 18.6094 67.3018 18.5918H64.1729V23.6104Z" fill="white"/>
|
<path d="M64.1729 24.9902V30H62.4854V17.2031H67.2051C68.6055 17.2031 69.7012 17.5605 70.4922 18.2754C71.2891 18.9902 71.6875 19.9365 71.6875 21.1143C71.6875 22.3564 71.2979 23.3145 70.5186 23.9883C69.7451 24.6562 68.6348 24.9902 67.1875 24.9902H64.1729ZM64.1729 23.6104H67.2051C68.1074 23.6104 68.7988 23.3994 69.2793 22.9775C69.7598 22.5498 70 21.9346 70 21.1318C70 20.3701 69.7598 19.7607 69.2793 19.3037C68.7988 18.8467 68.1396 18.6094 67.3018 18.5918H64.1729V23.6104Z"
|
||||||
|
fill="white"/>
|
||||||
</g>
|
</g>
|
||||||
<line x1="43" y1="78" x2="72" y2="78" stroke="white" stroke-width="2"/>
|
<line x1="43" y1="78" x2="72" y2="78" stroke="white" stroke-width="2"/>
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="filter0_d" x="32" y="63" width="14" height="14" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter0_d" x="32" y="63" width="14" height="14" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -35,7 +40,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter1_d" x="19.4777" y="46" width="40.4518" height="30" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter1_d" x="19.4777" y="46" width="40.4518" height="30" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -44,7 +50,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter2_d" x="9" y="57" width="28" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter2_d" x="9" y="57" width="28" height="28" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -53,7 +60,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter3_d" x="41" y="57" width="28" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter3_d" x="41" y="57" width="28" height="28" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -62,7 +70,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter4_d" x="49" y="10" width="34" height="34" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter4_d" x="49" y="10" width="34" height="34" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -71,7 +80,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter5_d" x="51" y="12" width="30" height="30" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter5_d" x="51" y="12" width="30" height="30" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -80,7 +90,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter6_d" x="58.4854" y="17.2031" width="17.2021" height="20.7969" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter6_d" x="58.4854" y="17.2031" width="17.2021" height="20.7969" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
|
Before Width: | Height: | Size: 6 KiB After Width: | Height: | Size: 7 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||||
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.st0{fill:#0181C2;}
|
.st0{fill:#0181C2;}
|
||||||
|
@ -99,7 +99,8 @@
|
||||||
C-1180.6,246.5-1181.2,246-1181.5,245.3z"/>
|
C-1180.6,246.5-1181.2,246-1181.5,245.3z"/>
|
||||||
<path class="st5" d="M-1190.8,240.4c-1,0.6-2.2,0.6-3.3,0c-0.3-0.2-0.6-0.4-0.9-0.6c0.4-0.5,0.8-0.9,1.2-1.4
|
<path class="st5" d="M-1190.8,240.4c-1,0.6-2.2,0.6-3.3,0c-0.3-0.2-0.6-0.4-0.9-0.6c0.4-0.5,0.8-0.9,1.2-1.4
|
||||||
C-1192.8,239.2-1191.8,239.8-1190.8,240.4z"/>
|
C-1192.8,239.2-1191.8,239.8-1190.8,240.4z"/>
|
||||||
<path class="st5" d="M-1167.7,249.2c-3.2-0.3-6.3-0.9-9.5-1.7c0-0.2,0.1-0.3,0.1-0.5C-1173.8,248.2-1170.6,248.9-1167.7,249.2z"
|
<path class="st5"
|
||||||
|
d="M-1167.7,249.2c-3.2-0.3-6.3-0.9-9.5-1.7c0-0.2,0.1-0.3,0.1-0.5C-1173.8,248.2-1170.6,248.9-1167.7,249.2z"
|
||||||
/>
|
/>
|
||||||
<path class="st5" d="M-1190.7,234.8c1.5,0.9,2,2.9,1.1,4.5c-0.3,0.5-0.7,0.9-1.2,1.1c-1-0.6-2-1.3-3-2
|
<path class="st5" d="M-1190.7,234.8c1.5,0.9,2,2.9,1.1,4.5c-0.3,0.5-0.7,0.9-1.2,1.1c-1-0.6-2-1.3-3-2
|
||||||
C-1192.8,237.2-1191.8,236-1190.7,234.8z"/>
|
C-1192.8,237.2-1191.8,236-1190.7,234.8z"/>
|
||||||
|
@ -140,7 +141,8 @@
|
||||||
L-1115.1,219.6z"/>
|
L-1115.1,219.6z"/>
|
||||||
<path class="st6" d="M-1178.1,219.6h-12c1.8,0,3.2,1.4,3.2,3.2v14.8h12v-14.8C-1174.9,221-1176.3,219.6-1178.1,219.6
|
<path class="st6" d="M-1178.1,219.6h-12c1.8,0,3.2,1.4,3.2,3.2v14.8h12v-14.8C-1174.9,221-1176.3,219.6-1178.1,219.6
|
||||||
L-1178.1,219.6z"/>
|
L-1178.1,219.6z"/>
|
||||||
<path class="st6" d="M-1038.4,110.7h-183.4c-4.4,0-8-3.6-8-8.1v-9.9h199.5v9.9C-1030.4,107.1-1034,110.7-1038.4,110.7z"/>
|
<path class="st6"
|
||||||
|
d="M-1038.4,110.7h-183.4c-4.4,0-8-3.6-8-8.1v-9.9h199.5v9.9C-1030.4,107.1-1034,110.7-1038.4,110.7z"/>
|
||||||
</g>
|
</g>
|
||||||
<path class="st6" d="M-1042.4,92.8v9.9c0,4.5-3.6,8.1-8,8.1h12c4.4,0,8-3.6,8-8.1v-9.9L-1042.4,92.8z"/>
|
<path class="st6" d="M-1042.4,92.8v9.9c0,4.5-3.6,8.1-8,8.1h12c4.4,0,8-3.6,8-8.1v-9.9L-1042.4,92.8z"/>
|
||||||
<path class="st6" d="M-1038.4,231.6h-183.4c-4.4,0-8,3.6-8,8.1v7.9c0,1.1,0.9,2,2,2h195.5c1.1,0,2-0.9,2-2v-7.9
|
<path class="st6" d="M-1038.4,231.6h-183.4c-4.4,0-8,3.6-8,8.1v7.9c0,1.1,0.9,2,2,2h195.5c1.1,0,2-0.9,2-2v-7.9
|
||||||
|
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 22 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||||
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.st0{fill:#0181C2;}
|
.st0{fill:#0181C2;}
|
||||||
|
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||||
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.st0{fill:#0181C2;}
|
.st0{fill:#0181C2;}
|
||||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||||
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.st0{fill:#0181C2;}
|
.st0{fill:#0181C2;}
|
||||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||||
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
viewBox="0 0 300 300" style="enable-background:new 0 0 300 300;" xml:space="preserve">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.st0{fill:#0181C2;}
|
.st0{fill:#0181C2;}
|
||||||
|
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
@ -3,10 +3,9 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="98"
|
width="98"
|
||||||
height="98"
|
height="98"
|
||||||
viewBox="0 0 98 98"
|
viewBox="0 0 98 98"
|
||||||
|
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
@ -1,8 +1,10 @@
|
||||||
<svg width="104" height="123" viewBox="0 0 104 123" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="104" height="123" viewBox="0 0 104 123" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M60.0445 113.094C58.2614 116.981 52.7386 116.981 50.9555 113.094L20.2124 46.085C18.6928 42.7729 21.1129 39 24.7569 39L86.2431 39C89.8871 39 92.3072 42.7729 90.7876 46.085L60.0445 113.094Z" fill="#171615"/>
|
<path d="M60.0445 113.094C58.2614 116.981 52.7386 116.981 50.9555 113.094L20.2124 46.085C18.6928 42.7729 21.1129 39 24.7569 39L86.2431 39C89.8871 39 92.3072 42.7729 90.7876 46.085L60.0445 113.094Z"
|
||||||
|
fill="#171615"/>
|
||||||
<circle cx="55" cy="49" r="49" fill="#171615"/>
|
<circle cx="55" cy="49" r="49" fill="#171615"/>
|
||||||
<g clip-path="url(#clip0)" filter="url(#filter0_d)">
|
<g clip-path="url(#clip0)" filter="url(#filter0_d)">
|
||||||
<path d="M59.2519 79.0738C60.5075 79.0738 61.7117 78.5751 62.5995 77.6872C63.4874 76.7994 63.9862 76.2998 63.9862 75.0442C63.9862 73.7886 63.4874 73.3516 62.5996 72.4637C61.7117 71.5759 60.5075 71.0771 59.2519 71.0771L53.3555 71.0815V69.4784L54.8823 69.4739C56.1376 69.4729 57.3412 68.9738 58.2288 68.0862C59.1164 67.1986 60.2656 66.2038 60.2666 64.9485L60.3118 33.5699C60.3119 33.2223 60.3118 32.5699 60.401 32.2506C60.5341 31.9295 60.547 31.5699 60.725 31.3919C60.9708 31.1462 61.1038 30.9511 61.4249 30.8181C61.746 30.6852 62.6524 30.5698 63 30.5699C63.3475 30.5699 63.9907 30.5669 64.3118 30.7C64.6329 30.833 64.9889 31.2478 65.3118 31.5699C65.5575 31.8156 65.5753 31.9295 65.7083 32.2506C65.8412 32.5717 65.9096 32.9158 65.9096 33.2634L65.9169 59.1411L64.8659 59.1411C64.5926 59.1418 64.3306 59.2497 64.136 59.4415C63.9414 59.6334 63.8298 59.8938 63.8251 60.167L63.7587 64.9175C63.7491 65.609 63.8771 66.2955 64.1351 66.9371C64.393 67.5787 64.776 68.1626 65.2616 68.6549C65.7472 69.1473 66.3258 69.5382 66.9638 69.805C67.6017 70.0718 68.2864 70.2091 68.9779 70.2091L72.1237 70.2091C72.4005 70.209 72.666 70.0991 72.8617 69.9033C73.0574 69.7076 73.1674 69.4422 73.1674 69.1654L73.1674 64.7367C73.1674 64.5979 73.1396 64.4605 73.0857 64.3326C73.0319 64.2046 72.9531 64.0887 72.8539 63.9916C72.7547 63.8944 72.6372 63.8181 72.5081 63.7669C72.3791 63.7158 72.2411 63.6909 72.1023 63.6938L70.1412 63.7358L70.091 60.1693C70.0863 59.8961 69.9747 59.6356 69.7801 59.4438C69.5855 59.2519 69.3235 59.1441 69.0502 59.1433L68.3794 59.1411L68.7232 33.5699C68.7232 32.3143 68.1997 30.4577 67.3118 29.5699C66.424 28.682 65.5 28.0699 63 28.0699C60.7903 28.0699 59.6997 28.682 58.8118 29.5699C57.924 30.4577 57.5395 32.0115 57.5395 33.2671L57.5395 64.7441C57.5383 65.4457 57.2591 66.1183 56.7629 66.6144C56.2668 67.1105 55.5943 67.3898 54.8926 67.391L53.3555 67.391V35.2151C53.3555 34.9383 53.2455 34.6729 53.0498 34.4771C52.854 34.2814 52.5886 34.1715 52.3118 34.1714L51.4973 34.1714L51.4973 25.1871L60.7872 25.1871C61.064 25.187 61.3294 25.0771 61.5252 24.8814C61.7209 24.6856 61.8309 24.4202 61.8309 24.1434V18.9766C61.8308 18.6998 61.7209 18.4344 61.5252 18.2386C61.3294 18.0429 61.064 17.933 60.7872 17.9329L35.6913 17.9329C35.4145 17.9329 35.1491 18.0429 34.9534 18.2386C34.7577 18.4344 34.6477 18.6998 34.6476 18.9766L34.6476 24.1434C34.6477 24.4202 34.7577 24.6856 34.9534 24.8814C35.1491 25.0771 35.4145 25.187 35.6913 25.1871L44.9812 25.1871L44.9812 34.1714L44.1543 34.1714C43.8775 34.1715 43.6121 34.2814 43.4164 34.4771C43.2206 34.6729 43.1107 34.9383 43.1106 35.2151L43.1106 71.0771L37.2266 71.0771C35.971 71.0771 34.7668 71.5759 33.879 72.4637C32.9911 73.3516 32.4923 73.7886 32.4923 75.0442C32.4923 76.2998 32.9911 76.7994 33.879 77.6872C34.7668 78.575 35.971 79.0738 37.2266 79.0738L59.2519 79.0738ZM68.0612 64.8135C68.0631 64.951 68.0922 65.0869 68.1468 65.2131C68.2014 65.3394 68.2805 65.4536 68.3794 65.5493C68.4783 65.6449 68.5952 65.72 68.7232 65.7703C68.8512 65.8206 68.988 65.8451 69.1255 65.8424L71.0749 65.8033L71.0771 68.1246L68.975 68.1246C68.5599 68.1247 68.149 68.0423 67.7661 67.8822C67.3832 67.722 67.0359 67.4874 66.7445 67.1918C66.4531 66.8963 66.2234 66.5458 66.0686 66.1607C65.9139 65.7756 65.8372 65.3635 65.8431 64.9485L65.8926 61.2248H68.0154L68.0612 64.8135ZM36.735 23.0997L36.735 20.0203L59.7435 20.0203L59.7435 23.0997L50.4536 23.0997L46.0249 23.0997L36.735 23.0997ZM47.0686 25.1871L49.4099 25.1871L49.4099 34.1714L47.0686 34.1714V25.1871ZM44.8543 36.2588H46.0249L50.4536 36.2588L51.6243 36.2588L51.6243 67.3865L44.8543 67.3865L44.8543 36.2588ZM44.8543 69.4739L51.6243 69.4739L51.6243 74.0296L44.8543 74.0296L44.8543 69.4739ZM34.5797 75.0442C34.5929 74.3464 34.876 74.4479 35.3696 73.9543C35.8631 73.4608 36.5287 73.1777 37.2266 73.1645L43.1106 73.1645L43.1106 74.3061C43.1107 74.5829 43.2206 74.8483 43.4163 75.0441C43.6121 75.2398 43.8775 75.3498 44.1543 75.3498L52.3118 75.3542C52.5886 75.3542 52.854 75.2442 53.0498 75.0485C53.2455 74.8528 53.3555 74.5873 53.3555 74.3105V73.1689L59.2519 73.1645C59.5999 73.163 59.9448 73.2305 60.2666 73.363C60.5884 73.4955 60.8808 73.6904 61.1268 73.9365C61.3729 74.1825 61.5678 73.7078 61.7003 74.0296C61.8328 74.3514 61.9003 74.6962 61.8988 75.0442C61.8856 75.7421 61.6025 75.7031 61.1089 76.1966C60.6154 76.6902 59.9498 76.9733 59.2519 76.9864L37.2266 76.9864C36.8786 76.9879 36.5337 76.9205 36.2119 76.788C35.8901 76.6555 35.5978 76.4606 35.3517 76.2145C35.1056 75.9684 34.9107 75.676 34.7782 75.3542C34.6457 75.0324 34.5783 75.3922 34.5797 75.0442Z" fill="white"/>
|
<path d="M59.2519 79.0738C60.5075 79.0738 61.7117 78.5751 62.5995 77.6872C63.4874 76.7994 63.9862 76.2998 63.9862 75.0442C63.9862 73.7886 63.4874 73.3516 62.5996 72.4637C61.7117 71.5759 60.5075 71.0771 59.2519 71.0771L53.3555 71.0815V69.4784L54.8823 69.4739C56.1376 69.4729 57.3412 68.9738 58.2288 68.0862C59.1164 67.1986 60.2656 66.2038 60.2666 64.9485L60.3118 33.5699C60.3119 33.2223 60.3118 32.5699 60.401 32.2506C60.5341 31.9295 60.547 31.5699 60.725 31.3919C60.9708 31.1462 61.1038 30.9511 61.4249 30.8181C61.746 30.6852 62.6524 30.5698 63 30.5699C63.3475 30.5699 63.9907 30.5669 64.3118 30.7C64.6329 30.833 64.9889 31.2478 65.3118 31.5699C65.5575 31.8156 65.5753 31.9295 65.7083 32.2506C65.8412 32.5717 65.9096 32.9158 65.9096 33.2634L65.9169 59.1411L64.8659 59.1411C64.5926 59.1418 64.3306 59.2497 64.136 59.4415C63.9414 59.6334 63.8298 59.8938 63.8251 60.167L63.7587 64.9175C63.7491 65.609 63.8771 66.2955 64.1351 66.9371C64.393 67.5787 64.776 68.1626 65.2616 68.6549C65.7472 69.1473 66.3258 69.5382 66.9638 69.805C67.6017 70.0718 68.2864 70.2091 68.9779 70.2091L72.1237 70.2091C72.4005 70.209 72.666 70.0991 72.8617 69.9033C73.0574 69.7076 73.1674 69.4422 73.1674 69.1654L73.1674 64.7367C73.1674 64.5979 73.1396 64.4605 73.0857 64.3326C73.0319 64.2046 72.9531 64.0887 72.8539 63.9916C72.7547 63.8944 72.6372 63.8181 72.5081 63.7669C72.3791 63.7158 72.2411 63.6909 72.1023 63.6938L70.1412 63.7358L70.091 60.1693C70.0863 59.8961 69.9747 59.6356 69.7801 59.4438C69.5855 59.2519 69.3235 59.1441 69.0502 59.1433L68.3794 59.1411L68.7232 33.5699C68.7232 32.3143 68.1997 30.4577 67.3118 29.5699C66.424 28.682 65.5 28.0699 63 28.0699C60.7903 28.0699 59.6997 28.682 58.8118 29.5699C57.924 30.4577 57.5395 32.0115 57.5395 33.2671L57.5395 64.7441C57.5383 65.4457 57.2591 66.1183 56.7629 66.6144C56.2668 67.1105 55.5943 67.3898 54.8926 67.391L53.3555 67.391V35.2151C53.3555 34.9383 53.2455 34.6729 53.0498 34.4771C52.854 34.2814 52.5886 34.1715 52.3118 34.1714L51.4973 34.1714L51.4973 25.1871L60.7872 25.1871C61.064 25.187 61.3294 25.0771 61.5252 24.8814C61.7209 24.6856 61.8309 24.4202 61.8309 24.1434V18.9766C61.8308 18.6998 61.7209 18.4344 61.5252 18.2386C61.3294 18.0429 61.064 17.933 60.7872 17.9329L35.6913 17.9329C35.4145 17.9329 35.1491 18.0429 34.9534 18.2386C34.7577 18.4344 34.6477 18.6998 34.6476 18.9766L34.6476 24.1434C34.6477 24.4202 34.7577 24.6856 34.9534 24.8814C35.1491 25.0771 35.4145 25.187 35.6913 25.1871L44.9812 25.1871L44.9812 34.1714L44.1543 34.1714C43.8775 34.1715 43.6121 34.2814 43.4164 34.4771C43.2206 34.6729 43.1107 34.9383 43.1106 35.2151L43.1106 71.0771L37.2266 71.0771C35.971 71.0771 34.7668 71.5759 33.879 72.4637C32.9911 73.3516 32.4923 73.7886 32.4923 75.0442C32.4923 76.2998 32.9911 76.7994 33.879 77.6872C34.7668 78.575 35.971 79.0738 37.2266 79.0738L59.2519 79.0738ZM68.0612 64.8135C68.0631 64.951 68.0922 65.0869 68.1468 65.2131C68.2014 65.3394 68.2805 65.4536 68.3794 65.5493C68.4783 65.6449 68.5952 65.72 68.7232 65.7703C68.8512 65.8206 68.988 65.8451 69.1255 65.8424L71.0749 65.8033L71.0771 68.1246L68.975 68.1246C68.5599 68.1247 68.149 68.0423 67.7661 67.8822C67.3832 67.722 67.0359 67.4874 66.7445 67.1918C66.4531 66.8963 66.2234 66.5458 66.0686 66.1607C65.9139 65.7756 65.8372 65.3635 65.8431 64.9485L65.8926 61.2248H68.0154L68.0612 64.8135ZM36.735 23.0997L36.735 20.0203L59.7435 20.0203L59.7435 23.0997L50.4536 23.0997L46.0249 23.0997L36.735 23.0997ZM47.0686 25.1871L49.4099 25.1871L49.4099 34.1714L47.0686 34.1714V25.1871ZM44.8543 36.2588H46.0249L50.4536 36.2588L51.6243 36.2588L51.6243 67.3865L44.8543 67.3865L44.8543 36.2588ZM44.8543 69.4739L51.6243 69.4739L51.6243 74.0296L44.8543 74.0296L44.8543 69.4739ZM34.5797 75.0442C34.5929 74.3464 34.876 74.4479 35.3696 73.9543C35.8631 73.4608 36.5287 73.1777 37.2266 73.1645L43.1106 73.1645L43.1106 74.3061C43.1107 74.5829 43.2206 74.8483 43.4163 75.0441C43.6121 75.2398 43.8775 75.3498 44.1543 75.3498L52.3118 75.3542C52.5886 75.3542 52.854 75.2442 53.0498 75.0485C53.2455 74.8528 53.3555 74.5873 53.3555 74.3105V73.1689L59.2519 73.1645C59.5999 73.163 59.9448 73.2305 60.2666 73.363C60.5884 73.4955 60.8808 73.6904 61.1268 73.9365C61.3729 74.1825 61.5678 73.7078 61.7003 74.0296C61.8328 74.3514 61.9003 74.6962 61.8988 75.0442C61.8856 75.7421 61.6025 75.7031 61.1089 76.1966C60.6154 76.6902 59.9498 76.9733 59.2519 76.9864L37.2266 76.9864C36.8786 76.9879 36.5337 76.9205 36.2119 76.788C35.8901 76.6555 35.5978 76.4606 35.3517 76.2145C35.1056 75.9684 34.9107 75.676 34.7782 75.3542C34.6457 75.0324 34.5783 75.3922 34.5797 75.0442Z"
|
||||||
|
fill="white"/>
|
||||||
<rect x="44.3118" y="35.5698" width="8" height="39" fill="white"/>
|
<rect x="44.3118" y="35.5698" width="8" height="39" fill="white"/>
|
||||||
<rect x="35.3118" y="19.5699" width="25" height="4" fill="white"/>
|
<rect x="35.3118" y="19.5699" width="25" height="4" fill="white"/>
|
||||||
<rect x="46.3118" y="21.5698" width="4" height="14" fill="white"/>
|
<rect x="46.3118" y="21.5698" width="4" height="14" fill="white"/>
|
||||||
|
@ -11,10 +13,12 @@
|
||||||
<rect x="68.3118" y="64.5699" width="3" height="4" fill="white"/>
|
<rect x="68.3118" y="64.5699" width="3" height="4" fill="white"/>
|
||||||
<rect x="56" y="42" width="5" height="10" fill="#171615"/>
|
<rect x="56" y="42" width="5" height="10" fill="#171615"/>
|
||||||
</g>
|
</g>
|
||||||
<rect x="72.4167" y="53.8615" width="29.0549" height="7.85787" transform="rotate(43.5782 72.4167 53.8615)" fill="#F00D0D"/>
|
<rect x="72.4167" y="53.8615" width="29.0549" height="7.85787" transform="rotate(43.5782 72.4167 53.8615)"
|
||||||
|
fill="#F00D0D"/>
|
||||||
<path d="M68.2141 73.9097L88.6128 54L94.0003 59.5199L73.6016 79.4295L68.2141 73.9097Z" fill="#F00D0D"/>
|
<path d="M68.2141 73.9097L88.6128 54L94.0003 59.5199L73.6016 79.4295L68.2141 73.9097Z" fill="#F00D0D"/>
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="filter0_d" x="-3" y="2" width="102.479" height="102.479" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter0_d" x="-3" y="2" width="102.479" height="102.479" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.5 KiB |
|
@ -3,10 +3,9 @@
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="123"
|
width="123"
|
||||||
height="123"
|
height="123"
|
||||||
viewBox="0 0 123 123"
|
viewBox="0 0 123 123"
|
||||||
|
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 10 KiB |
|
@ -1,8 +1,10 @@
|
||||||
<svg width="99" height="123" viewBox="0 0 99 123" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="99" height="123" viewBox="0 0 99 123" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M55.0445 113.094C53.2614 116.981 47.7386 116.981 45.9555 113.094L15.2124 46.085C13.6928 42.7729 16.1129 39 19.7569 39L81.2431 39C84.8871 39 87.3072 42.7729 85.7876 46.085L55.0445 113.094Z" fill="#E2783D"/>
|
<path d="M55.0445 113.094C53.2614 116.981 47.7386 116.981 45.9555 113.094L15.2124 46.085C13.6928 42.7729 16.1129 39 19.7569 39L81.2431 39C84.8871 39 87.3072 42.7729 85.7876 46.085L55.0445 113.094Z"
|
||||||
|
fill="#E2783D"/>
|
||||||
<circle cx="50" cy="49" r="49" fill="#E2783D"/>
|
<circle cx="50" cy="49" r="49" fill="#E2783D"/>
|
||||||
<g clip-path="url(#clip0)" filter="url(#filter0_d)">
|
<g clip-path="url(#clip0)" filter="url(#filter0_d)">
|
||||||
<path d="M59.2519 79.0738C60.5075 79.0738 61.7117 78.5751 62.5995 77.6872C63.4874 76.7994 63.9862 76.2998 63.9862 75.0442C63.9862 73.7886 63.4874 73.3516 62.5996 72.4637C61.7117 71.5759 60.5075 71.0771 59.2519 71.0771L53.3555 71.0815V69.4784L54.8823 69.4739C56.1376 69.4729 57.3412 68.9738 58.2288 68.0862C59.1164 67.1986 60.2656 66.2038 60.2666 64.9485L60.3118 33.5699C60.3119 33.2223 60.3118 32.5699 60.401 32.2506C60.5341 31.9295 60.547 31.5699 60.725 31.3919C60.9708 31.1462 61.1038 30.9511 61.4249 30.8181C61.746 30.6852 62.6524 30.5698 63 30.5699C63.3475 30.5699 63.9907 30.5669 64.3118 30.7C64.6329 30.833 64.9889 31.2478 65.3118 31.5699C65.5575 31.8156 65.5753 31.9295 65.7083 32.2506C65.8412 32.5717 65.9096 32.9158 65.9096 33.2634L65.9169 59.1411L64.8659 59.1411C64.5926 59.1418 64.3306 59.2497 64.136 59.4415C63.9414 59.6334 63.8298 59.8938 63.8251 60.167L63.7587 64.9175C63.7491 65.609 63.8771 66.2955 64.1351 66.9371C64.393 67.5787 64.776 68.1626 65.2616 68.6549C65.7472 69.1473 66.3258 69.5382 66.9638 69.805C67.6017 70.0718 68.2864 70.2091 68.9779 70.2091L72.1237 70.2091C72.4005 70.209 72.666 70.0991 72.8617 69.9033C73.0574 69.7076 73.1674 69.4422 73.1674 69.1654L73.1674 64.7367C73.1674 64.5979 73.1396 64.4605 73.0857 64.3326C73.0319 64.2046 72.9531 64.0887 72.8539 63.9916C72.7547 63.8944 72.6372 63.8181 72.5081 63.7669C72.3791 63.7158 72.2411 63.6909 72.1023 63.6938L70.1412 63.7358L70.091 60.1693C70.0863 59.8961 69.9747 59.6356 69.7801 59.4438C69.5855 59.2519 69.3235 59.1441 69.0502 59.1433L68.3794 59.1411L68.7232 33.5699C68.7232 32.3143 68.1997 30.4577 67.3118 29.5699C66.424 28.682 65.5 28.0699 63 28.0699C60.7903 28.0699 59.6997 28.682 58.8118 29.5699C57.924 30.4577 57.5395 32.0115 57.5395 33.2671L57.5395 64.7441C57.5383 65.4457 57.2591 66.1183 56.7629 66.6144C56.2668 67.1105 55.5943 67.3898 54.8926 67.391L53.3555 67.391V35.2151C53.3555 34.9383 53.2455 34.6729 53.0498 34.4771C52.854 34.2814 52.5886 34.1715 52.3118 34.1714L51.4973 34.1714L51.4973 25.1871L60.7872 25.1871C61.064 25.187 61.3294 25.0771 61.5252 24.8814C61.7209 24.6856 61.8309 24.4202 61.8309 24.1434V18.9766C61.8308 18.6998 61.7209 18.4344 61.5252 18.2386C61.3294 18.0429 61.064 17.933 60.7872 17.9329L35.6913 17.9329C35.4145 17.9329 35.1491 18.0429 34.9534 18.2386C34.7577 18.4344 34.6477 18.6998 34.6476 18.9766L34.6476 24.1434C34.6477 24.4202 34.7577 24.6856 34.9534 24.8814C35.1491 25.0771 35.4145 25.187 35.6913 25.1871L44.9812 25.1871L44.9812 34.1714L44.1543 34.1714C43.8775 34.1715 43.6121 34.2814 43.4164 34.4771C43.2206 34.6729 43.1107 34.9383 43.1106 35.2151L43.1106 71.0771L37.2266 71.0771C35.971 71.0771 34.7668 71.5759 33.879 72.4637C32.9911 73.3516 32.4923 73.7886 32.4923 75.0442C32.4923 76.2998 32.9911 76.7994 33.879 77.6872C34.7668 78.575 35.971 79.0738 37.2266 79.0738L59.2519 79.0738ZM68.0612 64.8135C68.0631 64.951 68.0922 65.0869 68.1468 65.2131C68.2014 65.3394 68.2805 65.4536 68.3794 65.5493C68.4783 65.6449 68.5952 65.72 68.7232 65.7703C68.8512 65.8206 68.988 65.8451 69.1255 65.8424L71.0749 65.8033L71.0771 68.1246L68.975 68.1246C68.5599 68.1247 68.149 68.0423 67.7661 67.8822C67.3832 67.722 67.0359 67.4874 66.7445 67.1918C66.4531 66.8963 66.2234 66.5458 66.0686 66.1607C65.9139 65.7756 65.8372 65.3635 65.8431 64.9485L65.8926 61.2248H68.0154L68.0612 64.8135ZM36.735 23.0997L36.735 20.0203L59.7435 20.0203L59.7435 23.0997L50.4536 23.0997L46.0249 23.0997L36.735 23.0997ZM47.0686 25.1871L49.4099 25.1871L49.4099 34.1714L47.0686 34.1714V25.1871ZM44.8543 36.2588H46.0249L50.4536 36.2588L51.6243 36.2588L51.6243 67.3865L44.8543 67.3865L44.8543 36.2588ZM44.8543 69.4739L51.6243 69.4739L51.6243 74.0296L44.8543 74.0296L44.8543 69.4739ZM34.5797 75.0442C34.5929 74.3464 34.876 74.4479 35.3696 73.9543C35.8631 73.4608 36.5287 73.1777 37.2266 73.1645L43.1106 73.1645L43.1106 74.3061C43.1107 74.5829 43.2206 74.8483 43.4163 75.0441C43.6121 75.2398 43.8775 75.3498 44.1543 75.3498L52.3118 75.3542C52.5886 75.3542 52.854 75.2442 53.0498 75.0485C53.2455 74.8528 53.3555 74.5873 53.3555 74.3105V73.1689L59.2519 73.1645C59.5999 73.163 59.9448 73.2305 60.2666 73.363C60.5884 73.4955 60.8808 73.6904 61.1268 73.9365C61.3729 74.1825 61.5678 73.7078 61.7003 74.0296C61.8328 74.3514 61.9003 74.6962 61.8988 75.0442C61.8856 75.7421 61.6025 75.7031 61.1089 76.1966C60.6154 76.6902 59.9498 76.9733 59.2519 76.9864L37.2266 76.9864C36.8786 76.9879 36.5337 76.9205 36.2119 76.788C35.8901 76.6555 35.5978 76.4606 35.3517 76.2145C35.1056 75.9684 34.9107 75.676 34.7782 75.3542C34.6457 75.0324 34.5783 75.3922 34.5797 75.0442Z" fill="white"/>
|
<path d="M59.2519 79.0738C60.5075 79.0738 61.7117 78.5751 62.5995 77.6872C63.4874 76.7994 63.9862 76.2998 63.9862 75.0442C63.9862 73.7886 63.4874 73.3516 62.5996 72.4637C61.7117 71.5759 60.5075 71.0771 59.2519 71.0771L53.3555 71.0815V69.4784L54.8823 69.4739C56.1376 69.4729 57.3412 68.9738 58.2288 68.0862C59.1164 67.1986 60.2656 66.2038 60.2666 64.9485L60.3118 33.5699C60.3119 33.2223 60.3118 32.5699 60.401 32.2506C60.5341 31.9295 60.547 31.5699 60.725 31.3919C60.9708 31.1462 61.1038 30.9511 61.4249 30.8181C61.746 30.6852 62.6524 30.5698 63 30.5699C63.3475 30.5699 63.9907 30.5669 64.3118 30.7C64.6329 30.833 64.9889 31.2478 65.3118 31.5699C65.5575 31.8156 65.5753 31.9295 65.7083 32.2506C65.8412 32.5717 65.9096 32.9158 65.9096 33.2634L65.9169 59.1411L64.8659 59.1411C64.5926 59.1418 64.3306 59.2497 64.136 59.4415C63.9414 59.6334 63.8298 59.8938 63.8251 60.167L63.7587 64.9175C63.7491 65.609 63.8771 66.2955 64.1351 66.9371C64.393 67.5787 64.776 68.1626 65.2616 68.6549C65.7472 69.1473 66.3258 69.5382 66.9638 69.805C67.6017 70.0718 68.2864 70.2091 68.9779 70.2091L72.1237 70.2091C72.4005 70.209 72.666 70.0991 72.8617 69.9033C73.0574 69.7076 73.1674 69.4422 73.1674 69.1654L73.1674 64.7367C73.1674 64.5979 73.1396 64.4605 73.0857 64.3326C73.0319 64.2046 72.9531 64.0887 72.8539 63.9916C72.7547 63.8944 72.6372 63.8181 72.5081 63.7669C72.3791 63.7158 72.2411 63.6909 72.1023 63.6938L70.1412 63.7358L70.091 60.1693C70.0863 59.8961 69.9747 59.6356 69.7801 59.4438C69.5855 59.2519 69.3235 59.1441 69.0502 59.1433L68.3794 59.1411L68.7232 33.5699C68.7232 32.3143 68.1997 30.4577 67.3118 29.5699C66.424 28.682 65.5 28.0699 63 28.0699C60.7903 28.0699 59.6997 28.682 58.8118 29.5699C57.924 30.4577 57.5395 32.0115 57.5395 33.2671L57.5395 64.7441C57.5383 65.4457 57.2591 66.1183 56.7629 66.6144C56.2668 67.1105 55.5943 67.3898 54.8926 67.391L53.3555 67.391V35.2151C53.3555 34.9383 53.2455 34.6729 53.0498 34.4771C52.854 34.2814 52.5886 34.1715 52.3118 34.1714L51.4973 34.1714L51.4973 25.1871L60.7872 25.1871C61.064 25.187 61.3294 25.0771 61.5252 24.8814C61.7209 24.6856 61.8309 24.4202 61.8309 24.1434V18.9766C61.8308 18.6998 61.7209 18.4344 61.5252 18.2386C61.3294 18.0429 61.064 17.933 60.7872 17.9329L35.6913 17.9329C35.4145 17.9329 35.1491 18.0429 34.9534 18.2386C34.7577 18.4344 34.6477 18.6998 34.6476 18.9766L34.6476 24.1434C34.6477 24.4202 34.7577 24.6856 34.9534 24.8814C35.1491 25.0771 35.4145 25.187 35.6913 25.1871L44.9812 25.1871L44.9812 34.1714L44.1543 34.1714C43.8775 34.1715 43.6121 34.2814 43.4164 34.4771C43.2206 34.6729 43.1107 34.9383 43.1106 35.2151L43.1106 71.0771L37.2266 71.0771C35.971 71.0771 34.7668 71.5759 33.879 72.4637C32.9911 73.3516 32.4923 73.7886 32.4923 75.0442C32.4923 76.2998 32.9911 76.7994 33.879 77.6872C34.7668 78.575 35.971 79.0738 37.2266 79.0738L59.2519 79.0738ZM68.0612 64.8135C68.0631 64.951 68.0922 65.0869 68.1468 65.2131C68.2014 65.3394 68.2805 65.4536 68.3794 65.5493C68.4783 65.6449 68.5952 65.72 68.7232 65.7703C68.8512 65.8206 68.988 65.8451 69.1255 65.8424L71.0749 65.8033L71.0771 68.1246L68.975 68.1246C68.5599 68.1247 68.149 68.0423 67.7661 67.8822C67.3832 67.722 67.0359 67.4874 66.7445 67.1918C66.4531 66.8963 66.2234 66.5458 66.0686 66.1607C65.9139 65.7756 65.8372 65.3635 65.8431 64.9485L65.8926 61.2248H68.0154L68.0612 64.8135ZM36.735 23.0997L36.735 20.0203L59.7435 20.0203L59.7435 23.0997L50.4536 23.0997L46.0249 23.0997L36.735 23.0997ZM47.0686 25.1871L49.4099 25.1871L49.4099 34.1714L47.0686 34.1714V25.1871ZM44.8543 36.2588H46.0249L50.4536 36.2588L51.6243 36.2588L51.6243 67.3865L44.8543 67.3865L44.8543 36.2588ZM44.8543 69.4739L51.6243 69.4739L51.6243 74.0296L44.8543 74.0296L44.8543 69.4739ZM34.5797 75.0442C34.5929 74.3464 34.876 74.4479 35.3696 73.9543C35.8631 73.4608 36.5287 73.1777 37.2266 73.1645L43.1106 73.1645L43.1106 74.3061C43.1107 74.5829 43.2206 74.8483 43.4163 75.0441C43.6121 75.2398 43.8775 75.3498 44.1543 75.3498L52.3118 75.3542C52.5886 75.3542 52.854 75.2442 53.0498 75.0485C53.2455 74.8528 53.3555 74.5873 53.3555 74.3105V73.1689L59.2519 73.1645C59.5999 73.163 59.9448 73.2305 60.2666 73.363C60.5884 73.4955 60.8808 73.6904 61.1268 73.9365C61.3729 74.1825 61.5678 73.7078 61.7003 74.0296C61.8328 74.3514 61.9003 74.6962 61.8988 75.0442C61.8856 75.7421 61.6025 75.7031 61.1089 76.1966C60.6154 76.6902 59.9498 76.9733 59.2519 76.9864L37.2266 76.9864C36.8786 76.9879 36.5337 76.9205 36.2119 76.788C35.8901 76.6555 35.5978 76.4606 35.3517 76.2145C35.1056 75.9684 34.9107 75.676 34.7782 75.3542C34.6457 75.0324 34.5783 75.3922 34.5797 75.0442Z"
|
||||||
|
fill="white"/>
|
||||||
<rect x="44.3118" y="35.5698" width="8" height="39" fill="white"/>
|
<rect x="44.3118" y="35.5698" width="8" height="39" fill="white"/>
|
||||||
<rect x="35.3118" y="19.5699" width="25" height="4" fill="white"/>
|
<rect x="35.3118" y="19.5699" width="25" height="4" fill="white"/>
|
||||||
<rect x="46.3119" y="21.5698" width="4" height="14" fill="white"/>
|
<rect x="46.3119" y="21.5698" width="4" height="14" fill="white"/>
|
||||||
|
@ -11,7 +13,8 @@
|
||||||
<rect x="68.3118" y="64.5699" width="3" height="4" fill="white"/>
|
<rect x="68.3118" y="64.5699" width="3" height="4" fill="white"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="filter0_d" x="-3" y="2" width="102.479" height="102.479" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter0_d" x="-3" y="2" width="102.479" height="102.479" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
|
Before Width: | Height: | Size: 6 KiB After Width: | Height: | Size: 6.2 KiB |
|
@ -1,27 +1,36 @@
|
||||||
<svg width="98" height="121" viewBox="0 0 98 121" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="98" height="121" viewBox="0 0 98 121" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M53.0072 111.614C51.1916 115.395 45.8084 115.395 43.9928 111.614L13.4024 47.9145C11.8084 44.5952 14.2275 40.75 17.9097 40.75L79.0903 40.75C82.7725 40.75 85.1916 44.5952 83.5976 47.9145L53.0072 111.614Z" fill="#32ADF2"/>
|
<path d="M53.0072 111.614C51.1916 115.395 45.8084 115.395 43.9928 111.614L13.4024 47.9145C11.8084 44.5952 14.2275 40.75 17.9097 40.75L79.0903 40.75C82.7725 40.75 85.1916 44.5952 83.5976 47.9145L53.0072 111.614Z"
|
||||||
|
fill="#32ADF2"/>
|
||||||
<circle cx="49" cy="49" r="49" fill="#32ADF2"/>
|
<circle cx="49" cy="49" r="49" fill="#32ADF2"/>
|
||||||
<g filter="url(#filter0_d)">
|
<g filter="url(#filter0_d)">
|
||||||
<path d="M62.84 50.816C63.9413 50.7413 64.912 50.704 65.752 50.704C68.1973 50.704 69.42 52.188 69.42 55.156C69.42 58.4787 68.0853 60.14 65.416 60.14C64.632 60.14 63.7733 60.07 62.84 59.93V50.816ZM65.416 59.16C66.0693 59.16 66.564 58.9967 66.9 58.67C67.236 58.3433 67.4553 57.914 67.558 57.382C67.6607 56.8407 67.712 56.164 67.712 55.352C67.712 54.2693 67.5673 53.3873 67.278 52.706C66.9887 52.0247 66.4473 51.684 65.654 51.684C65.3087 51.684 64.9167 51.7073 64.478 51.754V59.076C64.814 59.132 65.1267 59.16 65.416 59.16ZM72.3803 50.76V60H70.7423V50.76H72.3803ZM77.5646 55.73V60H75.9266V55.898L73.2386 50.76H75.0306L76.8506 54.554L78.5726 50.76H80.2526L77.5646 55.73Z" fill="#FFFBFB"/>
|
<path d="M62.84 50.816C63.9413 50.7413 64.912 50.704 65.752 50.704C68.1973 50.704 69.42 52.188 69.42 55.156C69.42 58.4787 68.0853 60.14 65.416 60.14C64.632 60.14 63.7733 60.07 62.84 59.93V50.816ZM65.416 59.16C66.0693 59.16 66.564 58.9967 66.9 58.67C67.236 58.3433 67.4553 57.914 67.558 57.382C67.6607 56.8407 67.712 56.164 67.712 55.352C67.712 54.2693 67.5673 53.3873 67.278 52.706C66.9887 52.0247 66.4473 51.684 65.654 51.684C65.3087 51.684 64.9167 51.7073 64.478 51.754V59.076C64.814 59.132 65.1267 59.16 65.416 59.16ZM72.3803 50.76V60H70.7423V50.76H72.3803ZM77.5646 55.73V60H75.9266V55.898L73.2386 50.76H75.0306L76.8506 54.554L78.5726 50.76H80.2526L77.5646 55.73Z"
|
||||||
|
fill="#FFFBFB"/>
|
||||||
</g>
|
</g>
|
||||||
<g filter="url(#filter1_d)">
|
<g filter="url(#filter1_d)">
|
||||||
<path d="M39.0246 31.9734L35.4086 34.9306L35.3903 34.9459C34.5486 35.6731 34.0429 36.7274 34.0026 37.8384C33.9731 38.6517 34.1956 39.4521 34.6251 40.1313L38.1101 36.6498C38.4539 36.3063 39.0114 36.3063 39.3553 36.6498C39.6992 36.9933 39.6992 37.5503 39.3553 37.8939L35.8705 41.3753C36.5103 41.7791 37.2574 42 38.0217 42C38.0696 42 38.1176 41.9991 38.1656 41.9974C39.2777 41.9571 40.333 41.4519 41.0609 40.6109L44.0362 36.9802L39.0246 31.9734Z" fill="#FFF7F7"/>
|
<path d="M39.0246 31.9734L35.4086 34.9306L35.3903 34.9459C34.5486 35.6731 34.0429 36.7274 34.0026 37.8384C33.9731 38.6517 34.1956 39.4521 34.6251 40.1313L38.1101 36.6498C38.4539 36.3063 39.0114 36.3063 39.3553 36.6498C39.6992 36.9933 39.6992 37.5503 39.3553 37.8939L35.8705 41.3753C36.5103 41.7791 37.2574 42 38.0217 42C38.0696 42 38.1176 41.9991 38.1656 41.9974C39.2777 41.9571 40.333 41.4519 41.0609 40.6109L44.0362 36.9802L39.0246 31.9734Z"
|
||||||
|
fill="#FFF7F7"/>
|
||||||
<path d="M42.008 29.5336L40.394 30.8535L45.1573 35.6121L46.4786 33.9998L42.008 29.5336Z" fill="#FFF7F7"/>
|
<path d="M42.008 29.5336L40.394 30.8535L45.1573 35.6121L46.4786 33.9998L42.008 29.5336Z" fill="#FFF7F7"/>
|
||||||
<path d="M44.8629 29.9L46.0573 28.7068L47.3023 29.9507L46.1079 31.1439L44.8629 29.9Z" fill="#FFF7F7"/>
|
<path d="M44.8629 29.9L46.0573 28.7068L47.3023 29.9507L46.1079 31.1439L44.8629 29.9Z" fill="#FFF7F7"/>
|
||||||
<path d="M52.5127 22.2598L57.2054 17.5716L58.4505 18.8155L53.7578 23.5036L52.5127 22.2598Z" fill="#FFF7F7"/>
|
<path d="M52.5127 22.2598L57.2054 17.5716L58.4505 18.8155L53.7578 23.5036L52.5127 22.2598Z" fill="#FFF7F7"/>
|
||||||
<path d="M57.5981 15.4757L61.0772 12L63.9954 14.9153L60.5163 18.3911L57.5981 15.4757Z" fill="#FFF7F7"/>
|
<path d="M57.5981 15.4757L61.0772 12L63.9954 14.9153L60.5163 18.3911L57.5981 15.4757Z" fill="#FFF7F7"/>
|
||||||
<path d="M60.4798 30.9612C59.5828 30.0651 58.4814 29.5914 57.295 29.5914C56.9717 29.5914 56.6419 29.627 56.3147 29.6972C55.9636 29.7724 55.582 29.6566 55.3244 29.3991L44.7335 18.8186C44.4694 18.5548 44.3563 18.1695 44.4387 17.813C44.8015 16.2466 44.358 14.7415 43.1901 13.5748C42.1736 12.5592 40.822 12 39.3843 12C38.6498 12 37.9365 12.1457 37.2643 12.4332L36.8657 12.6037L39.9617 15.6966L37.7009 17.9551L34.6051 14.8621L34.4344 15.2604C34.016 16.2367 33.8969 17.3068 34.0898 18.3552C34.2874 19.4288 34.8017 20.4057 35.577 21.1804C36.474 22.0765 37.5753 22.5502 38.7617 22.5502C39.0851 22.5502 39.415 22.5146 39.7421 22.4444C39.8146 22.4288 39.8888 22.421 39.963 22.421C40.2476 22.421 40.5281 22.5382 40.7325 22.7425L51.3233 33.323C51.5877 33.587 51.7007 33.9726 51.618 34.3292C51.2554 35.8951 51.6988 37.4001 52.8667 38.5668C53.8832 39.5824 55.2348 40.1417 56.6725 40.1416C57.4071 40.1416 58.1204 39.9958 58.7924 39.7084L59.1912 39.5379L56.0952 36.445L58.3559 34.1866L61.4517 37.2794L61.6224 36.8811C62.0408 35.9049 62.1599 34.8348 61.967 33.7865C61.7694 32.7128 61.2551 31.7358 60.4798 30.9612Z" fill="#FFF7F7"/>
|
<path d="M60.4798 30.9612C59.5828 30.0651 58.4814 29.5914 57.295 29.5914C56.9717 29.5914 56.6419 29.627 56.3147 29.6972C55.9636 29.7724 55.582 29.6566 55.3244 29.3991L44.7335 18.8186C44.4694 18.5548 44.3563 18.1695 44.4387 17.813C44.8015 16.2466 44.358 14.7415 43.1901 13.5748C42.1736 12.5592 40.822 12 39.3843 12C38.6498 12 37.9365 12.1457 37.2643 12.4332L36.8657 12.6037L39.9617 15.6966L37.7009 17.9551L34.6051 14.8621L34.4344 15.2604C34.016 16.2367 33.8969 17.3068 34.0898 18.3552C34.2874 19.4288 34.8017 20.4057 35.577 21.1804C36.474 22.0765 37.5753 22.5502 38.7617 22.5502C39.0851 22.5502 39.415 22.5146 39.7421 22.4444C39.8146 22.4288 39.8888 22.421 39.963 22.421C40.2476 22.421 40.5281 22.5382 40.7325 22.7425L51.3233 33.323C51.5877 33.587 51.7007 33.9726 51.618 34.3292C51.2554 35.8951 51.6988 37.4001 52.8667 38.5668C53.8832 39.5824 55.2348 40.1417 56.6725 40.1416C57.4071 40.1416 58.1204 39.9958 58.7924 39.7084L59.1912 39.5379L56.0952 36.445L58.3559 34.1866L61.4517 37.2794L61.6224 36.8811C62.0408 35.9049 62.1599 34.8348 61.967 33.7865C61.7694 32.7128 61.2551 31.7358 60.4798 30.9612Z"
|
||||||
|
fill="#FFF7F7"/>
|
||||||
</g>
|
</g>
|
||||||
<g filter="url(#filter2_d)">
|
<g filter="url(#filter2_d)">
|
||||||
<path d="M37.5636 72.4372H24.7595L31.7436 56.4962H38.7276H43.7716H49.2037M49.2037 56.4962L47.2636 52H49.9797H52.6957M49.2037 56.4962L49.9797 58.5399L51.5317 61.8098L55.7997 72.4372M49.2037 56.4962L45.5176 62.6273L43.306 66.306M41.8316 68.7585L43.306 66.306M34.4596 60.9924L38.3396 69.9847L30.5796 52L32.9076 56.9049M40.6676 70.8022L43.306 66.306" stroke="white" stroke-width="2"/>
|
<path d="M37.5636 72.4372H24.7595L31.7436 56.4962H38.7276H43.7716H49.2037M49.2037 56.4962L47.2636 52H49.9797H52.6957M49.2037 56.4962L49.9797 58.5399L51.5317 61.8098L55.7997 72.4372M49.2037 56.4962L45.5176 62.6273L43.306 66.306M41.8316 68.7585L43.306 66.306M34.4596 60.9924L38.3396 69.9847L30.5796 52L32.9076 56.9049M40.6676 70.8022L43.306 66.306"
|
||||||
<path d="M41.6601 71.7418C41.6601 73.0707 40.6438 74.103 39.4441 74.103C38.2444 74.103 37.2281 73.0707 37.2281 71.7418C37.2281 70.4128 38.2444 69.3806 39.4441 69.3806C40.6438 69.3806 41.6601 70.4128 41.6601 71.7418Z" stroke="white"/>
|
stroke="white" stroke-width="2"/>
|
||||||
<path d="M33.4001 70.9243C33.4001 76.0653 29.4565 80.1429 24.7001 80.1429C19.9436 80.1429 16 76.0653 16 70.9243C16 65.7833 19.9436 61.7057 24.7001 61.7057C29.4565 61.7057 33.4001 65.7833 33.4001 70.9243Z" stroke="white" stroke-width="2"/>
|
<path d="M41.6601 71.7418C41.6601 73.0707 40.6438 74.103 39.4441 74.103C38.2444 74.103 37.2281 73.0707 37.2281 71.7418C37.2281 70.4128 38.2444 69.3806 39.4441 69.3806C40.6438 69.3806 41.6601 70.4128 41.6601 71.7418Z"
|
||||||
|
stroke="white"/>
|
||||||
|
<path d="M33.4001 70.9243C33.4001 76.0653 29.4565 80.1429 24.7001 80.1429C19.9436 80.1429 16 76.0653 16 70.9243C16 65.7833 19.9436 61.7057 24.7001 61.7057C29.4565 61.7057 33.4001 65.7833 33.4001 70.9243Z"
|
||||||
|
stroke="white" stroke-width="2"/>
|
||||||
</g>
|
</g>
|
||||||
<g filter="url(#filter3_d)">
|
<g filter="url(#filter3_d)">
|
||||||
<path d="M64 71.5C64 76.7932 59.9251 81 55 81C50.0749 81 46 76.7932 46 71.5C46 66.2068 50.0749 62 55 62C59.9251 62 64 66.2068 64 71.5Z" stroke="white" stroke-width="2"/>
|
<path d="M64 71.5C64 76.7932 59.9251 81 55 81C50.0749 81 46 76.7932 46 71.5C46 66.2068 50.0749 62 55 62C59.9251 62 64 66.2068 64 71.5Z"
|
||||||
|
stroke="white" stroke-width="2"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="filter0_d" x="58.84" y="50.704" width="25.4126" height="17.436" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter0_d" x="58.84" y="50.704" width="25.4126" height="17.436" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -30,7 +39,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter1_d" x="30" y="12" width="37.9954" height="38" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter1_d" x="30" y="12" width="37.9954" height="38" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -39,7 +49,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter2_d" x="11" y="51" width="54.7667" height="38.1429" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter2_d" x="11" y="51" width="54.7667" height="38.1429" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
@ -48,7 +59,8 @@
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
</filter>
|
</filter>
|
||||||
<filter id="filter3_d" x="41" y="61" width="28" height="29" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
<filter id="filter3_d" x="41" y="61" width="28" height="29" filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB">
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
<feOffset dy="4"/>
|
<feOffset dy="4"/>
|
||||||
|
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 7.2 KiB |