58 Commits

Author SHA1 Message Date
b3936ae649 Forgot to change int to uint8_t in Point constructor 2024-05-08 00:28:29 +02:00
08dce8eb7e Update readme 2024-05-08 00:17:32 +02:00
e739821264 Added filepath to heightmap class 2024-05-08 00:17:09 +02:00
59ce1c0177 Fix report formating 2024-05-08 00:16:34 +02:00
6e3217105e report 2024-05-07 23:57:12 +02:00
093f55f525 Added one example file and renamed the rest 2024-05-07 22:49:49 +02:00
903f2e740f Merge remote-tracking branch 'origin/main' 2024-05-07 22:29:49 +02:00
esther
16279bb224 wrote on report 2024-05-07 22:26:36 +02:00
3bf8dbfb79 Update report 2024-05-07 22:26:11 +02:00
dc020a4f38 Update cmakelists 2024-05-07 22:25:42 +02:00
f857f7e951 Remove cellmap class 2024-05-07 22:25:13 +02:00
264c0341ed FINALLY FOUND THE LAST ERROR IN THE LOOKUPTABLE 😎🥳 2024-05-07 21:03:47 +02:00
b4b89c2282 Added steepness cli arg 2024-05-07 20:47:33 +02:00
9ab5aac40f Changed last remaining mallocs to new 2024-05-07 20:34:40 +02:00
7037874923 Added statistics cli arg 2024-05-07 19:44:03 +02:00
a785407c6d Merge branch 'Statistics' 2024-05-07 19:41:15 +02:00
97c52ecef3 Tried fixing gdal bullshit in steepnes method 2024-05-07 19:38:34 +02:00
9300fa729c Fix lookuptable 2024-05-07 18:48:33 +02:00
esther
c47565eabb added some methods to the heightmap class to calculate steepness and statistics 2024-05-07 18:32:07 +02:00
62d62987d3 use lookuptable to draw lines 2024-05-07 17:20:23 +02:00
5845ae6693 Tried to fix check for if cases can connect 2024-05-07 16:18:42 +02:00
47d0e29868 Started on validation if a case can come after another 2024-05-07 15:26:50 +02:00
43f8b78830 Implemented cli 2024-05-07 13:29:49 +02:00
08255875c1 Added the argh library as a subproject 2024-05-07 11:40:33 +02:00
ec0a31db5d Small typo 2024-05-07 11:00:49 +02:00
esther
32a0b18f8e Merge branch 'main' of gitlab.com:Trygve/contour-creator 2024-05-07 10:58:15 +02:00
esther
ab96f9477e added some comments 2024-05-07 10:48:48 +02:00
790cf44f8b bugfix 2024-05-07 10:35:31 +02:00
df7cac1095 cleanup 2024-05-07 10:34:29 +02:00
93fcbc6a39 Merge branch 'drawing-lines' 2024-05-07 10:25:01 +02:00
95649f005b ITS WORKING (somewhat) 2024-05-06 23:50:11 +02:00
1ec3e8c778 slides 2024-05-06 14:16:04 +02:00
c535eec958 Debugging without omp 2024-05-06 11:37:10 +02:00
4f709d3b07 Use linked list to store the order of the points 2024-05-05 16:53:00 +02:00
4cd4f773bf Fixed stupid mistake in for loop 2024-05-03 20:54:45 +02:00
9d8df3256d Started on continus line drawing 2024-05-03 20:33:28 +02:00
esther
77467594bd improved vector_cellmap function 2024-05-02 21:02:48 +02:00
0188b9e29d Merge branch 'main' into HEAD 2024-04-30 15:12:48 +02:00
b800ceaf98 Changed file wrriting to use list of points 2024-04-30 15:11:44 +02:00
1dcfb0e737 Changed file wrriting to use list of points 2024-04-30 15:09:18 +02:00
esther
228945a767 tried to implement finding contour lines 2024-04-30 15:07:04 +02:00
esther
d046e18c43 changed to create a vector 2024-04-29 15:02:50 +02:00
esther
33dd409c43 changed contour creator 2024-04-29 14:56:06 +02:00
esther
5cd5627bb7 introduced class Point and changed cell map to create lines 2024-04-29 14:54:44 +02:00
29a7ddb083 Cleanup 2024-04-28 22:31:05 +02:00
98a312094e Added box blur 2024-04-28 22:30:37 +02:00
882764a13d Created a lookup table 2024-04-27 18:01:43 +02:00
f962a40ade Fixed segfault 2024-04-27 17:15:37 +02:00
ee0b87c2b3 Start to implement line drawing 2024-04-26 15:40:09 +02:00
0485253893 Added georeferencing 2024-04-25 23:20:38 +02:00
e457adf244 Fixed spelling 2024-04-23 22:45:40 +02:00
6469a26cf1 Update documentation 2024-04-23 22:37:11 +02:00
esther
c94a59616a Merge branch 'main' of gitlab.com:Trygve/contour-creator 2024-04-23 22:00:48 +02:00
esther
781b96215a Wrote on lab 5 about parallelization and definitions. 2024-04-23 20:37:53 +02:00
e287323332 Oppdaterte ER diagram 2024-04-23 15:05:46 +02:00
0319f2ae29 lab 5 2024-04-23 14:33:50 +02:00
789f5aa84e Update readme 2024-04-22 16:13:06 +02:00
8084db97a5 Put all classes in one header and rename case to cell 2024-04-22 16:10:02 +02:00
24 changed files with 4100 additions and 461 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "extern/argh"]
path = extern/argh
url = https://github.com/adishavit/argh.git

View File

@@ -1,15 +1,22 @@
cmake_minimum_required(VERSION 3.20)
project( project(
contour-creator contour-creator
LANGUAGES CXX) LANGUAGES CXX)
find_package(GDAL CONFIG REQUIRED)
add_executable(${PROJECT_NAME} add_executable(${PROJECT_NAME}
src/HeightMap.cpp src/CaseMap.cpp src/main.cpp src/HeightMap.cpp src/main.cpp
) )
# Argh is a simple argrument parser
add_subdirectory(extern/argh)
target_link_libraries(${PROJECT_NAME} PRIVATE argh)
# Gdal is used for geodata IO
find_package(GDAL CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE GDAL::GDAL)
find_package(OpenMP) find_package(OpenMP)
if(OpenMP_CXX_FOUND) if(OpenMP_CXX_FOUND)
target_link_libraries(${PROJECT_NAME} PUBLIC OpenMP::OpenMP_CXX) target_link_libraries(${PROJECT_NAME} PUBLIC OpenMP::OpenMP_CXX)
endif() endif()
target_link_libraries(${PROJECT_NAME} GDAL::GDAL)

View File

@@ -42,7 +42,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places. # title of most generated pages and in a few other places.
# The default value is: My Project. # The default value is: My Project.
PROJECT_NAME = "Marching Squares" PROJECT_NAME = "Contour Creator"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This # The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version

View File

@@ -3,11 +3,26 @@ This program takes a tiff heightmap and produces vector contours.
This is our project for the INF205: Resource-efficient programming course This is our project for the INF205: Resource-efficient programming course
## Status ## Status
- [x] Read .tif file into memory using gdal - [x] Read .tif file into memory using gdal
- [ ] Run the marching squares algorithm and produce a "casemap" - [x] Run the marching squares algorithm and produce a "cellmap"
- [ ] Use a lookuptable to produce a vector file from the "casemap" - [x] Use a lookuptable to produce a vector file from the "cellmap"
## Dependencies ## Dependencies
- GDAL - GDAL >= 3.5
- OpenMP - OpenMP
- CMake
If you want to clone the repo with the example files you need [git-lfs](https://git-lfs.com/) installed and activated with ´git lfs install´
You also need to clone with submodules to get the argh library:
```
git clone --recurse-submodules https://gitlab.com/Trygve/contour-creator
```
To install the packages on Fedora run
```
dnf install g++ git-lfs cmake gdal-devel
```
on Debian:
```
apt install g++ git-lfs cmake libgdal-dev
```
## How to build: ## How to build:
``` ```
mkdir build mkdir build
@@ -15,4 +30,8 @@ cd build
cmake -DCMAKE_BUILD_TYPE=Debug .. cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . --parallel cmake --build . --parallel
``` ```
Then you can run `./contour-creator PATH/TO/HEIGTHMAP.TIF` Then you can run `./contour-creator PATH/TO/HEIGTHMAP.TIF`
Run an example file: `./contour-creator "../example_files/ås.tif"`
## Docs
[Doxygen output](https://trygve.gitlab.io/contour-creator/)

View File

@@ -3,4 +3,4 @@ rm -rf build
mkdir build mkdir build
cmake -DCMAKE_BUILD_TYPE=Debug -B build cmake -DCMAKE_BUILD_TYPE=Debug -B build
cmake --build build --parallel cmake --build build --parallel
build/contour-creator 'example_files/crop.tif' build/contour-creator --interval=1 --blur --stats example_files/ås_crop.tif

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<gaphor xmlns="http://gaphor.sourceforge.net/model" version="3.0" gaphor-version="2.24.0"> <gaphor xmlns="http://gaphor.sourceforge.net/model" version="3.0" gaphor-version="2.25.1">
<StyleSheet id="58d6989a-66f8-11ec-b4c8-0456e5e540ed"/> <StyleSheet id="58d6989a-66f8-11ec-b4c8-0456e5e540ed"/>
<Package id="58d6c2e8-66f8-11ec-b4c8-0456e5e540ed"> <Package id="58d6c2e8-66f8-11ec-b4c8-0456e5e540ed">
<name> <name>
<val>New model</val> <val>Contour Creator</val>
</name> </name>
<ownedDiagram> <ownedDiagram>
<reflist> <reflist>
@@ -13,7 +13,7 @@
<ownedType> <ownedType>
<reflist> <reflist>
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/> <ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
<ref refid="4a8d98db-e76f-11ee-9ded-8bb162b1502a"/> <ref refid="1754a50e-0cac-11ef-86ae-59b56c446183"/>
</reflist> </reflist>
</ownedType> </ownedType>
</Package> </Package>
@@ -22,24 +22,15 @@
<ref refid="58d6c2e8-66f8-11ec-b4c8-0456e5e540ed"/> <ref refid="58d6c2e8-66f8-11ec-b4c8-0456e5e540ed"/>
</element> </element>
<name> <name>
<val>New diagram</val> <val>ER</val>
</name> </name>
<ownedPresentation> <ownedPresentation>
<reflist> <reflist>
<ref refid="0c228e70-e76f-11ee-90ec-8bb162b1502a"/> <ref refid="0c228e70-e76f-11ee-90ec-8bb162b1502a"/>
<ref refid="4a8ddfb4-e76f-11ee-b091-8bb162b1502a"/> <ref refid="1754dd05-0cac-11ef-824e-59b56c446183"/>
<ref refid="af7f9c76-f19d-11ee-b2af-49ae45d8f008"/>
</reflist> </reflist>
</ownedPresentation> </ownedPresentation>
</Diagram> </Diagram>
<Diagram id="0712faa4-e76f-11ee-80e8-8bb162b1502a">
<diagramType>
<val>cls</val>
</diagramType>
<name>
<val>New Diagram</val>
</name>
</Diagram>
<Class id="0c22379b-e76f-11ee-8193-8bb162b1502a"> <Class id="0c22379b-e76f-11ee-8193-8bb162b1502a">
<name> <name>
<val>HeightMap</val> <val>HeightMap</val>
@@ -52,6 +43,12 @@
<ref refid="159a588d-e76f-11ee-84cd-8bb162b1502a"/> <ref refid="159a588d-e76f-11ee-84cd-8bb162b1502a"/>
<ref refid="175c0a93-e76f-11ee-8c73-8bb162b1502a"/> <ref refid="175c0a93-e76f-11ee-8c73-8bb162b1502a"/>
<ref refid="47a99d4d-e76f-11ee-9c60-8bb162b1502a"/> <ref refid="47a99d4d-e76f-11ee-9c60-8bb162b1502a"/>
<ref refid="f1a417ac-f674-11ee-8f46-756c0364fd19"/>
<ref refid="f72f1442-f674-11ee-b3f4-756c0364fd19"/>
<ref refid="033b1fcf-f675-11ee-8fa9-756c0364fd19"/>
<ref refid="79fcf06c-0171-11ef-b98e-75fbb1f7e3ee"/>
<ref refid="56cb7284-0cac-11ef-8675-59b56c446183"/>
<ref refid="77a8bf26-0cac-11ef-9642-59b56c446183"/>
</reflist> </reflist>
</ownedAttribute> </ownedAttribute>
<package> <package>
@@ -65,16 +62,16 @@
</Class> </Class>
<ClassItem id="0c228e70-e76f-11ee-90ec-8bb162b1502a"> <ClassItem id="0c228e70-e76f-11ee-90ec-8bb162b1502a">
<matrix> <matrix>
<val>(1.0, 0.0, 0.0, 1.0, 213.62031249999998, 137.04296875)</val> <val>(1.0, 0.0, 0.0, 1.0, 213.89827124049944, 137.04296875)</val>
</matrix> </matrix>
<top-left> <top-left>
<val>(0.0, 0.0)</val> <val>(0.0, 0.0)</val>
</top-left> </top-left>
<width> <width>
<val>177.0</val> <val>311.0</val>
</width> </width>
<height> <height>
<val>108.0</val> <val>185.0</val>
</height> </height>
<diagram> <diagram>
<ref refid="58d6c536-66f8-11ec-b4c8-0456e5e540ed"/> <ref refid="58d6c536-66f8-11ec-b4c8-0456e5e540ed"/>
@@ -91,7 +88,7 @@
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/> <ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_> </class_>
<name> <name>
<val>x</val> <val>width</val>
</name> </name>
<typeValue> <typeValue>
<val>int</val> <val>int</val>
@@ -102,7 +99,7 @@
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/> <ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_> </class_>
<name> <name>
<val>y</val> <val>height</val>
</name> </name>
<typeValue> <typeValue>
<val>int</val> <val>int</val>
@@ -113,18 +110,65 @@
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/> <ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_> </class_>
<name> <name>
<val>+ heights: float*</val> <val></val>
</name> </name>
</Property> </Property>
<Class id="4a8d98db-e76f-11ee-9ded-8bb162b1502a"> <Property id="f1a417ac-f674-11ee-8f46-756c0364fd19">
<class_>
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_>
<name> <name>
<val>Cells</val> <val>min</val>
</name>
<typeValue>
<val>float</val>
</typeValue>
</Property>
<Property id="f72f1442-f674-11ee-b3f4-756c0364fd19">
<class_>
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_>
<name>
<val>max float</val>
</name>
</Property>
<Property id="033b1fcf-f675-11ee-8fa9-756c0364fd19">
<class_>
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_>
<name>
<val>+ data: float*</val>
</name>
</Property>
<Property id="79fcf06c-0171-11ef-b98e-75fbb1f7e3ee">
<class_>
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_>
<name>
<val>OGRSpatialReference</val>
</name>
<typeValue>
<val>reference_system</val>
</typeValue>
</Property>
<Diagram id="14a35e81-0cac-11ef-8c1c-59b56c446183">
<diagramType>
<val>cls</val>
</diagramType>
<name>
<val>New Diagram</val>
</name>
</Diagram>
<Class id="1754a50e-0cac-11ef-86ae-59b56c446183">
<name>
<val>Point</val>
</name> </name>
<ownedAttribute> <ownedAttribute>
<reflist> <reflist>
<ref refid="58a782c4-e76f-11ee-af59-8bb162b1502a"/> <ref refid="34feac8d-0cac-11ef-85b7-59b56c446183"/>
<ref refid="59eb8e6d-e76f-11ee-9d79-8bb162b1502a"/> <ref refid="3768ce02-0cac-11ef-9b57-59b56c446183"/>
<ref refid="625d120c-e76f-11ee-aeac-8bb162b1502a"/> <ref refid="3eeba789-0cac-11ef-b42f-59b56c446183"/>
<ref refid="46c075e3-0cac-11ef-8e54-59b56c446183"/>
</reflist> </reflist>
</ownedAttribute> </ownedAttribute>
<package> <package>
@@ -132,22 +176,22 @@
</package> </package>
<presentation> <presentation>
<reflist> <reflist>
<ref refid="4a8ddfb4-e76f-11ee-b091-8bb162b1502a"/> <ref refid="1754dd05-0cac-11ef-824e-59b56c446183"/>
</reflist> </reflist>
</presentation> </presentation>
</Class> </Class>
<ClassItem id="4a8ddfb4-e76f-11ee-b091-8bb162b1502a"> <ClassItem id="1754dd05-0cac-11ef-824e-59b56c446183">
<matrix> <matrix>
<val>(1.0, 0.0, 0.0, 1.0, 412.3077864636515, 137.04296875)</val> <val>(1.0, 0.0, 0.0, 1.0, 584.7889709472656, 160.69140625)</val>
</matrix> </matrix>
<top-left> <top-left>
<val>(0.0, 0.0)</val> <val>(0.0, 0.0)</val>
</top-left> </top-left>
<width> <width>
<val>155.0</val> <val>130.0</val>
</width> </width>
<height> <height>
<val>108.0</val> <val>125.0</val>
</height> </height>
<diagram> <diagram>
<ref refid="58d6c536-66f8-11ec-b4c8-0456e5e540ed"/> <ref refid="58d6c536-66f8-11ec-b4c8-0456e5e540ed"/>
@@ -156,12 +200,12 @@
<val>0</val> <val>0</val>
</show_operations> </show_operations>
<subject> <subject>
<ref refid="4a8d98db-e76f-11ee-9ded-8bb162b1502a"/> <ref refid="1754a50e-0cac-11ef-86ae-59b56c446183"/>
</subject> </subject>
</ClassItem> </ClassItem>
<Property id="58a782c4-e76f-11ee-af59-8bb162b1502a"> <Property id="34feac8d-0cac-11ef-85b7-59b56c446183">
<class_> <class_>
<ref refid="4a8d98db-e76f-11ee-9ded-8bb162b1502a"/> <ref refid="1754a50e-0cac-11ef-86ae-59b56c446183"/>
</class_> </class_>
<name> <name>
<val>x</val> <val>x</val>
@@ -170,9 +214,9 @@
<val>int</val> <val>int</val>
</typeValue> </typeValue>
</Property> </Property>
<Property id="59eb8e6d-e76f-11ee-9d79-8bb162b1502a"> <Property id="3768ce02-0cac-11ef-9b57-59b56c446183">
<class_> <class_>
<ref refid="4a8d98db-e76f-11ee-9ded-8bb162b1502a"/> <ref refid="1754a50e-0cac-11ef-86ae-59b56c446183"/>
</class_> </class_>
<name> <name>
<val>y</val> <val>y</val>
@@ -181,42 +225,42 @@
<val>int</val> <val>int</val>
</typeValue> </typeValue>
</Property> </Property>
<Property id="625d120c-e76f-11ee-aeac-8bb162b1502a"> <Property id="3eeba789-0cac-11ef-b42f-59b56c446183">
<class_> <class_>
<ref refid="4a8d98db-e76f-11ee-9ded-8bb162b1502a"/> <ref refid="1754a50e-0cac-11ef-86ae-59b56c446183"/>
</class_> </class_>
<name> <name>
<val>+ cases: int*</val> <val>mscase</val>
</name>
<typeValue>
<val>int</val>
</typeValue>
</Property>
<Property id="46c075e3-0cac-11ef-8e54-59b56c446183">
<class_>
<ref refid="1754a50e-0cac-11ef-86ae-59b56c446183"/>
</class_>
<name>
<val>allocated</val>
</name>
<typeValue>
<val>bool</val>
</typeValue>
</Property>
<Property id="56cb7284-0cac-11ef-8675-59b56c446183">
<class_>
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_>
<name>
<val>geotransform: double*</val>
</name>
</Property>
<Property id="77a8bf26-0cac-11ef-9642-59b56c446183">
<class_>
<ref refid="0c22379b-e76f-11ee-8193-8bb162b1502a"/>
</class_>
<name>
<val>filepath: char*</val>
</name> </name>
</Property> </Property>
<Comment id="af7f7fe7-f19d-11ee-bfaf-49ae45d8f008">
<body>
<val>Both will need to implement the rule of three because they store raw pointers to arrays</val>
</body>
<presentation>
<reflist>
<ref refid="af7f9c76-f19d-11ee-b2af-49ae45d8f008"/>
</reflist>
</presentation>
</Comment>
<CommentItem id="af7f9c76-f19d-11ee-b2af-49ae45d8f008">
<matrix>
<val>(1.0, 0.0, 0.0, 1.0, 315.77064657107337, 163.47265625)</val>
</matrix>
<top-left>
<val>(0.0, 124.1015625)</val>
</top-left>
<width>
<val>193.07427978515625</val>
</width>
<height>
<val>97.14059448242188</val>
</height>
<diagram>
<ref refid="58d6c536-66f8-11ec-b4c8-0456e5e540ed"/>
</diagram>
<subject>
<ref refid="af7f7fe7-f19d-11ee-bfaf-49ae45d8f008"/>
</subject>
</CommentItem>
</gaphor> </gaphor>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="373" height="266" viewBox="0 0 373 266"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="520" height="204" viewBox="0 0 520 204">
<defs> <defs>
<g> <g>
<g id="glyph-0-0"> <g id="glyph-0-0">
@@ -30,13 +30,13 @@
<path d="M 3.625 -1.109375 L 3.625 2.90625 L 1.171875 2.90625 L 1.171875 -7.65625 L 3.625 -7.65625 L 3.625 -6.53125 C 3.957031 -6.976562 4.328125 -7.304688 4.734375 -7.515625 C 5.148438 -7.734375 5.625 -7.84375 6.15625 -7.84375 C 7.101562 -7.84375 7.878906 -7.46875 8.484375 -6.71875 C 9.085938 -5.96875 9.390625 -5.003906 9.390625 -3.828125 C 9.390625 -2.640625 9.085938 -1.671875 8.484375 -0.921875 C 7.878906 -0.171875 7.101562 0.203125 6.15625 0.203125 C 5.625 0.203125 5.148438 0.0976562 4.734375 -0.109375 C 4.328125 -0.328125 3.957031 -0.660156 3.625 -1.109375 Z M 5.25 -6.0625 C 4.726562 -6.0625 4.328125 -5.867188 4.046875 -5.484375 C 3.765625 -5.097656 3.625 -4.546875 3.625 -3.828125 C 3.625 -3.097656 3.765625 -2.539062 4.046875 -2.15625 C 4.328125 -1.769531 4.726562 -1.578125 5.25 -1.578125 C 5.769531 -1.578125 6.164062 -1.769531 6.4375 -2.15625 C 6.71875 -2.539062 6.859375 -3.097656 6.859375 -3.828125 C 6.859375 -4.554688 6.71875 -5.109375 6.4375 -5.484375 C 6.164062 -5.867188 5.769531 -6.0625 5.25 -6.0625 Z M 5.25 -6.0625 "/> <path d="M 3.625 -1.109375 L 3.625 2.90625 L 1.171875 2.90625 L 1.171875 -7.65625 L 3.625 -7.65625 L 3.625 -6.53125 C 3.957031 -6.976562 4.328125 -7.304688 4.734375 -7.515625 C 5.148438 -7.734375 5.625 -7.84375 6.15625 -7.84375 C 7.101562 -7.84375 7.878906 -7.46875 8.484375 -6.71875 C 9.085938 -5.96875 9.390625 -5.003906 9.390625 -3.828125 C 9.390625 -2.640625 9.085938 -1.671875 8.484375 -0.921875 C 7.878906 -0.171875 7.101562 0.203125 6.15625 0.203125 C 5.625 0.203125 5.148438 0.0976562 4.734375 -0.109375 C 4.328125 -0.328125 3.957031 -0.660156 3.625 -1.109375 Z M 5.25 -6.0625 C 4.726562 -6.0625 4.328125 -5.867188 4.046875 -5.484375 C 3.765625 -5.097656 3.625 -4.546875 3.625 -3.828125 C 3.625 -3.097656 3.765625 -2.539062 4.046875 -2.15625 C 4.328125 -1.769531 4.726562 -1.578125 5.25 -1.578125 C 5.769531 -1.578125 6.164062 -1.769531 6.4375 -2.15625 C 6.71875 -2.539062 6.859375 -3.097656 6.859375 -3.828125 C 6.859375 -4.554688 6.71875 -5.109375 6.4375 -5.484375 C 6.164062 -5.867188 5.769531 -6.0625 5.25 -6.0625 Z M 5.25 -6.0625 "/>
</g> </g>
<g id="glyph-0-9"> <g id="glyph-0-9">
<path d="M 9.375 -0.5625 C 8.894531 -0.3125 8.390625 -0.125 7.859375 0 C 7.335938 0.132812 6.796875 0.203125 6.234375 0.203125 C 4.523438 0.203125 3.175781 -0.269531 2.1875 -1.21875 C 1.195312 -2.175781 0.703125 -3.46875 0.703125 -5.09375 C 0.703125 -6.726562 1.195312 -8.019531 2.1875 -8.96875 C 3.175781 -9.914062 4.523438 -10.390625 6.234375 -10.390625 C 6.796875 -10.390625 7.335938 -10.328125 7.859375 -10.203125 C 8.390625 -10.078125 8.894531 -9.882812 9.375 -9.625 L 9.375 -7.515625 C 8.882812 -7.847656 8.398438 -8.09375 7.921875 -8.25 C 7.453125 -8.40625 6.957031 -8.484375 6.4375 -8.484375 C 5.5 -8.484375 4.757812 -8.179688 4.21875 -7.578125 C 3.6875 -6.972656 3.421875 -6.144531 3.421875 -5.09375 C 3.421875 -4.039062 3.6875 -3.210938 4.21875 -2.609375 C 4.757812 -2.003906 5.5 -1.703125 6.4375 -1.703125 C 6.957031 -1.703125 7.453125 -1.78125 7.921875 -1.9375 C 8.398438 -2.09375 8.882812 -2.335938 9.375 -2.671875 Z M 9.375 -0.5625 "/> <path d="M 1.28125 -10.203125 L 5.65625 -10.203125 C 6.957031 -10.203125 7.953125 -9.914062 8.640625 -9.34375 C 9.335938 -8.769531 9.6875 -7.945312 9.6875 -6.875 C 9.6875 -5.800781 9.335938 -4.976562 8.640625 -4.40625 C 7.953125 -3.832031 6.957031 -3.546875 5.65625 -3.546875 L 3.921875 -3.546875 L 3.921875 0 L 1.28125 0 Z M 3.921875 -8.296875 L 3.921875 -5.453125 L 5.375 -5.453125 C 5.882812 -5.453125 6.273438 -5.570312 6.546875 -5.8125 C 6.828125 -6.0625 6.96875 -6.414062 6.96875 -6.875 C 6.96875 -7.332031 6.828125 -7.679688 6.546875 -7.921875 C 6.273438 -8.171875 5.882812 -8.296875 5.375 -8.296875 Z M 3.921875 -8.296875 "/>
</g> </g>
<g id="glyph-0-10"> <g id="glyph-0-10">
<path d="M 1.171875 -10.640625 L 3.625 -10.640625 L 3.625 0 L 1.171875 0 Z M 1.171875 -10.640625 "/> <path d="M 4.8125 -6.09375 C 4.269531 -6.09375 3.859375 -5.894531 3.578125 -5.5 C 3.296875 -5.113281 3.15625 -4.554688 3.15625 -3.828125 C 3.15625 -3.085938 3.296875 -2.519531 3.578125 -2.125 C 3.859375 -1.738281 4.269531 -1.546875 4.8125 -1.546875 C 5.351562 -1.546875 5.765625 -1.738281 6.046875 -2.125 C 6.328125 -2.519531 6.46875 -3.085938 6.46875 -3.828125 C 6.46875 -4.554688 6.328125 -5.113281 6.046875 -5.5 C 5.765625 -5.894531 5.351562 -6.09375 4.8125 -6.09375 Z M 4.8125 -7.84375 C 6.132812 -7.84375 7.164062 -7.484375 7.90625 -6.765625 C 8.644531 -6.054688 9.015625 -5.078125 9.015625 -3.828125 C 9.015625 -2.566406 8.644531 -1.578125 7.90625 -0.859375 C 7.164062 -0.148438 6.132812 0.203125 4.8125 0.203125 C 3.5 0.203125 2.46875 -0.148438 1.71875 -0.859375 C 0.976562 -1.578125 0.609375 -2.566406 0.609375 -3.828125 C 0.609375 -5.078125 0.976562 -6.054688 1.71875 -6.765625 C 2.46875 -7.484375 3.5 -7.84375 4.8125 -7.84375 Z M 4.8125 -7.84375 "/>
</g> </g>
<g id="glyph-0-11"> <g id="glyph-0-11">
<path d="M 7.15625 -7.421875 L 7.15625 -5.5625 C 6.632812 -5.78125 6.128906 -5.941406 5.640625 -6.046875 C 5.148438 -6.160156 4.691406 -6.21875 4.265625 -6.21875 C 3.796875 -6.21875 3.445312 -6.15625 3.21875 -6.03125 C 3 -5.914062 2.890625 -5.738281 2.890625 -5.5 C 2.890625 -5.300781 2.972656 -5.148438 3.140625 -5.046875 C 3.304688 -4.941406 3.613281 -4.863281 4.0625 -4.8125 L 4.484375 -4.765625 C 5.742188 -4.597656 6.585938 -4.332031 7.015625 -3.96875 C 7.453125 -3.601562 7.671875 -3.03125 7.671875 -2.25 C 7.671875 -1.4375 7.367188 -0.820312 6.765625 -0.40625 C 6.160156 0 5.265625 0.203125 4.078125 0.203125 C 3.566406 0.203125 3.039062 0.160156 2.5 0.078125 C 1.96875 -0.00390625 1.414062 -0.125 0.84375 -0.28125 L 0.84375 -2.140625 C 1.332031 -1.898438 1.832031 -1.71875 2.34375 -1.59375 C 2.851562 -1.476562 3.375 -1.421875 3.90625 -1.421875 C 4.382812 -1.421875 4.742188 -1.488281 4.984375 -1.625 C 5.222656 -1.757812 5.34375 -1.957031 5.34375 -2.21875 C 5.34375 -2.4375 5.257812 -2.597656 5.09375 -2.703125 C 4.925781 -2.804688 4.597656 -2.890625 4.109375 -2.953125 L 3.671875 -3.015625 C 2.578125 -3.148438 1.8125 -3.398438 1.375 -3.765625 C 0.9375 -4.140625 0.71875 -4.703125 0.71875 -5.453125 C 0.71875 -6.265625 0.992188 -6.863281 1.546875 -7.25 C 2.109375 -7.644531 2.960938 -7.84375 4.109375 -7.84375 C 4.566406 -7.84375 5.039062 -7.804688 5.53125 -7.734375 C 6.03125 -7.671875 6.570312 -7.566406 7.15625 -7.421875 Z M 7.15625 -7.421875 "/> <path d="M 8.875 -4.65625 L 8.875 0 L 6.40625 0 L 6.40625 -3.5625 C 6.40625 -4.226562 6.390625 -4.6875 6.359375 -4.9375 C 6.335938 -5.1875 6.289062 -5.367188 6.21875 -5.484375 C 6.125 -5.648438 5.992188 -5.773438 5.828125 -5.859375 C 5.660156 -5.953125 5.472656 -6 5.265625 -6 C 4.753906 -6 4.351562 -5.800781 4.0625 -5.40625 C 3.769531 -5.007812 3.625 -4.460938 3.625 -3.765625 L 3.625 0 L 1.171875 0 L 1.171875 -7.65625 L 3.625 -7.65625 L 3.625 -6.53125 C 3.988281 -6.976562 4.378906 -7.304688 4.796875 -7.515625 C 5.210938 -7.734375 5.671875 -7.84375 6.171875 -7.84375 C 7.054688 -7.84375 7.726562 -7.570312 8.1875 -7.03125 C 8.644531 -6.488281 8.875 -5.695312 8.875 -4.65625 Z M 8.875 -4.65625 "/>
</g> </g>
<g id="glyph-1-0"> <g id="glyph-1-0">
<path d="M 6.4375 -8.78125 L 6.4375 -4.96875 L 10.25 -4.96875 L 10.25 -3.8125 L 6.4375 -3.8125 L 6.4375 0 L 5.296875 0 L 5.296875 -3.8125 L 1.484375 -3.8125 L 1.484375 -4.96875 L 5.296875 -4.96875 L 5.296875 -8.78125 Z M 6.4375 -8.78125 "/> <path d="M 6.4375 -8.78125 L 6.4375 -4.96875 L 10.25 -4.96875 L 10.25 -3.8125 L 6.4375 -3.8125 L 6.4375 0 L 5.296875 0 L 5.296875 -3.8125 L 1.484375 -3.8125 L 1.484375 -4.96875 L 5.296875 -4.96875 L 5.296875 -8.78125 Z M 6.4375 -8.78125 "/>
@@ -44,25 +44,25 @@
<g id="glyph-1-1"> <g id="glyph-1-1">
</g> </g>
<g id="glyph-1-2"> <g id="glyph-1-2">
<path d="M 7.6875 -7.65625 L 4.921875 -3.9375 L 7.828125 0 L 6.34375 0 L 4.109375 -3.015625 L 1.890625 0 L 0.40625 0 L 3.375 -4 L 0.65625 -7.65625 L 2.140625 -7.65625 L 4.171875 -4.921875 L 6.203125 -7.65625 Z M 7.6875 -7.65625 "/> <path d="M 0.59375 -7.65625 L 1.84375 -7.65625 L 3.421875 -1.6875 L 4.984375 -7.65625 L 6.46875 -7.65625 L 8.046875 -1.6875 L 9.609375 -7.65625 L 10.859375 -7.65625 L 8.859375 0 L 7.375 0 L 5.734375 -6.28125 L 4.078125 0 L 2.59375 0 Z M 0.59375 -7.65625 "/>
</g> </g>
<g id="glyph-1-3"> <g id="glyph-1-3">
<path d="M 1.640625 -1.734375 L 3.078125 -1.734375 L 3.078125 0 L 1.640625 0 Z M 1.640625 -7.234375 L 3.078125 -7.234375 L 3.078125 -5.5 L 1.640625 -5.5 Z M 1.640625 -7.234375 "/>
</g>
<g id="glyph-1-4">
<path d="M 1.3125 -7.65625 L 2.578125 -7.65625 L 2.578125 0 L 1.3125 0 Z M 1.3125 -10.640625 L 2.578125 -10.640625 L 2.578125 -9.046875 L 1.3125 -9.046875 Z M 1.3125 -10.640625 "/> <path d="M 1.3125 -7.65625 L 2.578125 -7.65625 L 2.578125 0 L 1.3125 0 Z M 1.3125 -10.640625 L 2.578125 -10.640625 L 2.578125 -9.046875 L 1.3125 -9.046875 Z M 1.3125 -10.640625 "/>
</g> </g>
<g id="glyph-1-5"> <g id="glyph-1-4">
<path d="M 7.6875 -4.625 L 7.6875 0 L 6.421875 0 L 6.421875 -4.578125 C 6.421875 -5.304688 6.28125 -5.847656 6 -6.203125 C 5.71875 -6.566406 5.296875 -6.75 4.734375 -6.75 C 4.054688 -6.75 3.519531 -6.53125 3.125 -6.09375 C 2.726562 -5.664062 2.53125 -5.078125 2.53125 -4.328125 L 2.53125 0 L 1.265625 0 L 1.265625 -7.65625 L 2.53125 -7.65625 L 2.53125 -6.46875 C 2.832031 -6.925781 3.1875 -7.269531 3.59375 -7.5 C 4.007812 -7.726562 4.484375 -7.84375 5.015625 -7.84375 C 5.890625 -7.84375 6.550781 -7.566406 7 -7.015625 C 7.457031 -6.472656 7.6875 -5.675781 7.6875 -4.625 Z M 7.6875 -4.625 "/> <path d="M 6.359375 -6.5 L 6.359375 -10.640625 L 7.609375 -10.640625 L 7.609375 0 L 6.359375 0 L 6.359375 -1.15625 C 6.097656 -0.695312 5.765625 -0.351562 5.359375 -0.125 C 4.953125 0.09375 4.46875 0.203125 3.90625 0.203125 C 2.976562 0.203125 2.222656 -0.164062 1.640625 -0.90625 C 1.054688 -1.644531 0.765625 -2.617188 0.765625 -3.828125 C 0.765625 -5.023438 1.054688 -5.992188 1.640625 -6.734375 C 2.222656 -7.472656 2.976562 -7.84375 3.90625 -7.84375 C 4.46875 -7.84375 4.953125 -7.726562 5.359375 -7.5 C 5.765625 -7.28125 6.097656 -6.945312 6.359375 -6.5 Z M 2.078125 -3.828125 C 2.078125 -2.898438 2.265625 -2.171875 2.640625 -1.640625 C 3.023438 -1.117188 3.550781 -0.859375 4.21875 -0.859375 C 4.875 -0.859375 5.394531 -1.117188 5.78125 -1.640625 C 6.164062 -2.171875 6.359375 -2.898438 6.359375 -3.828125 C 6.359375 -4.742188 6.164062 -5.460938 5.78125 -5.984375 C 5.394531 -6.515625 4.875 -6.78125 4.21875 -6.78125 C 3.550781 -6.78125 3.023438 -6.515625 2.640625 -5.984375 C 2.265625 -5.460938 2.078125 -4.742188 2.078125 -3.828125 Z M 2.078125 -3.828125 "/>
</g> </g>
<g id="glyph-1-6"> <g id="glyph-1-5">
<path d="M 2.5625 -9.828125 L 2.5625 -7.65625 L 5.15625 -7.65625 L 5.15625 -6.671875 L 2.5625 -6.671875 L 2.5625 -2.515625 C 2.5625 -1.898438 2.644531 -1.5 2.8125 -1.3125 C 2.988281 -1.132812 3.335938 -1.046875 3.859375 -1.046875 L 5.15625 -1.046875 L 5.15625 0 L 3.859375 0 C 2.890625 0 2.21875 -0.179688 1.84375 -0.546875 C 1.476562 -0.910156 1.296875 -1.566406 1.296875 -2.515625 L 1.296875 -6.671875 L 0.375 -6.671875 L 0.375 -7.65625 L 1.296875 -7.65625 L 1.296875 -9.828125 Z M 2.5625 -9.828125 "/> <path d="M 2.5625 -9.828125 L 2.5625 -7.65625 L 5.15625 -7.65625 L 5.15625 -6.671875 L 2.5625 -6.671875 L 2.5625 -2.515625 C 2.5625 -1.898438 2.644531 -1.5 2.8125 -1.3125 C 2.988281 -1.132812 3.335938 -1.046875 3.859375 -1.046875 L 5.15625 -1.046875 L 5.15625 0 L 3.859375 0 C 2.890625 0 2.21875 -0.179688 1.84375 -0.546875 C 1.476562 -0.910156 1.296875 -1.566406 1.296875 -2.515625 L 1.296875 -6.671875 L 0.375 -6.671875 L 0.375 -7.65625 L 1.296875 -7.65625 L 1.296875 -9.828125 Z M 2.5625 -9.828125 "/>
</g> </g>
<g id="glyph-1-6">
<path d="M 7.6875 -4.625 L 7.6875 0 L 6.421875 0 L 6.421875 -4.578125 C 6.421875 -5.304688 6.28125 -5.847656 6 -6.203125 C 5.71875 -6.566406 5.296875 -6.75 4.734375 -6.75 C 4.054688 -6.75 3.519531 -6.53125 3.125 -6.09375 C 2.726562 -5.664062 2.53125 -5.078125 2.53125 -4.328125 L 2.53125 0 L 1.265625 0 L 1.265625 -10.640625 L 2.53125 -10.640625 L 2.53125 -6.46875 C 2.832031 -6.925781 3.1875 -7.269531 3.59375 -7.5 C 4.007812 -7.726562 4.484375 -7.84375 5.015625 -7.84375 C 5.890625 -7.84375 6.550781 -7.566406 7 -7.015625 C 7.457031 -6.472656 7.6875 -5.675781 7.6875 -4.625 Z M 7.6875 -4.625 "/>
</g>
<g id="glyph-1-7"> <g id="glyph-1-7">
<path d="M 4.5 0.71875 C 4.144531 1.625 3.796875 2.210938 3.453125 2.484375 C 3.117188 2.765625 2.671875 2.90625 2.109375 2.90625 L 1.109375 2.90625 L 1.109375 1.859375 L 1.84375 1.859375 C 2.1875 1.859375 2.453125 1.773438 2.640625 1.609375 C 2.835938 1.453125 3.050781 1.066406 3.28125 0.453125 L 3.515625 -0.125 L 0.421875 -7.65625 L 1.75 -7.65625 L 4.140625 -1.671875 L 6.53125 -7.65625 L 7.875 -7.65625 Z M 4.5 0.71875 "/> <path d="M 1.640625 -1.734375 L 3.078125 -1.734375 L 3.078125 0 L 1.640625 0 Z M 1.640625 -7.234375 L 3.078125 -7.234375 L 3.078125 -5.5 L 1.640625 -5.5 Z M 1.640625 -7.234375 "/>
</g> </g>
<g id="glyph-1-8"> <g id="glyph-1-8">
<path d="M 7.6875 -4.625 L 7.6875 0 L 6.421875 0 L 6.421875 -4.578125 C 6.421875 -5.304688 6.28125 -5.847656 6 -6.203125 C 5.71875 -6.566406 5.296875 -6.75 4.734375 -6.75 C 4.054688 -6.75 3.519531 -6.53125 3.125 -6.09375 C 2.726562 -5.664062 2.53125 -5.078125 2.53125 -4.328125 L 2.53125 0 L 1.265625 0 L 1.265625 -10.640625 L 2.53125 -10.640625 L 2.53125 -6.46875 C 2.832031 -6.925781 3.1875 -7.269531 3.59375 -7.5 C 4.007812 -7.726562 4.484375 -7.84375 5.015625 -7.84375 C 5.890625 -7.84375 6.550781 -7.566406 7 -7.015625 C 7.457031 -6.472656 7.6875 -5.675781 7.6875 -4.625 Z M 7.6875 -4.625 "/> <path d="M 7.6875 -4.625 L 7.6875 0 L 6.421875 0 L 6.421875 -4.578125 C 6.421875 -5.304688 6.28125 -5.847656 6 -6.203125 C 5.71875 -6.566406 5.296875 -6.75 4.734375 -6.75 C 4.054688 -6.75 3.519531 -6.53125 3.125 -6.09375 C 2.726562 -5.664062 2.53125 -5.078125 2.53125 -4.328125 L 2.53125 0 L 1.265625 0 L 1.265625 -7.65625 L 2.53125 -7.65625 L 2.53125 -6.46875 C 2.832031 -6.925781 3.1875 -7.269531 3.59375 -7.5 C 4.007812 -7.726562 4.484375 -7.84375 5.015625 -7.84375 C 5.890625 -7.84375 6.550781 -7.566406 7 -7.015625 C 7.457031 -6.472656 7.6875 -5.675781 7.6875 -4.625 Z M 7.6875 -4.625 "/>
</g> </g>
<g id="glyph-1-9"> <g id="glyph-1-9">
<path d="M 7.875 -4.140625 L 7.875 -3.53125 L 2.078125 -3.53125 C 2.140625 -2.664062 2.398438 -2.003906 2.859375 -1.546875 C 3.328125 -1.097656 3.976562 -0.875 4.8125 -0.875 C 5.300781 -0.875 5.769531 -0.929688 6.21875 -1.046875 C 6.675781 -1.160156 7.128906 -1.335938 7.578125 -1.578125 L 7.578125 -0.390625 C 7.117188 -0.203125 6.648438 -0.0546875 6.171875 0.046875 C 5.703125 0.148438 5.226562 0.203125 4.75 0.203125 C 3.519531 0.203125 2.546875 -0.148438 1.828125 -0.859375 C 1.117188 -1.578125 0.765625 -2.539062 0.765625 -3.75 C 0.765625 -5.007812 1.101562 -6.003906 1.78125 -6.734375 C 2.457031 -7.472656 3.375 -7.84375 4.53125 -7.84375 C 5.5625 -7.84375 6.375 -7.507812 6.96875 -6.84375 C 7.570312 -6.1875 7.875 -5.285156 7.875 -4.140625 Z M 6.609375 -4.515625 C 6.597656 -5.203125 6.40625 -5.75 6.03125 -6.15625 C 5.65625 -6.570312 5.160156 -6.78125 4.546875 -6.78125 C 3.835938 -6.78125 3.269531 -6.578125 2.84375 -6.171875 C 2.425781 -5.773438 2.1875 -5.21875 2.125 -4.5 Z M 6.609375 -4.515625 "/> <path d="M 7.875 -4.140625 L 7.875 -3.53125 L 2.078125 -3.53125 C 2.140625 -2.664062 2.398438 -2.003906 2.859375 -1.546875 C 3.328125 -1.097656 3.976562 -0.875 4.8125 -0.875 C 5.300781 -0.875 5.769531 -0.929688 6.21875 -1.046875 C 6.675781 -1.160156 7.128906 -1.335938 7.578125 -1.578125 L 7.578125 -0.390625 C 7.117188 -0.203125 6.648438 -0.0546875 6.171875 0.046875 C 5.703125 0.148438 5.226562 0.203125 4.75 0.203125 C 3.519531 0.203125 2.546875 -0.148438 1.828125 -0.859375 C 1.117188 -1.578125 0.765625 -2.539062 0.765625 -3.75 C 0.765625 -5.007812 1.101562 -6.003906 1.78125 -6.734375 C 2.457031 -7.472656 3.375 -7.84375 4.53125 -7.84375 C 5.5625 -7.84375 6.375 -7.507812 6.96875 -6.84375 C 7.570312 -6.1875 7.875 -5.285156 7.875 -4.140625 Z M 6.609375 -4.515625 C 6.597656 -5.203125 6.40625 -5.75 6.03125 -6.15625 C 5.65625 -6.570312 5.160156 -6.78125 4.546875 -6.78125 C 3.835938 -6.78125 3.269531 -6.578125 2.84375 -6.171875 C 2.425781 -5.773438 2.1875 -5.21875 2.125 -4.5 Z M 6.609375 -4.515625 "/>
@@ -71,7 +71,7 @@
<path d="M 6.359375 -3.921875 C 6.359375 -4.828125 6.171875 -5.53125 5.796875 -6.03125 C 5.421875 -6.53125 4.894531 -6.78125 4.21875 -6.78125 C 3.539062 -6.78125 3.015625 -6.53125 2.640625 -6.03125 C 2.265625 -5.53125 2.078125 -4.828125 2.078125 -3.921875 C 2.078125 -3.015625 2.265625 -2.304688 2.640625 -1.796875 C 3.015625 -1.296875 3.539062 -1.046875 4.21875 -1.046875 C 4.894531 -1.046875 5.421875 -1.296875 5.796875 -1.796875 C 6.171875 -2.304688 6.359375 -3.015625 6.359375 -3.921875 Z M 7.609375 -0.953125 C 7.609375 0.347656 7.316406 1.316406 6.734375 1.953125 C 6.160156 2.585938 5.28125 2.90625 4.09375 2.90625 C 3.644531 2.90625 3.222656 2.875 2.828125 2.8125 C 2.441406 2.75 2.066406 2.648438 1.703125 2.515625 L 1.703125 1.28125 C 2.066406 1.488281 2.425781 1.640625 2.78125 1.734375 C 3.144531 1.828125 3.515625 1.875 3.890625 1.875 C 4.710938 1.875 5.328125 1.65625 5.734375 1.21875 C 6.148438 0.789062 6.359375 0.144531 6.359375 -0.71875 L 6.359375 -1.34375 C 6.097656 -0.894531 5.765625 -0.554688 5.359375 -0.328125 C 4.953125 -0.109375 4.46875 0 3.90625 0 C 2.96875 0 2.207031 -0.351562 1.625 -1.0625 C 1.050781 -1.78125 0.765625 -2.734375 0.765625 -3.921875 C 0.765625 -5.097656 1.050781 -6.046875 1.625 -6.765625 C 2.207031 -7.484375 2.96875 -7.84375 3.90625 -7.84375 C 4.46875 -7.84375 4.953125 -7.726562 5.359375 -7.5 C 5.765625 -7.28125 6.097656 -6.945312 6.359375 -6.5 L 6.359375 -7.65625 L 7.609375 -7.65625 Z M 7.609375 -0.953125 "/> <path d="M 6.359375 -3.921875 C 6.359375 -4.828125 6.171875 -5.53125 5.796875 -6.03125 C 5.421875 -6.53125 4.894531 -6.78125 4.21875 -6.78125 C 3.539062 -6.78125 3.015625 -6.53125 2.640625 -6.03125 C 2.265625 -5.53125 2.078125 -4.828125 2.078125 -3.921875 C 2.078125 -3.015625 2.265625 -2.304688 2.640625 -1.796875 C 3.015625 -1.296875 3.539062 -1.046875 4.21875 -1.046875 C 4.894531 -1.046875 5.421875 -1.296875 5.796875 -1.796875 C 6.171875 -2.304688 6.359375 -3.015625 6.359375 -3.921875 Z M 7.609375 -0.953125 C 7.609375 0.347656 7.316406 1.316406 6.734375 1.953125 C 6.160156 2.585938 5.28125 2.90625 4.09375 2.90625 C 3.644531 2.90625 3.222656 2.875 2.828125 2.8125 C 2.441406 2.75 2.066406 2.648438 1.703125 2.515625 L 1.703125 1.28125 C 2.066406 1.488281 2.425781 1.640625 2.78125 1.734375 C 3.144531 1.828125 3.515625 1.875 3.890625 1.875 C 4.710938 1.875 5.328125 1.65625 5.734375 1.21875 C 6.148438 0.789062 6.359375 0.144531 6.359375 -0.71875 L 6.359375 -1.34375 C 6.097656 -0.894531 5.765625 -0.554688 5.359375 -0.328125 C 4.953125 -0.109375 4.46875 0 3.90625 0 C 2.96875 0 2.207031 -0.351562 1.625 -1.0625 C 1.050781 -1.78125 0.765625 -2.734375 0.765625 -3.921875 C 0.765625 -5.097656 1.050781 -6.046875 1.625 -6.765625 C 2.207031 -7.484375 2.96875 -7.84375 3.90625 -7.84375 C 4.46875 -7.84375 4.953125 -7.726562 5.359375 -7.5 C 5.765625 -7.28125 6.097656 -6.945312 6.359375 -6.5 L 6.359375 -7.65625 L 7.609375 -7.65625 Z M 7.609375 -0.953125 "/>
</g> </g>
<g id="glyph-1-11"> <g id="glyph-1-11">
<path d="M 6.203125 -7.4375 L 6.203125 -6.234375 C 5.847656 -6.421875 5.476562 -6.554688 5.09375 -6.640625 C 4.707031 -6.734375 4.3125 -6.78125 3.90625 -6.78125 C 3.28125 -6.78125 2.8125 -6.6875 2.5 -6.5 C 2.1875 -6.3125 2.03125 -6.023438 2.03125 -5.640625 C 2.03125 -5.347656 2.140625 -5.117188 2.359375 -4.953125 C 2.585938 -4.785156 3.039062 -4.628906 3.71875 -4.484375 L 4.140625 -4.375 C 5.035156 -4.1875 5.671875 -3.914062 6.046875 -3.5625 C 6.421875 -3.21875 6.609375 -2.734375 6.609375 -2.109375 C 6.609375 -1.398438 6.328125 -0.835938 5.765625 -0.421875 C 5.203125 -0.00390625 4.429688 0.203125 3.453125 0.203125 C 3.035156 0.203125 2.601562 0.160156 2.15625 0.078125 C 1.71875 -0.00390625 1.253906 -0.125 0.765625 -0.28125 L 0.765625 -1.578125 C 1.222656 -1.335938 1.675781 -1.15625 2.125 -1.03125 C 2.582031 -0.914062 3.03125 -0.859375 3.46875 -0.859375 C 4.0625 -0.859375 4.515625 -0.957031 4.828125 -1.15625 C 5.148438 -1.363281 5.3125 -1.648438 5.3125 -2.015625 C 5.3125 -2.359375 5.195312 -2.617188 4.96875 -2.796875 C 4.738281 -2.984375 4.234375 -3.160156 3.453125 -3.328125 L 3.015625 -3.4375 C 2.242188 -3.59375 1.679688 -3.84375 1.328125 -4.1875 C 0.984375 -4.53125 0.8125 -4.992188 0.8125 -5.578125 C 0.8125 -6.304688 1.066406 -6.863281 1.578125 -7.25 C 2.085938 -7.644531 2.8125 -7.84375 3.75 -7.84375 C 4.21875 -7.84375 4.65625 -7.804688 5.0625 -7.734375 C 5.476562 -7.671875 5.859375 -7.570312 6.203125 -7.4375 Z M 6.203125 -7.4375 "/> <path d="M 7.28125 -6.1875 C 7.59375 -6.75 7.96875 -7.164062 8.40625 -7.4375 C 8.84375 -7.707031 9.359375 -7.84375 9.953125 -7.84375 C 10.753906 -7.84375 11.367188 -7.5625 11.796875 -7 C 12.234375 -6.445312 12.453125 -5.65625 12.453125 -4.625 L 12.453125 0 L 11.1875 0 L 11.1875 -4.578125 C 11.1875 -5.316406 11.054688 -5.863281 10.796875 -6.21875 C 10.535156 -6.570312 10.140625 -6.75 9.609375 -6.75 C 8.953125 -6.75 8.4375 -6.53125 8.0625 -6.09375 C 7.6875 -5.664062 7.5 -5.078125 7.5 -4.328125 L 7.5 0 L 6.234375 0 L 6.234375 -4.578125 C 6.234375 -5.316406 6.101562 -5.863281 5.84375 -6.21875 C 5.582031 -6.570312 5.179688 -6.75 4.640625 -6.75 C 3.992188 -6.75 3.476562 -6.53125 3.09375 -6.09375 C 2.71875 -5.65625 2.53125 -5.066406 2.53125 -4.328125 L 2.53125 0 L 1.265625 0 L 1.265625 -7.65625 L 2.53125 -7.65625 L 2.53125 -6.46875 C 2.820312 -6.9375 3.164062 -7.28125 3.5625 -7.5 C 3.96875 -7.726562 4.445312 -7.84375 5 -7.84375 C 5.550781 -7.84375 6.019531 -7.703125 6.40625 -7.421875 C 6.800781 -7.140625 7.09375 -6.726562 7.28125 -6.1875 Z M 7.28125 -6.1875 "/>
</g> </g>
<g id="glyph-1-12"> <g id="glyph-1-12">
<path d="M 4 -10.640625 L 7.5 -10.640625 L 7.5 0 L 6.234375 0 L 6.234375 -9.59375 L 4 -9.59375 C 3.539062 -9.59375 3.222656 -9.5 3.046875 -9.3125 C 2.878906 -9.132812 2.796875 -8.804688 2.796875 -8.328125 L 2.796875 -7.65625 L 4.859375 -7.65625 L 4.859375 -6.671875 L 2.796875 -6.671875 L 2.796875 0 L 1.53125 0 L 1.53125 -6.671875 L 0.328125 -6.671875 L 0.328125 -7.65625 L 1.53125 -7.65625 L 1.53125 -8.1875 C 1.53125 -9.039062 1.726562 -9.660156 2.125 -10.046875 C 2.519531 -10.441406 3.144531 -10.640625 4 -10.640625 Z M 4 -10.640625 "/> <path d="M 4 -10.640625 L 7.5 -10.640625 L 7.5 0 L 6.234375 0 L 6.234375 -9.59375 L 4 -9.59375 C 3.539062 -9.59375 3.222656 -9.5 3.046875 -9.3125 C 2.878906 -9.132812 2.796875 -8.804688 2.796875 -8.328125 L 2.796875 -7.65625 L 4.859375 -7.65625 L 4.859375 -6.671875 L 2.796875 -6.671875 L 2.796875 0 L 1.53125 0 L 1.53125 -6.671875 L 0.328125 -6.671875 L 0.328125 -7.65625 L 1.53125 -7.65625 L 1.53125 -8.1875 C 1.53125 -9.039062 1.726562 -9.660156 2.125 -10.046875 C 2.519531 -10.441406 3.144531 -10.640625 4 -10.640625 Z M 4 -10.640625 "/>
@@ -83,230 +83,285 @@
<path d="M 4.796875 -3.84375 C 3.785156 -3.84375 3.082031 -3.726562 2.6875 -3.5 C 2.289062 -3.269531 2.09375 -2.875 2.09375 -2.3125 C 2.09375 -1.863281 2.238281 -1.507812 2.53125 -1.25 C 2.832031 -0.988281 3.234375 -0.859375 3.734375 -0.859375 C 4.429688 -0.859375 4.988281 -1.101562 5.40625 -1.59375 C 5.832031 -2.09375 6.046875 -2.75 6.046875 -3.5625 L 6.046875 -3.84375 Z M 7.3125 -4.375 L 7.3125 0 L 6.046875 0 L 6.046875 -1.15625 C 5.765625 -0.695312 5.40625 -0.351562 4.96875 -0.125 C 4.539062 0.09375 4.019531 0.203125 3.40625 0.203125 C 2.625 0.203125 2 -0.015625 1.53125 -0.453125 C 1.070312 -0.898438 0.84375 -1.492188 0.84375 -2.234375 C 0.84375 -3.085938 1.128906 -3.734375 1.703125 -4.171875 C 2.285156 -4.609375 3.144531 -4.828125 4.28125 -4.828125 L 6.046875 -4.828125 L 6.046875 -4.953125 C 6.046875 -5.535156 5.851562 -5.984375 5.46875 -6.296875 C 5.09375 -6.617188 4.5625 -6.78125 3.875 -6.78125 C 3.4375 -6.78125 3.007812 -6.722656 2.59375 -6.609375 C 2.175781 -6.503906 1.78125 -6.347656 1.40625 -6.140625 L 1.40625 -7.3125 C 1.863281 -7.488281 2.304688 -7.617188 2.734375 -7.703125 C 3.171875 -7.796875 3.59375 -7.84375 4 -7.84375 C 5.113281 -7.84375 5.941406 -7.554688 6.484375 -6.984375 C 7.035156 -6.410156 7.3125 -5.539062 7.3125 -4.375 Z M 7.3125 -4.375 "/> <path d="M 4.796875 -3.84375 C 3.785156 -3.84375 3.082031 -3.726562 2.6875 -3.5 C 2.289062 -3.269531 2.09375 -2.875 2.09375 -2.3125 C 2.09375 -1.863281 2.238281 -1.507812 2.53125 -1.25 C 2.832031 -0.988281 3.234375 -0.859375 3.734375 -0.859375 C 4.429688 -0.859375 4.988281 -1.101562 5.40625 -1.59375 C 5.832031 -2.09375 6.046875 -2.75 6.046875 -3.5625 L 6.046875 -3.84375 Z M 7.3125 -4.375 L 7.3125 0 L 6.046875 0 L 6.046875 -1.15625 C 5.765625 -0.695312 5.40625 -0.351562 4.96875 -0.125 C 4.539062 0.09375 4.019531 0.203125 3.40625 0.203125 C 2.625 0.203125 2 -0.015625 1.53125 -0.453125 C 1.070312 -0.898438 0.84375 -1.492188 0.84375 -2.234375 C 0.84375 -3.085938 1.128906 -3.734375 1.703125 -4.171875 C 2.285156 -4.609375 3.144531 -4.828125 4.28125 -4.828125 L 6.046875 -4.828125 L 6.046875 -4.953125 C 6.046875 -5.535156 5.851562 -5.984375 5.46875 -6.296875 C 5.09375 -6.617188 4.5625 -6.78125 3.875 -6.78125 C 3.4375 -6.78125 3.007812 -6.722656 2.59375 -6.609375 C 2.175781 -6.503906 1.78125 -6.347656 1.40625 -6.140625 L 1.40625 -7.3125 C 1.863281 -7.488281 2.304688 -7.617188 2.734375 -7.703125 C 3.171875 -7.796875 3.59375 -7.84375 4 -7.84375 C 5.113281 -7.84375 5.941406 -7.554688 6.484375 -6.984375 C 7.035156 -6.410156 7.3125 -5.539062 7.3125 -4.375 Z M 7.3125 -4.375 "/>
</g> </g>
<g id="glyph-1-15"> <g id="glyph-1-15">
<path d="M 6.578125 -8.53125 L 4.125 -7.203125 L 6.578125 -5.859375 L 6.1875 -5.203125 L 3.890625 -6.578125 L 3.890625 -4 L 3.109375 -4 L 3.109375 -6.578125 L 0.8125 -5.203125 L 0.421875 -5.859375 L 2.875 -7.203125 L 0.421875 -8.53125 L 0.8125 -9.203125 L 3.109375 -7.8125 L 3.109375 -10.390625 L 3.890625 -10.390625 L 3.890625 -7.8125 L 6.1875 -9.203125 Z M 6.578125 -8.53125 "/> <path d="M 7.6875 -7.65625 L 4.921875 -3.9375 L 7.828125 0 L 6.34375 0 L 4.109375 -3.015625 L 1.890625 0 L 0.40625 0 L 3.375 -4 L 0.65625 -7.65625 L 2.140625 -7.65625 L 4.171875 -4.921875 L 6.203125 -7.65625 Z M 7.6875 -7.65625 "/>
</g> </g>
<g id="glyph-1-16"> <g id="glyph-1-16">
<path d="M 6.828125 -7.359375 L 6.828125 -6.1875 C 6.472656 -6.382812 6.113281 -6.53125 5.75 -6.625 C 5.394531 -6.726562 5.035156 -6.78125 4.671875 -6.78125 C 3.859375 -6.78125 3.222656 -6.519531 2.765625 -6 C 2.316406 -5.476562 2.09375 -4.753906 2.09375 -3.828125 C 2.09375 -2.890625 2.316406 -2.160156 2.765625 -1.640625 C 3.222656 -1.128906 3.859375 -0.875 4.671875 -0.875 C 5.035156 -0.875 5.394531 -0.921875 5.75 -1.015625 C 6.113281 -1.109375 6.472656 -1.253906 6.828125 -1.453125 L 6.828125 -0.296875 C 6.472656 -0.128906 6.109375 -0.00390625 5.734375 0.078125 C 5.359375 0.160156 4.960938 0.203125 4.546875 0.203125 C 3.390625 0.203125 2.46875 -0.15625 1.78125 -0.875 C 1.101562 -1.601562 0.765625 -2.585938 0.765625 -3.828125 C 0.765625 -5.066406 1.109375 -6.046875 1.796875 -6.765625 C 2.484375 -7.484375 3.425781 -7.84375 4.625 -7.84375 C 5.007812 -7.84375 5.382812 -7.800781 5.75 -7.71875 C 6.125 -7.644531 6.484375 -7.523438 6.828125 -7.359375 Z M 6.828125 -7.359375 "/> <path d="M 6.578125 -8.53125 L 4.125 -7.203125 L 6.578125 -5.859375 L 6.1875 -5.203125 L 3.890625 -6.578125 L 3.890625 -4 L 3.109375 -4 L 3.109375 -6.578125 L 0.8125 -5.203125 L 0.421875 -5.859375 L 2.875 -7.203125 L 0.421875 -8.53125 L 0.8125 -9.203125 L 3.109375 -7.8125 L 3.109375 -10.390625 L 3.890625 -10.390625 L 3.890625 -7.8125 L 6.1875 -9.203125 Z M 6.578125 -8.53125 "/>
</g> </g>
<g id="glyph-1-17"> <g id="glyph-1-17">
<path d="M 2.75 -4.875 L 2.75 -1.140625 L 4.96875 -1.140625 C 5.707031 -1.140625 6.253906 -1.289062 6.609375 -1.59375 C 6.972656 -1.90625 7.15625 -2.378906 7.15625 -3.015625 C 7.15625 -3.648438 6.972656 -4.117188 6.609375 -4.421875 C 6.253906 -4.722656 5.707031 -4.875 4.96875 -4.875 Z M 2.75 -9.078125 L 2.75 -6 L 4.796875 -6 C 5.472656 -6 5.972656 -6.125 6.296875 -6.375 C 6.628906 -6.625 6.796875 -7.007812 6.796875 -7.53125 C 6.796875 -8.050781 6.628906 -8.4375 6.296875 -8.6875 C 5.972656 -8.945312 5.472656 -9.078125 4.796875 -9.078125 Z M 1.375 -10.203125 L 4.90625 -10.203125 C 5.957031 -10.203125 6.765625 -9.984375 7.328125 -9.546875 C 7.898438 -9.109375 8.1875 -8.488281 8.1875 -7.6875 C 8.1875 -7.0625 8.039062 -6.5625 7.75 -6.1875 C 7.457031 -5.820312 7.03125 -5.59375 6.46875 -5.5 C 7.144531 -5.351562 7.671875 -5.046875 8.046875 -4.578125 C 8.421875 -4.117188 8.609375 -3.546875 8.609375 -2.859375 C 8.609375 -1.941406 8.296875 -1.234375 7.671875 -0.734375 C 7.054688 -0.242188 6.175781 0 5.03125 0 L 1.375 0 Z M 1.375 -10.203125 "/> <path d="M 5.515625 -9.265625 C 4.515625 -9.265625 3.71875 -8.890625 3.125 -8.140625 C 2.539062 -7.398438 2.25 -6.382812 2.25 -5.09375 C 2.25 -3.8125 2.539062 -2.796875 3.125 -2.046875 C 3.71875 -1.296875 4.515625 -0.921875 5.515625 -0.921875 C 6.515625 -0.921875 7.304688 -1.296875 7.890625 -2.046875 C 8.484375 -2.796875 8.78125 -3.8125 8.78125 -5.09375 C 8.78125 -6.382812 8.484375 -7.398438 7.890625 -8.140625 C 7.304688 -8.890625 6.515625 -9.265625 5.515625 -9.265625 Z M 5.515625 -10.390625 C 6.941406 -10.390625 8.082031 -9.910156 8.9375 -8.953125 C 9.800781 -7.992188 10.234375 -6.707031 10.234375 -5.09375 C 10.234375 -3.488281 9.800781 -2.203125 8.9375 -1.234375 C 8.082031 -0.273438 6.941406 0.203125 5.515625 0.203125 C 4.078125 0.203125 2.925781 -0.273438 2.0625 -1.234375 C 1.207031 -2.191406 0.78125 -3.476562 0.78125 -5.09375 C 0.78125 -6.707031 1.207031 -7.992188 2.0625 -8.953125 C 2.925781 -9.910156 4.078125 -10.390625 5.515625 -10.390625 Z M 5.515625 -10.390625 "/>
</g> </g>
<g id="glyph-1-18"> <g id="glyph-1-18">
<path d="M 0.59375 -7.65625 L 1.84375 -7.65625 L 3.421875 -1.6875 L 4.984375 -7.65625 L 6.46875 -7.65625 L 8.046875 -1.6875 L 9.609375 -7.65625 L 10.859375 -7.65625 L 8.859375 0 L 7.375 0 L 5.734375 -6.28125 L 4.078125 0 L 2.59375 0 Z M 0.59375 -7.65625 "/> <path d="M 8.328125 -1.453125 L 8.328125 -4.203125 L 6.078125 -4.203125 L 6.078125 -5.328125 L 9.703125 -5.328125 L 9.703125 -0.953125 C 9.171875 -0.578125 8.582031 -0.289062 7.9375 -0.09375 C 7.289062 0.101562 6.601562 0.203125 5.875 0.203125 C 4.28125 0.203125 3.03125 -0.257812 2.125 -1.1875 C 1.226562 -2.125 0.78125 -3.425781 0.78125 -5.09375 C 0.78125 -6.757812 1.226562 -8.054688 2.125 -8.984375 C 3.03125 -9.921875 4.28125 -10.390625 5.875 -10.390625 C 6.539062 -10.390625 7.171875 -10.304688 7.765625 -10.140625 C 8.367188 -9.984375 8.925781 -9.742188 9.4375 -9.421875 L 9.4375 -7.953125 C 8.925781 -8.378906 8.382812 -8.703125 7.8125 -8.921875 C 7.238281 -9.140625 6.632812 -9.25 6 -9.25 C 4.75 -9.25 3.8125 -8.898438 3.1875 -8.203125 C 2.5625 -7.515625 2.25 -6.476562 2.25 -5.09375 C 2.25 -3.71875 2.5625 -2.679688 3.1875 -1.984375 C 3.8125 -1.285156 4.75 -0.9375 6 -0.9375 C 6.488281 -0.9375 6.921875 -0.976562 7.296875 -1.0625 C 7.679688 -1.144531 8.023438 -1.273438 8.328125 -1.453125 Z M 8.328125 -1.453125 "/>
</g> </g>
<g id="glyph-1-19"> <g id="glyph-1-19">
<path d="M 1.3125 -10.640625 L 2.578125 -10.640625 L 2.578125 0 L 1.3125 0 Z M 1.3125 -10.640625 "/> <path d="M 6.21875 -4.78125 C 6.507812 -4.6875 6.796875 -4.472656 7.078125 -4.140625 C 7.359375 -3.816406 7.640625 -3.367188 7.921875 -2.796875 L 9.328125 0 L 7.84375 0 L 6.53125 -2.625 C 6.195312 -3.300781 5.867188 -3.75 5.546875 -3.96875 C 5.234375 -4.195312 4.804688 -4.3125 4.265625 -4.3125 L 2.75 -4.3125 L 2.75 0 L 1.375 0 L 1.375 -10.203125 L 4.484375 -10.203125 C 5.648438 -10.203125 6.519531 -9.957031 7.09375 -9.46875 C 7.675781 -8.988281 7.96875 -8.253906 7.96875 -7.265625 C 7.96875 -6.617188 7.816406 -6.082031 7.515625 -5.65625 C 7.210938 -5.238281 6.78125 -4.945312 6.21875 -4.78125 Z M 2.75 -9.078125 L 2.75 -5.453125 L 4.484375 -5.453125 C 5.148438 -5.453125 5.65625 -5.601562 6 -5.90625 C 6.34375 -6.21875 6.515625 -6.671875 6.515625 -7.265625 C 6.515625 -7.859375 6.34375 -8.304688 6 -8.609375 C 5.65625 -8.921875 5.148438 -9.078125 4.484375 -9.078125 Z M 2.75 -9.078125 "/>
</g> </g>
<g id="glyph-1-20"> <g id="glyph-1-20">
<path d="M 6.359375 -6.5 L 6.359375 -10.640625 L 7.609375 -10.640625 L 7.609375 0 L 6.359375 0 L 6.359375 -1.15625 C 6.097656 -0.695312 5.765625 -0.351562 5.359375 -0.125 C 4.953125 0.09375 4.46875 0.203125 3.90625 0.203125 C 2.976562 0.203125 2.222656 -0.164062 1.640625 -0.90625 C 1.054688 -1.644531 0.765625 -2.617188 0.765625 -3.828125 C 0.765625 -5.023438 1.054688 -5.992188 1.640625 -6.734375 C 2.222656 -7.472656 2.976562 -7.84375 3.90625 -7.84375 C 4.46875 -7.84375 4.953125 -7.726562 5.359375 -7.5 C 5.765625 -7.28125 6.097656 -6.945312 6.359375 -6.5 Z M 2.078125 -3.828125 C 2.078125 -2.898438 2.265625 -2.171875 2.640625 -1.640625 C 3.023438 -1.117188 3.550781 -0.859375 4.21875 -0.859375 C 4.875 -0.859375 5.394531 -1.117188 5.78125 -1.640625 C 6.164062 -2.171875 6.359375 -2.898438 6.359375 -3.828125 C 6.359375 -4.742188 6.164062 -5.460938 5.78125 -5.984375 C 5.394531 -6.515625 4.875 -6.78125 4.21875 -6.78125 C 3.550781 -6.78125 3.023438 -6.515625 2.640625 -5.984375 C 2.265625 -5.460938 2.078125 -4.742188 2.078125 -3.828125 Z M 2.078125 -3.828125 "/> <path d="M 7.5 -9.875 L 7.5 -8.53125 C 6.96875 -8.78125 6.46875 -8.960938 6 -9.078125 C 5.539062 -9.203125 5.09375 -9.265625 4.65625 -9.265625 C 3.90625 -9.265625 3.328125 -9.117188 2.921875 -8.828125 C 2.515625 -8.535156 2.3125 -8.125 2.3125 -7.59375 C 2.3125 -7.132812 2.445312 -6.789062 2.71875 -6.5625 C 2.988281 -6.332031 3.503906 -6.148438 4.265625 -6.015625 L 5.09375 -5.84375 C 6.125 -5.644531 6.882812 -5.296875 7.375 -4.796875 C 7.863281 -4.304688 8.109375 -3.644531 8.109375 -2.8125 C 8.109375 -1.820312 7.773438 -1.070312 7.109375 -0.5625 C 6.453125 -0.0507812 5.484375 0.203125 4.203125 0.203125 C 3.710938 0.203125 3.195312 0.144531 2.65625 0.03125 C 2.113281 -0.0703125 1.550781 -0.234375 0.96875 -0.453125 L 0.96875 -1.875 C 1.53125 -1.5625 2.078125 -1.320312 2.609375 -1.15625 C 3.148438 -1 3.679688 -0.921875 4.203125 -0.921875 C 4.984375 -0.921875 5.585938 -1.078125 6.015625 -1.390625 C 6.453125 -1.703125 6.671875 -2.144531 6.671875 -2.71875 C 6.671875 -3.21875 6.515625 -3.609375 6.203125 -3.890625 C 5.898438 -4.171875 5.394531 -4.382812 4.6875 -4.53125 L 3.84375 -4.6875 C 2.8125 -4.894531 2.066406 -5.21875 1.609375 -5.65625 C 1.148438 -6.09375 0.921875 -6.703125 0.921875 -7.484375 C 0.921875 -8.378906 1.238281 -9.085938 1.875 -9.609375 C 2.507812 -10.128906 3.382812 -10.390625 4.5 -10.390625 C 4.976562 -10.390625 5.46875 -10.34375 5.96875 -10.25 C 6.46875 -10.164062 6.976562 -10.039062 7.5 -9.875 Z M 7.5 -9.875 "/>
</g> </g>
<g id="glyph-1-21"> <g id="glyph-1-21">
<path d="M 7.28125 -6.1875 C 7.59375 -6.75 7.96875 -7.164062 8.40625 -7.4375 C 8.84375 -7.707031 9.359375 -7.84375 9.953125 -7.84375 C 10.753906 -7.84375 11.367188 -7.5625 11.796875 -7 C 12.234375 -6.445312 12.453125 -5.65625 12.453125 -4.625 L 12.453125 0 L 11.1875 0 L 11.1875 -4.578125 C 11.1875 -5.316406 11.054688 -5.863281 10.796875 -6.21875 C 10.535156 -6.570312 10.140625 -6.75 9.609375 -6.75 C 8.953125 -6.75 8.4375 -6.53125 8.0625 -6.09375 C 7.6875 -5.664062 7.5 -5.078125 7.5 -4.328125 L 7.5 0 L 6.234375 0 L 6.234375 -4.578125 C 6.234375 -5.316406 6.101562 -5.863281 5.84375 -6.21875 C 5.582031 -6.570312 5.179688 -6.75 4.640625 -6.75 C 3.992188 -6.75 3.476562 -6.53125 3.09375 -6.09375 C 2.71875 -5.65625 2.53125 -5.066406 2.53125 -4.328125 L 2.53125 0 L 1.265625 0 L 1.265625 -7.65625 L 2.53125 -7.65625 L 2.53125 -6.46875 C 2.820312 -6.9375 3.164062 -7.28125 3.5625 -7.5 C 3.96875 -7.726562 4.445312 -7.84375 5 -7.84375 C 5.550781 -7.84375 6.019531 -7.703125 6.40625 -7.421875 C 6.800781 -7.140625 7.09375 -6.726562 7.28125 -6.1875 Z M 7.28125 -6.1875 "/>
</g>
<g id="glyph-1-22">
<path d="M 2.53125 -1.15625 L 2.53125 2.90625 L 1.265625 2.90625 L 1.265625 -7.65625 L 2.53125 -7.65625 L 2.53125 -6.5 C 2.800781 -6.945312 3.132812 -7.28125 3.53125 -7.5 C 3.9375 -7.726562 4.421875 -7.84375 4.984375 -7.84375 C 5.910156 -7.84375 6.664062 -7.472656 7.25 -6.734375 C 7.832031 -5.992188 8.125 -5.023438 8.125 -3.828125 C 8.125 -2.617188 7.832031 -1.644531 7.25 -0.90625 C 6.664062 -0.164062 5.910156 0.203125 4.984375 0.203125 C 4.421875 0.203125 3.9375 0.09375 3.53125 -0.125 C 3.132812 -0.351562 2.800781 -0.695312 2.53125 -1.15625 Z M 6.8125 -3.828125 C 6.8125 -4.742188 6.617188 -5.460938 6.234375 -5.984375 C 5.859375 -6.515625 5.335938 -6.78125 4.671875 -6.78125 C 4.003906 -6.78125 3.476562 -6.515625 3.09375 -5.984375 C 2.71875 -5.460938 2.53125 -4.742188 2.53125 -3.828125 C 2.53125 -2.898438 2.71875 -2.171875 3.09375 -1.640625 C 3.476562 -1.117188 4.003906 -0.859375 4.671875 -0.859375 C 5.335938 -0.859375 5.859375 -1.117188 6.234375 -1.640625 C 6.617188 -2.171875 6.8125 -2.898438 6.8125 -3.828125 Z M 6.8125 -3.828125 "/> <path d="M 2.53125 -1.15625 L 2.53125 2.90625 L 1.265625 2.90625 L 1.265625 -7.65625 L 2.53125 -7.65625 L 2.53125 -6.5 C 2.800781 -6.945312 3.132812 -7.28125 3.53125 -7.5 C 3.9375 -7.726562 4.421875 -7.84375 4.984375 -7.84375 C 5.910156 -7.84375 6.664062 -7.472656 7.25 -6.734375 C 7.832031 -5.992188 8.125 -5.023438 8.125 -3.828125 C 8.125 -2.617188 7.832031 -1.644531 7.25 -0.90625 C 6.664062 -0.164062 5.910156 0.203125 4.984375 0.203125 C 4.421875 0.203125 3.9375 0.09375 3.53125 -0.125 C 3.132812 -0.351562 2.800781 -0.695312 2.53125 -1.15625 Z M 6.8125 -3.828125 C 6.8125 -4.742188 6.617188 -5.460938 6.234375 -5.984375 C 5.859375 -6.515625 5.335938 -6.78125 4.671875 -6.78125 C 4.003906 -6.78125 3.476562 -6.515625 3.09375 -5.984375 C 2.71875 -5.460938 2.53125 -4.742188 2.53125 -3.828125 C 2.53125 -2.898438 2.71875 -2.171875 3.09375 -1.640625 C 3.476562 -1.117188 4.003906 -0.859375 4.671875 -0.859375 C 5.335938 -0.859375 5.859375 -1.117188 6.234375 -1.640625 C 6.617188 -2.171875 6.8125 -2.898438 6.8125 -3.828125 Z M 6.8125 -3.828125 "/>
</g> </g>
<g id="glyph-1-22">
<path d="M 1.3125 -10.640625 L 2.578125 -10.640625 L 2.578125 0 L 1.3125 0 Z M 1.3125 -10.640625 "/>
</g>
<g id="glyph-1-23"> <g id="glyph-1-23">
<path d="M 5.75 -6.484375 C 5.613281 -6.566406 5.460938 -6.625 5.296875 -6.65625 C 5.128906 -6.695312 4.945312 -6.71875 4.75 -6.71875 C 4.03125 -6.71875 3.476562 -6.484375 3.09375 -6.015625 C 2.71875 -5.554688 2.53125 -4.894531 2.53125 -4.03125 L 2.53125 0 L 1.265625 0 L 1.265625 -7.65625 L 2.53125 -7.65625 L 2.53125 -6.46875 C 2.800781 -6.9375 3.144531 -7.28125 3.5625 -7.5 C 3.988281 -7.726562 4.503906 -7.84375 5.109375 -7.84375 C 5.203125 -7.84375 5.300781 -7.835938 5.40625 -7.828125 C 5.507812 -7.816406 5.625 -7.796875 5.75 -7.765625 Z M 5.75 -6.484375 "/>
</g>
<g id="glyph-1-24">
<path d="M 1.1875 -3.015625 L 1.1875 -7.65625 L 2.453125 -7.65625 L 2.453125 -3.0625 C 2.453125 -2.34375 2.59375 -1.800781 2.875 -1.4375 C 3.15625 -1.070312 3.578125 -0.890625 4.140625 -0.890625 C 4.816406 -0.890625 5.351562 -1.101562 5.75 -1.53125 C 6.144531 -1.96875 6.34375 -2.5625 6.34375 -3.3125 L 6.34375 -7.65625 L 7.609375 -7.65625 L 7.609375 0 L 6.34375 0 L 6.34375 -1.171875 C 6.039062 -0.710938 5.6875 -0.367188 5.28125 -0.140625 C 4.875 0.0859375 4.40625 0.203125 3.875 0.203125 C 3 0.203125 2.332031 -0.0664062 1.875 -0.609375 C 1.414062 -1.160156 1.1875 -1.960938 1.1875 -3.015625 Z M 4.359375 -7.84375 Z M 4.359375 -7.84375 "/>
</g>
<g id="glyph-1-25">
<path d="M 5.203125 -10.640625 L 5.203125 -9.59375 L 4 -9.59375 C 3.539062 -9.59375 3.222656 -9.5 3.046875 -9.3125 C 2.878906 -9.132812 2.796875 -8.804688 2.796875 -8.328125 L 2.796875 -7.65625 L 4.859375 -7.65625 L 4.859375 -6.671875 L 2.796875 -6.671875 L 2.796875 0 L 1.53125 0 L 1.53125 -6.671875 L 0.328125 -6.671875 L 0.328125 -7.65625 L 1.53125 -7.65625 L 1.53125 -8.1875 C 1.53125 -9.039062 1.726562 -9.660156 2.125 -10.046875 C 2.519531 -10.441406 3.144531 -10.640625 4 -10.640625 Z M 5.203125 -10.640625 "/> <path d="M 5.203125 -10.640625 L 5.203125 -9.59375 L 4 -9.59375 C 3.539062 -9.59375 3.222656 -9.5 3.046875 -9.3125 C 2.878906 -9.132812 2.796875 -8.804688 2.796875 -8.328125 L 2.796875 -7.65625 L 4.859375 -7.65625 L 4.859375 -6.671875 L 2.796875 -6.671875 L 2.796875 0 L 1.53125 0 L 1.53125 -6.671875 L 0.328125 -6.671875 L 0.328125 -7.65625 L 1.53125 -7.65625 L 1.53125 -8.1875 C 1.53125 -9.039062 1.726562 -9.660156 2.125 -10.046875 C 2.519531 -10.441406 3.144531 -10.640625 4 -10.640625 Z M 5.203125 -10.640625 "/>
</g> </g>
<g id="glyph-1-24">
<path d="M 5.75 -6.484375 C 5.613281 -6.566406 5.460938 -6.625 5.296875 -6.65625 C 5.128906 -6.695312 4.945312 -6.71875 4.75 -6.71875 C 4.03125 -6.71875 3.476562 -6.484375 3.09375 -6.015625 C 2.71875 -5.554688 2.53125 -4.894531 2.53125 -4.03125 L 2.53125 0 L 1.265625 0 L 1.265625 -7.65625 L 2.53125 -7.65625 L 2.53125 -6.46875 C 2.800781 -6.9375 3.144531 -7.28125 3.5625 -7.5 C 3.988281 -7.726562 4.503906 -7.84375 5.109375 -7.84375 C 5.203125 -7.84375 5.300781 -7.835938 5.40625 -7.828125 C 5.507812 -7.816406 5.625 -7.796875 5.75 -7.765625 Z M 5.75 -6.484375 "/>
</g>
<g id="glyph-1-25">
<path d="M 6.828125 -7.359375 L 6.828125 -6.1875 C 6.472656 -6.382812 6.113281 -6.53125 5.75 -6.625 C 5.394531 -6.726562 5.035156 -6.78125 4.671875 -6.78125 C 3.859375 -6.78125 3.222656 -6.519531 2.765625 -6 C 2.316406 -5.476562 2.09375 -4.753906 2.09375 -3.828125 C 2.09375 -2.890625 2.316406 -2.160156 2.765625 -1.640625 C 3.222656 -1.128906 3.859375 -0.875 4.671875 -0.875 C 5.035156 -0.875 5.394531 -0.921875 5.75 -1.015625 C 6.113281 -1.109375 6.472656 -1.253906 6.828125 -1.453125 L 6.828125 -0.296875 C 6.472656 -0.128906 6.109375 -0.00390625 5.734375 0.078125 C 5.359375 0.160156 4.960938 0.203125 4.546875 0.203125 C 3.390625 0.203125 2.46875 -0.15625 1.78125 -0.875 C 1.101562 -1.601562 0.765625 -2.585938 0.765625 -3.828125 C 0.765625 -5.066406 1.109375 -6.046875 1.796875 -6.765625 C 2.484375 -7.484375 3.425781 -7.84375 4.625 -7.84375 C 5.007812 -7.84375 5.382812 -7.800781 5.75 -7.71875 C 6.125 -7.644531 6.484375 -7.523438 6.828125 -7.359375 Z M 6.828125 -7.359375 "/>
</g>
<g id="glyph-1-26"> <g id="glyph-1-26">
<path d="M 7.140625 2.328125 L 7.140625 3.296875 L -0.140625 3.296875 L -0.140625 2.328125 Z M 7.140625 2.328125 "/>
</g>
<g id="glyph-1-27">
<path d="M 6.203125 -7.4375 L 6.203125 -6.234375 C 5.847656 -6.421875 5.476562 -6.554688 5.09375 -6.640625 C 4.707031 -6.734375 4.3125 -6.78125 3.90625 -6.78125 C 3.28125 -6.78125 2.8125 -6.6875 2.5 -6.5 C 2.1875 -6.3125 2.03125 -6.023438 2.03125 -5.640625 C 2.03125 -5.347656 2.140625 -5.117188 2.359375 -4.953125 C 2.585938 -4.785156 3.039062 -4.628906 3.71875 -4.484375 L 4.140625 -4.375 C 5.035156 -4.1875 5.671875 -3.914062 6.046875 -3.5625 C 6.421875 -3.21875 6.609375 -2.734375 6.609375 -2.109375 C 6.609375 -1.398438 6.328125 -0.835938 5.765625 -0.421875 C 5.203125 -0.00390625 4.429688 0.203125 3.453125 0.203125 C 3.035156 0.203125 2.601562 0.160156 2.15625 0.078125 C 1.71875 -0.00390625 1.253906 -0.125 0.765625 -0.28125 L 0.765625 -1.578125 C 1.222656 -1.335938 1.675781 -1.15625 2.125 -1.03125 C 2.582031 -0.914062 3.03125 -0.859375 3.46875 -0.859375 C 4.0625 -0.859375 4.515625 -0.957031 4.828125 -1.15625 C 5.148438 -1.363281 5.3125 -1.648438 5.3125 -2.015625 C 5.3125 -2.359375 5.195312 -2.617188 4.96875 -2.796875 C 4.738281 -2.984375 4.234375 -3.160156 3.453125 -3.328125 L 3.015625 -3.4375 C 2.242188 -3.59375 1.679688 -3.84375 1.328125 -4.1875 C 0.984375 -4.53125 0.8125 -4.992188 0.8125 -5.578125 C 0.8125 -6.304688 1.066406 -6.863281 1.578125 -7.25 C 2.085938 -7.644531 2.8125 -7.84375 3.75 -7.84375 C 4.21875 -7.84375 4.65625 -7.804688 5.0625 -7.734375 C 5.476562 -7.671875 5.859375 -7.570312 6.203125 -7.4375 Z M 6.203125 -7.4375 "/>
</g>
<g id="glyph-1-28">
<path d="M 4.5 0.71875 C 4.144531 1.625 3.796875 2.210938 3.453125 2.484375 C 3.117188 2.765625 2.671875 2.90625 2.109375 2.90625 L 1.109375 2.90625 L 1.109375 1.859375 L 1.84375 1.859375 C 2.1875 1.859375 2.453125 1.773438 2.640625 1.609375 C 2.835938 1.453125 3.050781 1.066406 3.28125 0.453125 L 3.515625 -0.125 L 0.421875 -7.65625 L 1.75 -7.65625 L 4.140625 -1.671875 L 6.53125 -7.65625 L 7.875 -7.65625 Z M 4.5 0.71875 "/>
</g>
<g id="glyph-1-29">
<path d="M 1.1875 -3.015625 L 1.1875 -7.65625 L 2.453125 -7.65625 L 2.453125 -3.0625 C 2.453125 -2.34375 2.59375 -1.800781 2.875 -1.4375 C 3.15625 -1.070312 3.578125 -0.890625 4.140625 -0.890625 C 4.816406 -0.890625 5.351562 -1.101562 5.75 -1.53125 C 6.144531 -1.96875 6.34375 -2.5625 6.34375 -3.3125 L 6.34375 -7.65625 L 7.609375 -7.65625 L 7.609375 0 L 6.34375 0 L 6.34375 -1.171875 C 6.039062 -0.710938 5.6875 -0.367188 5.28125 -0.140625 C 4.875 0.0859375 4.40625 0.203125 3.875 0.203125 C 3 0.203125 2.332031 -0.0664062 1.875 -0.609375 C 1.414062 -1.160156 1.1875 -1.960938 1.1875 -3.015625 Z M 4.359375 -7.84375 Z M 4.359375 -7.84375 "/>
</g>
<g id="glyph-1-30">
<path d="M 6.8125 -3.828125 C 6.8125 -4.742188 6.617188 -5.460938 6.234375 -5.984375 C 5.859375 -6.515625 5.335938 -6.78125 4.671875 -6.78125 C 4.003906 -6.78125 3.476562 -6.515625 3.09375 -5.984375 C 2.71875 -5.460938 2.53125 -4.742188 2.53125 -3.828125 C 2.53125 -2.898438 2.71875 -2.171875 3.09375 -1.640625 C 3.476562 -1.117188 4.003906 -0.859375 4.671875 -0.859375 C 5.335938 -0.859375 5.859375 -1.117188 6.234375 -1.640625 C 6.617188 -2.171875 6.8125 -2.898438 6.8125 -3.828125 Z M 2.53125 -6.5 C 2.800781 -6.945312 3.132812 -7.28125 3.53125 -7.5 C 3.9375 -7.726562 4.421875 -7.84375 4.984375 -7.84375 C 5.910156 -7.84375 6.664062 -7.472656 7.25 -6.734375 C 7.832031 -5.992188 8.125 -5.023438 8.125 -3.828125 C 8.125 -2.617188 7.832031 -1.644531 7.25 -0.90625 C 6.664062 -0.164062 5.910156 0.203125 4.984375 0.203125 C 4.421875 0.203125 3.9375 0.09375 3.53125 -0.125 C 3.132812 -0.351562 2.800781 -0.695312 2.53125 -1.15625 L 2.53125 0 L 1.265625 0 L 1.265625 -10.640625 L 2.53125 -10.640625 Z M 2.53125 -6.5 "/> <path d="M 6.8125 -3.828125 C 6.8125 -4.742188 6.617188 -5.460938 6.234375 -5.984375 C 5.859375 -6.515625 5.335938 -6.78125 4.671875 -6.78125 C 4.003906 -6.78125 3.476562 -6.515625 3.09375 -5.984375 C 2.71875 -5.460938 2.53125 -4.742188 2.53125 -3.828125 C 2.53125 -2.898438 2.71875 -2.171875 3.09375 -1.640625 C 3.476562 -1.117188 4.003906 -0.859375 4.671875 -0.859375 C 5.335938 -0.859375 5.859375 -1.117188 6.234375 -1.640625 C 6.617188 -2.171875 6.8125 -2.898438 6.8125 -3.828125 Z M 2.53125 -6.5 C 2.800781 -6.945312 3.132812 -7.28125 3.53125 -7.5 C 3.9375 -7.726562 4.421875 -7.84375 4.984375 -7.84375 C 5.910156 -7.84375 6.664062 -7.472656 7.25 -6.734375 C 7.832031 -5.992188 8.125 -5.023438 8.125 -3.828125 C 8.125 -2.617188 7.832031 -1.644531 7.25 -0.90625 C 6.664062 -0.164062 5.910156 0.203125 4.984375 0.203125 C 4.421875 0.203125 3.9375 0.09375 3.53125 -0.125 C 3.132812 -0.351562 2.800781 -0.695312 2.53125 -1.15625 L 2.53125 0 L 1.265625 0 L 1.265625 -10.640625 L 2.53125 -10.640625 Z M 2.53125 -6.5 "/>
</g> </g>
<g id="glyph-1-31">
<path d="M 7.5 -7.65625 L 7.5 0 L 6.234375 0 L 6.234375 -6.671875 L 2.796875 -6.671875 L 2.796875 0 L 1.53125 0 L 1.53125 -6.671875 L 0.328125 -6.671875 L 0.328125 -7.65625 L 1.53125 -7.65625 L 1.53125 -8.1875 C 1.53125 -9.019531 1.722656 -9.632812 2.109375 -10.03125 C 2.503906 -10.4375 3.113281 -10.640625 3.9375 -10.640625 L 5.203125 -10.640625 L 5.203125 -9.59375 L 4 -9.59375 C 3.539062 -9.59375 3.222656 -9.5 3.046875 -9.3125 C 2.878906 -9.132812 2.796875 -8.804688 2.796875 -8.328125 L 2.796875 -7.65625 Z M 6.234375 -10.625 L 7.5 -10.625 L 7.5 -9.03125 L 6.234375 -9.03125 Z M 6.234375 -10.625 "/>
</g>
</g> </g>
</defs> </defs>
<path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.00078125 0 L 177.000781 0 L 177.000781 108 L 0.00078125 108 Z M 0.00078125 0 Z M 0.00078125 0 " transform="matrix(1, 0, 0, 1, 9.620312, 9.042969)"/> <path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.00016626 0 L 311.000166 0 L 311.000166 185 L 0.00016626 185 Z M 0.00016626 0 Z M 0.00016626 0 " transform="matrix(1, 0, 0, 1, 9.898271, 9.042969)"/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-0" x="55.621094" y="40.042969"/> <use xlink:href="#glyph-0-0" x="122.898438" y="40.042969"/>
<use xlink:href="#glyph-0-1" x="67.621094" y="40.042969"/> <use xlink:href="#glyph-0-1" x="134.898438" y="40.042969"/>
<use xlink:href="#glyph-0-2" x="76.621094" y="40.042969"/> <use xlink:href="#glyph-0-2" x="143.898438" y="40.042969"/>
<use xlink:href="#glyph-0-3" x="81.621094" y="40.042969"/> <use xlink:href="#glyph-0-3" x="148.898438" y="40.042969"/>
<use xlink:href="#glyph-0-4" x="91.621094" y="40.042969"/> <use xlink:href="#glyph-0-4" x="158.898438" y="40.042969"/>
<use xlink:href="#glyph-0-5" x="101.621094" y="40.042969"/> <use xlink:href="#glyph-0-5" x="168.898438" y="40.042969"/>
<use xlink:href="#glyph-0-6" x="108.621094" y="40.042969"/> <use xlink:href="#glyph-0-6" x="175.898438" y="40.042969"/>
<use xlink:href="#glyph-0-7" x="122.621094" y="40.042969"/> <use xlink:href="#glyph-0-7" x="189.898438" y="40.042969"/>
<use xlink:href="#glyph-0-8" x="131.621094" y="40.042969"/> <use xlink:href="#glyph-0-8" x="198.898438" y="40.042969"/>
</g> </g>
<path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.00078125 41 L 177.000781 41 " transform="matrix(1, 0, 0, 1, 9.620312, 9.042969)"/> <path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.00016626 41 L 311.000166 41 " transform="matrix(1, 0, 0, 1, 9.898271, 9.042969)"/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="13.621094" y="67.042969"/> <use xlink:href="#glyph-1-0" x="13.898438" y="67.042969"/>
<use xlink:href="#glyph-1-1" x="25.621094" y="67.042969"/> <use xlink:href="#glyph-1-1" x="25.898438" y="67.042969"/>
<use xlink:href="#glyph-1-2" x="29.621094" y="67.042969"/> <use xlink:href="#glyph-1-2" x="29.898438" y="67.042969"/>
<use xlink:href="#glyph-1-3" x="37.621094" y="67.042969"/> <use xlink:href="#glyph-1-3" x="40.898438" y="67.042969"/>
<use xlink:href="#glyph-1-1" x="42.621094" y="67.042969"/> <use xlink:href="#glyph-1-4" x="44.898438" y="67.042969"/>
<use xlink:href="#glyph-1-4" x="46.621094" y="67.042969"/> <use xlink:href="#glyph-1-5" x="53.898438" y="67.042969"/>
<use xlink:href="#glyph-1-5" x="50.621094" y="67.042969"/> <use xlink:href="#glyph-1-6" x="58.898438" y="67.042969"/>
<use xlink:href="#glyph-1-6" x="59.621094" y="67.042969"/> <use xlink:href="#glyph-1-7" x="67.898438" y="67.042969"/>
<use xlink:href="#glyph-1-1" x="72.898438" y="67.042969"/>
<use xlink:href="#glyph-1-3" x="76.898438" y="67.042969"/>
<use xlink:href="#glyph-1-8" x="80.898438" y="67.042969"/>
<use xlink:href="#glyph-1-5" x="89.898438" y="67.042969"/>
</g> </g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="13.621094" y="84.042969"/> <use xlink:href="#glyph-1-0" x="13.898438" y="84.042969"/>
<use xlink:href="#glyph-1-1" x="25.621094" y="84.042969"/> <use xlink:href="#glyph-1-1" x="25.898438" y="84.042969"/>
<use xlink:href="#glyph-1-7" x="29.621094" y="84.042969"/> <use xlink:href="#glyph-1-6" x="29.898438" y="84.042969"/>
<use xlink:href="#glyph-1-3" x="36.621094" y="84.042969"/> <use xlink:href="#glyph-1-9" x="38.898438" y="84.042969"/>
<use xlink:href="#glyph-1-1" x="41.621094" y="84.042969"/> <use xlink:href="#glyph-1-3" x="47.898438" y="84.042969"/>
<use xlink:href="#glyph-1-4" x="45.621094" y="84.042969"/> <use xlink:href="#glyph-1-10" x="51.898438" y="84.042969"/>
<use xlink:href="#glyph-1-5" x="49.621094" y="84.042969"/> <use xlink:href="#glyph-1-6" x="60.898438" y="84.042969"/>
<use xlink:href="#glyph-1-6" x="58.621094" y="84.042969"/> <use xlink:href="#glyph-1-5" x="69.898438" y="84.042969"/>
<use xlink:href="#glyph-1-7" x="74.898438" y="84.042969"/>
<use xlink:href="#glyph-1-1" x="79.898438" y="84.042969"/>
<use xlink:href="#glyph-1-3" x="83.898438" y="84.042969"/>
<use xlink:href="#glyph-1-8" x="87.898438" y="84.042969"/>
<use xlink:href="#glyph-1-5" x="96.898438" y="84.042969"/>
</g> </g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="13.621094" y="101.042969"/> <use xlink:href="#glyph-1-0" x="13.898438" y="101.042969"/>
<use xlink:href="#glyph-1-1" x="25.621094" y="101.042969"/> <use xlink:href="#glyph-1-1" x="25.898438" y="101.042969"/>
<use xlink:href="#glyph-1-8" x="29.621094" y="101.042969"/> <use xlink:href="#glyph-1-11" x="29.898438" y="101.042969"/>
<use xlink:href="#glyph-1-9" x="38.621094" y="101.042969"/> <use xlink:href="#glyph-1-3" x="43.898438" y="101.042969"/>
<use xlink:href="#glyph-1-4" x="47.621094" y="101.042969"/> <use xlink:href="#glyph-1-8" x="47.898438" y="101.042969"/>
<use xlink:href="#glyph-1-10" x="51.621094" y="101.042969"/> <use xlink:href="#glyph-1-7" x="56.898438" y="101.042969"/>
<use xlink:href="#glyph-1-8" x="60.621094" y="101.042969"/> <use xlink:href="#glyph-1-1" x="61.898438" y="101.042969"/>
<use xlink:href="#glyph-1-6" x="69.621094" y="101.042969"/> <use xlink:href="#glyph-1-12" x="65.898438" y="101.042969"/>
<use xlink:href="#glyph-1-11" x="74.621094" y="101.042969"/> <use xlink:href="#glyph-1-13" x="74.898438" y="101.042969"/>
<use xlink:href="#glyph-1-3" x="81.621094" y="101.042969"/> <use xlink:href="#glyph-1-14" x="83.898438" y="101.042969"/>
<use xlink:href="#glyph-1-1" x="86.621094" y="101.042969"/> <use xlink:href="#glyph-1-5" x="92.898438" y="101.042969"/>
<use xlink:href="#glyph-1-12" x="90.621094" y="101.042969"/>
<use xlink:href="#glyph-1-13" x="99.621094" y="101.042969"/>
<use xlink:href="#glyph-1-14" x="108.621094" y="101.042969"/>
<use xlink:href="#glyph-1-6" x="117.621094" y="101.042969"/>
<use xlink:href="#glyph-1-15" x="122.621094" y="101.042969"/>
</g>
<path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.000807286 0 L 155.000807 0 L 155.000807 108 L 0.000807286 108 Z M 0.000807286 0 Z M 0.000807286 0 " transform="matrix(1, 0, 0, 1, 208.307786, 9.042969)"/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-9" x="267.308594" y="40.042969"/>
<use xlink:href="#glyph-0-1" x="277.308594" y="40.042969"/>
<use xlink:href="#glyph-0-10" x="286.308594" y="40.042969"/>
<use xlink:href="#glyph-0-10" x="291.308594" y="40.042969"/>
<use xlink:href="#glyph-0-11" x="296.308594" y="40.042969"/>
</g>
<path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.000807286 41 L 155.000807 41 " transform="matrix(1, 0, 0, 1, 208.307786, 9.042969)"/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="212.308594" y="67.042969"/>
<use xlink:href="#glyph-1-1" x="224.308594" y="67.042969"/>
<use xlink:href="#glyph-1-2" x="228.308594" y="67.042969"/>
<use xlink:href="#glyph-1-3" x="236.308594" y="67.042969"/>
<use xlink:href="#glyph-1-1" x="241.308594" y="67.042969"/>
<use xlink:href="#glyph-1-4" x="245.308594" y="67.042969"/>
<use xlink:href="#glyph-1-5" x="249.308594" y="67.042969"/>
<use xlink:href="#glyph-1-6" x="258.308594" y="67.042969"/>
</g> </g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="212.308594" y="84.042969"/> <use xlink:href="#glyph-1-0" x="13.898438" y="118.042969"/>
<use xlink:href="#glyph-1-1" x="224.308594" y="84.042969"/> <use xlink:href="#glyph-1-1" x="25.898438" y="118.042969"/>
<use xlink:href="#glyph-1-7" x="228.308594" y="84.042969"/> <use xlink:href="#glyph-1-11" x="29.898438" y="118.042969"/>
<use xlink:href="#glyph-1-3" x="235.308594" y="84.042969"/> <use xlink:href="#glyph-1-14" x="43.898438" y="118.042969"/>
<use xlink:href="#glyph-1-1" x="240.308594" y="84.042969"/> <use xlink:href="#glyph-1-15" x="52.898438" y="118.042969"/>
<use xlink:href="#glyph-1-4" x="244.308594" y="84.042969"/> <use xlink:href="#glyph-1-1" x="60.898438" y="118.042969"/>
<use xlink:href="#glyph-1-5" x="248.308594" y="84.042969"/> <use xlink:href="#glyph-1-12" x="64.898438" y="118.042969"/>
<use xlink:href="#glyph-1-6" x="257.308594" y="84.042969"/> <use xlink:href="#glyph-1-13" x="73.898438" y="118.042969"/>
<use xlink:href="#glyph-1-14" x="82.898438" y="118.042969"/>
<use xlink:href="#glyph-1-5" x="91.898438" y="118.042969"/>
</g> </g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="212.308594" y="101.042969"/> <use xlink:href="#glyph-1-0" x="13.898438" y="135.042969"/>
<use xlink:href="#glyph-1-1" x="224.308594" y="101.042969"/> <use xlink:href="#glyph-1-1" x="25.898438" y="135.042969"/>
<use xlink:href="#glyph-1-16" x="228.308594" y="101.042969"/> <use xlink:href="#glyph-1-4" x="29.898438" y="135.042969"/>
<use xlink:href="#glyph-1-14" x="236.308594" y="101.042969"/> <use xlink:href="#glyph-1-14" x="38.898438" y="135.042969"/>
<use xlink:href="#glyph-1-11" x="245.308594" y="101.042969"/> <use xlink:href="#glyph-1-5" x="47.898438" y="135.042969"/>
<use xlink:href="#glyph-1-9" x="252.308594" y="101.042969"/> <use xlink:href="#glyph-1-14" x="52.898438" y="135.042969"/>
<use xlink:href="#glyph-1-11" x="261.308594" y="101.042969"/> <use xlink:href="#glyph-1-7" x="61.898438" y="135.042969"/>
<use xlink:href="#glyph-1-3" x="268.308594" y="101.042969"/> <use xlink:href="#glyph-1-1" x="66.898438" y="135.042969"/>
<use xlink:href="#glyph-1-1" x="273.308594" y="101.042969"/> <use xlink:href="#glyph-1-12" x="70.898438" y="135.042969"/>
<use xlink:href="#glyph-1-4" x="277.308594" y="101.042969"/> <use xlink:href="#glyph-1-13" x="79.898438" y="135.042969"/>
<use xlink:href="#glyph-1-5" x="281.308594" y="101.042969"/> <use xlink:href="#glyph-1-14" x="88.898438" y="135.042969"/>
<use xlink:href="#glyph-1-6" x="290.308594" y="101.042969"/> <use xlink:href="#glyph-1-5" x="97.898438" y="135.042969"/>
<use xlink:href="#glyph-1-15" x="295.308594" y="101.042969"/> <use xlink:href="#glyph-1-16" x="102.898438" y="135.042969"/>
</g>
<path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 181.073103 0 L 181.073103 12 L 193.073103 12 L 181.073103 0 L -0.00111532 0 L -0.00111532 97.140625 L 193.073103 97.140625 L 193.073103 12 " transform="matrix(1, 0, 0, 1, 111.770647, 159.574219)"/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-17" x="115.769531" y="176.574219"/>
<use xlink:href="#glyph-1-13" x="125.769531" y="176.574219"/>
<use xlink:href="#glyph-1-6" x="134.769531" y="176.574219"/>
<use xlink:href="#glyph-1-8" x="139.769531" y="176.574219"/>
<use xlink:href="#glyph-1-1" x="148.769531" y="176.574219"/>
<use xlink:href="#glyph-1-18" x="152.769531" y="176.574219"/>
<use xlink:href="#glyph-1-4" x="163.769531" y="176.574219"/>
<use xlink:href="#glyph-1-19" x="167.769531" y="176.574219"/>
<use xlink:href="#glyph-1-19" x="171.769531" y="176.574219"/>
<use xlink:href="#glyph-1-1" x="175.769531" y="176.574219"/>
<use xlink:href="#glyph-1-5" x="179.769531" y="176.574219"/>
<use xlink:href="#glyph-1-9" x="188.769531" y="176.574219"/>
<use xlink:href="#glyph-1-9" x="197.769531" y="176.574219"/>
<use xlink:href="#glyph-1-20" x="206.769531" y="176.574219"/>
<use xlink:href="#glyph-1-1" x="215.769531" y="176.574219"/>
<use xlink:href="#glyph-1-6" x="219.769531" y="176.574219"/>
<use xlink:href="#glyph-1-13" x="224.769531" y="176.574219"/>
</g> </g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-4" x="115.769531" y="193.574219"/> <use xlink:href="#glyph-1-0" x="13.898438" y="152.042969"/>
<use xlink:href="#glyph-1-21" x="119.769531" y="193.574219"/> <use xlink:href="#glyph-1-1" x="25.898438" y="152.042969"/>
<use xlink:href="#glyph-1-22" x="133.769531" y="193.574219"/> <use xlink:href="#glyph-1-17" x="29.898438" y="152.042969"/>
<use xlink:href="#glyph-1-19" x="142.769531" y="193.574219"/> <use xlink:href="#glyph-1-18" x="40.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="146.769531" y="193.574219"/> <use xlink:href="#glyph-1-19" x="51.898438" y="152.042969"/>
<use xlink:href="#glyph-1-21" x="155.769531" y="193.574219"/> <use xlink:href="#glyph-1-20" x="61.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="169.769531" y="193.574219"/> <use xlink:href="#glyph-1-21" x="70.898438" y="152.042969"/>
<use xlink:href="#glyph-1-5" x="178.769531" y="193.574219"/> <use xlink:href="#glyph-1-14" x="79.898438" y="152.042969"/>
<use xlink:href="#glyph-1-6" x="187.769531" y="193.574219"/> <use xlink:href="#glyph-1-5" x="88.898438" y="152.042969"/>
<use xlink:href="#glyph-1-1" x="192.769531" y="193.574219"/> <use xlink:href="#glyph-1-3" x="93.898438" y="152.042969"/>
<use xlink:href="#glyph-1-6" x="196.769531" y="193.574219"/> <use xlink:href="#glyph-1-14" x="97.898438" y="152.042969"/>
<use xlink:href="#glyph-1-8" x="201.769531" y="193.574219"/> <use xlink:href="#glyph-1-22" x="106.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="210.769531" y="193.574219"/> <use xlink:href="#glyph-1-19" x="110.898438" y="152.042969"/>
<use xlink:href="#glyph-1-1" x="219.769531" y="193.574219"/> <use xlink:href="#glyph-1-9" x="119.898438" y="152.042969"/>
<use xlink:href="#glyph-1-23" x="223.769531" y="193.574219"/> <use xlink:href="#glyph-1-23" x="128.898438" y="152.042969"/>
<use xlink:href="#glyph-1-24" x="229.769531" y="193.574219"/> <use xlink:href="#glyph-1-9" x="133.898438" y="152.042969"/>
<use xlink:href="#glyph-1-19" x="238.769531" y="193.574219"/> <use xlink:href="#glyph-1-24" x="142.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="242.769531" y="193.574219"/> <use xlink:href="#glyph-1-9" x="147.898438" y="152.042969"/>
<use xlink:href="#glyph-1-1" x="251.769531" y="193.574219"/> <use xlink:href="#glyph-1-8" x="156.898438" y="152.042969"/>
<use xlink:href="#glyph-1-13" x="255.769531" y="193.574219"/> <use xlink:href="#glyph-1-25" x="165.898438" y="152.042969"/>
<use xlink:href="#glyph-1-25" x="264.769531" y="193.574219"/> <use xlink:href="#glyph-1-9" x="173.898438" y="152.042969"/>
<use xlink:href="#glyph-1-7" x="182.898438" y="152.042969"/>
<use xlink:href="#glyph-1-1" x="187.898438" y="152.042969"/>
<use xlink:href="#glyph-1-24" x="191.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="196.898438" y="152.042969"/>
<use xlink:href="#glyph-1-23" x="205.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="210.898438" y="152.042969"/>
<use xlink:href="#glyph-1-24" x="219.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="224.898438" y="152.042969"/>
<use xlink:href="#glyph-1-8" x="233.898438" y="152.042969"/>
<use xlink:href="#glyph-1-25" x="242.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="250.898438" y="152.042969"/>
<use xlink:href="#glyph-1-26" x="259.898438" y="152.042969"/>
<use xlink:href="#glyph-1-27" x="266.898438" y="152.042969"/>
<use xlink:href="#glyph-1-28" x="273.898438" y="152.042969"/>
<use xlink:href="#glyph-1-27" x="281.898438" y="152.042969"/>
<use xlink:href="#glyph-1-5" x="288.898438" y="152.042969"/>
<use xlink:href="#glyph-1-9" x="293.898438" y="152.042969"/>
<use xlink:href="#glyph-1-11" x="302.898438" y="152.042969"/>
</g> </g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-6" x="115.769531" y="210.574219"/> <use xlink:href="#glyph-1-0" x="13.898438" y="169.042969"/>
<use xlink:href="#glyph-1-8" x="120.769531" y="210.574219"/> <use xlink:href="#glyph-1-1" x="25.898438" y="169.042969"/>
<use xlink:href="#glyph-1-23" x="129.769531" y="210.574219"/> <use xlink:href="#glyph-1-10" x="29.898438" y="169.042969"/>
<use xlink:href="#glyph-1-9" x="134.769531" y="210.574219"/> <use xlink:href="#glyph-1-9" x="38.898438" y="169.042969"/>
<use xlink:href="#glyph-1-9" x="143.769531" y="210.574219"/> <use xlink:href="#glyph-1-13" x="47.898438" y="169.042969"/>
<use xlink:href="#glyph-1-1" x="152.769531" y="210.574219"/> <use xlink:href="#glyph-1-5" x="56.898438" y="169.042969"/>
<use xlink:href="#glyph-1-26" x="156.769531" y="210.574219"/> <use xlink:href="#glyph-1-24" x="61.898438" y="169.042969"/>
<use xlink:href="#glyph-1-9" x="165.769531" y="210.574219"/> <use xlink:href="#glyph-1-14" x="67.898438" y="169.042969"/>
<use xlink:href="#glyph-1-16" x="174.769531" y="210.574219"/> <use xlink:href="#glyph-1-8" x="76.898438" y="169.042969"/>
<use xlink:href="#glyph-1-14" x="182.769531" y="210.574219"/> <use xlink:href="#glyph-1-27" x="85.898438" y="169.042969"/>
<use xlink:href="#glyph-1-24" x="191.769531" y="210.574219"/> <use xlink:href="#glyph-1-23" x="92.898438" y="169.042969"/>
<use xlink:href="#glyph-1-11" x="200.769531" y="210.574219"/> <use xlink:href="#glyph-1-13" x="97.898438" y="169.042969"/>
<use xlink:href="#glyph-1-9" x="207.769531" y="210.574219"/> <use xlink:href="#glyph-1-24" x="106.898438" y="169.042969"/>
<use xlink:href="#glyph-1-1" x="216.769531" y="210.574219"/> <use xlink:href="#glyph-1-11" x="112.898438" y="169.042969"/>
<use xlink:href="#glyph-1-6" x="220.769531" y="210.574219"/> <use xlink:href="#glyph-1-7" x="126.898438" y="169.042969"/>
<use xlink:href="#glyph-1-8" x="225.769531" y="210.574219"/> <use xlink:href="#glyph-1-1" x="131.898438" y="169.042969"/>
<use xlink:href="#glyph-1-9" x="234.769531" y="210.574219"/> <use xlink:href="#glyph-1-4" x="135.898438" y="169.042969"/>
<use xlink:href="#glyph-1-7" x="243.769531" y="210.574219"/> <use xlink:href="#glyph-1-13" x="144.898438" y="169.042969"/>
<use xlink:href="#glyph-1-29" x="153.898438" y="169.042969"/>
<use xlink:href="#glyph-1-30" x="162.898438" y="169.042969"/>
<use xlink:href="#glyph-1-22" x="171.898438" y="169.042969"/>
<use xlink:href="#glyph-1-9" x="175.898438" y="169.042969"/>
<use xlink:href="#glyph-1-16" x="184.898438" y="169.042969"/>
</g> </g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-11" x="115.769531" y="227.574219"/> <use xlink:href="#glyph-1-0" x="13.898438" y="186.042969"/>
<use xlink:href="#glyph-1-6" x="122.769531" y="227.574219"/> <use xlink:href="#glyph-1-1" x="25.898438" y="186.042969"/>
<use xlink:href="#glyph-1-13" x="127.769531" y="227.574219"/> <use xlink:href="#glyph-1-31" x="29.898438" y="186.042969"/>
<use xlink:href="#glyph-1-23" x="136.769531" y="227.574219"/> <use xlink:href="#glyph-1-22" x="38.898438" y="186.042969"/>
<use xlink:href="#glyph-1-9" x="141.769531" y="227.574219"/> <use xlink:href="#glyph-1-9" x="42.898438" y="186.042969"/>
<use xlink:href="#glyph-1-1" x="150.769531" y="227.574219"/> <use xlink:href="#glyph-1-21" x="51.898438" y="186.042969"/>
<use xlink:href="#glyph-1-23" x="154.769531" y="227.574219"/> <use xlink:href="#glyph-1-14" x="60.898438" y="186.042969"/>
<use xlink:href="#glyph-1-14" x="160.769531" y="227.574219"/> <use xlink:href="#glyph-1-5" x="69.898438" y="186.042969"/>
<use xlink:href="#glyph-1-18" x="169.769531" y="227.574219"/> <use xlink:href="#glyph-1-6" x="74.898438" y="186.042969"/>
<use xlink:href="#glyph-1-1" x="180.769531" y="227.574219"/> <use xlink:href="#glyph-1-7" x="83.898438" y="186.042969"/>
<use xlink:href="#glyph-1-22" x="184.769531" y="227.574219"/> <use xlink:href="#glyph-1-1" x="88.898438" y="186.042969"/>
<use xlink:href="#glyph-1-13" x="193.769531" y="227.574219"/> <use xlink:href="#glyph-1-25" x="92.898438" y="186.042969"/>
<use xlink:href="#glyph-1-4" x="202.769531" y="227.574219"/> <use xlink:href="#glyph-1-6" x="100.898438" y="186.042969"/>
<use xlink:href="#glyph-1-5" x="206.769531" y="227.574219"/> <use xlink:href="#glyph-1-14" x="109.898438" y="186.042969"/>
<use xlink:href="#glyph-1-6" x="215.769531" y="227.574219"/> <use xlink:href="#glyph-1-24" x="118.898438" y="186.042969"/>
<use xlink:href="#glyph-1-9" x="220.769531" y="227.574219"/> <use xlink:href="#glyph-1-16" x="124.898438" y="186.042969"/>
<use xlink:href="#glyph-1-23" x="229.769531" y="227.574219"/> </g>
<use xlink:href="#glyph-1-11" x="235.769531" y="227.574219"/> <path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.0000915527 0 L 130.000092 0 L 130.000092 125 L 0.0000915527 125 Z M 0.0000915527 0 Z M 0.0000915527 0 " transform="matrix(1, 0, 0, 1, 380.788971, 32.691406)"/>
<use xlink:href="#glyph-1-1" x="242.769531" y="227.574219"/> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-6" x="246.769531" y="227.574219"/> <use xlink:href="#glyph-0-9" x="424.789062" y="63.691406"/>
<use xlink:href="#glyph-1-13" x="251.769531" y="227.574219"/> <use xlink:href="#glyph-0-10" x="434.789062" y="63.691406"/>
<use xlink:href="#glyph-0-2" x="444.789062" y="63.691406"/>
<use xlink:href="#glyph-0-11" x="449.789062" y="63.691406"/>
<use xlink:href="#glyph-0-5" x="459.789062" y="63.691406"/>
</g>
<path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.0000915527 41 L 130.000092 41 " transform="matrix(1, 0, 0, 1, 380.788971, 32.691406)"/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="384.789062" y="90.691406"/>
<use xlink:href="#glyph-1-1" x="396.789062" y="90.691406"/>
<use xlink:href="#glyph-1-15" x="400.789062" y="90.691406"/>
<use xlink:href="#glyph-1-7" x="408.789062" y="90.691406"/>
<use xlink:href="#glyph-1-1" x="413.789062" y="90.691406"/>
<use xlink:href="#glyph-1-3" x="417.789062" y="90.691406"/>
<use xlink:href="#glyph-1-8" x="421.789062" y="90.691406"/>
<use xlink:href="#glyph-1-5" x="430.789062" y="90.691406"/>
</g> </g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> <g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-14" x="115.769531" y="244.574219"/> <use xlink:href="#glyph-1-0" x="384.789062" y="107.691406"/>
<use xlink:href="#glyph-1-23" x="124.769531" y="244.574219"/> <use xlink:href="#glyph-1-1" x="396.789062" y="107.691406"/>
<use xlink:href="#glyph-1-23" x="130.769531" y="244.574219"/> <use xlink:href="#glyph-1-28" x="400.789062" y="107.691406"/>
<use xlink:href="#glyph-1-14" x="136.769531" y="244.574219"/> <use xlink:href="#glyph-1-7" x="407.789062" y="107.691406"/>
<use xlink:href="#glyph-1-7" x="145.769531" y="244.574219"/> <use xlink:href="#glyph-1-1" x="412.789062" y="107.691406"/>
<use xlink:href="#glyph-1-11" x="153.769531" y="244.574219"/> <use xlink:href="#glyph-1-3" x="416.789062" y="107.691406"/>
<use xlink:href="#glyph-1-8" x="420.789062" y="107.691406"/>
<use xlink:href="#glyph-1-5" x="429.789062" y="107.691406"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="384.789062" y="124.691406"/>
<use xlink:href="#glyph-1-1" x="396.789062" y="124.691406"/>
<use xlink:href="#glyph-1-11" x="400.789062" y="124.691406"/>
<use xlink:href="#glyph-1-27" x="414.789062" y="124.691406"/>
<use xlink:href="#glyph-1-25" x="421.789062" y="124.691406"/>
<use xlink:href="#glyph-1-14" x="429.789062" y="124.691406"/>
<use xlink:href="#glyph-1-27" x="438.789062" y="124.691406"/>
<use xlink:href="#glyph-1-9" x="445.789062" y="124.691406"/>
<use xlink:href="#glyph-1-7" x="454.789062" y="124.691406"/>
<use xlink:href="#glyph-1-1" x="459.789062" y="124.691406"/>
<use xlink:href="#glyph-1-3" x="463.789062" y="124.691406"/>
<use xlink:href="#glyph-1-8" x="467.789062" y="124.691406"/>
<use xlink:href="#glyph-1-5" x="476.789062" y="124.691406"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-0" x="384.789062" y="141.691406"/>
<use xlink:href="#glyph-1-1" x="396.789062" y="141.691406"/>
<use xlink:href="#glyph-1-14" x="400.789062" y="141.691406"/>
<use xlink:href="#glyph-1-22" x="409.789062" y="141.691406"/>
<use xlink:href="#glyph-1-22" x="413.789062" y="141.691406"/>
<use xlink:href="#glyph-1-13" x="417.789062" y="141.691406"/>
<use xlink:href="#glyph-1-25" x="426.789062" y="141.691406"/>
<use xlink:href="#glyph-1-14" x="434.789062" y="141.691406"/>
<use xlink:href="#glyph-1-5" x="443.789062" y="141.691406"/>
<use xlink:href="#glyph-1-9" x="448.789062" y="141.691406"/>
<use xlink:href="#glyph-1-4" x="457.789062" y="141.691406"/>
<use xlink:href="#glyph-1-7" x="466.789062" y="141.691406"/>
<use xlink:href="#glyph-1-1" x="471.789062" y="141.691406"/>
<use xlink:href="#glyph-1-30" x="475.789062" y="141.691406"/>
<use xlink:href="#glyph-1-13" x="484.789062" y="141.691406"/>
<use xlink:href="#glyph-1-13" x="493.789062" y="141.691406"/>
<use xlink:href="#glyph-1-22" x="502.789062" y="141.691406"/>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

59
documentation/lab5.md Normal file
View File

@@ -0,0 +1,59 @@
% INF205 Lab 5
% Esther and Trygve
% April 23 2024
# 29. Glossary contributions:
## dynamic library
Dynamic libraries are libraries that are pre compiled and often provided by the operating system, as opposed to compiling them as part of your project. This saves space as each program dont need its own "copy".
## command-line arguments
Command-line arguments are extra commands that we enter after the program's executable name so that the functionality of the program changes.
# 30. Draft slides:
See slides.pdf
# 31. Basic functionality and validation per
We ran a simple benchmark against gdal_contour as the reference implementation using `time` in the shell. My laptop has a 6 core AMD Ryzen 5 PRO 5675U running linux 6.8. The average of three tests was:
```
Ours: 33,53 s
Reference: 4,46 s
```
This is despite the reference gdal implementation beinge single threaded and our being paritally paralell. We think we will gaing a significant speedup from optimizing the part of he program drawing the contours into a file. Right now its a placeholder that just creates points, not lines.
This innital gap in performance leaves us a lot of room to improve and it will be interesting to see what the final performance will be.
The plan is to create a more sophisticated benchmark program in c++, but for now we just use the time command
Memory usage is also very big because of our datastructure for CellMap. It is storing essentially a line in a 2d array, so most of the items are 0. We will try to fix this by making a cell type that stores its coordinates or by getting rid of the cellmap entirely.
The source code is available at [https://gitlab.com/Trygve/contour-creator](https://gitlab.com/Trygve/contour-creator) with instructions in the readme for building and running.
If you want to view the .shp file you can use this simple webapp: [https://mapshaper.org/](https://mapshaper.org/)
# 32 Special interest functionality and responsibilities
It does not seem like we will have time to add any extra functionality.
# 33. Programming project: Progress on data structure implementation
![ER diagram](ER_diagram.svg)
We need to create destructors to call free on data in HeightMap and cells in Cells as those are arrays allocated with malloc. The default copy behaviur is fine for our program.
\newpage
# 34. Parallelization
We are using openMP because we want multiple threads using the same data and the files are small enough to fit into memory (~500mb). To scale it to multiple machines we would use mpi to distrubute seperate iamge tiles to each node.
We haven't had time to test the performance and we have only parallelized half of what is possible. But we can see that it is using all the cores.
The following code was used for parallelization using openMP, each thread produces one "layer" of the cellmap:
```cpp
#pragma omp parallel
{
std::vector<CellMap> vec_private;
#pragma omp for
for (int i = 1; i <= num_contours; i++)
{
vec_private.push_back(produce_cellmap(heightmap, heightmap->min + interval*i));
}
#pragma omp critical
vector_contours.insert(vector_contours.end(), vec_private.begin(), vec_private.end());
}
```

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -1,17 +1,53 @@
## Group: Trygve and Esther % INF205 Project report
# Functionality % Creating contour maps from raster heightmaps
Our program usees the marching squares algorithm to create a vector contour map from a raster heightmap. % Esther and Trygve 7. May 2024
The cli interface is `gdal_contour [OPTIONS] <src_filename> <dst_filename>` with these options:
```
-i <elevation intervall> Interval between contours
-f <format> Fileformat to output
```
# data structure and input/output
![](ER_diagram.svg)
# Responsibilities:
Esther will create the algorithm itself with multitreading. This will essentially be a function that takes a grid of pixels as input and returns a similar grid of cells.
Trygve will take care of reading in the tiff file into our own datastructure and creating a vector image from the output of the algorithm.
# How do you plan to make it easily verifiable that your objectives are reached? ![Sample output from our program, a contour map of NMBU and Ås](kurver_ås.png)
We can compare against the `gdal_contour` cli program which is a implementation widely used in other software. We can compare speed, memory usage and the result itself. # Introduction
Each step in our program also produces a output which we can be worked on and evaluated independently. The source code is available on [https://gitlab.com/Trygve/contour-creator](https://gitlab.com/Trygve/contour-creator)
The branch 7-5-2024 contains the source code as it was on the day of the deadline.
Becouse of the 90/90 rule we had to focus on the core functionality and unfortunatly we have a few bugs and performance issues left. If we fix these issues they will be available on the main branch.
# Functionality
Our program uses the marching squares algorithm to create a vector contour map from a raster heightmap (DTM).
It outputs a geojson file that can be read by gis software. [https://mapshaper.org/](https://mapshaper.org/) is a simple website where you can view geojson files.
Instructions on running the program is available in the README.md file
# data structures and input/output
![ER diagram](ER_diagram.svg)
The [HeightMap](https://trygve.gitlab.io/contour-creator/classHeightMap.html) class stores the heightmap as a array on the heap. It was not nececarry to copy or move this class, so we did not implement copy or move constructors/assignment operators.
The [Point](https://trygve.gitlab.io/contour-creator/classPoint.html) class represents a point in a line. The points are stored in vectors, wich are again stored in a big vector containing all the lines.
The `produce_cellmap` function finds the points for a contour at a given elevation. The `create_lines` uses `produce_cellmap` the get the points and then sorts them into contiguous lines before returning a `std::vector<std::vector<Point>>`{.cpp} thats used by the function `write_output_file` to write them to a geojson file.
# Performance
| | 1 | 2 | 3 | 4 | 5 | Avarage |
| ---------- | ----- | ----- | ----- | ----- | ----- | ------- |
| 12 threads | 7,03 | 6,74 | 6,88 | 6,86 | 6,85 | 6,872 |
| 1 thread | 21,48 | 21,27 | 20,82 | 20,35 | 20,81 | 20,946 |
| reference | 4,5 | 5,61 | 5,24 | 4,81 | 5,02 | 5,036 |
| | slowdown |
| ---------------------------- | -------- |
| ours/gdal | 1,36 |
| singlethreaded/multithreaded | 3,05 |
Our program is 1,36 times slower than gdal_contour wich is bad considering ours is multithreaded and gdals is not. On the other hand gdals is has 11 years of development.
The running on 12 threads yields a nice speedup 3,05 times.
The program assumes the whole heightmap can fit in memory, this is not a problem for heightmaps from [hoydedata.no](https://hoydedata.no/LaserInnsyn2/) as the maximum tile size is about 700mb.
# Functionality of special interest
## Trygve
I can created a blur method that performs a simple box blur on the whole heigtmap. This is usefull to smooth out noise and create a more readable output.
I wanted to implement a gaussion blur, and the code is ready for that, but in the end we became short on time.
The blur is activated by passing the `--blur` flag
## Esther
Calculated some statistical estimates for the average, variance and standard deviation for the pixels in the image. Also tried to calculate the steepness around each pixel. However, we didn't manage to get the Gdal to work for this.
Statistics output is activated by passing the `--stats` flag

35
documentation/slides.md Normal file
View File

@@ -0,0 +1,35 @@
---
title:
- "INF205: creating contours using the marching squares algorithm"
author:
- Trygve og Esther
---
# Output of our program:
![Contour map of Ås](kurver_ås.png)
# Marching squares
![By Nicoguaro; Adroitwhiz - File:Marching_squares_algorithm.svg, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=143418710](ms_wikipedia.svg)
# The logical flow of our program
```cpp
int main(int argc, const char* argv[])
{
const char* filepath = argv[1];
HeightMap map(filepath);
map.blur(0.8)
auto lines = create_lines(&map, 5);
write_output_file(cellmaps, "out.geojson", &map);
}
```
# Performance
| | Time |
|--------------------|--------------------|
| 12 threads | 41s |
| 1 thread | 116s |
# Problems we encountered

View File

@@ -1,11 +0,0 @@
<PAMDataset>
<PAMRasterBand band="1">
<Metadata>
<MDI key="STATISTICS_MAXIMUM">50.05460357666</MDI>
<MDI key="STATISTICS_MEAN">43.851418194979</MDI>
<MDI key="STATISTICS_MINIMUM">37.187175750732</MDI>
<MDI key="STATISTICS_STDDEV">3.3140235738276</MDI>
<MDI key="STATISTICS_VALID_PERCENT">100</MDI>
</Metadata>
</PAMRasterBand>
</PAMDataset>

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:28f96c6f7191c6577bcdb872b5c6f7c0cd73d5431a304f556bf6c66ec7d7650d
size 149951469

1
extern/argh vendored Submodule

Submodule extern/argh added at 431bf323ac

View File

@@ -1,19 +0,0 @@
#include <cstdint>
#include <gdal/ogr_spatialref.h>
#include <ogr_spatialref.h>
#include "CaseMap.hh"
CaseMap::CaseMap(int width, int height, uint8_t* cases, OGRSpatialReference reference_system)
{
this->width = width;
this->height = height;
this->cases = cases;
this->reference_system = reference_system;
}
int CaseMap::get_case(int x, int y)
{
// all the cases are in an array of ints from left to right, top to bottom
int offset = ((this->width * y) + x);
return *(this->cases + offset);
}

View File

@@ -1,17 +0,0 @@
#include <gdal/ogr_spatialref.h>
#include <ogr_spatialref.h>
#include <cstdint>
/**
@brief stores the cases from marching squars for one elevation level
*/
class CaseMap
{
public:
uint8_t* cases; //!< pointer to the first case in the array. uint8_t is a 8 bit unsigned integer
int width; //!< width of image in cases
int height; //!< height of image in cases
OGRSpatialReference reference_system;
CaseMap(int width, int height, uint8_t* cases, OGRSpatialReference reference_system);
int get_case(int x,int y);
};

View File

@@ -1,11 +1,13 @@
#include <cstddef>
#include <gdal/cpl_conv.h>
#include <iostream> #include <iostream>
#include <stdexcept> #include <stdexcept>
#include <omp.h>
#include <gdal/gdal.h> #include <gdal/gdal.h>
#include "gdal/gdal_priv.h" #include "gdal/gdal_priv.h"
#include <gdal/gdal_frmts.h> #include <gdal/gdal_frmts.h>
#include "contour_creator.hh"
#include "HeightMap.hh"
HeightMap::HeightMap(const char* filepath) HeightMap::HeightMap(const char* filepath)
{ {
@@ -27,19 +29,163 @@ HeightMap::HeightMap(const char* filepath)
this->height = band->GetYSize(); this->height = band->GetYSize();
this->min = band->GetMinimum(); this->min = band->GetMinimum();
this->max = band-> GetMaximum(); this->max = band-> GetMaximum();
//https://gdal.org/api/gdaldataset_cpp.html#_CPPv4N11GDALDataset15GetGeoTransformEPd
this->geotransform = new double[6];
this->reference_system = *(file->GetSpatialRef()); this->reference_system = *(file->GetSpatialRef());
this->filepath = filepath;
file->GetGeoTransform(this->geotransform);
this->data = (float *) CPLMalloc(sizeof(float)*width*height); this->data = new float[width*height];
CPLErr error = band->RasterIO( GF_Read, 0, 0, width, height, CPLErr error = band->RasterIO( GF_Read, 0, 0, width, height,
this->data, width, height, GDT_Float32, this->data, width, height, GDT_Float32,
0, 0 ); 0, 0 );
if (error) { throw std::runtime_error("Could not read tif file!"); } if (error) { throw std::runtime_error("Could not read tif file!"); }
band->FlushCache(); band->FlushCache();
const int size = this->width*this->height;
} }
float HeightMap::get_pixel(int x, int y) float HeightMap::get_pixel(int x, int y)
{ {
// all the pixels are in an array of floats from left to right, top to bottom // all the pixels are in an array of floats from left to right, top to bottom
int offset = ((this->width * y) + x); return this->data[((this->width * y) + x)];
//std::cout << " offset: " << offset << " " << x << ","<< y; }
return *(this->data + offset);
} void HeightMap::blur(float standard_deviation)
{
// standard_deviation does not do anything yet. This is currently a simple box blur
int kernel_height = 5;
int kernel_width = 5;
int kernel_size = kernel_height*kernel_width;
float* kernel = new float [kernel_size];
for (int i=0; i<kernel_size; i++)
{
kernel[i] = 1.0;
}
float* blurred = new float[this->width*this->height];
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < this->height * this->width; i++)
{
float blurred_pixel = 0;
for (int j = 0; j < kernel_size; j++)
{
int x = j%kernel_width - kernel_width/2 + i%this->width;
int y = j/kernel_width - kernel_height/2 + i/this->width;
if (x<0 || x>=this->width)
{
x = 0;
}
if (y<0 || y>=this->height)
{
y = 0;
}
blurred_pixel += this->get_pixel(x, y);
}
blurred[i] = blurred_pixel/float(kernel_size);
}
}
delete[] kernel;
delete[] this->data;
this->data = blurred;
blurred = nullptr;
}
void HeightMap::statistics()
{
float avg = 0;
float var = 0;
float std = 0;
for (int i = 0; i < this->width*this->height; i++)
{int x = i%this->width;
int y = i/this->width;
if (x<0 || x>=this->width)
{
x = 0;
}
if (y<0 || y>=this->height)
{
y = 0;
}
avg += this->get_pixel(x, y);}
//std::cout << this->get_pixel(x, y);}
avg = avg/(this->width*this->height);
std::cout << "Average value: " << avg <<"\n";
for (int i = 0; i < this->width*this->height; i++)
{
int x = i%this->width;
int y = i/this->width;
var += (avg - this->get_pixel(x, y))*(avg - this->get_pixel(x, y));
}
std = sqrt(var)/(this->width*this->height-1);
var = var / (this->width*this->height-1);
std::cout << "std: " << std << "\n";
std::cout << "var: " << var << "\n";
};
void HeightMap::calculate_steepness(const char* filepath)
{
int kernel_height = 5;
int kernel_width = 5;
int kernel_size = kernel_height*kernel_width;
float* kernel = new float[kernel_size];
float* steepness = new float[this->width*this->height];
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < this->height * this->width; i++)
{
int x = i%this->width;
int y = i/this->width;
float max = 0;
float min = 0;
for (int j = 0; j < kernel_size; j++)
{
if (this->get_pixel(x, y) > max)
{
max = get_pixel(x, y);
}
if (this->get_pixel(x, y) < min)
{
min = get_pixel(x, y);
}
if (x<0 || x>=this->width)
{
x = 0;
}
if (y<0 || y>=this->height)
{
y = 0;
}
}
steepness[i] = max - min;
}
}
GDALAllRegister();
GDALDataset *original_file = (GDALDataset *) GDALOpen( this->filepath, GA_ReadOnly );
auto driver = GetGDALDriverManager()->GetDriverByName("GeoRaster");
GDALDataset *file;
file = driver->CreateCopy(filepath, original_file, FALSE, NULL, NULL, NULL);
file->AddBand(GDT_Float32, NULL);
GDALRasterBand *band = file->GetRasterBand(0);
CPLErr error = band->RasterIO( GF_Write, 0, 0, this->width, this->height,
steepness, this->width, this->height, GDT_Float32,
0, 0 );
GDALClose(file);
}

View File

@@ -1,17 +0,0 @@
#include <gdal/ogr_spatialref.h>
/**
@brief stores the contents of a tif file with float32 values
*/
class HeightMap
{
public:
float* data;
int width; //!< width of image in pixels
int height; //!< height of image in pixels
float min; //!< Minimum value in image
float max; //!< Maximum value in image
OGRSpatialReference reference_system;
HeightMap(const char* filepath);
float get_pixel(int x,int y);
};

44
src/contour_creator.hh Normal file
View File

@@ -0,0 +1,44 @@
#include <gdal/ogr_spatialref.h>
#include <gdal/ogr_spatialref.h>
#include <ogr_spatialref.h>
/**
@brief stores the contents of a tif file with float32 values
*/
class HeightMap
{
public:
float* data;
double* geotransform; //!< Six double buffer for storing the affine transformations
// https://gdal.org/api/gdaldataset_cpp.html#_CPPv4N11GDALDataset15GetGeoTransformEPd
int width; //!< width of image in pixels
int height; //!< height of image in pixels
float min; //!< Minimum value in image
float max; //!< Maximum value in image
const char* filepath; //!< Where the heightmap was read from
OGRSpatialReference reference_system;
HeightMap(const char* filepath);
~HeightMap()
{
delete[] data;
delete[] geotransform;
}
float get_pixel(int x,int y);
void blur(float standard_deviation);
void statistics(); //!< Print statistical information about the heightmap
void calculate_steepness(const char*); //!< Output a raster file with the steepness of each pixel
};
class Point
{
public:
int x;
int y;
uint8_t mscase; //!< The case outputted by the algorithm. A number between 0 and 15
bool allocated = false; //!< Used when sorting the points to see if it has been sorted
Point(int x, int y, uint8_t mscase){
this -> x = x;
this -> y = y;
this -> mscase = mscase;
};
};

View File

@@ -1,61 +1,190 @@
#include "HeightMap.hh" #include "contour_creator.hh"
#include "CaseMap.hh" #include <algorithm>
#include <array>
#include <gdal/ogr_api.h> #include <gdal/ogr_api.h>
#include "ogrsf_frmts.h" #include "ogrsf_frmts.h"
#include <gdal/ogr_core.h>
#include <gdal/ogr_feature.h>
#include <gdal/ogr_geometry.h>
#include <iostream> #include <iostream>
#include <ostream> #include <ostream>
#include <sys/types.h>
#include <tuple>
#include <vector> #include <vector>
#include <cstdint> #include <cstdint>
#include <gdal/gdal.h> #include <gdal/gdal.h>
#include "gdal/gdal_priv.h" #include "gdal/gdal_priv.h"
#include <gdal/gdal_frmts.h> #include <gdal/gdal_frmts.h>
#include <omp.h> #include <omp.h>
#include "argh.h"
CaseMap produce_casemap(HeightMap* heightmap, float z) std::vector<Point> produce_cellmap(HeightMap* heightmap, float z)
{ {
int length = (heightmap->width-1)*(heightmap->height-1); int length = (heightmap->width-1)*(heightmap->height-1); // Defining length of vector
uint8_t *cases = (uint8_t *) CPLMalloc(sizeof(uint8_t)*length); std::vector<Point> points; // Initiating a vector of points
for (int i = 0; i<length; i++) { for (int i = 0; i<length; i++) {
int y = i/(heightmap->width-1); int y = i/(heightmap->width-1);
int x = i%(heightmap->width-1); int x = i%(heightmap->width-1);
uint8_t result = (heightmap->get_pixel(x,y)>z) + uint8_t result = (heightmap->get_pixel(x,y)>z)*8 +
(heightmap->get_pixel(x+1,y)>z)*2 + (heightmap->get_pixel(x+1,y)>z)*4 +
(heightmap->get_pixel(x+1,y+1)>z)*4 + (heightmap->get_pixel(x+1,y+1)>z)*2 +
(heightmap->get_pixel(x,y+1)>z)*8; (heightmap->get_pixel(x,y+1)>z);
*(cases + i) = result; if (result != 0 and result != 15 ) {
points.push_back(Point(x, y, result));
};
} }
return points;
return CaseMap(heightmap->width-1, heightmap->height-1, cases, heightmap->reference_system);
} }
std::vector<CaseMap> vector_casemap(HeightMap* heightmap, int interval) bool is_in(int value, std::array<int, 8> array)
{
return std::binary_search(array.begin(), array.end(), value);
}
std::vector<std::vector<Point>> create_lines(HeightMap* heightmap, int interval)
{ {
int num_contours = (heightmap->max - heightmap->min)/interval; int num_contours = (heightmap->max - heightmap->min)/interval;
std::vector<CaseMap> vector_contours; std::vector<std::vector<Point>> vector_contours;
omp_set_num_threads(12);
#pragma omp parallel std::array<int,8> north{4, 5,6,7,8,9,10,11};
{ std::array<int,8> south{1,2,5,6,9,10,13,14};
std::vector<CaseMap> vec_private; std::array<int,8> east{2,3,4,5,10,11,12,13};
#pragma omp for std::array<int,8> west{1,3,5,7,8,10,12,14};
for (int i = 1; i <= num_contours; i++)
#pragma omp parallel
{ {
vec_private.push_back(produce_casemap(heightmap, heightmap->min + interval*i)); std::vector<std::vector<Point>> vec_private;
std::cout << "Execute thread " << omp_get_num_threads() << " "; #pragma omp for
for (int i = 1; i <= num_contours; i++)
{
auto points = produce_cellmap(heightmap, heightmap->min + interval*i);
std::vector<Point> line;
int x;
int y;
int points_allocated = 0;
x = points[0].x;
y = points[0].y;
int current_case = points[0].mscase;
points[0].allocated = true;
line.push_back(points[0]);
for (int j = 0; j < points.size(); j++){
for (int k = 0; k < points.size(); k++){
Point* candidate = &points[k];
if (!candidate->allocated) {
if (candidate->x == x +1 && candidate->y == y /*&& is_in(current_case, east)*/) {
candidate->allocated = true;
x = candidate->x;
y = candidate->y;
current_case = candidate->mscase;
line.push_back(*candidate);
points_allocated++;
break;
}
else if (candidate->x == x -1 && candidate->y == y /*&& is_in(current_case, west)*/) {
x = candidate->x;
y = candidate->y;
current_case = candidate->mscase;
candidate->allocated = true;
line.push_back(*candidate);
points_allocated++;
break;
}
else if (candidate->x == x && candidate->y == y + 1 /*&& is_in(current_case, north)*/) {
x = candidate->x;
y = candidate->y;
current_case = candidate->mscase;
candidate->allocated = true;
line.push_back(*candidate);
points_allocated++;
break;
}
else if (candidate->x == x && candidate->y == y - 1 /*&& is_in(current_case, south)*/) {
x = candidate->x;
y = candidate->y;
current_case = candidate->mscase;
candidate->allocated = true;
line.push_back(*candidate);
points_allocated++;
break;
}
}
}
if (j > points_allocated)
{
vec_private.push_back(line);
line.clear();
//std::cout << points.size() << " ";
for (int k = 0; k < points.size(); k++){
Point* candidate = &points[k];
if (!candidate->allocated)
{
line.push_back(*candidate);
candidate->allocated = true;
x = candidate->x;
y = candidate->y;
current_case = candidate->mscase;
points_allocated++;
break;
}
}
}
}
}
#pragma omp critical
vector_contours.insert(vector_contours.end(), vec_private.begin(), vec_private.end());
} }
#pragma omp critical return vector_contours;
vector_contours.insert(vector_contours.end(), vec_private.begin(), vec_private.end());
}
return vector_contours;
} }
void write_output_file(std::vector<CaseMap> casemaps, const char *filepath) std::tuple<double, double> local_to_projected(double* geotransform, int x, int y)
{
return {
geotransform[1] * x + geotransform[2] * y +
geotransform[1] * 0.5 + geotransform[2] * 0.5 + geotransform[0],
geotransform[4] * x + geotransform[5] * y +
geotransform[4] * 0.5 + geotransform[5] * 0.5 + geotransform[3]
};
}
constexpr std::tuple<double, double, double, double> marching_squares_lookup(int mcase)
{
switch (mcase) {
case 1:
return {0, 0.5, 0.5, 0};
case 14:
return {0.5, 0, 0, 0.5};
case 2:
return {0.5, 0, 1, 0.5};
case 13:
return {1, 0.5, 0.5, 0};
case 3:
return {0, 0.5, 1, 0.5};
case 12:
return {1, 0.5, 0, 0.5};
case 4:
return {0.5, 1, 1, 0.5};
case 11:
return {1, 0.5, 0.5, 1};
case 5:
case 10:
return {0, 0, 0, 0}; //FIXME
case 6:
return {0.5, 1, 0.5, 0};
case 9:
return {0.5, 0, 0.5, 1};
case 7:
return {0, 0.5, 0.5, 1};
case 8:
return {0.5, 1, 0, 0.5};
};
}
void write_output_file(std::vector<std::vector<Point>> all_points, const char *filepath, HeightMap* heightmap)
{ {
const char *pszDriverName = "ESRI Shapefile"; const char *pszDriverName = "GeoJSON";
GDALDriver *poDriver; GDALDriver *poDriver;
GDALAllRegister(); GDALAllRegister();
@@ -78,7 +207,7 @@ void write_output_file(std::vector<CaseMap> casemaps, const char *filepath)
OGRLayer *poLayer; OGRLayer *poLayer;
poLayer = poDS->CreateLayer( "contours", &(casemaps[0]).reference_system, wkbPoint, NULL ); poLayer = poDS->CreateLayer( "contours", &heightmap->reference_system, wkbLineString, NULL );
if( poLayer == NULL ) if( poLayer == NULL )
{ {
printf( "Layer creation failed.\n" ); printf( "Layer creation failed.\n" );
@@ -94,81 +223,111 @@ void write_output_file(std::vector<CaseMap> casemaps, const char *filepath)
printf( "Creating Name field failed.\n" ); printf( "Creating Name field failed.\n" );
exit( 1 ); exit( 1 );
} }
for (int j = 0; j < casemaps.size(); j++) int width = heightmap->width -1;
int height = heightmap->height -1;
int size = width * height;
for (int j = 0; j < all_points.size(); j++)
{ {
CaseMap* casemap = &casemaps[j]; OGRFeature *feature;
for (int i = 0; i<casemap->height*casemap->width; i++) { OGRLineString *geometry = new OGRLineString();
if (*(casemap->cases + i) != 0 && *(casemap->cases + i) != 15) feature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
feature->SetField( "Name", j );
std::vector<Point> points = all_points[j];
bool left_to_right = true;
if ((points[0].y - points[1].y) < 0)
left_to_right = true;
else
left_to_right = false;
for (int k = 0; k < points.size(); k++)
{
bool left_to_right = true;
if ((points[k].x - points[k-1].x) < 0)
left_to_right = false;
bool top_to_bottom = true;
if ((points[k].y - points[k-1].y) < 0)
top_to_bottom = false;
int x_raw = points[k].x;
int y_raw = points[k].y;
auto [x, y] = local_to_projected(heightmap->geotransform, x_raw, y_raw);
auto [x1, y1, x2, y2] = marching_squares_lookup(points[k].mscase);
if (left_to_right or top_to_bottom)
{ {
int x_int = i%casemap->width; geometry->setPoint(geometry->getNumPoints(),x + (x1/4) ,y + (y1/4));
int y_int = casemap->height*casemap->width - i/casemap->width; geometry->setPoint(geometry->getNumPoints(),x + (x2/4) ,y + (y2/4));
double x = double(x_int); }
double y = double(y_int); else {
geometry->setPoint(geometry->getNumPoints(),x + (x2/4) ,y + (y2/4));
OGRFeature *poFeature; geometry->setPoint(geometry->getNumPoints(),x + (x1/4) ,y + (y1/4));
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
poFeature->SetField( "Name", *(casemap->cases + i) );
//OGRSpatialReference local;
//auto poCT = OGRCreateCoordinateTransformation( &local, &casemap->reference_system );
/*
if( poCT == NULL || !poCT->Transform( 1, &x, &y ) )
printf( "Transformation failed.\n" );
*/
OGRPoint pt;
pt.setX( x );
pt.setY( y );
poFeature->SetGeometry( &pt );
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
{
printf( "Failed to create feature in shapefile.\n" );
exit( 1 );
}
OGRFeature::DestroyFeature( poFeature );
} }
} }
if ( feature->SetGeometry(geometry) != OGRERR_NONE)
{
printf( "Failed to set geometry.\n" );
exit( 1 );
}
OGRGeometryFactory::destroyGeometry(geometry);
if( poLayer->CreateFeature( feature ) != OGRERR_NONE )
{
printf( "Failed to create feature in shapefile.\n" );
exit( 1 );
}
OGRFeature::DestroyFeature( feature );
} }
GDALClose( poDS ); GDALClose( poDS );
/*
OGRDataSourceH datasource = OGR_Dr_CreateDataSource(OGRGetDriverByName("GeoJSON"), "contour.geojson", new char*);
OGRSpatialReference reference_system = casemap->reference_system;
OGRLayerH layer = OGR_DS_CreateLayer(datasource, "contour", &reference_system, wkbLineString25D, new char*);
auto feature = OGR_F_Create(OGR_L_GetLayerDefn(static_cast<OGRLayerH>(layer)));
OGRGeometryH geometry = OGR_G_CreateGeometry(wkbLineString25D);
*/
} }
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
const char* filepath = argv[1]; argh::parser cmdl(argv);
HeightMap map(filepath);
if (cmdl[{ "-h", "--help" }])
std::cout << "x: " << map.width << " y: " << map.height << "\n";
std::cout << "max: " << map.max << " min: " << map.min << "\n";
auto casemap = produce_casemap(&map, 40);
/*
for (int y = 0; y < casemap.height; y++)
{ {
for (int x = 0; x < casemap.width; x++) std::cout << "Usage:\n"
{ << "contour_creator [OPTIONS] <input_file>\n\n"
if (casemap.get_case(x, y) && casemap.get_case(x, y)!=15) { << "Arguments in the form --<name>=<value>:"
std::cout << x << ","<< y << "=" << casemap.get_case(x, y) << " "; << "-o; --output <FILENAME.geojson> - File to write output to (Default: contours.geojson)\n"
} << "-i; --interval <int> - Set the interval between contours (Default: 5)\n"
} << "-b; --blur - Blur the image\n"
//std::cout << "\n"; << "--stats - Print statistical information about the heightmap\n"
<< "--steepness <filename> - Create steepness map\n";
exit(0);
} }
*/
int interval;
cmdl({"-i", "--interval"}, 5) >> interval;
if (interval <= 0)
std::cerr << "Interval must be valid positive integer!" << "\n";
auto casemaps = vector_casemap(&map, 5); std::string output_file;
write_output_file(casemaps, "out.shp"); cmdl({"-o", "--output"}, "contours.geojson") >> output_file;
std::string input_file;
cmdl(1) >> input_file;
HeightMap map(input_file.c_str());
if (cmdl[{"-b", "--blur"}])
map.blur(0.8);
if (cmdl[{"--stats"}])
map.statistics();
std::string steepness_output_file;
//if (cmdl({"--steepness"}, "steepness.tif") >> steepness_output_file)
// map.calculate_steepness(output_file.c_str());
auto lines = create_lines(&map, interval);
write_output_file(lines, output_file.c_str(), &map);
std::cout << "Contours written to " << output_file << " 🗺️\n";
} }