Initial commit
79
.gitignore
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
# PlatformIO
|
||||
.pio
|
||||
|
||||
# VS Code
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/extensions.json
|
||||
.vscode/ipch
|
||||
.vscode/launch.json
|
||||
|
||||
# Own folders
|
||||
_unused/
|
||||
|
||||
# Own files
|
||||
log.txt
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# Python
|
||||
venv
|
||||
.venv
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Local backup
|
||||
*.*_
|
||||
*.*bak*
|
||||
66
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"cmake.configureOnOpen": false,
|
||||
"editor.rulers": [
|
||||
120
|
||||
],
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"map": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"csignal": "cpp",
|
||||
"set": "cpp",
|
||||
"mutex": "cpp",
|
||||
"*.h_": "cpp"
|
||||
}
|
||||
}
|
||||
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Techniccontroller, Ranse
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
42
README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Important Note:
|
||||
This project has been unofficially forked from https://github.com/techniccontroller/wordclock_esp8266 which was initially created by techniccontroller. Copyright and licensing is respected. Very many thanks for the initial code!
|
||||
|
||||
|
||||
# Wordclock 2.0
|
||||
|
||||
Wordclock 2.0 with ESP32 and NTP time.
|
||||
|
||||
|
||||
**Languages**
|
||||
|
||||
The Wordclock is available in **German** language.
|
||||
|
||||
|
||||
## Features
|
||||
- Time update via NTP server
|
||||
- Games: Pong, Snake, Tetris, ...
|
||||
- Automatic summer/wintertime change
|
||||
- Easy wifi setup with WifiManager
|
||||
- Configurable color
|
||||
- Configurable night mode (start and end time)
|
||||
- Configurable brightness
|
||||
- Automatic mode change
|
||||
- Webserver interface for configuration and control (web address: wordclock.local)
|
||||
- Automatic current limiting of LEDs
|
||||
|
||||
## Pictures of clock
|
||||

|
||||
|
||||
## Quickstart
|
||||
|
||||
1. Clone the project into the a directory.
|
||||
2. Open directory in VSCode with PlatformIO extension installed.
|
||||
3. Current dependencies (TBD):
|
||||
- Platform TBD
|
||||
- Libraries TBD
|
||||
|
||||
|
||||
|
||||
## Remark about the WiFi setup
|
||||
|
||||
By default the WifiManager is activated. That is, the word clock makes the first time its own WiFi (should be called "WordclockAP"). There you simply connect to the cell phone and you can perform configuration of the WiFi settings conveniently as with SmartHome devices.
|
||||
24
include/animation_functions.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef ANIMATIONFUNCTIONS_H
|
||||
#define ANIMATIONFUNCTIONS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "wordclock_constants.h"
|
||||
|
||||
extern bool spiral_direction; // Direction of sprial animation
|
||||
|
||||
enum Direction
|
||||
{
|
||||
RIGHT,
|
||||
LEFT,
|
||||
UP,
|
||||
DOWN
|
||||
};
|
||||
|
||||
Direction next_direction(Direction dir, int d);
|
||||
int random_snake(bool init, const uint8_t len, const uint32_t color, int numSteps);
|
||||
int random_tetris(bool init);
|
||||
int draw_heart_animation(void);
|
||||
int draw_spiral(bool init, bool empty, uint8_t size);
|
||||
void show_digital_clock(uint8_t hours, uint8_t minutes, uint32_t color);
|
||||
|
||||
#endif /* ANIMATIONFUNCTIONS_H */
|
||||
97
include/compile_time.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
*
|
||||
* Created: 29.03.2018
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* Assembled from the code released on Stackoverflow by:
|
||||
* Dennis (instructable.com/member/nqtronix) | https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string
|
||||
* and
|
||||
* Alexis Wilke | https://stackoverflow.com/questions/10538444/do-you-know-of-a-c-macro-to-compute-unix-time-and-date
|
||||
*
|
||||
* Assembled by Jean Rabault
|
||||
*
|
||||
* UNIX_TIMESTAMP gives the UNIX timestamp (unsigned long integer of seconds since 1st Jan 1970) of compilation from macros using the compiler defined __TIME__ macro.
|
||||
* This should include Gregorian calendar leap days, in particular the 29ths of February, 100 and 400 years modulo leaps.
|
||||
*
|
||||
* Careful: __TIME__ is the local time of the computer, NOT the UTC time in general!
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMPILE_TIME_H_
|
||||
#define COMPILE_TIME_H_
|
||||
|
||||
// Some definitions for calculation
|
||||
#define SEC_PER_MIN 60UL
|
||||
#define SEC_PER_HOUR 3600UL
|
||||
#define SEC_PER_DAY 86400UL
|
||||
#define SEC_PER_YEAR (SEC_PER_DAY*365)
|
||||
|
||||
// extracts 1..4 characters from a string and interprets it as a decimal value
|
||||
#define CONV_STR2DEC_1(str, i) (str[i]>'0'?str[i]-'0':0)
|
||||
#define CONV_STR2DEC_2(str, i) (CONV_STR2DEC_1(str, i)*10 + str[i+1]-'0')
|
||||
#define CONV_STR2DEC_3(str, i) (CONV_STR2DEC_2(str, i)*10 + str[i+2]-'0')
|
||||
#define CONV_STR2DEC_4(str, i) (CONV_STR2DEC_3(str, i)*10 + str[i+3]-'0')
|
||||
|
||||
// Custom "glue logic" to convert the month name to a usable number
|
||||
#define GET_MONTH(str, i) (str[i]=='J' && str[i+1]=='a' && str[i+2]=='n' ? 1 : \
|
||||
str[i]=='F' && str[i+1]=='e' && str[i+2]=='b' ? 2 : \
|
||||
str[i]=='M' && str[i+1]=='a' && str[i+2]=='r' ? 3 : \
|
||||
str[i]=='A' && str[i+1]=='p' && str[i+2]=='r' ? 4 : \
|
||||
str[i]=='M' && str[i+1]=='a' && str[i+2]=='y' ? 5 : \
|
||||
str[i]=='J' && str[i+1]=='u' && str[i+2]=='n' ? 6 : \
|
||||
str[i]=='J' && str[i+1]=='u' && str[i+2]=='l' ? 7 : \
|
||||
str[i]=='A' && str[i+1]=='u' && str[i+2]=='g' ? 8 : \
|
||||
str[i]=='S' && str[i+1]=='e' && str[i+2]=='p' ? 9 : \
|
||||
str[i]=='O' && str[i+1]=='c' && str[i+2]=='t' ? 10 : \
|
||||
str[i]=='N' && str[i+1]=='o' && str[i+2]=='v' ? 11 : \
|
||||
str[i]=='D' && str[i+1]=='e' && str[i+2]=='c' ? 12 : 0)
|
||||
|
||||
// extract the information from the time string given by __TIME__ and __DATE__
|
||||
#define __TIME_SECONDS__ CONV_STR2DEC_2(__TIME__, 6)
|
||||
#define __TIME_MINUTES__ CONV_STR2DEC_2(__TIME__, 3)
|
||||
#define __TIME_HOURS__ CONV_STR2DEC_2(__TIME__, 0)
|
||||
#define __TIME_DAYS__ CONV_STR2DEC_2(__DATE__, 4)
|
||||
#define __TIME_MONTH__ GET_MONTH(__DATE__, 0)
|
||||
#define __TIME_YEARS__ CONV_STR2DEC_4(__DATE__, 7)
|
||||
|
||||
// Days in February
|
||||
#define _UNIX_TIMESTAMP_FDAY(year) \
|
||||
(((year) % 400) == 0UL ? 29UL : \
|
||||
(((year) % 100) == 0UL ? 28UL : \
|
||||
(((year) % 4) == 0UL ? 29UL : \
|
||||
28UL)))
|
||||
|
||||
// Days in the year
|
||||
#define _UNIX_TIMESTAMP_YDAY(year, month, day) \
|
||||
( \
|
||||
/* January */ day \
|
||||
/* February */ + (month >= 2 ? 31UL : 0UL) \
|
||||
/* March */ + (month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) \
|
||||
/* April */ + (month >= 4 ? 31UL : 0UL) \
|
||||
/* May */ + (month >= 5 ? 30UL : 0UL) \
|
||||
/* June */ + (month >= 6 ? 31UL : 0UL) \
|
||||
/* July */ + (month >= 7 ? 30UL : 0UL) \
|
||||
/* August */ + (month >= 8 ? 31UL : 0UL) \
|
||||
/* September */+ (month >= 9 ? 31UL : 0UL) \
|
||||
/* October */ + (month >= 10 ? 30UL : 0UL) \
|
||||
/* November */ + (month >= 11 ? 31UL : 0UL) \
|
||||
/* December */ + (month >= 12 ? 30UL : 0UL) \
|
||||
)
|
||||
|
||||
// get the UNIX timestamp from a digits representation
|
||||
#define _UNIX_TIMESTAMP(year, month, day, hour, minute, second) \
|
||||
( /* time */ second \
|
||||
+ minute * SEC_PER_MIN \
|
||||
+ hour * SEC_PER_HOUR \
|
||||
+ /* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * SEC_PER_DAY \
|
||||
+ /* year */ (year - 1970UL) * SEC_PER_YEAR \
|
||||
+ ((year - 1969UL) / 4UL) * SEC_PER_DAY \
|
||||
- ((year - 1901UL) / 100UL) * SEC_PER_DAY \
|
||||
+ ((year - 1601UL) / 400UL) * SEC_PER_DAY \
|
||||
)
|
||||
|
||||
// the UNIX timestamp
|
||||
#define UNIX_TIMESTAMP (_UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, __TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__))
|
||||
|
||||
#endif
|
||||
25
include/diagnosis.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef DIAGNOSIS_H
|
||||
#define DIAGNOSIS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "led_matrix.h"
|
||||
#include "udp_logger.h"
|
||||
|
||||
class Diagnosis
|
||||
{
|
||||
public:
|
||||
Diagnosis(UDPLogger *logger, LEDMatrix *matrix); // constructor
|
||||
|
||||
String handle_command(const String &command);
|
||||
String print_device_info();
|
||||
String print_sketch_info();
|
||||
String print_last_reset_details();
|
||||
String print_matrix_fps();
|
||||
|
||||
private:
|
||||
UDPLogger *_logger;
|
||||
LEDMatrix * _matrix;
|
||||
void print(const String &s);
|
||||
};
|
||||
|
||||
#endif // DIAGNOSIS_H
|
||||
60
include/led_matrix.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef LEDMATRIX_H
|
||||
#define LEDMATRIX_H
|
||||
|
||||
#ifndef FASTLED_INTERNAL
|
||||
#define FASTLED_INTERNAL
|
||||
#endif
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <FastLED_NeoMatrix.h>
|
||||
#include "wordclock_constants.h"
|
||||
#include "udp_logger.h"
|
||||
|
||||
#define DEFAULT_CURRENT_LIMIT 9999
|
||||
|
||||
extern const uint32_t colors_24bit[NUM_COLORS];
|
||||
class LEDMatrix
|
||||
{
|
||||
public:
|
||||
LEDMatrix(FastLED_NeoMatrix *matrix, uint8_t brightness, UDPLogger *logger);
|
||||
static uint16_t color_24_to_16bit(uint32_t color24bit);
|
||||
static uint32_t color_24bit(uint8_t r, uint8_t g, uint8_t b);
|
||||
static uint32_t interpolate_color_24bit(uint32_t color1, uint32_t color2, float factor);
|
||||
static uint32_t wheel(uint8_t WheelPos);
|
||||
uint16_t get_fps(void);
|
||||
void draw_on_matrix_instant();
|
||||
void draw_on_matrix_smooth(float factor);
|
||||
void flush(void);
|
||||
void grid_add_pixel(uint8_t x, uint8_t y, uint32_t color);
|
||||
void print_char(uint8_t xpos, uint8_t ypos, char character, uint32_t color);
|
||||
void print_number(uint8_t xpos, uint8_t ypos, uint8_t number, uint32_t color);
|
||||
void set_brightness(uint8_t mybrightness);
|
||||
void set_current_limit(uint16_t new_current_limit);
|
||||
void set_min_indicator(uint8_t pattern, uint32_t color);
|
||||
void setup_matrix();
|
||||
|
||||
private:
|
||||
FastLED_NeoMatrix *_neomatrix;
|
||||
UDPLogger *_logger;
|
||||
|
||||
uint8_t _brightness;
|
||||
uint16_t _current_limit;
|
||||
|
||||
// target representation of matrix as 2D array
|
||||
uint32_t _target_grid[MATRIX_HEIGHT][MATRIX_WIDTH];
|
||||
|
||||
// current representation of matrix as 2D array
|
||||
uint32_t _current_grid[MATRIX_HEIGHT][MATRIX_WIDTH];
|
||||
|
||||
// target representation of minutes indicator LEDs
|
||||
uint32_t _target_minute_indicators[4] = {0, 0, 0, 0};
|
||||
|
||||
// current representation of minutes indicator LEDs
|
||||
uint32_t _current_minute_indicators[4] = {0, 0, 0, 0};
|
||||
|
||||
void _draw_on_matrix(float factor);
|
||||
uint16_t _calc_estimated_led_current(uint32_t color);
|
||||
};
|
||||
|
||||
#endif /* LEDMATRIX_H */
|
||||
29
include/littlefs_wrapper.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef LITTLEFS_WRAPPER_H
|
||||
#define LITTLEFS_WRAPPER_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#define USE_LittleFS
|
||||
|
||||
//#define DEBUGGING // Einkommentieren für die Serielle Ausgabe
|
||||
|
||||
#ifdef DEBUGGING
|
||||
#define DEBUG_B(...) Serial.begin(__VA_ARGS__)
|
||||
#define DEBUG_P(...) Serial.println(__VA_ARGS__)
|
||||
#define DEBUG_F(...) Serial.printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_B(...)
|
||||
#define DEBUG_P(...)
|
||||
#define DEBUG_F(...)
|
||||
#endif
|
||||
|
||||
bool handle_file(String &&path);
|
||||
bool handle_list();
|
||||
const String format_bytes(size_t const &bytes);
|
||||
void delete_recursive(const String &path);
|
||||
void format_filesystem();
|
||||
void handle_upload();
|
||||
void send_response();
|
||||
void setup_filesystem();
|
||||
|
||||
#endif /* LITTLEFS_WRAPPER_H */
|
||||
9
include/ota_wrapper.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef OTA_FUNCTIONS_H
|
||||
#define OTA_FUNCTIONS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
void handleOTA();
|
||||
void setupOTA(String hostname);
|
||||
|
||||
#endif /* OTA_FUNCTIONS_H */
|
||||
20
include/own_font.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef OWN_FONT_H
|
||||
#define OWN_FONT_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
uint8_t numbers_font[10][5] = {{0b00000111, 0b00000101, 0b00000101, 0b00000101, 0b00000111},
|
||||
{0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001},
|
||||
{0b00000111, 0b00000001, 0b00000111, 0b00000100, 0b00000111},
|
||||
{0b00000111, 0b00000001, 0b00000111, 0b00000001, 0b00000111},
|
||||
{0b00000101, 0b00000101, 0b00000111, 0b00000001, 0b00000001},
|
||||
{0b00000111, 0b00000100, 0b00000111, 0b00000001, 0b00000111},
|
||||
{0b00000111, 0b00000100, 0b00000111, 0b00000101, 0b00000111},
|
||||
{0b00000111, 0b00000001, 0b00000001, 0b00000001, 0b00000001},
|
||||
{0b00000111, 0b00000101, 0b00000111, 0b00000101, 0b00000111},
|
||||
{0b00000111, 0b00000101, 0b00000111, 0b00000001, 0b00000111}};
|
||||
|
||||
uint8_t chars_font[2][5] = {{0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b00000010},
|
||||
{0b00000111, 0b00000101, 0b00000111, 0b00000100, 0b00000100}};
|
||||
|
||||
#endif /* OWN_FONT_H */
|
||||
100
include/pong.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @file pong.h
|
||||
* @author techniccontroller (mail[at]techniccontroller.com)
|
||||
* @brief Class declaration for pong game
|
||||
* @version 0.1
|
||||
* @date 2022-03-05
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
* main code from https://elektro.turanis.de/html/prj041/index.html
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PONG_H
|
||||
#define PONG_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "led_matrix.h"
|
||||
#include "udp_logger.h"
|
||||
|
||||
#ifdef DEBOUNCE_TIME
|
||||
#undef DEBOUNCE_TIME
|
||||
#endif
|
||||
#define DEBOUNCE_TIME 10 // in ms
|
||||
|
||||
#define X_MAX 11
|
||||
#define Y_MAX 11
|
||||
|
||||
#ifdef GAME_DELAY
|
||||
#undef GAME_DELAY
|
||||
#endif
|
||||
#define GAME_DELAY 80 // in ms
|
||||
|
||||
#define BALL_DELAY_MAX 350 // in ms
|
||||
#define BALL_DELAY_MIN 50 // in ms
|
||||
#define BALL_DELAY_STEP 5 // in ms
|
||||
|
||||
#define PLAYER_AMOUNT 2
|
||||
#define PLAYER_1 0
|
||||
#define PLAYER_2 1
|
||||
|
||||
#define PADDLE_WIDTH 3
|
||||
|
||||
#define PADDLE_MOVE_NONE 0
|
||||
#define PADDLE_MOVE_UP 1
|
||||
#define PADDLE_MOVE_DOWN 2
|
||||
|
||||
#ifdef LED_TYPE_OFF
|
||||
#undef LED_TYPE_OFF
|
||||
#endif
|
||||
#define LED_TYPE_OFF 1
|
||||
#define LED_TYPE_PADDLE 2
|
||||
#define LED_TYPE_BALL 3
|
||||
#define LED_TYPE_BALL_RED 4
|
||||
|
||||
#define GAME_STATE_RUNNING 1
|
||||
#define GAME_STATE_END 2
|
||||
#define GAME_STATE_INIT 3
|
||||
|
||||
class Pong
|
||||
{
|
||||
struct Coords
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
};
|
||||
|
||||
public:
|
||||
Pong();
|
||||
Pong(LEDMatrix * matrix, UDPLogger * logger);
|
||||
void loopCycle();
|
||||
void initGame(uint8_t numBots);
|
||||
void ctrlUp(uint8_t playerid);
|
||||
void ctrlDown(uint8_t playerid);
|
||||
void ctrlNone(uint8_t playerid);
|
||||
|
||||
private:
|
||||
LEDMatrix *_ledmatrix;
|
||||
UDPLogger *_logger;
|
||||
uint8_t _gameState = 0;
|
||||
uint8_t _numBots = 0;
|
||||
uint8_t _playerMovement[PLAYER_AMOUNT];
|
||||
Coords _paddles[PLAYER_AMOUNT][PADDLE_WIDTH];
|
||||
Coords _ball = {0, 0};
|
||||
Coords _ball_old = {0, 0};
|
||||
int _ballMovement[2] = {0, 0};
|
||||
unsigned int _ballDelay = 0;
|
||||
unsigned long _lastDrawUpdate = 0;
|
||||
unsigned long _lastBallUpdate = 0;
|
||||
unsigned long _lastButtonClick = 0;
|
||||
|
||||
void updateBall();
|
||||
void endGame();
|
||||
void updateGame();
|
||||
uint8_t getPlayerMovement(uint8_t playerId);
|
||||
void resetLEDs();
|
||||
void toggleLed(uint8_t x, uint8_t y, uint8_t type);
|
||||
};
|
||||
|
||||
#endif /* PONG_H */
|
||||
11
include/render_functions.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef RENDER_FUNCTIONS_H
|
||||
#define RENDER_FUNCTIONS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
int show_string_on_clock(String message, uint32_t color);
|
||||
String split(String s, char parser, int index);
|
||||
String time_to_string(uint8_t hours, uint8_t minutes);
|
||||
void draw_minute_indicator(uint8_t minutes, uint32_t color);
|
||||
|
||||
#endif /* RENDER_FUNCTIONS_H */
|
||||
94
include/snake.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @file snake.h
|
||||
* @author techniccontroller (mail[at]techniccontroller.com)
|
||||
* @brief Class declaration of snake game
|
||||
* @version 0.1
|
||||
* @date 2022-03-05
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
* main code from https://elektro.turanis.de/html/prj099/index.html
|
||||
*
|
||||
*/
|
||||
#ifndef snake_h
|
||||
#define snake_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "led_matrix.h"
|
||||
#include "udp_logger.h"
|
||||
|
||||
#ifdef DEBOUNCE_TIME
|
||||
#undef DEBOUNCE_TIME
|
||||
#endif
|
||||
#define DEBOUNCE_TIME 250 // in ms
|
||||
|
||||
#define X_MAX 11
|
||||
#define Y_MAX 11
|
||||
|
||||
#ifdef GAME_DELAY
|
||||
#undef GAME_DELAY
|
||||
#endif
|
||||
#define GAME_DELAY 400 // in ms
|
||||
|
||||
#define LED_TYPE_SNAKE 1
|
||||
#ifdef LED_TYPE_OFF
|
||||
#undef LED_TYPE_OFF
|
||||
#endif
|
||||
#define LED_TYPE_OFF 2
|
||||
#define LED_TYPE_FOOD 3
|
||||
#define LED_TYPE_BLOOD 4
|
||||
|
||||
#define DIRECTION_NONE 0
|
||||
#define DIRECTION_UP 1
|
||||
#define DIRECTION_DOWN 2
|
||||
#define DIRECTION_LEFT 3
|
||||
#define DIRECTION_RIGHT 4
|
||||
|
||||
#define GAME_STATE_RUNNING 1
|
||||
#define GAME_STATE_END 2
|
||||
#define GAME_STATE_INIT 3
|
||||
|
||||
#define MAX_TAIL_LENGTH (X_MAX * Y_MAX)
|
||||
#define MIN_TAIL_LENGTH 3
|
||||
|
||||
class Snake
|
||||
{
|
||||
|
||||
struct Coords
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
public:
|
||||
Snake();
|
||||
Snake(LEDMatrix * matrix, UDPLogger * logger);
|
||||
void loopCycle();
|
||||
void initGame();
|
||||
void ctrlUp();
|
||||
void ctrlDown();
|
||||
void ctrlLeft();
|
||||
void ctrlRight();
|
||||
|
||||
private:
|
||||
LEDMatrix * _ledmatrix;
|
||||
UDPLogger * _logger;
|
||||
uint8_t _userDirection = 0;
|
||||
uint8_t _gameState = 0;
|
||||
Coords _head = {0, 0};
|
||||
Coords _tail[MAX_TAIL_LENGTH] = {0, 0};
|
||||
Coords _food = {0, 0};
|
||||
unsigned long _lastDrawUpdate = 0;
|
||||
unsigned long _lastButtonClick = 0;
|
||||
unsigned int _wormLength = 0;
|
||||
|
||||
void resetLEDs();
|
||||
void updateGame();
|
||||
void endGame();
|
||||
void updateTail();
|
||||
void updateFood();
|
||||
bool isCollision();
|
||||
void toggleLed(uint8_t x, uint8_t y, uint8_t type);
|
||||
};
|
||||
|
||||
#endif
|
||||
199
include/tetris.h
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* @file tetris.h
|
||||
* @author techniccontroller (mail[at]techniccontroller.com)
|
||||
* @brief Class definition for tetris game
|
||||
* @version 0.1
|
||||
* @date 2022-03-05
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
* main tetris code originally written by Klaas De Craemer, Ing. David Hrbaty
|
||||
*
|
||||
*/
|
||||
#ifndef TETRIS_H
|
||||
#define TETRIS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "led_matrix.h"
|
||||
#include "udp_logger.h"
|
||||
|
||||
#ifdef DEBOUNCE_TIME
|
||||
#undef DEBOUNCE_TIME
|
||||
#endif
|
||||
#define DEBOUNCE_TIME 100
|
||||
|
||||
#define RED_END_TIME 1500
|
||||
#define GAME_STATE_RUNNING 1
|
||||
#define GAME_STATE_END 2
|
||||
#define GAME_STATE_INIT 3
|
||||
#define GAME_STATE_PAUSED 4
|
||||
#define GAME_STATE_READY 5
|
||||
|
||||
// common
|
||||
#define DIR_UP 1
|
||||
#define DIR_DOWN 2
|
||||
#define DIR_LEFT 3
|
||||
#define DIR_RIGHT 4
|
||||
// Maximum size of bricks. Individual bricks can still be smaller (eg 3x3)
|
||||
#define GREEN 0x008000
|
||||
#define RED 0xFF0000
|
||||
#define BLUE 0x0000FF
|
||||
#define YELLOW 0xFFFF00
|
||||
#define CHOCOLATE 0xD2691E
|
||||
#define PURPLE 0xFF00FF
|
||||
#define WHITE 0XFFFFFF
|
||||
#define AQUA 0x00FFFF
|
||||
#define HOTPINK 0xFF1493
|
||||
#define DARKORANGE 0xFF8C00
|
||||
|
||||
#define MAX_BRICK_SIZE 4
|
||||
#define BRICKOFFSET -1 // Y offset for new bricks
|
||||
|
||||
#define INIT_SPEED 800 // Initial delay in ms between brick drops
|
||||
#define SPEED_STEP 10 // Factor for speed increase between levels, default 10
|
||||
#define LEVELUP 4 // Number of rows before levelup, default 5
|
||||
|
||||
#define WIDTH 11
|
||||
#define HEIGHT 11
|
||||
|
||||
class Tetris
|
||||
{
|
||||
|
||||
// Playing field
|
||||
struct Field
|
||||
{
|
||||
uint8_t pix[MATRIX_WIDTH][MATRIX_HEIGHT + 1]; // Make field one larger so that collision detection with bottom of field can be done in a uniform way
|
||||
uint32_t color[MATRIX_WIDTH][MATRIX_HEIGHT];
|
||||
};
|
||||
|
||||
// Structure to represent active brick on screen
|
||||
struct Brick
|
||||
{
|
||||
boolean enabled; // Brick is disabled when it has landed
|
||||
int xpos, ypos;
|
||||
|
||||
int yOffset; // Y-offset to use when placing brick at top of field
|
||||
uint8_t siz;
|
||||
uint8_t pix[MAX_BRICK_SIZE][MAX_BRICK_SIZE];
|
||||
|
||||
uint32_t col;
|
||||
};
|
||||
|
||||
// Struct to contain the different choices of blocks
|
||||
struct AbstractBrick
|
||||
{
|
||||
int yOffset; // Y-offset to use when placing brick at top of field
|
||||
uint8_t siz;
|
||||
uint8_t pix[MAX_BRICK_SIZE][MAX_BRICK_SIZE];
|
||||
uint32_t col;
|
||||
};
|
||||
|
||||
public:
|
||||
Tetris();
|
||||
Tetris(LEDMatrix *myledmatrix, UDPLogger *mylogger);
|
||||
|
||||
void ctrlStart();
|
||||
void ctrlPlayPause();
|
||||
void ctrlRight();
|
||||
void ctrlLeft();
|
||||
void ctrlUp();
|
||||
void ctrlDown();
|
||||
void setSpeed(int32_t i);
|
||||
|
||||
void loopCycle();
|
||||
|
||||
private:
|
||||
void resetLEDs();
|
||||
void tetrisInit();
|
||||
void printField();
|
||||
|
||||
/* *** Game functions *** */
|
||||
void newActiveBrick();
|
||||
boolean checkFieldCollision(struct Brick *brick);
|
||||
boolean checkSidesCollision(struct Brick *brick);
|
||||
void rotateActiveBrick();
|
||||
void shiftActiveBrick(int dir);
|
||||
void addActiveBrickToField();
|
||||
void moveFieldDownOne(uint8_t startRow);
|
||||
void checkFullLines();
|
||||
|
||||
void clearField();
|
||||
void everythingRed();
|
||||
void showscore();
|
||||
|
||||
LEDMatrix *_ledmatrix;
|
||||
UDPLogger *_logger;
|
||||
Brick _activeBrick = {0};
|
||||
Field _field;
|
||||
|
||||
bool _allowdrop = false;
|
||||
bool _tetrisGameOver = false;
|
||||
int _gameState = GAME_STATE_INIT;
|
||||
int _score = 0;
|
||||
unsigned int _speedtetris = 80;
|
||||
unsigned long _brickSpeed = 0;
|
||||
unsigned long _droptime = 0;
|
||||
unsigned long _lastButtonClick = 0;
|
||||
unsigned long _lastButtonClickr = 0;
|
||||
unsigned long _nbRowsThisLevel = 0;
|
||||
unsigned long _nbRowsTotal = 0;
|
||||
unsigned long _prevUpdateTime = 0;
|
||||
unsigned long _tetrisshowscore = 0;
|
||||
|
||||
// color library
|
||||
uint32_t _colorLib[10] = {RED, GREEN, BLUE, YELLOW, CHOCOLATE, PURPLE, WHITE, AQUA, HOTPINK, DARKORANGE};
|
||||
|
||||
// Brick "library"
|
||||
AbstractBrick _brickLib[7] = {
|
||||
{1, // yoffset when adding brick to field
|
||||
4,
|
||||
{{0, 0, 0, 0},
|
||||
{0, 1, 1, 0},
|
||||
{0, 1, 1, 0},
|
||||
{0, 0, 0, 0}},
|
||||
WHITE},
|
||||
{0,
|
||||
4,
|
||||
{{0, 1, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 1, 0, 0}},
|
||||
GREEN},
|
||||
{1,
|
||||
3,
|
||||
{{0, 0, 0, 0},
|
||||
{1, 1, 1, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 0}},
|
||||
BLUE},
|
||||
{1,
|
||||
3,
|
||||
{{0, 0, 1, 0},
|
||||
{1, 1, 1, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0}},
|
||||
YELLOW},
|
||||
{1,
|
||||
3,
|
||||
{{0, 0, 0, 0},
|
||||
{1, 1, 1, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 0, 0}},
|
||||
AQUA},
|
||||
{1,
|
||||
3,
|
||||
{{0, 1, 1, 0},
|
||||
{1, 1, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0}},
|
||||
HOTPINK},
|
||||
{1,
|
||||
3,
|
||||
{{1, 1, 0, 0},
|
||||
{0, 1, 1, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0}},
|
||||
RED}};
|
||||
};
|
||||
|
||||
#endif /* TETRIS_H */
|
||||
37
include/udp_logger.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @file udp_logger.h
|
||||
* @author techniccontroller (mail[at]techniccontroller.com)
|
||||
* @brief Class for sending logging Strings as multicast messages
|
||||
* @version 0.1
|
||||
* @date 2022-03-21
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UDP_LOGGER_H
|
||||
#define UDP_LOGGER_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
class UDPLogger
|
||||
{
|
||||
public:
|
||||
UDPLogger();
|
||||
UDPLogger(IPAddress interface_addr, IPAddress multicast_addr, uint16_t port, String name);
|
||||
void set_name(String name);
|
||||
void log_string(String message);
|
||||
void log_color_24bit(uint32_t color);
|
||||
|
||||
private:
|
||||
char _packetBuffer[100] = {0};
|
||||
int _port;
|
||||
IPAddress _interfaceAddr;
|
||||
IPAddress _multicastAddr;
|
||||
String _name = "Logger";
|
||||
unsigned long _lastSend = 0;
|
||||
WiFiUDP _udp;
|
||||
};
|
||||
|
||||
#endif /* UDP_LOGGER_H */
|
||||
79
include/wordclock_constants.h
Normal file
@@ -0,0 +1,79 @@
|
||||
#ifndef WORDCLOCK_CONSTANTS_H
|
||||
#define WORDCLOCK_CONSTANTS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// CONSTANTS
|
||||
// ----------------------------------------------------------------------------------
|
||||
#define AP_SSID "WordclockAP" // SSID name of Access Point
|
||||
#define NTP_SERVER_URL "de.pool.ntp.org" // NTP server address
|
||||
#define MY_TZ "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" // Timezone
|
||||
|
||||
#define HOSTNAME (String("wordclock")) // Local hostname
|
||||
#define LOGGER_MULTICAST_IP (IPAddress(230, 120, 10, 2)) // IP for UDP server
|
||||
#define LOGGER_MULTICAST_PORT (8123) // Port for UDP server
|
||||
#define HTTP_PORT (80) // Standard HTTP port
|
||||
|
||||
// ESP8266 Pins
|
||||
#define FASTLED_PIN (0) // pin to which the LEDs are attached
|
||||
#define BUTTON_PIN (5) // pin to which the button is attached
|
||||
|
||||
// Time limits
|
||||
#define HOUR_MAX (23)
|
||||
#define MINUTE_MAX (59)
|
||||
|
||||
#define MINUTES_IN_HOUR (60)
|
||||
#define HOURS_IN_DAY (24)
|
||||
|
||||
// Night mode
|
||||
#define NIGHTMODE_START_HR (23)
|
||||
#define NIGHTMODE_START_MIN (0)
|
||||
#define NIGHTMODE_END_HR (7)
|
||||
#define NIGHTMODE_END_MIN (0)
|
||||
|
||||
// Timings in us
|
||||
#define PERIOD_ANIMATION_US (200 * 1000) // 200ms
|
||||
#define PERIOD_CLOCK_UPDATE_US (1 * 1000 * 1000) // Must be 1s! Do not change!
|
||||
#define PERIOD_HEARTBEAT_US (1 * 1000 * 1000) // 1s
|
||||
#define PERIOD_MATRIX_UPDATE_US (33 * 1000) // 33ms
|
||||
#define PERIOD_NIGHTMODE_CHECK_US (30 * 1000 * 1000) // 30s
|
||||
#define PERIOD_TIME_UPDATE_US (1 * 1000 * 1000) // 1000ms
|
||||
#define PERIOD_PONG_US (10 * 1000) // 10ms
|
||||
#define PERIOD_SNAKE_US (50 * 1000) // 50ms
|
||||
#define PERIOD_STATE_CHANGE_US (10 * 1000 * 1000) // 10s
|
||||
#define PERIOD_TETRIS_US (50 * 1000) // 50ms
|
||||
#define TIMEOUT_LEDDIRECT_US (5 * 1000 * 1000) // 5s
|
||||
#define PERIOD_BRIGHTNESS_UPDATE_US (5 * 60 * 1000 * 1000) // 300s
|
||||
|
||||
#define SHORT_PRESS_US (100 * 1000) // 100ms
|
||||
#define LONG_PRESS_US (2 * 1000 * 1000) // 2s
|
||||
#define VERY_LONG_PRESS_US (10 * 1000 * 1000) // 10s
|
||||
|
||||
// Current limit
|
||||
#define CURRENT_LIMIT_LED (2500) // limit the total current consumed by LEDs (mA)
|
||||
|
||||
// Brightness ranges range: 0 - 255
|
||||
#define DEFAULT_BRIGHTNESS (40)
|
||||
#define MIN_BRIGHTNESS (10)
|
||||
#define MAX_BRIGHTNESS UINT8_MAX
|
||||
|
||||
// LED smoothing
|
||||
#define DEFAULT_SMOOTHING_FACTOR (0.5f)
|
||||
|
||||
// Number of colors in colors array
|
||||
#define NUM_COLORS (7)
|
||||
#define COLOR_ORDER GRB // WS2812B color order
|
||||
|
||||
// LED matrix size
|
||||
#define MATRIX_WIDTH (11)
|
||||
#define MATRIX_HEIGHT (11)
|
||||
#define NUM_MATRIX (MATRIX_WIDTH * (MATRIX_HEIGHT + 1))
|
||||
|
||||
// NTP macros TODO
|
||||
#define BUILD_YEAR (__DATE__ + 7) // Will expand to current year at compile time as string.
|
||||
#define NTP_MINIMUM_RX_YEAR (atoi(BUILD_YEAR) - 1) // Will expand to current year minus one at compile time.
|
||||
#define NTP_START_YEAR (1900) // NTP minimum year is 1900
|
||||
#define NTP_MAX_OFFLINE_TIME_S (7 * 24 * 3600) // Watchdog value, maximum offline time before a restart is triggered
|
||||
|
||||
#endif /* WORDCLOCK_CONSTANTS_H */
|
||||
89
include/wordclock_esp32.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef WORDCLOCK_ESP8266_H
|
||||
#define WORDCLOCK_ESP8266_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdlib.h>
|
||||
#include <WebServer.h>
|
||||
#include "led_matrix.h"
|
||||
#include "udp_logger.h"
|
||||
|
||||
#define RANGE_LIMIT(X, MIN, MAX) (((X) < (MIN)) ? (MIN) : (((X) > (MAX)) ? (MAX) : (X)))
|
||||
#define RANGE_LIMIT_SUB(X, MIN, MAX, SUB) (((X) < (MIN)) ? (SUB) : (((X) > (MAX)) ? (SUB) : (X)))
|
||||
|
||||
#define EEPROM_SIZE (sizeof(EepromLayout_st) / sizeof(uint8_t))
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// TYPEDEFS
|
||||
// ----------------------------------------------------------------------------------
|
||||
typedef struct
|
||||
{
|
||||
int start_hour;
|
||||
int start_min;
|
||||
int end_hour;
|
||||
int end_min;
|
||||
} NightModeTimes_st;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t alpha; // note: unused
|
||||
} Color_st;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t static_brightness; // user-controlled static brightness of LEDs
|
||||
uint8_t dyn_brightness_min; // user-controlled min brightness of LEDs
|
||||
uint8_t dyn_brightness_max; // user-controlled max brightness of LEDs
|
||||
bool flg_dynamic_brightness; // flag if user wants to use daytime dynamic brightness
|
||||
} Brightness_st;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NightModeTimes_st night_mode_times;
|
||||
Brightness_st brightness_values;
|
||||
Color_st color_values;
|
||||
} EepromLayout_st;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ST_CLOCK,
|
||||
ST_DICLOCK,
|
||||
ST_SPIRAL,
|
||||
ST_TETRIS,
|
||||
ST_SNAKE,
|
||||
ST_PINGPONG,
|
||||
ST_HEARTS,
|
||||
NUM_STATES
|
||||
} ClockState_en;
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// FUNCTIONS DECLARATIONS
|
||||
// ----------------------------------------------------------------------------------
|
||||
bool check_wifi_status(void);
|
||||
String leading_zero2digit(int value);
|
||||
uint8_t calculate_dynamic_brightness(uint8_t min_brightness, uint8_t max_brightness, int hours, int minutes, bool summertime);
|
||||
uint8_t update_brightness(void);
|
||||
void check_night_mode(void);
|
||||
void cold_start_setup(void);
|
||||
void draw_main_color(void);
|
||||
void handle_button(void);
|
||||
void handle_command(void);
|
||||
void handle_current_state(void);
|
||||
void handle_data_request(void);
|
||||
void handle_led_direct(void);
|
||||
void limit_value_ranges(void);
|
||||
void log_data(void);
|
||||
void on_state_entry(uint8_t state);
|
||||
void read_settings_from_EEPROM(void);
|
||||
void reset_wifi_credentials(void);
|
||||
void send_heartbeat(void);
|
||||
void set_dynamic_brightness(bool state);
|
||||
void set_main_color(uint8_t red, uint8_t green, uint8_t blue);
|
||||
void set_night_mode(bool on);
|
||||
void state_change(ClockState_en new_state);
|
||||
void update_matrix(void);
|
||||
void write_settings_to_EEPROM(void);
|
||||
|
||||
#endif /* WORDCLOCK_ESP8266_H */
|
||||
46
lib/README
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
30
platformio.ini
Normal file
@@ -0,0 +1,30 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
default_envs = az-delivery-devkit-v4_ota
|
||||
|
||||
[env]
|
||||
platform = espressif32
|
||||
board = az-delivery-devkit-v4
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
densaugeo/base64@^1.4.0
|
||||
fastled/FastLED@^3.9.2
|
||||
marcmerlin/FastLED NeoMatrix@^1.2
|
||||
tzapu/WiFiManager@^2.0.17
|
||||
|
||||
[env:az-delivery-devkit-v4]
|
||||
monitor_speed = 115200
|
||||
monitor_filters = direct
|
||||
|
||||
[env:az-delivery-devkit-v4_ota]
|
||||
upload_protocol = espota
|
||||
upload_port = 192.168.178.xxx
|
||||
BIN
res/frontplate/WordClock_DrillingTemplate.pdf
Normal file
1828
res/frontplate/WordClock_DrillingTemplate.svg
Normal file
|
After Width: | Height: | Size: 186 KiB |
1828
res/frontplate/WordClock_DrillingTemplate_Overlay.svg
Normal file
|
After Width: | Height: | Size: 186 KiB |
1301
res/frontplate/WordClock_Front.svg
Normal file
|
After Width: | Height: | Size: 90 KiB |
775
res/frontplate/WordClock_Front_Paths.svg
Normal file
@@ -0,0 +1,775 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="500mm"
|
||||
height="500mm"
|
||||
viewBox="0 0 500 500"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="layer1">
|
||||
<g
|
||||
id="g1">
|
||||
<path
|
||||
id="rect2951"
|
||||
style="display:inline;fill-rule:evenodd;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round"
|
||||
d="M 0,0 H 500 V 500 H 0 Z" />
|
||||
</g>
|
||||
<g
|
||||
id="g3"
|
||||
style="display:inline">
|
||||
<path
|
||||
d="M 81.224283,86.25 V 72.10854 H 91.44935 v 1.668808 h -8.353687 v 4.331184 h 7.823141 v 1.659162 h -7.823141 v 4.813498 h 8.681661 V 86.25 Z"
|
||||
id="text3140"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="M 147.16962,86.25 V 72.10854 h 6.27009 q 1.89067,0 2.87459,0.385852 0.98393,0.376205 1.57235,1.340834 0.58842,0.964629 0.58842,2.13183 0,1.504821 -0.97427,2.536974 -0.97428,1.032153 -3.00964,1.311895 0.74276,0.356913 1.12861,0.704179 0.81994,0.752411 1.55305,1.881027 L 159.63263,86.25 h -2.3537 l -1.87138,-2.942118 q -0.81993,-1.27331 -1.35048,-1.948551 -0.53054,-0.67524 -0.95498,-0.945336 -0.41479,-0.270096 -0.84887,-0.376205 -0.31833,-0.06752 -1.0418,-0.06752 H 149.041 V 86.25 Z m 1.87138,-7.900311 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.270096 1.09968,-0.848873 0.3762,-0.588424 0.3762,-1.27331 0,-1.003214 -0.73311,-1.649516 -0.72347,-0.646301 -2.29582,-0.646301 H 149.041 Z"
|
||||
id="text1"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 113.79905,81.706598 1.76527,-0.154341 q 0.1254,1.061092 0.57878,1.745979 0.46302,0.67524 1.42765,1.099677 0.96463,0.41479 2.17041,0.41479 1.07074,0 1.89068,-0.318328 0.81993,-0.318327 1.21543,-0.868166 0.40514,-0.559484 0.40514,-1.215432 0,-0.665594 -0.38585,-1.157555 -0.38585,-0.501607 -1.27331,-0.839227 -0.56913,-0.221865 -2.51768,-0.684886 -1.94855,-0.472669 -2.7299,-0.887459 -1.01286,-0.530546 -1.51447,-1.311895 -0.49196,-0.790996 -0.49196,-1.765271 0,-1.070738 0.60772,-1.996782 0.60772,-0.93569 1.77492,-1.418005 1.1672,-0.482314 2.59485,-0.482314 1.57234,0 2.76848,0.511253 1.20579,0.501607 1.85209,1.485529 0.6463,0.983921 0.69453,2.228293 l -1.79421,0.135048 q -0.14469,-1.340835 -0.98392,-2.025721 -0.82958,-0.684887 -2.4598,-0.684887 -1.69775,0 -2.4791,0.627009 -0.7717,0.617363 -0.7717,1.495175 0,0.762057 0.54984,1.254018 0.54019,0.49196 2.81671,1.01286 2.28617,0.511253 3.13505,0.897105 1.23472,0.569131 1.82315,1.446943 0.58842,0.868166 0.58842,2.006428 0,1.128616 -0.6463,2.13183 -0.6463,0.993568 -1.86174,1.553053 -1.20578,0.549838 -2.72025,0.549838 -1.91961,0 -3.22186,-0.559485 -1.2926,-0.559484 -2.03537,-1.678454 -0.73311,-1.128616 -0.7717,-2.54662 z"
|
||||
id="text3144"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="M 185.09807,86.25 V 72.10854 h 1.87138 V 86.25 Z"
|
||||
id="text3971"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 213.54904,81.706598 1.76527,-0.154341 q 0.12541,1.061092 0.57878,1.745979 0.46302,0.67524 1.42765,1.099677 0.96463,0.41479 2.17042,0.41479 1.07074,0 1.89067,-0.318328 0.81993,-0.318327 1.21543,-0.868166 0.40515,-0.559484 0.40515,-1.215432 0,-0.665594 -0.38586,-1.157555 -0.38585,-0.501607 -1.27331,-0.839227 -0.56913,-0.221865 -2.51768,-0.684886 -1.94855,-0.472669 -2.7299,-0.887459 -1.01286,-0.530546 -1.51446,-1.311895 -0.49196,-0.790996 -0.49196,-1.765271 0,-1.070738 0.60771,-1.996782 0.60772,-0.93569 1.77492,-1.418005 1.1672,-0.482314 2.59485,-0.482314 1.57235,0 2.76849,0.511253 1.20578,0.501607 1.85208,1.485529 0.6463,0.983921 0.69454,2.228293 l -1.79421,0.135048 q -0.1447,-1.340835 -0.98393,-2.025721 -0.82958,-0.684887 -2.4598,-0.684887 -1.69775,0 -2.4791,0.627009 -0.7717,0.617363 -0.7717,1.495175 0,0.762057 0.54984,1.254018 0.54019,0.49196 2.81672,1.01286 2.28617,0.511253 3.13504,0.897105 1.23473,0.569131 1.82315,1.446943 0.58842,0.868166 0.58842,2.006428 0,1.128616 -0.6463,2.13183 -0.6463,0.993568 -1.86173,1.553053 -1.20579,0.549838 -2.72026,0.549838 -1.91961,0 -3.22186,-0.559485 -1.2926,-0.559484 -2.03536,-1.678454 -0.73312,-1.128616 -0.77171,-2.54662 z"
|
||||
id="text3975"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="M 251.58843,86.25 V 73.777348 h -4.65916 V 72.10854 h 11.20899 v 1.668808 h -4.67845 V 86.25 Z"
|
||||
id="text3979"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="M 280.12139,86.25 V 72.10854 h 1.91961 l 7.42764,11.102879 V 72.10854 h 1.79421 V 86.25 h -1.91961 L 281.9156,75.137475 V 86.25 Z"
|
||||
id="text3983"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="M 314.58682,86.25 V 72.10854 h 9.54018 v 1.668808 h -7.6688 v 4.379415 h 6.63665 v 1.668808 H 316.4582 V 86.25 Z"
|
||||
id="text3987"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 355.92041,72.10854 h 1.87138 v 8.170407 q 0,2.13183 -0.48231,3.385848 -0.48232,1.254017 -1.74598,2.045013 -1.25402,0.781349 -3.29903,0.781349 -1.98714,0 -3.2508,-0.684886 -1.26366,-0.684887 -1.80386,-1.97749 -0.54019,-1.302249 -0.54019,-3.549834 V 72.10854 h 1.87138 v 8.160761 q 0,1.842441 0.33762,2.720253 0.34727,0.868166 1.17685,1.340834 0.83923,0.472669 2.04501,0.472669 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.598066 z m -6.42443,-0.868166 v -1.977489 h 1.81351 v 1.977489 z m 3.59807,0 v -1.977489 h 1.8135 v 1.977489 z"
|
||||
id="text3991"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Ü" />
|
||||
<path
|
||||
d="M 379.87136,86.25 V 72.10854 h 1.91961 l 7.42764,11.102879 V 72.10854 h 1.79421 V 86.25 h -1.91961 L 381.66557,75.137475 V 86.25 Z"
|
||||
id="text3995"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="M 414.33679,86.25 V 72.10854 h 9.54018 v 1.668808 h -7.6688 v 4.379415 h 6.63665 v 1.668808 h -6.63665 V 86.25 Z"
|
||||
id="text3999"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 85.227493,119.50001 -5.479092,-14.14146 h 2.025721 l 3.675236,10.2733 q 0.443729,1.23472 0.742764,2.31511 0.327974,-1.15756 0.762057,-2.31511 l 3.819931,-10.2733 h 1.909965 l -5.53697,14.14146 z"
|
||||
id="text4003"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="V" />
|
||||
<path
|
||||
d="m 118.59808,119.50001 v -14.14146 h 1.87138 v 14.14146 z"
|
||||
id="text4007"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 147.72428,119.50001 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4011"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 180.41962,119.50001 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98393,0.3762 1.57235,1.34083 0.58842,0.96463 0.58842,2.13183 0,1.50482 -0.97427,2.53698 -0.97428,1.03215 -3.00964,1.31189 0.74276,0.35692 1.12861,0.70418 0.81994,0.75241 1.55305,1.88103 l 2.45981,3.84887 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94534 -0.41479,-0.27009 -0.84887,-0.3762 -0.31833,-0.0675 -1.0418,-0.0675 H 182.291 v 6.27974 z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84888 0.3762,-0.58842 0.3762,-1.27331 0,-1.00321 -0.73311,-1.64951 -0.72347,-0.6463 -2.29582,-0.6463 H 182.291 Z"
|
||||
id="text4015"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 218.33843,119.50001 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 v 12.47265 z"
|
||||
id="text4019"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="m 247.47428,119.50001 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4023"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 281.70338,119.50001 v -14.14146 h 1.87138 v 12.47265 h 6.96462 v 1.66881 z"
|
||||
id="text4027"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="L" />
|
||||
<path
|
||||
d="m 313.36174,119.50001 v -1.73633 l 7.24437,-9.05787 q 0.7717,-0.96463 1.46623,-1.67845 h -7.89066 v -1.66881 h 10.1286 v 1.66881 l -7.93889,9.81027 -0.85852,0.99357 h 9.02892 v 1.66881 z"
|
||||
id="text4031"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 347.22428,119.50001 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4035"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 379.94853,119.50001 v -14.14146 h 1.87138 v 5.80706 h 7.35047 v -5.80706 h 1.87138 v 14.14146 h -1.87138 v -6.66559 h -7.35047 v 6.66559 z"
|
||||
id="text4039"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 413.12136,119.50001 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42764,-11.11253 v 11.11253 z"
|
||||
id="text4043"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 80.611744,152.75 v -1.73633 l 7.244363,-9.05787 q 0.771703,-0.96463 1.466236,-1.67845 h -7.890664 v -1.66881 h 10.128603 v 1.66881 l -7.938896,9.81027 -0.858519,0.99357 h 9.028926 V 152.75 Z"
|
||||
id="text4047"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 114.17043,152.75 -3.75241,-14.14146 h 1.91961 l 2.15112,9.27008 q 0.34727,1.45659 0.59807,2.89389 0.54019,-2.26688 0.63666,-2.61414 l 2.69131,-9.54983 h 2.25723 l 2.02572,7.15755 q 0.76206,2.66237 1.09968,5.00642 0.2701,-1.34083 0.70418,-3.07717 l 2.21865,-9.0868 h 1.88102 l -3.8778,14.14146 h -1.80386 l -2.9807,-10.7749 q -0.37621,-1.35049 -0.44373,-1.65917 -0.22187,0.97428 -0.41479,1.65917 l -3,10.7749 z"
|
||||
id="text4051"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="W" />
|
||||
<path
|
||||
d="m 146.13265,152.75 5.43086,-14.14146 h 2.01607 l 5.78777,14.14146 h -2.13183 l -1.64951,-4.28295 h -5.91318 l -1.55305,4.28295 z m 4.08038,-5.80707 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00321,-2.93247 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4055"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 180.37139,152.75 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 152.75 h -1.91961 L 182.1656,141.63748 V 152.75 Z"
|
||||
id="text4059"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 213.61174,152.75 v -1.73633 l 7.24437,-9.05787 q 0.7717,-0.96463 1.46623,-1.67845 h -7.89066 v -1.66881 h 10.1286 v 1.66881 l -7.93889,9.81027 -0.85852,0.99357 h 9.02892 V 152.75 Z"
|
||||
id="text4063"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 251.59806,152.75 v -14.14146 h 1.87138 V 152.75 Z"
|
||||
id="text4067"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 286.2082,147.20338 v -1.65916 l 5.99034,-0.01 v 5.24758 q -1.37942,1.09967 -2.84565,1.65916 -1.46624,0.54984 -3.00964,0.54984 -2.0836,0 -3.79099,-0.88746 -1.69775,-0.89711 -2.56592,-2.58521 -0.86816,-1.6881 -0.86816,-3.7717 0,-2.0643 0.85852,-3.84887 0.86816,-1.7942 2.48874,-2.66237 1.62058,-0.86817 3.73311,-0.86817 1.53376,0 2.76849,0.50161 1.24437,0.49196 1.94855,1.37942 0.70418,0.88746 1.07074,2.31511 l -1.6881,0.46302 q -0.31833,-1.08038 -0.791,-1.69775 -0.47267,-0.61736 -1.35048,-0.98392 -0.87781,-0.3762 -1.94855,-0.3762 -1.28296,0 -2.21865,0.39549 -0.93569,0.38586 -1.51447,1.02251 -0.56913,0.63666 -0.88745,1.39871 -0.5402,1.3119 -0.5402,2.84566 0,1.89067 0.64631,3.16398 0.65594,1.27331 1.90031,1.89067 1.24438,0.61737 2.64309,0.61737 1.21543,0 2.37298,-0.46303 1.15756,-0.47266 1.75563,-1.00321 v -2.63344 z"
|
||||
id="text4071"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="G" />
|
||||
<path
|
||||
d="m 313.44856,152.75 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 152.75 h -1.87138 v -6.66559 h -7.35047 V 152.75 Z"
|
||||
id="text4075"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 351.22749,152.75 -5.47909,-14.14146 h 2.02572 l 3.67524,10.2733 q 0.44373,1.23472 0.74276,2.31511 0.32798,-1.15756 0.76206,-2.31511 l 3.81993,-10.2733 h 1.90996 L 353.1471,152.75 Z"
|
||||
id="text4079"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="V" />
|
||||
<path
|
||||
d="m 378.77168,145.86255 q 0,-3.5209 1.89068,-5.50803 1.89067,-1.99678 4.88102,-1.99678 1.95819,0 3.53054,0.93569 1.57234,0.93569 2.39228,2.61414 0.82958,1.66881 0.82958,3.79099 0,2.15113 -0.86817,3.84887 -0.86816,1.69775 -2.4598,2.57556 -1.59164,0.86817 -3.43408,0.86817 -1.99678,0 -3.56913,-0.96463 -1.57234,-0.96463 -2.38263,-2.63344 -0.81029,-1.66881 -0.81029,-3.53054 z m 1.92926,0.0289 q 0,2.55627 1.36977,4.03215 1.37942,1.46623 3.45338,1.46623 2.11253,0 3.47266,-1.48553 1.36977,-1.48552 1.36977,-4.21542 0,-1.72669 -0.58842,-3.00965 -0.57878,-1.2926 -1.70739,-1.99678 -1.11897,-0.71382 -2.51769,-0.71382 -1.98713,0 -3.42443,1.36977 -1.42765,1.36013 -1.42765,4.55305 z"
|
||||
id="text4083"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="O" />
|
||||
<path
|
||||
d="m 413.16959,152.75 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98392,0.37621 1.57235,1.34084 0.58842,0.96462 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03215 -3.00965,1.3119 0.74277,0.35691 1.12862,0.70417 0.81994,0.75241 1.55305,1.88103 l 2.45981,3.84887 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94533 -0.41479,-0.2701 -0.84887,-0.37621 -0.31833,-0.0675 -1.0418,-0.0675 h -2.17042 V 152.75 Z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84887 0.3762,-0.58843 0.3762,-1.27331 0,-1.00322 -0.73311,-1.64952 -0.72348,-0.6463 -2.29582,-0.6463 h -4.47588 z"
|
||||
id="text4087"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 81.185698,186 v -14.14146 h 5.334398 q 1.408358,0 2.151123,0.13505 1.041799,0.17363 1.745978,0.66559 0.704179,0.48232 1.128616,1.36013 0.434083,0.87781 0.434083,1.92926 0,1.80385 -1.147909,3.05787 -1.147908,1.24437 -4.147904,1.24437 H 83.057078 V 186 Z m 1.87138,-7.418 h 3.655944 q 1.813502,0 2.575559,-0.67524 0.762057,-0.67524 0.762057,-1.90032 0,-0.88745 -0.453376,-1.51446 -0.443729,-0.63666 -1.176847,-0.83923 -0.472668,-0.1254 -1.745978,-0.1254 h -3.617359 z"
|
||||
id="text4091"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="P" />
|
||||
<path
|
||||
d="m 118.59809,186 v -14.14146 h 1.87138 V 186 Z"
|
||||
id="text4095"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 147.60853,186 v -14.14146 h 1.87138 v 7.01285 l 7.0225,-7.01285 h 2.53697 l -5.93247,5.7299 6.19292,8.41156 h -2.46945 l -5.03536,-7.15755 -2.31511,2.25724 V 186 Z"
|
||||
id="text4099"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="K" />
|
||||
<path
|
||||
d="m 179.38265,186 5.43086,-14.14146 h 2.01607 L 192.61735,186 h -2.13183 l -1.64951,-4.28295 h -5.91318 L 181.36978,186 Z m 4.08038,-5.80707 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00321,-2.93247 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4103"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 223.7307,181.04181 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.52089 -1.52412,1.20579 -3.73312,1.20579 -2.28617,0 -3.72346,-0.92605 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64951 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08039 1.44694,1.08038 2.01607,3.03858 l -1.84244,0.43408 q -0.49196,-1.5434 -1.42765,-2.24758 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.31189 -0.44373,2.7106 0,1.80386 0.5209,3.15434 0.53054,1.34084 1.63987,2.00643 1.10932,0.66559 2.40192,0.66559 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69131 z"
|
||||
id="text4107"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 246.94855,186 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 186 h -1.87138 v -6.66559 h -7.35047 V 186 Z"
|
||||
id="text4111"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 289.42041,171.85854 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4115"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 313.37139,186 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 186 h -1.91961 L 315.1656,174.88748 V 186 Z"
|
||||
id="text4119"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 345.63265,186 5.43086,-14.14146 h 2.01607 L 358.86735,186 h -2.13183 l -1.64951,-4.28295 h -5.91318 L 347.61978,186 Z m 4.08038,-5.80707 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00321,-2.93247 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4123"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 389.98067,181.04181 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.52089 -1.52412,1.20579 -3.73312,1.20579 -2.28617,0 -3.72346,-0.92605 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64951 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08039 1.44694,1.08038 2.01607,3.03858 l -1.84244,0.43408 q -0.49196,-1.5434 -1.42765,-2.24758 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.31189 -0.44373,2.7106 0,1.80386 0.5209,3.15434 0.53054,1.34084 1.63987,2.00643 1.10932,0.66559 2.40192,0.66559 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69131 z"
|
||||
id="text4127"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 413.19853,186 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 186 h -1.87138 v -6.66559 h -7.35047 V 186 Z"
|
||||
id="text4131"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 80.698561,219.25 v -14.14146 h 1.87138 v 5.80707 h 7.350472 v -5.80707 h 1.87138 V 219.25 h -1.87138 v -6.66559 H 82.569941 V 219.25 Z"
|
||||
id="text4135"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 112.88265,219.25 5.43086,-14.14146 h 2.01608 l 5.78777,14.14146 h -2.13183 l -1.64951,-4.28295 h -5.91318 l -1.55305,4.28295 z m 4.08038,-5.80707 h 4.79421 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00322,-2.93247 -0.27009,1.36013 -0.76205,2.70096 z"
|
||||
id="text4139"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 148.70338,219.25 v -14.14146 h 1.87138 v 12.47265 h 6.96462 V 219.25 Z"
|
||||
id="text4143"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="L" />
|
||||
<path
|
||||
d="m 180.85853,219.25 v -14.14146 h 5.30546 q 1.62057,0 2.59485,0.43408 0.98392,0.42444 1.53376,1.32154 0.55948,0.88746 0.55948,1.86174 0,0.90675 -0.49196,1.70739 -0.49196,0.80064 -1.48553,1.2926 1.28296,0.37621 1.96785,1.28296 0.69453,0.90675 0.69453,2.14148 0,0.99356 -0.42444,1.85208 -0.41479,0.84888 -1.03215,1.3119 -0.61736,0.46302 -1.55305,0.70418 -0.92605,0.23151 -2.27653,0.23151 z m 1.87138,-8.19935 h 3.05787 q 1.24437,0 1.78457,-0.16398 0.71382,-0.21222 1.07073,-0.70418 0.36656,-0.49196 0.36656,-1.23473 0,-0.70418 -0.33762,-1.23472 -0.33762,-0.54019 -0.96463,-0.73312 -0.62701,-0.20257 -2.15112,-0.20257 h -2.82636 z m 0,6.53054 h 3.52089 q 0.90675,0 1.27331,-0.0675 0.64631,-0.11576 1.08039,-0.38585 0.43408,-0.2701 0.71382,-0.78135 0.27975,-0.5209 0.27975,-1.19614 0,-0.791 -0.40515,-1.36978 -0.40514,-0.58842 -1.12861,-0.81993 -0.71383,-0.24116 -2.06431,-0.24116 h -3.27009 z"
|
||||
id="text4147"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="B" />
|
||||
<path
|
||||
d="m 212.48795,219.25 v -14.14146 h 2.81672 l 3.34726,10.01285 q 0.46302,1.39871 0.67524,2.09324 0.24116,-0.7717 0.75241,-2.26687 l 3.38585,-9.83922 h 2.51768 V 219.25 h -1.80386 v -11.836 l -4.10932,11.836 h -1.6881 l -4.09002,-12.03857 V 219.25 Z"
|
||||
id="text4151"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="M" />
|
||||
<path
|
||||
d="m 247.47428,219.25 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 219.25 Z"
|
||||
id="text4155"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 281.70338,219.25 v -14.14146 h 1.87138 v 12.47265 h 6.96462 V 219.25 Z"
|
||||
id="text4159"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="L" />
|
||||
<path
|
||||
d="m 314.58682,219.25 v -14.14146 h 9.54018 v 1.66881 h -7.6688 v 4.37941 h 6.63665 v 1.66881 H 316.4582 V 219.25 Z"
|
||||
id="text4163"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 355.92041,205.10854 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z m -6.42443,-0.86817 v -1.97749 h 1.81351 v 1.97749 z m 3.59807,0 v -1.97749 h 1.8135 v 1.97749 z"
|
||||
id="text4167"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Ü" />
|
||||
<path
|
||||
d="m 379.87136,219.25 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 219.25 h -1.91961 l -7.42764,-11.11252 V 219.25 Z"
|
||||
id="text4171"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 414.33679,219.25 v -14.14146 h 9.54018 v 1.66881 h -7.6688 v 4.37941 h 6.63665 v 1.66881 h -6.63665 V 219.25 Z"
|
||||
id="text4175"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 79.487951,252.49998 v -14.14146 h 2.816717 l 3.347262,10.01285 q 0.463022,1.39871 0.67524,2.09325 0.241158,-0.77171 0.752411,-2.26688 l 3.385847,-9.83922 h 2.517682 v 14.14146 h -1.803856 v -11.83599 l -4.109319,11.83599 h -1.688101 l -4.090027,-12.03856 v 12.03856 z"
|
||||
id="text4179"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="M" />
|
||||
<path
|
||||
d="m 118.59809,252.49998 v -14.14146 h 1.87138 v 14.14146 z"
|
||||
id="text4183"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 151.83843,252.49998 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 v 12.47265 z"
|
||||
id="text4187"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="m 185.08843,252.49998 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 v 12.47265 z"
|
||||
id="text4191"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="m 214.22428,252.49998 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33119 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.6688 z"
|
||||
id="text4195"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 246.91959,252.49998 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38586 0.98392,0.3762 1.57235,1.34083 0.58842,0.96463 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03216 -3.00965,1.3119 0.74277,0.35691 1.12862,0.70418 0.81994,0.75241 1.55305,1.88103 l 2.45981,3.84886 h -2.3537 l -1.87138,-2.94211 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94534 -0.41479,-0.2701 -0.84887,-0.37621 -0.31833,-0.0675 -1.0418,-0.0675 h -2.17042 V 252.5 Z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.27009 1.09968,-0.84887 0.3762,-0.58842 0.3762,-1.27331 0,-1.00321 -0.73311,-1.64951 -0.72348,-0.64631 -2.29582,-0.64631 h -4.47588 z"
|
||||
id="text4199"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 280.12139,252.49998 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42764,-11.11252 v 11.11252 z"
|
||||
id="text4203"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 312.38265,252.49998 5.43086,-14.14146 h 2.01607 l 5.78777,14.14146 h -2.13183 l -1.64951,-4.28295 h -5.91318 l -1.55305,4.28295 z m 4.08038,-5.80706 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78457 -1.00321,-2.93248 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4207"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 356.7307,247.54179 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.5209 -1.52412,1.20578 -3.73312,1.20578 -2.28617,0 -3.72346,-0.92604 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64952 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08038 1.44694,1.08039 2.01607,3.03858 l -1.84244,0.43409 q -0.49196,-1.54341 -1.42765,-2.24759 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.3119 -0.44373,2.71061 0,1.80386 0.5209,3.15434 0.53054,1.34083 1.63987,2.00642 1.10932,0.6656 2.40192,0.6656 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69132 z"
|
||||
id="text4211"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 379.94853,252.49998 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 v 14.14146 h -1.87138 v -6.66558 h -7.35047 v 6.66558 z"
|
||||
id="text4215"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 417.8384,252.49998 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 v 12.47265 z"
|
||||
id="text4219"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="M 81.224283,285.75 V 271.60854 H 91.44935 v 1.66881 h -8.353687 v 4.33118 h 7.823141 v 1.65916 h -7.823141 v 4.8135 h 8.681661 V 285.75 Z"
|
||||
id="text4223"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 118.59808,285.75 v -14.14146 h 1.87138 V 285.75 Z"
|
||||
id="text4227"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 147.12139,285.75 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 285.75 h -1.91961 L 148.9156,274.63748 V 285.75 Z"
|
||||
id="text4231"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 180.29904,281.2066 1.76527,-0.15434 q 0.12541,1.06109 0.57878,1.74598 0.46302,0.67524 1.42765,1.09967 0.96463,0.41479 2.17042,0.41479 1.07074,0 1.89067,-0.31832 0.81993,-0.31833 1.21543,-0.86817 0.40515,-0.55949 0.40515,-1.21543 0,-0.6656 -0.38586,-1.15756 -0.38585,-0.5016 -1.27331,-0.83922 -0.56913,-0.22187 -2.51768,-0.68489 -1.94855,-0.47267 -2.7299,-0.88746 -1.01286,-0.53055 -1.51446,-1.3119 -0.49196,-0.79099 -0.49196,-1.76527 0,-1.07073 0.60771,-1.99678 0.60772,-0.93569 1.77492,-1.418 1.1672,-0.48232 2.59485,-0.48232 1.57235,0 2.76849,0.51126 1.20578,0.5016 1.85208,1.48552 0.6463,0.98393 0.69454,2.2283 l -1.79421,0.13505 q -0.1447,-1.34084 -0.98393,-2.02573 -0.82958,-0.68488 -2.4598,-0.68488 -1.69775,0 -2.4791,0.62701 -0.7717,0.61736 -0.7717,1.49517 0,0.76206 0.54984,1.25402 0.54019,0.49196 2.81672,1.01286 2.28617,0.51125 3.13504,0.8971 1.23473,0.56914 1.82315,1.44695 0.58842,0.86816 0.58842,2.00643 0,1.12861 -0.6463,2.13183 -0.6463,0.99356 -1.86173,1.55305 -1.20579,0.54984 -2.72026,0.54984 -1.91961,0 -3.22186,-0.55949 -1.2926,-0.55948 -2.03536,-1.67845 -0.73312,-1.12862 -0.77171,-2.54662 z"
|
||||
id="text4235"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="m 222.92041,271.60854 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4239"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="M 247.17041,285.75 243.418,271.60854 h 1.91962 l 2.15112,9.27008 q 0.34726,1.45659 0.59807,2.89389 0.54019,-2.26688 0.63665,-2.61414 l 2.69132,-9.54983 h 2.25723 l 2.02572,7.15755 q 0.76206,2.66237 1.09968,5.00642 0.27009,-1.34083 0.70418,-3.07717 l 2.21864,-9.0868 h 1.88103 L 257.72345,285.75 h -1.80386 l -2.9807,-10.7749 q -0.3762,-1.35049 -0.44373,-1.65917 -0.22186,0.97428 -0.41479,1.65917 l -2.99999,10.7749 z"
|
||||
id="text4243"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="W" />
|
||||
<path
|
||||
d="m 289.42041,271.60854 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4247"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 313.36174,285.75 v -1.73633 l 7.24437,-9.05787 q 0.7717,-0.96463 1.46623,-1.67845 h -7.89066 v -1.66881 h 10.1286 v 1.66881 l -7.93889,9.81027 -0.85852,0.99357 h 9.02892 V 285.75 Z"
|
||||
id="text4251"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 346.92043,285.75 -3.75241,-14.14146 h 1.91961 l 2.15112,9.27008 q 0.34727,1.45659 0.59807,2.89389 0.54019,-2.26688 0.63666,-2.61414 l 2.69131,-9.54983 h 2.25723 l 2.02572,7.15755 q 0.76206,2.66237 1.09968,5.00642 0.2701,-1.34083 0.70418,-3.07717 l 2.21865,-9.0868 h 1.88102 l -3.8778,14.14146 h -1.80386 l -2.9807,-10.7749 q -0.37621,-1.35049 -0.44373,-1.65917 -0.22187,0.97428 -0.41479,1.65917 l -3,10.7749 z"
|
||||
id="text4255"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="W" />
|
||||
<path
|
||||
d="m 380.47425,285.75 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 285.75 Z"
|
||||
id="text4259"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 417.84804,285.75 v -14.14146 h 1.87138 V 285.75 Z"
|
||||
id="text4263"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 80.640683,319 v -14.14146 h 4.871376 q 1.649515,0 2.517681,0.20257 1.215433,0.27974 2.073952,1.01286 1.11897,0.94534 1.668808,2.42122 0.559485,1.46624 0.559485,3.35691 0,1.61093 -0.376205,2.8553 -0.376205,1.24437 -0.964629,2.06431 -0.588424,0.81029 -1.292603,1.28295 -0.694532,0.46303 -1.6881,0.70418 Q 87.026526,319 85.74357,319 Z m 1.87138,-1.66881 h 3.019288 q 1.398712,0 2.189708,-0.26045 0.800642,-0.26045 1.27331,-0.73312 0.665594,-0.66559 1.032153,-1.78456 0.376205,-1.12862 0.376205,-2.7299 0,-2.21865 -0.733118,-3.40514 -0.723471,-1.19614 -1.76527,-1.60128 -0.752411,-0.28939 -2.421219,-0.28939 h -2.971057 z"
|
||||
id="text4267"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="D" />
|
||||
<path
|
||||
d="m 113.91962,319 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98393,0.37621 1.57235,1.34084 0.58842,0.96462 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03215 -3.00964,1.3119 0.74276,0.35691 1.12861,0.70417 0.81994,0.75241 1.55305,1.88103 L 126.38263,319 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94533 -0.41479,-0.2701 -0.84887,-0.37621 -0.31833,-0.0675 -1.0418,-0.0675 H 115.791 V 319 Z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84887 0.3762,-0.58843 0.3762,-1.27331 0,-1.00322 -0.73311,-1.64952 -0.72347,-0.6463 -2.29582,-0.6463 H 115.791 Z"
|
||||
id="text4271"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 147.72428,319 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 319 Z"
|
||||
id="text4275"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 185.09807,319 v -14.14146 h 1.87138 V 319 Z"
|
||||
id="text4279"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 214.83682,319 v -14.14146 h 9.54018 v 1.66881 h -7.6688 v 4.37941 h 6.63665 v 1.66881 H 216.7082 V 319 Z"
|
||||
id="text4283"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 256.1704,304.85854 h 1.87138 v 8.17041 q 0,2.13183 -0.48232,3.38584 -0.48231,1.25402 -1.74597,2.04502 -1.25402,0.78135 -3.29904,0.78135 -1.98713,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80385,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34726,0.86817 1.17684,1.34084 0.83923,0.47267 2.04502,0.47267 2.0643,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4287"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 280.12139,319 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 319 h -1.91961 L 281.9156,307.88748 V 319 Z"
|
||||
id="text4291"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 317.97749,319 -5.47909,-14.14146 h 2.02572 l 3.67524,10.2733 q 0.44373,1.23472 0.74276,2.31511 0.32798,-1.15756 0.76206,-2.31511 l 3.81993,-10.2733 h 1.90996 L 319.8971,319 Z"
|
||||
id="text4295"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="V" />
|
||||
<path
|
||||
d="m 351.34807,319 v -14.14146 h 1.87138 V 319 Z"
|
||||
id="text4299"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 380.47425,319 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 319 Z"
|
||||
id="text4303"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 413.16959,319 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98392,0.37621 1.57235,1.34084 0.58842,0.96462 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03215 -3.00965,1.3119 0.74277,0.35691 1.12862,0.70417 0.81994,0.75241 1.55305,1.88103 L 425.6326,319 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94533 -0.41479,-0.2701 -0.84887,-0.37621 -0.31833,-0.0675 -1.0418,-0.0675 h -2.17042 V 319 Z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84887 0.3762,-0.58843 0.3762,-1.27331 0,-1.00322 -0.73311,-1.64952 -0.72348,-0.6463 -2.29582,-0.6463 h -4.47588 z"
|
||||
id="text4307"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 80.549043,347.7066 1.765271,-0.15434 q 0.125402,1.06109 0.578777,1.74598 0.463022,0.67524 1.427651,1.09967 0.964629,0.41479 2.170415,0.41479 1.070738,0 1.890673,-0.31832 0.819934,-0.31833 1.215432,-0.86817 0.405144,-0.55949 0.405144,-1.21543 0,-0.6656 -0.385851,-1.15756 -0.385852,-0.5016 -1.27331,-0.83922 -0.569131,-0.22187 -2.517682,-0.68489 -1.94855,-0.47267 -2.7299,-0.88746 -1.01286,-0.53055 -1.514467,-1.3119 -0.491961,-0.79099 -0.491961,-1.76527 0,-1.07073 0.607717,-1.99678 0.607716,-0.93569 1.774917,-1.418 1.167201,-0.48232 2.594852,-0.48232 1.572345,0 2.768484,0.51126 1.205787,0.5016 1.852088,1.48552 0.646301,0.98393 0.694533,2.2283 l -1.79421,0.13505 q -0.144694,-1.34084 -0.983921,-2.02573 -0.829581,-0.68488 -2.459804,-0.68488 -1.697747,0 -2.479096,0.62701 -0.771704,0.61736 -0.771704,1.49517 0,0.76206 0.549839,1.25402 0.540192,0.49196 2.816716,1.01286 2.286171,0.51125 3.135044,0.8971 1.234725,0.56914 1.823149,1.44695 0.588423,0.86816 0.588423,2.00643 0,1.12861 -0.646301,2.13183 -0.646301,0.99356 -1.861734,1.55305 -1.205786,0.54984 -2.720253,0.54984 -1.919612,0 -3.221861,-0.55949 -1.292602,-0.55948 -2.035367,-1.67845 -0.733118,-1.12862 -0.771703,-2.54662 z"
|
||||
id="text4311"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="m 114.47431,352.25 v -14.14146 h 10.22506 v 1.66881 h -8.35368 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 352.25 Z"
|
||||
id="text4315"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 157.2307,347.29181 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.52089 -1.52412,1.20579 -3.73312,1.20579 -2.28617,0 -3.72346,-0.92605 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64951 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08039 1.44694,1.08038 2.01607,3.03858 l -1.84244,0.43408 q -0.49196,-1.5434 -1.42765,-2.24758 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.31189 -0.44373,2.7106 0,1.80386 0.5209,3.15434 0.53054,1.34084 1.63987,2.00643 1.10932,0.66559 2.40192,0.66559 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69131 z"
|
||||
id="text4319"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 180.44856,352.25 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 352.25 h -1.87138 v -6.66559 h -7.35047 V 352.25 Z"
|
||||
id="text4323"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 213.54904,347.7066 1.76527,-0.15434 q 0.12541,1.06109 0.57878,1.74598 0.46302,0.67524 1.42765,1.09967 0.96463,0.41479 2.17042,0.41479 1.07074,0 1.89067,-0.31832 0.81993,-0.31833 1.21543,-0.86817 0.40515,-0.55949 0.40515,-1.21543 0,-0.6656 -0.38586,-1.15756 -0.38585,-0.5016 -1.27331,-0.83922 -0.56913,-0.22187 -2.51768,-0.68489 -1.94855,-0.47267 -2.7299,-0.88746 -1.01286,-0.53055 -1.51446,-1.3119 -0.49196,-0.79099 -0.49196,-1.76527 0,-1.07073 0.60771,-1.99678 0.60772,-0.93569 1.77492,-1.418 1.1672,-0.48232 2.59485,-0.48232 1.57235,0 2.76849,0.51126 1.20578,0.5016 1.85208,1.48552 0.6463,0.98393 0.69454,2.2283 l -1.79421,0.13505 q -0.1447,-1.34084 -0.98393,-2.02573 -0.82958,-0.68488 -2.4598,-0.68488 -1.69775,0 -2.4791,0.62701 -0.7717,0.61736 -0.7717,1.49517 0,0.76206 0.54984,1.25402 0.54019,0.49196 2.81672,1.01286 2.28617,0.51125 3.13504,0.8971 1.23473,0.56914 1.82315,1.44695 0.58842,0.86816 0.58842,2.00643 0,1.12861 -0.6463,2.13183 -0.6463,0.99356 -1.86173,1.55305 -1.20579,0.54984 -2.72026,0.54984 -1.91961,0 -3.22186,-0.55949 -1.2926,-0.55948 -2.03536,-1.67845 -0.73312,-1.12862 -0.77171,-2.54662 z"
|
||||
id="text4327"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="m 245.77171,345.36255 q 0,-3.5209 1.89068,-5.50803 1.89067,-1.99678 4.88102,-1.99678 1.95819,0 3.53054,0.93569 1.57235,0.93569 2.39228,2.61414 0.82958,1.66881 0.82958,3.79099 0,2.15113 -0.86817,3.84887 -0.86816,1.69775 -2.4598,2.57556 -1.59164,0.86817 -3.43408,0.86817 -1.99678,0 -3.56912,-0.96463 -1.57235,-0.96463 -2.38264,-2.63344 -0.81029,-1.66881 -0.81029,-3.53054 z m 1.92926,0.0289 q 0,2.55627 1.36977,4.03215 1.37942,1.46623 3.45338,1.46623 2.11253,0 3.47266,-1.48553 1.36977,-1.48552 1.36977,-4.21542 0,-1.72669 -0.58842,-3.00965 -0.57878,-1.2926 -1.70739,-1.99678 -1.11897,-0.71382 -2.51769,-0.71382 -1.98713,0 -3.42443,1.36977 -1.42765,1.36013 -1.42765,4.55305 z"
|
||||
id="text4331"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="O" />
|
||||
<path
|
||||
d="m 280.60853,352.25 v -14.14146 h 5.30546 q 1.62057,0 2.59485,0.43408 0.98392,0.42444 1.53376,1.32154 0.55948,0.88746 0.55948,1.86174 0,0.90675 -0.49196,1.70739 -0.49196,0.80064 -1.48553,1.2926 1.28296,0.37621 1.96785,1.28296 0.69453,0.90675 0.69453,2.14148 0,0.99356 -0.42444,1.85208 -0.41479,0.84888 -1.03215,1.3119 -0.61736,0.46302 -1.55305,0.70418 -0.92605,0.23151 -2.27653,0.23151 z m 1.87138,-8.19935 h 3.05787 q 1.24437,0 1.78457,-0.16398 0.71382,-0.21222 1.07073,-0.70418 0.36656,-0.49196 0.36656,-1.23473 0,-0.70418 -0.33762,-1.23472 -0.33762,-0.54019 -0.96463,-0.73312 -0.62701,-0.20257 -2.15112,-0.20257 h -2.82636 z m 0,6.53054 h 3.52089 q 0.90675,0 1.27331,-0.0675 0.64631,-0.11576 1.08039,-0.38585 0.43408,-0.2701 0.71382,-0.78135 0.27975,-0.5209 0.27975,-1.19614 0,-0.791 -0.40515,-1.36978 -0.40514,-0.58842 -1.12861,-0.81993 -0.71383,-0.24116 -2.06431,-0.24116 h -3.27009 z"
|
||||
id="text4335"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="B" />
|
||||
<path
|
||||
d="m 312.38265,352.25 5.43086,-14.14146 h 2.01607 l 5.78777,14.14146 h -2.13183 l -1.64951,-4.28295 h -5.91318 l -1.55305,4.28295 z m 4.08038,-5.80707 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00321,-2.93247 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4339"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 356.7307,347.29181 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.52089 -1.52412,1.20579 -3.73312,1.20579 -2.28617,0 -3.72346,-0.92605 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64951 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08039 1.44694,1.08038 2.01607,3.03858 l -1.84244,0.43408 q -0.49196,-1.5434 -1.42765,-2.24758 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.31189 -0.44373,2.7106 0,1.80386 0.5209,3.15434 0.53054,1.34084 1.63987,2.00643 1.10932,0.66559 2.40192,0.66559 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69131 z"
|
||||
id="text4343"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 379.94853,352.25 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 352.25 h -1.87138 v -6.66559 h -7.35047 V 352.25 Z"
|
||||
id="text4347"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 417.8384,352.25 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 V 352.25 Z"
|
||||
id="text4351"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="m 80.549043,380.95657 1.765271,-0.15434 q 0.125402,1.06109 0.578777,1.74598 0.463022,0.67524 1.427651,1.09967 0.964629,0.41479 2.170415,0.41479 1.070738,0 1.890673,-0.31833 0.819934,-0.31832 1.215432,-0.86816 0.405144,-0.55949 0.405144,-1.21543 0,-0.6656 -0.385851,-1.15756 -0.385852,-0.50161 -1.27331,-0.83923 -0.569131,-0.22186 -2.517682,-0.68488 -1.94855,-0.47267 -2.7299,-0.88746 -1.01286,-0.53055 -1.514467,-1.3119 -0.491961,-0.79099 -0.491961,-1.76527 0,-1.07073 0.607717,-1.99678 0.607716,-0.93569 1.774917,-1.418 1.167201,-0.48232 2.594852,-0.48232 1.572345,0 2.768484,0.51126 1.205787,0.5016 1.852088,1.48552 0.646301,0.98393 0.694533,2.2283 l -1.79421,0.13505 q -0.144694,-1.34084 -0.983921,-2.02573 -0.829581,-0.68488 -2.459804,-0.68488 -1.697747,0 -2.479096,0.62701 -0.771704,0.61736 -0.771704,1.49517 0,0.76206 0.549839,1.25402 0.540192,0.49196 2.816716,1.01286 2.286171,0.51125 3.135044,0.8971 1.234725,0.56914 1.823149,1.44695 0.588423,0.86816 0.588423,2.00643 0,1.12861 -0.646301,2.13183 -0.646301,0.99356 -1.861734,1.55305 -1.205786,0.54984 -2.720253,0.54984 -1.919612,0 -3.221861,-0.55949 -1.292602,-0.55948 -2.035367,-1.67845 -0.733118,-1.12862 -0.771703,-2.54662 z"
|
||||
id="text4355"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="m 118.59808,385.49997 v -14.14146 h 1.87138 v 14.14146 z"
|
||||
id="text4359"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 147.72428,385.49997 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4363"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 180.85853,385.49997 v -14.14146 h 5.30546 q 1.62057,0 2.59485,0.43408 0.98392,0.42444 1.53376,1.32154 0.55948,0.88746 0.55948,1.86174 0,0.90675 -0.49196,1.70739 -0.49196,0.80064 -1.48553,1.2926 1.28296,0.37621 1.96785,1.28296 0.69453,0.90675 0.69453,2.14148 0,0.99356 -0.42444,1.85208 -0.41479,0.84888 -1.03215,1.3119 -0.61736,0.46302 -1.55305,0.70418 -0.92605,0.23151 -2.27653,0.23151 z m 1.87138,-8.19935 h 3.05787 q 1.24437,0 1.78457,-0.16398 0.71382,-0.21222 1.07073,-0.70418 0.36656,-0.49196 0.36656,-1.23473 0,-0.70418 -0.33762,-1.23472 -0.33762,-0.54019 -0.96463,-0.73312 -0.62701,-0.20257 -2.15112,-0.20257 h -2.82636 z m 0,6.53054 h 3.52089 q 0.90675,0 1.27331,-0.0675 0.64631,-0.11576 1.08039,-0.38585 0.43408,-0.2701 0.71382,-0.78135 0.27975,-0.5209 0.27975,-1.19614 0,-0.791 -0.40515,-1.36978 -0.40514,-0.58842 -1.12861,-0.81993 -0.71383,-0.24116 -2.06431,-0.24116 h -3.27009 z"
|
||||
id="text4367"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="B" />
|
||||
<path
|
||||
d="m 214.22428,385.49997 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4371"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 246.87138,385.49997 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42765,-11.11253 v 11.11253 z"
|
||||
id="text4375"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 280.11174,385.49997 v -1.73633 l 7.24437,-9.05787 q 0.7717,-0.96463 1.46623,-1.67845 h -7.89066 v -1.66881 h 10.1286 v 1.66881 l -7.93889,9.81027 -0.85852,0.99357 h 9.02892 v 1.66881 z"
|
||||
id="text4379"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 313.67043,385.49997 -3.75241,-14.14146 h 1.91961 l 2.15112,9.27008 q 0.34727,1.45659 0.59807,2.89389 0.54019,-2.26688 0.63666,-2.61414 l 2.69131,-9.54983 h 2.25723 l 2.02572,7.15755 q 0.76206,2.66237 1.09968,5.00642 0.2701,-1.34083 0.70418,-3.07717 l 2.21865,-9.0868 h 1.88102 l -3.8778,14.14146 h -1.80386 l -2.9807,-10.77491 q -0.37621,-1.35048 -0.44373,-1.65916 -0.22187,0.97428 -0.41479,1.65916 l -3,10.77491 z"
|
||||
id="text4383"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="W" />
|
||||
<path
|
||||
d="m 345.52171,378.61252 q 0,-3.5209 1.89068,-5.50803 1.89067,-1.99678 4.88102,-1.99678 1.95819,0 3.53054,0.93569 1.57235,0.93569 2.39228,2.61414 0.82958,1.66881 0.82958,3.79099 0,2.15112 -0.86817,3.84887 -0.86816,1.69775 -2.4598,2.57556 -1.59164,0.86817 -3.43408,0.86817 -1.99678,0 -3.56912,-0.96463 -1.57235,-0.96463 -2.38264,-2.63344 -0.81029,-1.66881 -0.81029,-3.53054 z m 1.92926,0.0289 q 0,2.55626 1.36977,4.03215 1.37942,1.46623 3.45338,1.46623 2.11253,0 3.47266,-1.48553 1.36977,-1.48552 1.36977,-4.21542 0,-1.72669 -0.58842,-3.00965 -0.57878,-1.2926 -1.70739,-1.99678 -1.11897,-0.71382 -2.51769,-0.71382 -1.98713,0 -3.42443,1.36977 -1.42765,1.36013 -1.42765,4.55305 z m 2.09325,-8.15112 v -1.97749 h 1.8135 v 1.97749 z m 3.59806,0 v -1.97749 h 1.8135 v 1.97749 z"
|
||||
id="text4387"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Ö" />
|
||||
<path
|
||||
d="m 381.45335,385.49997 v -14.14146 h 1.87138 v 12.47265 h 6.96462 v 1.66881 z"
|
||||
id="text4391"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="L" />
|
||||
<path
|
||||
d="m 414.33679,385.49997 v -14.14146 h 9.54018 v 1.66881 h -7.6688 v 4.37941 h 6.63665 v 1.66881 h -6.63665 v 6.42443 z"
|
||||
id="text4395"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 80.611744,418.74997 v -1.73633 l 7.244363,-9.05787 q 0.771703,-0.96463 1.466236,-1.67845 h -7.890664 v -1.66881 h 10.128603 v 1.66881 l -7.938896,9.81027 -0.858519,0.99357 h 9.028926 v 1.66881 z"
|
||||
id="text4399"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 114.47431,418.74997 v -14.14146 h 10.22506 v 1.66881 h -8.35368 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4403"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 147.19856,418.74997 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 v 14.14146 h -1.87138 v -6.66559 h -7.35047 v 6.66559 z"
|
||||
id="text4407"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 180.37139,418.74997 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42764,-11.11253 v 11.11253 z"
|
||||
id="text4411"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 214.22428,418.74997 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4415"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 256.1704,404.60851 h 1.87138 v 8.17041 q 0,2.13183 -0.48232,3.38584 -0.48231,1.25402 -1.74597,2.04502 -1.25402,0.78135 -3.29904,0.78135 -1.98713,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80385,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34726,0.86817 1.17684,1.34084 0.83923,0.47267 2.04502,0.47267 2.0643,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4419"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 280.12139,418.74997 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42764,-11.11253 v 11.11253 z"
|
||||
id="text4423"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 313.97428,418.74997 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4427"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 355.92041,404.60851 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4431"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 379.94853,418.74997 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 v 14.14146 h -1.87138 v -6.66559 h -7.35047 v 6.66559 z"
|
||||
id="text4435"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 413.16959,418.74997 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98392,0.37621 1.57235,1.34084 0.58842,0.96462 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03215 -3.00965,1.31189 0.74277,0.35692 1.12862,0.70418 0.81994,0.75241 1.55305,1.88103 l 2.45981,3.84887 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94534 -0.41479,-0.27009 -0.84887,-0.3762 -0.31833,-0.0675 -1.0418,-0.0675 h -2.17042 v 6.27973 z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84887 0.3762,-0.58843 0.3762,-1.27331 0,-1.00322 -0.73311,-1.64952 -0.72348,-0.6463 -2.29582,-0.6463 h -4.47588 z"
|
||||
id="text4439"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
</g>
|
||||
<g
|
||||
id="g1663"
|
||||
transform="translate(252.87499,354.25)"
|
||||
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none">
|
||||
<path
|
||||
id="rect4466-1-4"
|
||||
style="fill:#ffffff;stroke-width:0.184347"
|
||||
d="M 7.7500038,84.25 H 19.750004 v 2 H 7.7500038 Z" />
|
||||
<path
|
||||
id="rect4466-1-4-2"
|
||||
style="fill:#ffffff;stroke-width:0.184347"
|
||||
d="m 41.000004,84.25 h 12 v 2 h -12 z" />
|
||||
<path
|
||||
id="rect4466-1-4-9"
|
||||
style="fill:#ffffff;stroke-width:0.184347"
|
||||
d="m -25.499994,84.25 h 12 v 2 h -12 z" />
|
||||
<path
|
||||
id="rect4466-1-4-6"
|
||||
style="fill:#ffffff;stroke-width:0.184347"
|
||||
d="m -58.749992,84.25 h 12 v 2 h -12 z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 82 KiB |
808
res/frontplate/WordClock_Front_Paths_Inkscape.svg
Normal file
@@ -0,0 +1,808 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="500mm"
|
||||
height="500mm"
|
||||
viewBox="0 0 500 500"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
|
||||
sodipodi:docname="WordClock_Front_Paths_Inkscape.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
labelstyle="default"
|
||||
inkscape:zoom="0.5"
|
||||
inkscape:cx="762"
|
||||
inkscape:cy="831"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1377"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g1"
|
||||
inkscape:label="Background"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
id="rect2951"
|
||||
style="display:inline;fill-rule:evenodd;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round"
|
||||
d="M 0,0 H 500 V 500 H 0 Z" />
|
||||
</g>
|
||||
<g
|
||||
id="g3"
|
||||
inkscape:label="Chars"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
d="M 81.224283,86.25 V 72.10854 H 91.44935 v 1.668808 h -8.353687 v 4.331184 h 7.823141 v 1.659162 h -7.823141 v 4.813498 h 8.681661 V 86.25 Z"
|
||||
id="text3140"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="M 147.16962,86.25 V 72.10854 h 6.27009 q 1.89067,0 2.87459,0.385852 0.98393,0.376205 1.57235,1.340834 0.58842,0.964629 0.58842,2.13183 0,1.504821 -0.97427,2.536974 -0.97428,1.032153 -3.00964,1.311895 0.74276,0.356913 1.12861,0.704179 0.81994,0.752411 1.55305,1.881027 L 159.63263,86.25 h -2.3537 l -1.87138,-2.942118 q -0.81993,-1.27331 -1.35048,-1.948551 -0.53054,-0.67524 -0.95498,-0.945336 -0.41479,-0.270096 -0.84887,-0.376205 -0.31833,-0.06752 -1.0418,-0.06752 H 149.041 V 86.25 Z m 1.87138,-7.900311 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.270096 1.09968,-0.848873 0.3762,-0.588424 0.3762,-1.27331 0,-1.003214 -0.73311,-1.649516 -0.72347,-0.646301 -2.29582,-0.646301 H 149.041 Z"
|
||||
id="text1"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
inkscape:label="text1"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 113.79905,81.706598 1.76527,-0.154341 q 0.1254,1.061092 0.57878,1.745979 0.46302,0.67524 1.42765,1.099677 0.96463,0.41479 2.17041,0.41479 1.07074,0 1.89068,-0.318328 0.81993,-0.318327 1.21543,-0.868166 0.40514,-0.559484 0.40514,-1.215432 0,-0.665594 -0.38585,-1.157555 -0.38585,-0.501607 -1.27331,-0.839227 -0.56913,-0.221865 -2.51768,-0.684886 -1.94855,-0.472669 -2.7299,-0.887459 -1.01286,-0.530546 -1.51447,-1.311895 -0.49196,-0.790996 -0.49196,-1.765271 0,-1.070738 0.60772,-1.996782 0.60772,-0.93569 1.77492,-1.418005 1.1672,-0.482314 2.59485,-0.482314 1.57234,0 2.76848,0.511253 1.20579,0.501607 1.85209,1.485529 0.6463,0.983921 0.69453,2.228293 l -1.79421,0.135048 q -0.14469,-1.340835 -0.98392,-2.025721 -0.82958,-0.684887 -2.4598,-0.684887 -1.69775,0 -2.4791,0.627009 -0.7717,0.617363 -0.7717,1.495175 0,0.762057 0.54984,1.254018 0.54019,0.49196 2.81671,1.01286 2.28617,0.511253 3.13505,0.897105 1.23472,0.569131 1.82315,1.446943 0.58842,0.868166 0.58842,2.006428 0,1.128616 -0.6463,2.13183 -0.6463,0.993568 -1.86174,1.553053 -1.20578,0.549838 -2.72025,0.549838 -1.91961,0 -3.22186,-0.559485 -1.2926,-0.559484 -2.03537,-1.678454 -0.73311,-1.128616 -0.7717,-2.54662 z"
|
||||
id="text3144"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="M 185.09807,86.25 V 72.10854 h 1.87138 V 86.25 Z"
|
||||
id="text3971"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 213.54904,81.706598 1.76527,-0.154341 q 0.12541,1.061092 0.57878,1.745979 0.46302,0.67524 1.42765,1.099677 0.96463,0.41479 2.17042,0.41479 1.07074,0 1.89067,-0.318328 0.81993,-0.318327 1.21543,-0.868166 0.40515,-0.559484 0.40515,-1.215432 0,-0.665594 -0.38586,-1.157555 -0.38585,-0.501607 -1.27331,-0.839227 -0.56913,-0.221865 -2.51768,-0.684886 -1.94855,-0.472669 -2.7299,-0.887459 -1.01286,-0.530546 -1.51446,-1.311895 -0.49196,-0.790996 -0.49196,-1.765271 0,-1.070738 0.60771,-1.996782 0.60772,-0.93569 1.77492,-1.418005 1.1672,-0.482314 2.59485,-0.482314 1.57235,0 2.76849,0.511253 1.20578,0.501607 1.85208,1.485529 0.6463,0.983921 0.69454,2.228293 l -1.79421,0.135048 q -0.1447,-1.340835 -0.98393,-2.025721 -0.82958,-0.684887 -2.4598,-0.684887 -1.69775,0 -2.4791,0.627009 -0.7717,0.617363 -0.7717,1.495175 0,0.762057 0.54984,1.254018 0.54019,0.49196 2.81672,1.01286 2.28617,0.511253 3.13504,0.897105 1.23473,0.569131 1.82315,1.446943 0.58842,0.868166 0.58842,2.006428 0,1.128616 -0.6463,2.13183 -0.6463,0.993568 -1.86173,1.553053 -1.20579,0.549838 -2.72026,0.549838 -1.91961,0 -3.22186,-0.559485 -1.2926,-0.559484 -2.03536,-1.678454 -0.73312,-1.128616 -0.77171,-2.54662 z"
|
||||
id="text3975"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="M 251.58843,86.25 V 73.777348 h -4.65916 V 72.10854 h 11.20899 v 1.668808 h -4.67845 V 86.25 Z"
|
||||
id="text3979"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="M 280.12139,86.25 V 72.10854 h 1.91961 l 7.42764,11.102879 V 72.10854 h 1.79421 V 86.25 h -1.91961 L 281.9156,75.137475 V 86.25 Z"
|
||||
id="text3983"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="M 314.58682,86.25 V 72.10854 h 9.54018 v 1.668808 h -7.6688 v 4.379415 h 6.63665 v 1.668808 H 316.4582 V 86.25 Z"
|
||||
id="text3987"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 355.92041,72.10854 h 1.87138 v 8.170407 q 0,2.13183 -0.48231,3.385848 -0.48232,1.254017 -1.74598,2.045013 -1.25402,0.781349 -3.29903,0.781349 -1.98714,0 -3.2508,-0.684886 -1.26366,-0.684887 -1.80386,-1.97749 -0.54019,-1.302249 -0.54019,-3.549834 V 72.10854 h 1.87138 v 8.160761 q 0,1.842441 0.33762,2.720253 0.34727,0.868166 1.17685,1.340834 0.83923,0.472669 2.04501,0.472669 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.598066 z m -6.42443,-0.868166 v -1.977489 h 1.81351 v 1.977489 z m 3.59807,0 v -1.977489 h 1.8135 v 1.977489 z"
|
||||
id="text3991"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Ü" />
|
||||
<path
|
||||
d="M 379.87136,86.25 V 72.10854 h 1.91961 l 7.42764,11.102879 V 72.10854 h 1.79421 V 86.25 h -1.91961 L 381.66557,75.137475 V 86.25 Z"
|
||||
id="text3995"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="M 414.33679,86.25 V 72.10854 h 9.54018 v 1.668808 h -7.6688 v 4.379415 h 6.63665 v 1.668808 h -6.63665 V 86.25 Z"
|
||||
id="text3999"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 85.227493,119.50001 -5.479092,-14.14146 h 2.025721 l 3.675236,10.2733 q 0.443729,1.23472 0.742764,2.31511 0.327974,-1.15756 0.762057,-2.31511 l 3.819931,-10.2733 h 1.909965 l -5.53697,14.14146 z"
|
||||
id="text4003"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="V" />
|
||||
<path
|
||||
d="m 118.59808,119.50001 v -14.14146 h 1.87138 v 14.14146 z"
|
||||
id="text4007"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 147.72428,119.50001 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4011"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 180.41962,119.50001 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98393,0.3762 1.57235,1.34083 0.58842,0.96463 0.58842,2.13183 0,1.50482 -0.97427,2.53698 -0.97428,1.03215 -3.00964,1.31189 0.74276,0.35692 1.12861,0.70418 0.81994,0.75241 1.55305,1.88103 l 2.45981,3.84887 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94534 -0.41479,-0.27009 -0.84887,-0.3762 -0.31833,-0.0675 -1.0418,-0.0675 H 182.291 v 6.27974 z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84888 0.3762,-0.58842 0.3762,-1.27331 0,-1.00321 -0.73311,-1.64951 -0.72347,-0.6463 -2.29582,-0.6463 H 182.291 Z"
|
||||
id="text4015"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 218.33843,119.50001 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 v 12.47265 z"
|
||||
id="text4019"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="m 247.47428,119.50001 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4023"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 281.70338,119.50001 v -14.14146 h 1.87138 v 12.47265 h 6.96462 v 1.66881 z"
|
||||
id="text4027"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="L" />
|
||||
<path
|
||||
d="m 313.36174,119.50001 v -1.73633 l 7.24437,-9.05787 q 0.7717,-0.96463 1.46623,-1.67845 h -7.89066 v -1.66881 h 10.1286 v 1.66881 l -7.93889,9.81027 -0.85852,0.99357 h 9.02892 v 1.66881 z"
|
||||
id="text4031"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 347.22428,119.50001 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4035"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 379.94853,119.50001 v -14.14146 h 1.87138 v 5.80706 h 7.35047 v -5.80706 h 1.87138 v 14.14146 h -1.87138 v -6.66559 h -7.35047 v 6.66559 z"
|
||||
id="text4039"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 413.12136,119.50001 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42764,-11.11253 v 11.11253 z"
|
||||
id="text4043"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 80.611744,152.75 v -1.73633 l 7.244363,-9.05787 q 0.771703,-0.96463 1.466236,-1.67845 h -7.890664 v -1.66881 h 10.128603 v 1.66881 l -7.938896,9.81027 -0.858519,0.99357 h 9.028926 V 152.75 Z"
|
||||
id="text4047"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 114.17043,152.75 -3.75241,-14.14146 h 1.91961 l 2.15112,9.27008 q 0.34727,1.45659 0.59807,2.89389 0.54019,-2.26688 0.63666,-2.61414 l 2.69131,-9.54983 h 2.25723 l 2.02572,7.15755 q 0.76206,2.66237 1.09968,5.00642 0.2701,-1.34083 0.70418,-3.07717 l 2.21865,-9.0868 h 1.88102 l -3.8778,14.14146 h -1.80386 l -2.9807,-10.7749 q -0.37621,-1.35049 -0.44373,-1.65917 -0.22187,0.97428 -0.41479,1.65917 l -3,10.7749 z"
|
||||
id="text4051"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="W" />
|
||||
<path
|
||||
d="m 146.13265,152.75 5.43086,-14.14146 h 2.01607 l 5.78777,14.14146 h -2.13183 l -1.64951,-4.28295 h -5.91318 l -1.55305,4.28295 z m 4.08038,-5.80707 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00321,-2.93247 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4055"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 180.37139,152.75 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 152.75 h -1.91961 L 182.1656,141.63748 V 152.75 Z"
|
||||
id="text4059"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 213.61174,152.75 v -1.73633 l 7.24437,-9.05787 q 0.7717,-0.96463 1.46623,-1.67845 h -7.89066 v -1.66881 h 10.1286 v 1.66881 l -7.93889,9.81027 -0.85852,0.99357 h 9.02892 V 152.75 Z"
|
||||
id="text4063"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 251.59806,152.75 v -14.14146 h 1.87138 V 152.75 Z"
|
||||
id="text4067"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 286.2082,147.20338 v -1.65916 l 5.99034,-0.01 v 5.24758 q -1.37942,1.09967 -2.84565,1.65916 -1.46624,0.54984 -3.00964,0.54984 -2.0836,0 -3.79099,-0.88746 -1.69775,-0.89711 -2.56592,-2.58521 -0.86816,-1.6881 -0.86816,-3.7717 0,-2.0643 0.85852,-3.84887 0.86816,-1.7942 2.48874,-2.66237 1.62058,-0.86817 3.73311,-0.86817 1.53376,0 2.76849,0.50161 1.24437,0.49196 1.94855,1.37942 0.70418,0.88746 1.07074,2.31511 l -1.6881,0.46302 q -0.31833,-1.08038 -0.791,-1.69775 -0.47267,-0.61736 -1.35048,-0.98392 -0.87781,-0.3762 -1.94855,-0.3762 -1.28296,0 -2.21865,0.39549 -0.93569,0.38586 -1.51447,1.02251 -0.56913,0.63666 -0.88745,1.39871 -0.5402,1.3119 -0.5402,2.84566 0,1.89067 0.64631,3.16398 0.65594,1.27331 1.90031,1.89067 1.24438,0.61737 2.64309,0.61737 1.21543,0 2.37298,-0.46303 1.15756,-0.47266 1.75563,-1.00321 v -2.63344 z"
|
||||
id="text4071"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="G" />
|
||||
<path
|
||||
d="m 313.44856,152.75 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 152.75 h -1.87138 v -6.66559 h -7.35047 V 152.75 Z"
|
||||
id="text4075"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 351.22749,152.75 -5.47909,-14.14146 h 2.02572 l 3.67524,10.2733 q 0.44373,1.23472 0.74276,2.31511 0.32798,-1.15756 0.76206,-2.31511 l 3.81993,-10.2733 h 1.90996 L 353.1471,152.75 Z"
|
||||
id="text4079"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="V" />
|
||||
<path
|
||||
d="m 378.77168,145.86255 q 0,-3.5209 1.89068,-5.50803 1.89067,-1.99678 4.88102,-1.99678 1.95819,0 3.53054,0.93569 1.57234,0.93569 2.39228,2.61414 0.82958,1.66881 0.82958,3.79099 0,2.15113 -0.86817,3.84887 -0.86816,1.69775 -2.4598,2.57556 -1.59164,0.86817 -3.43408,0.86817 -1.99678,0 -3.56913,-0.96463 -1.57234,-0.96463 -2.38263,-2.63344 -0.81029,-1.66881 -0.81029,-3.53054 z m 1.92926,0.0289 q 0,2.55627 1.36977,4.03215 1.37942,1.46623 3.45338,1.46623 2.11253,0 3.47266,-1.48553 1.36977,-1.48552 1.36977,-4.21542 0,-1.72669 -0.58842,-3.00965 -0.57878,-1.2926 -1.70739,-1.99678 -1.11897,-0.71382 -2.51769,-0.71382 -1.98713,0 -3.42443,1.36977 -1.42765,1.36013 -1.42765,4.55305 z"
|
||||
id="text4083"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="O" />
|
||||
<path
|
||||
d="m 413.16959,152.75 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98392,0.37621 1.57235,1.34084 0.58842,0.96462 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03215 -3.00965,1.3119 0.74277,0.35691 1.12862,0.70417 0.81994,0.75241 1.55305,1.88103 l 2.45981,3.84887 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94533 -0.41479,-0.2701 -0.84887,-0.37621 -0.31833,-0.0675 -1.0418,-0.0675 h -2.17042 V 152.75 Z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84887 0.3762,-0.58843 0.3762,-1.27331 0,-1.00322 -0.73311,-1.64952 -0.72348,-0.6463 -2.29582,-0.6463 h -4.47588 z"
|
||||
id="text4087"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 81.185698,186 v -14.14146 h 5.334398 q 1.408358,0 2.151123,0.13505 1.041799,0.17363 1.745978,0.66559 0.704179,0.48232 1.128616,1.36013 0.434083,0.87781 0.434083,1.92926 0,1.80385 -1.147909,3.05787 -1.147908,1.24437 -4.147904,1.24437 H 83.057078 V 186 Z m 1.87138,-7.418 h 3.655944 q 1.813502,0 2.575559,-0.67524 0.762057,-0.67524 0.762057,-1.90032 0,-0.88745 -0.453376,-1.51446 -0.443729,-0.63666 -1.176847,-0.83923 -0.472668,-0.1254 -1.745978,-0.1254 h -3.617359 z"
|
||||
id="text4091"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="P" />
|
||||
<path
|
||||
d="m 118.59809,186 v -14.14146 h 1.87138 V 186 Z"
|
||||
id="text4095"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 147.60853,186 v -14.14146 h 1.87138 v 7.01285 l 7.0225,-7.01285 h 2.53697 l -5.93247,5.7299 6.19292,8.41156 h -2.46945 l -5.03536,-7.15755 -2.31511,2.25724 V 186 Z"
|
||||
id="text4099"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="K" />
|
||||
<path
|
||||
d="m 179.38265,186 5.43086,-14.14146 h 2.01607 L 192.61735,186 h -2.13183 l -1.64951,-4.28295 h -5.91318 L 181.36978,186 Z m 4.08038,-5.80707 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00321,-2.93247 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4103"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 223.7307,181.04181 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.52089 -1.52412,1.20579 -3.73312,1.20579 -2.28617,0 -3.72346,-0.92605 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64951 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08039 1.44694,1.08038 2.01607,3.03858 l -1.84244,0.43408 q -0.49196,-1.5434 -1.42765,-2.24758 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.31189 -0.44373,2.7106 0,1.80386 0.5209,3.15434 0.53054,1.34084 1.63987,2.00643 1.10932,0.66559 2.40192,0.66559 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69131 z"
|
||||
id="text4107"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 246.94855,186 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 186 h -1.87138 v -6.66559 h -7.35047 V 186 Z"
|
||||
id="text4111"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 289.42041,171.85854 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4115"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 313.37139,186 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 186 h -1.91961 L 315.1656,174.88748 V 186 Z"
|
||||
id="text4119"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 345.63265,186 5.43086,-14.14146 h 2.01607 L 358.86735,186 h -2.13183 l -1.64951,-4.28295 h -5.91318 L 347.61978,186 Z m 4.08038,-5.80707 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00321,-2.93247 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4123"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 389.98067,181.04181 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.52089 -1.52412,1.20579 -3.73312,1.20579 -2.28617,0 -3.72346,-0.92605 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64951 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08039 1.44694,1.08038 2.01607,3.03858 l -1.84244,0.43408 q -0.49196,-1.5434 -1.42765,-2.24758 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.31189 -0.44373,2.7106 0,1.80386 0.5209,3.15434 0.53054,1.34084 1.63987,2.00643 1.10932,0.66559 2.40192,0.66559 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69131 z"
|
||||
id="text4127"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 413.19853,186 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 186 h -1.87138 v -6.66559 h -7.35047 V 186 Z"
|
||||
id="text4131"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 80.698561,219.25 v -14.14146 h 1.87138 v 5.80707 h 7.350472 v -5.80707 h 1.87138 V 219.25 h -1.87138 v -6.66559 H 82.569941 V 219.25 Z"
|
||||
id="text4135"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 112.88265,219.25 5.43086,-14.14146 h 2.01608 l 5.78777,14.14146 h -2.13183 l -1.64951,-4.28295 h -5.91318 l -1.55305,4.28295 z m 4.08038,-5.80707 h 4.79421 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00322,-2.93247 -0.27009,1.36013 -0.76205,2.70096 z"
|
||||
id="text4139"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 148.70338,219.25 v -14.14146 h 1.87138 v 12.47265 h 6.96462 V 219.25 Z"
|
||||
id="text4143"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="L" />
|
||||
<path
|
||||
d="m 180.85853,219.25 v -14.14146 h 5.30546 q 1.62057,0 2.59485,0.43408 0.98392,0.42444 1.53376,1.32154 0.55948,0.88746 0.55948,1.86174 0,0.90675 -0.49196,1.70739 -0.49196,0.80064 -1.48553,1.2926 1.28296,0.37621 1.96785,1.28296 0.69453,0.90675 0.69453,2.14148 0,0.99356 -0.42444,1.85208 -0.41479,0.84888 -1.03215,1.3119 -0.61736,0.46302 -1.55305,0.70418 -0.92605,0.23151 -2.27653,0.23151 z m 1.87138,-8.19935 h 3.05787 q 1.24437,0 1.78457,-0.16398 0.71382,-0.21222 1.07073,-0.70418 0.36656,-0.49196 0.36656,-1.23473 0,-0.70418 -0.33762,-1.23472 -0.33762,-0.54019 -0.96463,-0.73312 -0.62701,-0.20257 -2.15112,-0.20257 h -2.82636 z m 0,6.53054 h 3.52089 q 0.90675,0 1.27331,-0.0675 0.64631,-0.11576 1.08039,-0.38585 0.43408,-0.2701 0.71382,-0.78135 0.27975,-0.5209 0.27975,-1.19614 0,-0.791 -0.40515,-1.36978 -0.40514,-0.58842 -1.12861,-0.81993 -0.71383,-0.24116 -2.06431,-0.24116 h -3.27009 z"
|
||||
id="text4147"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="B" />
|
||||
<path
|
||||
d="m 212.48795,219.25 v -14.14146 h 2.81672 l 3.34726,10.01285 q 0.46302,1.39871 0.67524,2.09324 0.24116,-0.7717 0.75241,-2.26687 l 3.38585,-9.83922 h 2.51768 V 219.25 h -1.80386 v -11.836 l -4.10932,11.836 h -1.6881 l -4.09002,-12.03857 V 219.25 Z"
|
||||
id="text4151"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="M" />
|
||||
<path
|
||||
d="m 247.47428,219.25 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 219.25 Z"
|
||||
id="text4155"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 281.70338,219.25 v -14.14146 h 1.87138 v 12.47265 h 6.96462 V 219.25 Z"
|
||||
id="text4159"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="L" />
|
||||
<path
|
||||
d="m 314.58682,219.25 v -14.14146 h 9.54018 v 1.66881 h -7.6688 v 4.37941 h 6.63665 v 1.66881 H 316.4582 V 219.25 Z"
|
||||
id="text4163"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 355.92041,205.10854 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z m -6.42443,-0.86817 v -1.97749 h 1.81351 v 1.97749 z m 3.59807,0 v -1.97749 h 1.8135 v 1.97749 z"
|
||||
id="text4167"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Ü" />
|
||||
<path
|
||||
d="m 379.87136,219.25 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 219.25 h -1.91961 l -7.42764,-11.11252 V 219.25 Z"
|
||||
id="text4171"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 414.33679,219.25 v -14.14146 h 9.54018 v 1.66881 h -7.6688 v 4.37941 h 6.63665 v 1.66881 h -6.63665 V 219.25 Z"
|
||||
id="text4175"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 79.487951,252.49998 v -14.14146 h 2.816717 l 3.347262,10.01285 q 0.463022,1.39871 0.67524,2.09325 0.241158,-0.77171 0.752411,-2.26688 l 3.385847,-9.83922 h 2.517682 v 14.14146 h -1.803856 v -11.83599 l -4.109319,11.83599 h -1.688101 l -4.090027,-12.03856 v 12.03856 z"
|
||||
id="text4179"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="M" />
|
||||
<path
|
||||
d="m 118.59809,252.49998 v -14.14146 h 1.87138 v 14.14146 z"
|
||||
id="text4183"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 151.83843,252.49998 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 v 12.47265 z"
|
||||
id="text4187"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="m 185.08843,252.49998 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 v 12.47265 z"
|
||||
id="text4191"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="m 214.22428,252.49998 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33119 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.6688 z"
|
||||
id="text4195"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 246.91959,252.49998 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38586 0.98392,0.3762 1.57235,1.34083 0.58842,0.96463 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03216 -3.00965,1.3119 0.74277,0.35691 1.12862,0.70418 0.81994,0.75241 1.55305,1.88103 l 2.45981,3.84886 h -2.3537 l -1.87138,-2.94211 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94534 -0.41479,-0.2701 -0.84887,-0.37621 -0.31833,-0.0675 -1.0418,-0.0675 h -2.17042 V 252.5 Z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.27009 1.09968,-0.84887 0.3762,-0.58842 0.3762,-1.27331 0,-1.00321 -0.73311,-1.64951 -0.72348,-0.64631 -2.29582,-0.64631 h -4.47588 z"
|
||||
id="text4199"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 280.12139,252.49998 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42764,-11.11252 v 11.11252 z"
|
||||
id="text4203"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 312.38265,252.49998 5.43086,-14.14146 h 2.01607 l 5.78777,14.14146 h -2.13183 l -1.64951,-4.28295 h -5.91318 l -1.55305,4.28295 z m 4.08038,-5.80706 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78457 -1.00321,-2.93248 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4207"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 356.7307,247.54179 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.5209 -1.52412,1.20578 -3.73312,1.20578 -2.28617,0 -3.72346,-0.92604 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64952 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08038 1.44694,1.08039 2.01607,3.03858 l -1.84244,0.43409 q -0.49196,-1.54341 -1.42765,-2.24759 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.3119 -0.44373,2.71061 0,1.80386 0.5209,3.15434 0.53054,1.34083 1.63987,2.00642 1.10932,0.6656 2.40192,0.6656 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69132 z"
|
||||
id="text4211"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 379.94853,252.49998 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 v 14.14146 h -1.87138 v -6.66558 h -7.35047 v 6.66558 z"
|
||||
id="text4215"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 417.8384,252.49998 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 v 12.47265 z"
|
||||
id="text4219"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="M 81.224283,285.75 V 271.60854 H 91.44935 v 1.66881 h -8.353687 v 4.33118 h 7.823141 v 1.65916 h -7.823141 v 4.8135 h 8.681661 V 285.75 Z"
|
||||
id="text4223"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 118.59808,285.75 v -14.14146 h 1.87138 V 285.75 Z"
|
||||
id="text4227"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 147.12139,285.75 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 285.75 h -1.91961 L 148.9156,274.63748 V 285.75 Z"
|
||||
id="text4231"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 180.29904,281.2066 1.76527,-0.15434 q 0.12541,1.06109 0.57878,1.74598 0.46302,0.67524 1.42765,1.09967 0.96463,0.41479 2.17042,0.41479 1.07074,0 1.89067,-0.31832 0.81993,-0.31833 1.21543,-0.86817 0.40515,-0.55949 0.40515,-1.21543 0,-0.6656 -0.38586,-1.15756 -0.38585,-0.5016 -1.27331,-0.83922 -0.56913,-0.22187 -2.51768,-0.68489 -1.94855,-0.47267 -2.7299,-0.88746 -1.01286,-0.53055 -1.51446,-1.3119 -0.49196,-0.79099 -0.49196,-1.76527 0,-1.07073 0.60771,-1.99678 0.60772,-0.93569 1.77492,-1.418 1.1672,-0.48232 2.59485,-0.48232 1.57235,0 2.76849,0.51126 1.20578,0.5016 1.85208,1.48552 0.6463,0.98393 0.69454,2.2283 l -1.79421,0.13505 q -0.1447,-1.34084 -0.98393,-2.02573 -0.82958,-0.68488 -2.4598,-0.68488 -1.69775,0 -2.4791,0.62701 -0.7717,0.61736 -0.7717,1.49517 0,0.76206 0.54984,1.25402 0.54019,0.49196 2.81672,1.01286 2.28617,0.51125 3.13504,0.8971 1.23473,0.56914 1.82315,1.44695 0.58842,0.86816 0.58842,2.00643 0,1.12861 -0.6463,2.13183 -0.6463,0.99356 -1.86173,1.55305 -1.20579,0.54984 -2.72026,0.54984 -1.91961,0 -3.22186,-0.55949 -1.2926,-0.55948 -2.03536,-1.67845 -0.73312,-1.12862 -0.77171,-2.54662 z"
|
||||
id="text4235"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="m 222.92041,271.60854 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4239"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="M 247.17041,285.75 243.418,271.60854 h 1.91962 l 2.15112,9.27008 q 0.34726,1.45659 0.59807,2.89389 0.54019,-2.26688 0.63665,-2.61414 l 2.69132,-9.54983 h 2.25723 l 2.02572,7.15755 q 0.76206,2.66237 1.09968,5.00642 0.27009,-1.34083 0.70418,-3.07717 l 2.21864,-9.0868 h 1.88103 L 257.72345,285.75 h -1.80386 l -2.9807,-10.7749 q -0.3762,-1.35049 -0.44373,-1.65917 -0.22186,0.97428 -0.41479,1.65917 l -2.99999,10.7749 z"
|
||||
id="text4243"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="W" />
|
||||
<path
|
||||
d="m 289.42041,271.60854 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4247"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 313.36174,285.75 v -1.73633 l 7.24437,-9.05787 q 0.7717,-0.96463 1.46623,-1.67845 h -7.89066 v -1.66881 h 10.1286 v 1.66881 l -7.93889,9.81027 -0.85852,0.99357 h 9.02892 V 285.75 Z"
|
||||
id="text4251"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 346.92043,285.75 -3.75241,-14.14146 h 1.91961 l 2.15112,9.27008 q 0.34727,1.45659 0.59807,2.89389 0.54019,-2.26688 0.63666,-2.61414 l 2.69131,-9.54983 h 2.25723 l 2.02572,7.15755 q 0.76206,2.66237 1.09968,5.00642 0.2701,-1.34083 0.70418,-3.07717 l 2.21865,-9.0868 h 1.88102 l -3.8778,14.14146 h -1.80386 l -2.9807,-10.7749 q -0.37621,-1.35049 -0.44373,-1.65917 -0.22187,0.97428 -0.41479,1.65917 l -3,10.7749 z"
|
||||
id="text4255"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="W" />
|
||||
<path
|
||||
d="m 380.47425,285.75 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 285.75 Z"
|
||||
id="text4259"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 417.84804,285.75 v -14.14146 h 1.87138 V 285.75 Z"
|
||||
id="text4263"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 80.640683,319 v -14.14146 h 4.871376 q 1.649515,0 2.517681,0.20257 1.215433,0.27974 2.073952,1.01286 1.11897,0.94534 1.668808,2.42122 0.559485,1.46624 0.559485,3.35691 0,1.61093 -0.376205,2.8553 -0.376205,1.24437 -0.964629,2.06431 -0.588424,0.81029 -1.292603,1.28295 -0.694532,0.46303 -1.6881,0.70418 Q 87.026526,319 85.74357,319 Z m 1.87138,-1.66881 h 3.019288 q 1.398712,0 2.189708,-0.26045 0.800642,-0.26045 1.27331,-0.73312 0.665594,-0.66559 1.032153,-1.78456 0.376205,-1.12862 0.376205,-2.7299 0,-2.21865 -0.733118,-3.40514 -0.723471,-1.19614 -1.76527,-1.60128 -0.752411,-0.28939 -2.421219,-0.28939 h -2.971057 z"
|
||||
id="text4267"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="D" />
|
||||
<path
|
||||
d="m 113.91962,319 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98393,0.37621 1.57235,1.34084 0.58842,0.96462 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03215 -3.00964,1.3119 0.74276,0.35691 1.12861,0.70417 0.81994,0.75241 1.55305,1.88103 L 126.38263,319 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94533 -0.41479,-0.2701 -0.84887,-0.37621 -0.31833,-0.0675 -1.0418,-0.0675 H 115.791 V 319 Z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84887 0.3762,-0.58843 0.3762,-1.27331 0,-1.00322 -0.73311,-1.64952 -0.72347,-0.6463 -2.29582,-0.6463 H 115.791 Z"
|
||||
id="text4271"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 147.72428,319 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 319 Z"
|
||||
id="text4275"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 185.09807,319 v -14.14146 h 1.87138 V 319 Z"
|
||||
id="text4279"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 214.83682,319 v -14.14146 h 9.54018 v 1.66881 h -7.6688 v 4.37941 h 6.63665 v 1.66881 H 216.7082 V 319 Z"
|
||||
id="text4283"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 256.1704,304.85854 h 1.87138 v 8.17041 q 0,2.13183 -0.48232,3.38584 -0.48231,1.25402 -1.74597,2.04502 -1.25402,0.78135 -3.29904,0.78135 -1.98713,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80385,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34726,0.86817 1.17684,1.34084 0.83923,0.47267 2.04502,0.47267 2.0643,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4287"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 280.12139,319 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 V 319 h -1.91961 L 281.9156,307.88748 V 319 Z"
|
||||
id="text4291"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 317.97749,319 -5.47909,-14.14146 h 2.02572 l 3.67524,10.2733 q 0.44373,1.23472 0.74276,2.31511 0.32798,-1.15756 0.76206,-2.31511 l 3.81993,-10.2733 h 1.90996 L 319.8971,319 Z"
|
||||
id="text4295"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="V" />
|
||||
<path
|
||||
d="m 351.34807,319 v -14.14146 h 1.87138 V 319 Z"
|
||||
id="text4299"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 380.47425,319 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 319 Z"
|
||||
id="text4303"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 413.16959,319 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98392,0.37621 1.57235,1.34084 0.58842,0.96462 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03215 -3.00965,1.3119 0.74277,0.35691 1.12862,0.70417 0.81994,0.75241 1.55305,1.88103 L 425.6326,319 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94533 -0.41479,-0.2701 -0.84887,-0.37621 -0.31833,-0.0675 -1.0418,-0.0675 h -2.17042 V 319 Z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84887 0.3762,-0.58843 0.3762,-1.27331 0,-1.00322 -0.73311,-1.64952 -0.72348,-0.6463 -2.29582,-0.6463 h -4.47588 z"
|
||||
id="text4307"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
<path
|
||||
d="m 80.549043,347.7066 1.765271,-0.15434 q 0.125402,1.06109 0.578777,1.74598 0.463022,0.67524 1.427651,1.09967 0.964629,0.41479 2.170415,0.41479 1.070738,0 1.890673,-0.31832 0.819934,-0.31833 1.215432,-0.86817 0.405144,-0.55949 0.405144,-1.21543 0,-0.6656 -0.385851,-1.15756 -0.385852,-0.5016 -1.27331,-0.83922 -0.569131,-0.22187 -2.517682,-0.68489 -1.94855,-0.47267 -2.7299,-0.88746 -1.01286,-0.53055 -1.514467,-1.3119 -0.491961,-0.79099 -0.491961,-1.76527 0,-1.07073 0.607717,-1.99678 0.607716,-0.93569 1.774917,-1.418 1.167201,-0.48232 2.594852,-0.48232 1.572345,0 2.768484,0.51126 1.205787,0.5016 1.852088,1.48552 0.646301,0.98393 0.694533,2.2283 l -1.79421,0.13505 q -0.144694,-1.34084 -0.983921,-2.02573 -0.829581,-0.68488 -2.459804,-0.68488 -1.697747,0 -2.479096,0.62701 -0.771704,0.61736 -0.771704,1.49517 0,0.76206 0.549839,1.25402 0.540192,0.49196 2.816716,1.01286 2.286171,0.51125 3.135044,0.8971 1.234725,0.56914 1.823149,1.44695 0.588423,0.86816 0.588423,2.00643 0,1.12861 -0.646301,2.13183 -0.646301,0.99356 -1.861734,1.55305 -1.205786,0.54984 -2.720253,0.54984 -1.919612,0 -3.221861,-0.55949 -1.292602,-0.55948 -2.035367,-1.67845 -0.733118,-1.12862 -0.771703,-2.54662 z"
|
||||
id="text4311"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="m 114.47431,352.25 v -14.14146 h 10.22506 v 1.66881 h -8.35368 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 V 352.25 Z"
|
||||
id="text4315"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 157.2307,347.29181 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.52089 -1.52412,1.20579 -3.73312,1.20579 -2.28617,0 -3.72346,-0.92605 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64951 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08039 1.44694,1.08038 2.01607,3.03858 l -1.84244,0.43408 q -0.49196,-1.5434 -1.42765,-2.24758 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.31189 -0.44373,2.7106 0,1.80386 0.5209,3.15434 0.53054,1.34084 1.63987,2.00643 1.10932,0.66559 2.40192,0.66559 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69131 z"
|
||||
id="text4319"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 180.44856,352.25 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 352.25 h -1.87138 v -6.66559 h -7.35047 V 352.25 Z"
|
||||
id="text4323"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 213.54904,347.7066 1.76527,-0.15434 q 0.12541,1.06109 0.57878,1.74598 0.46302,0.67524 1.42765,1.09967 0.96463,0.41479 2.17042,0.41479 1.07074,0 1.89067,-0.31832 0.81993,-0.31833 1.21543,-0.86817 0.40515,-0.55949 0.40515,-1.21543 0,-0.6656 -0.38586,-1.15756 -0.38585,-0.5016 -1.27331,-0.83922 -0.56913,-0.22187 -2.51768,-0.68489 -1.94855,-0.47267 -2.7299,-0.88746 -1.01286,-0.53055 -1.51446,-1.3119 -0.49196,-0.79099 -0.49196,-1.76527 0,-1.07073 0.60771,-1.99678 0.60772,-0.93569 1.77492,-1.418 1.1672,-0.48232 2.59485,-0.48232 1.57235,0 2.76849,0.51126 1.20578,0.5016 1.85208,1.48552 0.6463,0.98393 0.69454,2.2283 l -1.79421,0.13505 q -0.1447,-1.34084 -0.98393,-2.02573 -0.82958,-0.68488 -2.4598,-0.68488 -1.69775,0 -2.4791,0.62701 -0.7717,0.61736 -0.7717,1.49517 0,0.76206 0.54984,1.25402 0.54019,0.49196 2.81672,1.01286 2.28617,0.51125 3.13504,0.8971 1.23473,0.56914 1.82315,1.44695 0.58842,0.86816 0.58842,2.00643 0,1.12861 -0.6463,2.13183 -0.6463,0.99356 -1.86173,1.55305 -1.20579,0.54984 -2.72026,0.54984 -1.91961,0 -3.22186,-0.55949 -1.2926,-0.55948 -2.03536,-1.67845 -0.73312,-1.12862 -0.77171,-2.54662 z"
|
||||
id="text4327"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="m 245.77171,345.36255 q 0,-3.5209 1.89068,-5.50803 1.89067,-1.99678 4.88102,-1.99678 1.95819,0 3.53054,0.93569 1.57235,0.93569 2.39228,2.61414 0.82958,1.66881 0.82958,3.79099 0,2.15113 -0.86817,3.84887 -0.86816,1.69775 -2.4598,2.57556 -1.59164,0.86817 -3.43408,0.86817 -1.99678,0 -3.56912,-0.96463 -1.57235,-0.96463 -2.38264,-2.63344 -0.81029,-1.66881 -0.81029,-3.53054 z m 1.92926,0.0289 q 0,2.55627 1.36977,4.03215 1.37942,1.46623 3.45338,1.46623 2.11253,0 3.47266,-1.48553 1.36977,-1.48552 1.36977,-4.21542 0,-1.72669 -0.58842,-3.00965 -0.57878,-1.2926 -1.70739,-1.99678 -1.11897,-0.71382 -2.51769,-0.71382 -1.98713,0 -3.42443,1.36977 -1.42765,1.36013 -1.42765,4.55305 z"
|
||||
id="text4331"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="O" />
|
||||
<path
|
||||
d="m 280.60853,352.25 v -14.14146 h 5.30546 q 1.62057,0 2.59485,0.43408 0.98392,0.42444 1.53376,1.32154 0.55948,0.88746 0.55948,1.86174 0,0.90675 -0.49196,1.70739 -0.49196,0.80064 -1.48553,1.2926 1.28296,0.37621 1.96785,1.28296 0.69453,0.90675 0.69453,2.14148 0,0.99356 -0.42444,1.85208 -0.41479,0.84888 -1.03215,1.3119 -0.61736,0.46302 -1.55305,0.70418 -0.92605,0.23151 -2.27653,0.23151 z m 1.87138,-8.19935 h 3.05787 q 1.24437,0 1.78457,-0.16398 0.71382,-0.21222 1.07073,-0.70418 0.36656,-0.49196 0.36656,-1.23473 0,-0.70418 -0.33762,-1.23472 -0.33762,-0.54019 -0.96463,-0.73312 -0.62701,-0.20257 -2.15112,-0.20257 h -2.82636 z m 0,6.53054 h 3.52089 q 0.90675,0 1.27331,-0.0675 0.64631,-0.11576 1.08039,-0.38585 0.43408,-0.2701 0.71382,-0.78135 0.27975,-0.5209 0.27975,-1.19614 0,-0.791 -0.40515,-1.36978 -0.40514,-0.58842 -1.12861,-0.81993 -0.71383,-0.24116 -2.06431,-0.24116 h -3.27009 z"
|
||||
id="text4335"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="B" />
|
||||
<path
|
||||
d="m 312.38265,352.25 5.43086,-14.14146 h 2.01607 l 5.78777,14.14146 h -2.13183 l -1.64951,-4.28295 h -5.91318 l -1.55305,4.28295 z m 4.08038,-5.80707 h 4.7942 l -1.47588,-3.91639 q -0.67524,-1.78456 -1.00321,-2.93247 -0.2701,1.36013 -0.76206,2.70096 z"
|
||||
id="text4339"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="A" />
|
||||
<path
|
||||
d="m 356.7307,347.29181 1.87138,0.47267 q -0.58842,2.30546 -2.12218,3.52089 -1.52412,1.20579 -3.73312,1.20579 -2.28617,0 -3.72346,-0.92605 -1.42765,-0.93569 -2.18007,-2.70096 -0.74276,-1.76527 -0.74276,-3.79099 0,-2.209 0.83923,-3.84887 0.84887,-1.64951 2.40192,-2.49839 1.5627,-0.85852 3.43408,-0.85852 2.12219,0 3.56913,1.08039 1.44694,1.08038 2.01607,3.03858 l -1.84244,0.43408 q -0.49196,-1.5434 -1.42765,-2.24758 -0.93569,-0.70418 -2.35369,-0.70418 -1.63023,0 -2.7299,0.78135 -1.09003,0.78135 -1.53376,2.10289 -0.44373,1.31189 -0.44373,2.7106 0,1.80386 0.5209,3.15434 0.53054,1.34084 1.63987,2.00643 1.10932,0.66559 2.40192,0.66559 1.57235,0 2.66238,-0.90675 1.09003,-0.90675 1.47588,-2.69131 z"
|
||||
id="text4343"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="C" />
|
||||
<path
|
||||
d="m 379.94853,352.25 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 V 352.25 h -1.87138 v -6.66559 h -7.35047 V 352.25 Z"
|
||||
id="text4347"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 417.8384,352.25 v -12.47265 h -4.65916 v -1.66881 h 11.20899 v 1.66881 h -4.67845 V 352.25 Z"
|
||||
id="text4351"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="T" />
|
||||
<path
|
||||
d="m 80.549043,380.95657 1.765271,-0.15434 q 0.125402,1.06109 0.578777,1.74598 0.463022,0.67524 1.427651,1.09967 0.964629,0.41479 2.170415,0.41479 1.070738,0 1.890673,-0.31833 0.819934,-0.31832 1.215432,-0.86816 0.405144,-0.55949 0.405144,-1.21543 0,-0.6656 -0.385851,-1.15756 -0.385852,-0.50161 -1.27331,-0.83923 -0.569131,-0.22186 -2.517682,-0.68488 -1.94855,-0.47267 -2.7299,-0.88746 -1.01286,-0.53055 -1.514467,-1.3119 -0.491961,-0.79099 -0.491961,-1.76527 0,-1.07073 0.607717,-1.99678 0.607716,-0.93569 1.774917,-1.418 1.167201,-0.48232 2.594852,-0.48232 1.572345,0 2.768484,0.51126 1.205787,0.5016 1.852088,1.48552 0.646301,0.98393 0.694533,2.2283 l -1.79421,0.13505 q -0.144694,-1.34084 -0.983921,-2.02573 -0.829581,-0.68488 -2.459804,-0.68488 -1.697747,0 -2.479096,0.62701 -0.771704,0.61736 -0.771704,1.49517 0,0.76206 0.549839,1.25402 0.540192,0.49196 2.816716,1.01286 2.286171,0.51125 3.135044,0.8971 1.234725,0.56914 1.823149,1.44695 0.588423,0.86816 0.588423,2.00643 0,1.12861 -0.646301,2.13183 -0.646301,0.99356 -1.861734,1.55305 -1.205786,0.54984 -2.720253,0.54984 -1.919612,0 -3.221861,-0.55949 -1.292602,-0.55948 -2.035367,-1.67845 -0.733118,-1.12862 -0.771703,-2.54662 z"
|
||||
id="text4355"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="S" />
|
||||
<path
|
||||
d="m 118.59808,385.49997 v -14.14146 h 1.87138 v 14.14146 z"
|
||||
id="text4359"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="I" />
|
||||
<path
|
||||
d="m 147.72428,385.49997 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4363"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 180.85853,385.49997 v -14.14146 h 5.30546 q 1.62057,0 2.59485,0.43408 0.98392,0.42444 1.53376,1.32154 0.55948,0.88746 0.55948,1.86174 0,0.90675 -0.49196,1.70739 -0.49196,0.80064 -1.48553,1.2926 1.28296,0.37621 1.96785,1.28296 0.69453,0.90675 0.69453,2.14148 0,0.99356 -0.42444,1.85208 -0.41479,0.84888 -1.03215,1.3119 -0.61736,0.46302 -1.55305,0.70418 -0.92605,0.23151 -2.27653,0.23151 z m 1.87138,-8.19935 h 3.05787 q 1.24437,0 1.78457,-0.16398 0.71382,-0.21222 1.07073,-0.70418 0.36656,-0.49196 0.36656,-1.23473 0,-0.70418 -0.33762,-1.23472 -0.33762,-0.54019 -0.96463,-0.73312 -0.62701,-0.20257 -2.15112,-0.20257 h -2.82636 z m 0,6.53054 h 3.52089 q 0.90675,0 1.27331,-0.0675 0.64631,-0.11576 1.08039,-0.38585 0.43408,-0.2701 0.71382,-0.78135 0.27975,-0.5209 0.27975,-1.19614 0,-0.791 -0.40515,-1.36978 -0.40514,-0.58842 -1.12861,-0.81993 -0.71383,-0.24116 -2.06431,-0.24116 h -3.27009 z"
|
||||
id="text4367"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="B" />
|
||||
<path
|
||||
d="m 214.22428,385.49997 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4371"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 246.87138,385.49997 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42765,-11.11253 v 11.11253 z"
|
||||
id="text4375"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 280.11174,385.49997 v -1.73633 l 7.24437,-9.05787 q 0.7717,-0.96463 1.46623,-1.67845 h -7.89066 v -1.66881 h 10.1286 v 1.66881 l -7.93889,9.81027 -0.85852,0.99357 h 9.02892 v 1.66881 z"
|
||||
id="text4379"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 313.67043,385.49997 -3.75241,-14.14146 h 1.91961 l 2.15112,9.27008 q 0.34727,1.45659 0.59807,2.89389 0.54019,-2.26688 0.63666,-2.61414 l 2.69131,-9.54983 h 2.25723 l 2.02572,7.15755 q 0.76206,2.66237 1.09968,5.00642 0.2701,-1.34083 0.70418,-3.07717 l 2.21865,-9.0868 h 1.88102 l -3.8778,14.14146 h -1.80386 l -2.9807,-10.77491 q -0.37621,-1.35048 -0.44373,-1.65916 -0.22187,0.97428 -0.41479,1.65916 l -3,10.77491 z"
|
||||
id="text4383"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="W" />
|
||||
<path
|
||||
d="m 345.52171,378.61252 q 0,-3.5209 1.89068,-5.50803 1.89067,-1.99678 4.88102,-1.99678 1.95819,0 3.53054,0.93569 1.57235,0.93569 2.39228,2.61414 0.82958,1.66881 0.82958,3.79099 0,2.15112 -0.86817,3.84887 -0.86816,1.69775 -2.4598,2.57556 -1.59164,0.86817 -3.43408,0.86817 -1.99678,0 -3.56912,-0.96463 -1.57235,-0.96463 -2.38264,-2.63344 -0.81029,-1.66881 -0.81029,-3.53054 z m 1.92926,0.0289 q 0,2.55626 1.36977,4.03215 1.37942,1.46623 3.45338,1.46623 2.11253,0 3.47266,-1.48553 1.36977,-1.48552 1.36977,-4.21542 0,-1.72669 -0.58842,-3.00965 -0.57878,-1.2926 -1.70739,-1.99678 -1.11897,-0.71382 -2.51769,-0.71382 -1.98713,0 -3.42443,1.36977 -1.42765,1.36013 -1.42765,4.55305 z m 2.09325,-8.15112 v -1.97749 h 1.8135 v 1.97749 z m 3.59806,0 v -1.97749 h 1.8135 v 1.97749 z"
|
||||
id="text4387"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Ö" />
|
||||
<path
|
||||
d="m 381.45335,385.49997 v -14.14146 h 1.87138 v 12.47265 h 6.96462 v 1.66881 z"
|
||||
id="text4391"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="L" />
|
||||
<path
|
||||
d="m 414.33679,385.49997 v -14.14146 h 9.54018 v 1.66881 h -7.6688 v 4.37941 h 6.63665 v 1.66881 h -6.63665 v 6.42443 z"
|
||||
id="text4395"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="F" />
|
||||
<path
|
||||
d="m 80.611744,418.74997 v -1.73633 l 7.244363,-9.05787 q 0.771703,-0.96463 1.466236,-1.67845 h -7.890664 v -1.66881 h 10.128603 v 1.66881 l -7.938896,9.81027 -0.858519,0.99357 h 9.028926 v 1.66881 z"
|
||||
id="text4399"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="Z" />
|
||||
<path
|
||||
d="m 114.47431,418.74997 v -14.14146 h 10.22506 v 1.66881 h -8.35368 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4403"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 147.19856,418.74997 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 v 14.14146 h -1.87138 v -6.66559 h -7.35047 v 6.66559 z"
|
||||
id="text4407"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 180.37139,418.74997 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42764,-11.11253 v 11.11253 z"
|
||||
id="text4411"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 214.22428,418.74997 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4415"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 256.1704,404.60851 h 1.87138 v 8.17041 q 0,2.13183 -0.48232,3.38584 -0.48231,1.25402 -1.74597,2.04502 -1.25402,0.78135 -3.29904,0.78135 -1.98713,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80385,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34726,0.86817 1.17684,1.34084 0.83923,0.47267 2.04502,0.47267 2.0643,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4419"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 280.12139,418.74997 v -14.14146 h 1.91961 l 7.42764,11.10288 v -11.10288 h 1.79421 v 14.14146 h -1.91961 l -7.42764,-11.11253 v 11.11253 z"
|
||||
id="text4423"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="N" />
|
||||
<path
|
||||
d="m 313.97428,418.74997 v -14.14146 h 10.22507 v 1.66881 h -8.35369 v 4.33118 h 7.82314 v 1.65916 h -7.82314 v 4.8135 h 8.68166 v 1.66881 z"
|
||||
id="text4427"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="E" />
|
||||
<path
|
||||
d="m 355.92041,404.60851 h 1.87138 v 8.17041 q 0,2.13183 -0.48231,3.38584 -0.48232,1.25402 -1.74598,2.04502 -1.25402,0.78135 -3.29903,0.78135 -1.98714,0 -3.2508,-0.68489 -1.26366,-0.68489 -1.80386,-1.97749 -0.54019,-1.30225 -0.54019,-3.54983 v -8.17041 h 1.87138 v 8.16076 q 0,1.84244 0.33762,2.72025 0.34727,0.86817 1.17685,1.34084 0.83923,0.47267 2.04501,0.47267 2.06431,0 2.94212,-0.93569 0.87781,-0.93569 0.87781,-3.59807 z"
|
||||
id="text4431"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="U" />
|
||||
<path
|
||||
d="m 379.94853,418.74997 v -14.14146 h 1.87138 v 5.80707 h 7.35047 v -5.80707 h 1.87138 v 14.14146 h -1.87138 v -6.66559 h -7.35047 v 6.66559 z"
|
||||
id="text4435"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="H" />
|
||||
<path
|
||||
d="m 413.16959,418.74997 v -14.14146 h 6.27009 q 1.89067,0 2.87459,0.38585 0.98392,0.37621 1.57235,1.34084 0.58842,0.96462 0.58842,2.13183 0,1.50482 -0.97427,2.53697 -0.97428,1.03215 -3.00965,1.31189 0.74277,0.35692 1.12862,0.70418 0.81994,0.75241 1.55305,1.88103 l 2.45981,3.84887 h -2.3537 l -1.87138,-2.94212 q -0.81993,-1.27331 -1.35048,-1.94855 -0.53054,-0.67524 -0.95498,-0.94534 -0.41479,-0.27009 -0.84887,-0.3762 -0.31833,-0.0675 -1.0418,-0.0675 h -2.17042 v 6.27973 z m 1.87138,-7.90031 h 4.0225 q 1.28296,0 2.00643,-0.26045 0.72347,-0.2701 1.09968,-0.84887 0.3762,-0.58843 0.3762,-1.27331 0,-1.00322 -0.73311,-1.64952 -0.72348,-0.6463 -2.29582,-0.6463 h -4.47588 z"
|
||||
id="text4439"
|
||||
style="font-size:19.7556px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;white-space:pre;fill:#ffffff;stroke-width:0.264583px"
|
||||
transform="translate(-2.6356579,-6.03331)"
|
||||
aria-label="R" />
|
||||
</g>
|
||||
<g
|
||||
id="g1663"
|
||||
transform="translate(252.87499,354.25)"
|
||||
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
inkscape:label="Minus"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
id="rect4466-1-4"
|
||||
style="fill:#ffffff;stroke-width:0.184347"
|
||||
d="M 7.7500038,84.25 H 19.750004 v 2 H 7.7500038 Z" />
|
||||
<path
|
||||
id="rect4466-1-4-2"
|
||||
style="fill:#ffffff;stroke-width:0.184347"
|
||||
d="m 41.000004,84.25 h 12 v 2 h -12 z" />
|
||||
<path
|
||||
id="rect4466-1-4-9"
|
||||
style="fill:#ffffff;stroke-width:0.184347"
|
||||
d="m -25.499994,84.25 h 12 v 2 h -12 z" />
|
||||
<path
|
||||
id="rect4466-1-4-6"
|
||||
style="fill:#ffffff;stroke-width:0.184347"
|
||||
d="m -58.749992,84.25 h 12 v 2 h -12 z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 84 KiB |
1912
res/frontplate/original/frontplate_wordclock2.0_english.svg
Normal file
|
After Width: | Height: | Size: 117 KiB |
1912
res/frontplate/original/frontplate_wordclock2.0_german.svg
Normal file
|
After Width: | Height: | Size: 117 KiB |
1912
res/frontplate/original/frontplate_wordclock2.0_italian.svg
Normal file
|
After Width: | Height: | Size: 117 KiB |
77
res/webserver/fs.html
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
<!DOCTYPE HTML> <!-- For more information visit: https://fipsok.de -->
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="style32.css">
|
||||
<title>Filesystem Manager</title>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
list(JSON.parse(localStorage.getItem('sortBy')));
|
||||
btn.addEventListener('click', () => {
|
||||
if (!confirm(`Wirklich formatieren? Alle Daten gehen verloren.\nDu musst anschließend fs.html wieder laden.`)) event.preventDefault();
|
||||
});
|
||||
});
|
||||
async function list(to){
|
||||
let resp = await fetch(`?sort=${to}`);
|
||||
let json = await resp.json();
|
||||
let myList = document.querySelector('main'), noted = '';
|
||||
myList.innerHTML = '<nav><input type="radio" id="/" name="group" checked="checked"><label for="/"> 📁</label><span id="cr">+📁</nav></span><span id="si"></span>';
|
||||
for (var i = 0; i < json.length - 1; i++) {
|
||||
let dir = '', f = json[i].folder, n = json[i].name, t = new Date(json[i].time*1000).toLocaleString();
|
||||
if (f != noted) {
|
||||
noted = f;
|
||||
dir = `<nav><input type="radio" id="${f}" name="group"><label for="${f}"></label> 📁 ${f} <a href="?delete=/${f}">🗑️</a></nav>`;
|
||||
}
|
||||
if (n != '') dir += `<li><a title="Geändert: ${t}" href="${f}/${n}">${n}</a><small> ${json[i].size}</small><a href="${f}/${n}"download="${n}"> Download</a> or<a href="?delete=${f}/${n}"> Delete</a>`;
|
||||
myList.insertAdjacentHTML('beforeend', dir);
|
||||
}
|
||||
myList.insertAdjacentHTML('beforeend', `<li><b id="so">▼ ${to ? to > 1 ? 'Time' : 'Size' : 'A - Z'}</b> LittleFS belegt ${json[i].usedBytes.replace(".00", "")} von ${json[i].totalBytes.replace(".00", "")}`);
|
||||
var free = json[i].freeBytes;
|
||||
cr.addEventListener('click', () => {
|
||||
document.getElementById('no').classList.toggle('no');
|
||||
});
|
||||
so.addEventListener('click', () => {
|
||||
list(to=++to%3);
|
||||
localStorage.setItem('sortBy', JSON.stringify(to));
|
||||
});
|
||||
document.addEventListener('change', (e) => {
|
||||
if (e.target.id == 'fs') {
|
||||
for (var bytes = 0, i = 0; i < event.target.files.length; i++) bytes += event.target.files[i].size;
|
||||
for (var output = `${bytes} Byte`, i = 0, circa = bytes / 1024; circa > 1; circa /= 1024) output = circa.toFixed(2) + [' KB', ' MB', ' GB'][i++];
|
||||
if (bytes > free) {
|
||||
si.innerHTML = `<li><b> ${output}</b><strong> Ungenügend Speicher frei</strong></li>`;
|
||||
up.setAttribute('disabled', 'disabled');
|
||||
}
|
||||
else {
|
||||
si.innerHTML = `<li><b>Dateigröße:</b> ${output}</li>`;
|
||||
up.removeAttribute('disabled');
|
||||
}
|
||||
}
|
||||
document.querySelectorAll(`input[type=radio]`).forEach(el => { if (el.checked) document.querySelector('form').setAttribute('action', '/upload?f=' + el.id)});
|
||||
});
|
||||
document.querySelectorAll('[href^="?delete=/"]').forEach(node => {
|
||||
node.addEventListener('click', () => {
|
||||
if (!confirm('Sicher!')) event.preventDefault();
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>ESP32 Filesystem Manager</h2>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<input id="fs" type="file" name="up[]" multiple>
|
||||
<button id="up" disabled>Upload</button>
|
||||
</form>
|
||||
<form id="no" class="no" method="POST">
|
||||
<input name="new" placeholder="Ordner Name" pattern="[^\x22/%&\\:;]{1,31}" title="Zeichen “ % & / : ; \ sind nicht erlaubt." required="">
|
||||
<button>Create</button>
|
||||
</form>
|
||||
<main></main>
|
||||
<form action="/format" method="POST">
|
||||
<button id="btn">Format LittleFS</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
273
res/webserver/icons/all_icons.svg
Normal file
@@ -0,0 +1,273 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="161.88095mm"
|
||||
height="106.73212mm"
|
||||
viewBox="0 0 161.88095 106.73212"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)"
|
||||
sodipodi:docname="icons.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="317.90861"
|
||||
inkscape:cy="275.63752"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="g970"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="3396"
|
||||
inkscape:window-height="1377"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="332"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="background"
|
||||
sodipodi:insensitive="true"
|
||||
style="display:inline"
|
||||
transform="translate(-3.7261978,-3.159226)">
|
||||
<rect
|
||||
style="opacity:0.998;fill:#1b2131;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="rect1277"
|
||||
width="265.1503"
|
||||
height="146.27678"
|
||||
x="-30.238094"
|
||||
y="-2.0788691" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline"
|
||||
transform="translate(-3.7261978,-3.159226)">
|
||||
<g
|
||||
id="g970"
|
||||
transform="translate(-41.231887,-0.1012095)"
|
||||
style="stroke:#ffffff;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 168.1994,20.178841 h 14.21205 v 17.10525 h 9.43341"
|
||||
id="path958"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<ellipse
|
||||
style="opacity:0.998;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.13808;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="path966"
|
||||
cx="191.5715"
|
||||
cy="37.26976"
|
||||
rx="2.4327564"
|
||||
ry="1.8899693" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 9.117282,10.213341 H 19.189006"
|
||||
id="path1018"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 35.942133,10.213341 h 8.68756"
|
||||
id="path1020"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 15.075495,18.899601 h 6.352876"
|
||||
id="path1022"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 27.668243,29.99128 h 10.76086"
|
||||
id="path1024"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 9.216526,45.35928 H 22.413267"
|
||||
id="path1026"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 40.155233,45.35928 h 8.26011"
|
||||
id="path1028"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:22.2661px;line-height:125%;font-family:Delicious;-inkscape-font-specification:'Delicious, Normal';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.392;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.935657"
|
||||
x="73.826271"
|
||||
y="47.316673"
|
||||
id="text843-1-6"><tspan
|
||||
sodipodi:role="line"
|
||||
x="73.826271"
|
||||
y="47.316673"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.2661px;font-family:'Century Gothic';-inkscape-font-specification:'Century Gothic, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.392;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.935657"
|
||||
id="tspan845-4-2">34</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:22.2661px;line-height:125%;font-family:Delicious;-inkscape-font-specification:'Delicious, Normal';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.392;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.935657"
|
||||
x="72.288368"
|
||||
y="25.09005"
|
||||
id="text843-1-1-4"><tspan
|
||||
sodipodi:role="line"
|
||||
x="72.288368"
|
||||
y="25.09005"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.2661px;font-family:'Century Gothic';-inkscape-font-specification:'Century Gothic, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.392;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.935657"
|
||||
id="tspan845-4-1-8">12</tspan></text>
|
||||
<g
|
||||
id="g976-1"
|
||||
transform="translate(-97.518244,58.179689)"
|
||||
style="stroke:#ffffff;stroke-opacity:1">
|
||||
<rect
|
||||
style="opacity:0.998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="rect897-4"
|
||||
width="48"
|
||||
height="48"
|
||||
x="159.50783"
|
||||
y="2.4869769"
|
||||
ry="6.8035712" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 68.266491,89.99753 v 9.99987 h 10.02362 V 84.997404 h -5.01793 l -0.0236,4.976496 z"
|
||||
id="path1114"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 87.907981,69.696525 v 4.999999 h 14.999999 v -4.999999 z"
|
||||
id="path1116"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<rect
|
||||
style="opacity:0.998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="rect1122"
|
||||
width="5"
|
||||
height="5"
|
||||
x="73.290115"
|
||||
y="69.696526" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 102.90757,89.98617 4.1e-4,-4.988563 -10.023619,-3.92e-4 -5.6e-4,14.999995 5.01793,1.9e-4 0.0238,-9.98781 z"
|
||||
id="path1114-0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<g
|
||||
id="g976-1-8"
|
||||
transform="translate(-43.503678,1.7696772)"
|
||||
style="display:inline;stroke:#ffffff;stroke-opacity:1">
|
||||
<rect
|
||||
style="opacity:0.998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="rect897-4-3"
|
||||
width="48"
|
||||
height="48"
|
||||
x="159.50783"
|
||||
y="2.4869769"
|
||||
ry="6.8035712" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10.069697,68.165892 V 79.221694"
|
||||
id="path1202"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 47.489339,90.74997 v 11.0558"
|
||||
id="path1204"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.66303;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 20.993455,77.647383 h 0.522676"
|
||||
id="path1206" />
|
||||
<path
|
||||
sodipodi:type="spiral"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1274"
|
||||
sodipodi:cx="138.1503"
|
||||
sodipodi:cy="84.477684"
|
||||
sodipodi:expansion="1"
|
||||
sodipodi:revolution="1.72963"
|
||||
sodipodi:radius="16.567476"
|
||||
sodipodi:argument="-9.8626442"
|
||||
sodipodi:t0="0"
|
||||
d="m 138.1503,84.477684 c -1.30485,0.610898 -1.46724,-1.457511 -1.01535,-2.168741 1.22459,-1.927387 4.03131,-1.29185 5.35283,0.138034 2.3639,2.557727 1.28985,6.586948 -1.29142,8.536929 -3.78811,2.861676 -9.18201,1.300939 -11.72102,-2.444809 -3.38411,-4.992493 -1.31841,-11.791687 3.59819,-14.905116 6.18704,-3.917932 14.40849,-1.339322 18.08921,4.751583 4.02746,6.664688 1.9218,15.40351 -4.12999,20.077234" />
|
||||
<g
|
||||
id="g976-1-8-7"
|
||||
transform="translate(-154.35033,58.404362)"
|
||||
style="display:inline;stroke:#ffffff;stroke-opacity:1">
|
||||
<rect
|
||||
style="opacity:0.998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="rect897-4-3-0"
|
||||
width="48"
|
||||
height="48"
|
||||
x="159.50783"
|
||||
y="2.4869769"
|
||||
ry="6.8035712" />
|
||||
</g>
|
||||
<g
|
||||
id="g976-1-8-5"
|
||||
transform="translate(-42.900683,57.801709)"
|
||||
style="display:inline;stroke:#ffffff;stroke-opacity:1">
|
||||
<rect
|
||||
style="opacity:0.998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="rect897-4-3-7"
|
||||
width="48"
|
||||
height="48"
|
||||
x="159.50783"
|
||||
y="2.4869769"
|
||||
ry="6.8035712" />
|
||||
</g>
|
||||
<g
|
||||
id="g976-1-8-78"
|
||||
transform="translate(-154.78163,1.8612363)"
|
||||
style="display:inline;stroke:#ffffff;stroke-opacity:1">
|
||||
<rect
|
||||
style="opacity:0.998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="rect897-4-3-1"
|
||||
width="48"
|
||||
height="48"
|
||||
x="159.50783"
|
||||
y="2.4869769"
|
||||
ry="6.8035712" />
|
||||
</g>
|
||||
<g
|
||||
id="g976-1-8-56"
|
||||
transform="translate(-98.463184,1.6722491)"
|
||||
style="display:inline;stroke:#ffffff;stroke-opacity:1">
|
||||
<rect
|
||||
style="opacity:0.998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:37.7953;stroke-opacity:1"
|
||||
id="rect897-4-3-5"
|
||||
width="48"
|
||||
height="48"
|
||||
x="159.50783"
|
||||
y="2.4869769"
|
||||
ry="6.8035712" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
15
res/webserver/icons/arrow_left.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="30mm" height="50mm" version="1.1" viewBox="0 0 30 50" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-67.53 -44.941)">
|
||||
<path d="m94.03 48.441-23 21.466 23 21.534" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="6.9999"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 698 B |
15
res/webserver/icons/arrow_right.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="30mm" height="50mm" version="1.1" viewBox="0 0 30 50" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-67.53 -44.941)">
|
||||
<path d="m71.03 48.441 23 21.466-23 21.534" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="6.9999"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 698 B |
25
res/webserver/icons/clock.svg
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="50mm" height="50mm" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-3.7262,-3.3482)" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="2">
|
||||
<path d="m9.1173 10.213h10.072"/>
|
||||
<path d="m35.942 10.213h8.6876"/>
|
||||
<path d="m15.075 18.9h6.3529"/>
|
||||
<path d="m27.668 29.991h10.761"/>
|
||||
<path d="m9.2165 45.359h13.197"/>
|
||||
<path d="m40.155 45.359h8.2601"/>
|
||||
</g>
|
||||
<g transform="translate(-3.7262,-3.3482)" stroke="#fff">
|
||||
<g transform="translate(-154.78,1.8612)">
|
||||
<rect x="159.51" y="2.487" width="48" height="48" ry="6.8036" fill="none" opacity=".998" stroke="#fff" stroke-dashoffset="37.795" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
20
res/webserver/icons/diclock.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="50mm" height="50mm" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-60.045 -3.1592)" display="none">
|
||||
<rect x="-30.238" y="-2.0789" width="265.15" height="146.28" fill="#1b2131" fill-rule="evenodd" opacity=".998"/>
|
||||
</g>
|
||||
<text x="13.781271" y="44.157475" fill="#ffffff" font-family="Delicious" font-size="22.266px" letter-spacing="0px" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".93566" stroke-width="1.392" word-spacing="0px" style="line-height:125%" xml:space="preserve"><tspan x="13.781271" y="44.157475" fill="#ffffff" font-family="'Century Gothic'" font-size="22.266px" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".93566" stroke-width="1.392" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">34</tspan></text>
|
||||
<text x="12.243368" y="21.930849" fill="#ffffff" font-family="Delicious" font-size="22.266px" letter-spacing="0px" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".93566" stroke-width="1.392" word-spacing="0px" style="line-height:125%" xml:space="preserve"><tspan x="12.243368" y="21.930849" fill="#ffffff" font-family="'Century Gothic'" font-size="22.266px" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".93566" stroke-width="1.392" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">12</tspan></text>
|
||||
<g transform="translate(-158.51 -1.487)" stroke="#fff">
|
||||
<rect x="159.51" y="2.487" width="48" height="48" ry="6.8036" fill="none" opacity=".998" stroke="#fff" stroke-dashoffset="37.795" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
71
res/webserver/icons/hearts.svg
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="50mm"
|
||||
height="50mm"
|
||||
version="1.1"
|
||||
viewBox="0 0 50 50"
|
||||
id="svg4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<metadata
|
||||
id="metadata1">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(-60.99,-59.667)"
|
||||
display="none"
|
||||
id="g1">
|
||||
<rect
|
||||
x="-30.238001"
|
||||
y="-2.0789001"
|
||||
width="265.14999"
|
||||
height="146.28"
|
||||
fill="#1b2131"
|
||||
fill-rule="evenodd"
|
||||
opacity="0.998"
|
||||
id="rect1" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-158.51 -1.487)"
|
||||
stroke="#fff"
|
||||
id="g2">
|
||||
<rect
|
||||
x="159.51"
|
||||
y="2.487"
|
||||
width="48"
|
||||
height="48"
|
||||
ry="6.8036"
|
||||
fill="none"
|
||||
opacity=".998"
|
||||
stroke="#fff"
|
||||
stroke-dashoffset="37.795"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
id="rect2" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-60.944598,-60.498371)"
|
||||
fill="none"
|
||||
stroke="#ffffff"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
id="g4">
|
||||
<path
|
||||
d="m 98.493049,73.311072 c -1.567368,-1.782803 -3.642384,-2.757209 -5.857002,-2.757209 -2.214619,0 -4.29598,0.981624 -5.863346,2.764427 l -0.818584,0.9311 -0.831275,-0.945536 c -1.567366,-1.782803 -3.655074,-2.771645 -5.869692,-2.771645 -2.208273,0 -4.289634,0.981625 -5.850654,2.757209 -1.567366,1.782803 -2.43037,4.15025 -2.424025,6.669271 0,2.519022 0.86935,4.87925 2.436716,6.662054 l 11.91706,13.555077 c 0.164986,0.18766 0.387082,0.28871 0.602834,0.28871 0.21575,0 0.437847,-0.0938 0.602832,-0.28149 l 11.94244,-13.533427 c 1.567367,-1.782803 2.430367,-4.150249 2.430367,-6.66927 0.006,-2.519021 -0.85031,-4.886468 -2.417671,-6.669271 z M 97.274689,85.271009 85.935081,98.118738 74.620853,85.249355 c -1.24374,-1.414693 -1.929067,-3.291328 -1.929067,-5.290666 0,-1.999337 0.678982,-3.875972 1.922721,-5.283447 1.237395,-1.407477 2.887254,-2.187003 4.638643,-2.187003 1.757735,0 3.413939,0.779526 4.657679,2.19422 l 1.43411,1.631228 c 0.336317,0.382545 0.875694,0.382545 1.212012,0 l 1.421416,-1.616792 c 1.24374,-1.414695 2.899945,-2.194219 4.651334,-2.194219 1.751392,0 3.401248,0.779524 4.644988,2.187001 1.24374,1.414694 1.922718,3.291328 1.922718,5.290666 0.0064,1.999337 -0.678978,3.875972 -1.922718,5.290666 z"
|
||||
id="path1"
|
||||
style="fill:#ffffff;stroke-width:0.067677" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
16
res/webserver/icons/pause.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="35.033mm" height="40mm" version="1.1" viewBox="0 0 35.033 40" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-43.597 -137.15)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="10">
|
||||
<path d="m48.597 142.15v30"/>
|
||||
<path d="m73.63 142.15v30"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 694 B |
23
res/webserver/icons/pingpong.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="50mm" height="50mm" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-4.1575 -59.891)" display="none">
|
||||
<rect x="-30.238" y="-2.0789" width="265.15" height="146.28" fill="#1b2131" fill-rule="evenodd" opacity=".998"/>
|
||||
</g>
|
||||
<g fill="none" stroke="#fff" stroke-linecap="round">
|
||||
<path d="m5.9125 8.275v11.056" stroke-width="2"/>
|
||||
<path d="m43.332 30.859v11.056" stroke-width="2"/>
|
||||
<path d="m16.836 17.756h0.52268" stroke-width="1.663"/>
|
||||
</g>
|
||||
<g transform="translate(-158.51 -1.487)" stroke="#fff">
|
||||
<rect x="159.51" y="2.487" width="48" height="48" ry="6.8036" fill="none" opacity=".998" stroke="#fff" stroke-dashoffset="37.795" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
15
res/webserver/icons/play.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="30mm" height="30mm" version="1.1" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-106.67 -126.02)">
|
||||
<path d="m109.4 128.75 24.538 12.25-24.538 12.289z" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="5.4618"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 715 B |
20
res/webserver/icons/playpause.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="59.063mm" height="47.621mm" version="1.1" viewBox="0 0 59.063 47.621" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-65.623 -25.716)" stroke="#000" stroke-linecap="round">
|
||||
<path d="m68.124 37.713 20.584 12.25-20.584 12.289z" fill-rule="evenodd" stroke-linejoin="round" stroke-width="5.0024"/>
|
||||
<g transform="matrix(.60155 0 0 .76867 77.988 -70.814)" fill="none" stroke-width="8">
|
||||
<path d="m48.597 142.15v30"/>
|
||||
<path d="m73.63 142.15v30"/>
|
||||
</g>
|
||||
<path d="m89.614 26.871 13.506 45.311" fill="none" stroke-width="2.31"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 967 B |
18
res/webserver/icons/refresh.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="129.55mm" height="129.18mm" version="1.1" viewBox="0 0 129.55 129.18" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-45.971 -35.572)">
|
||||
<path d="m89.202 99.03c-0.0011 0.0044-0.0042 8e-3 -0.0082 0.01003" fill="none" stroke="#000" stroke-width=".26458px"/>
|
||||
<g transform="matrix(.26458 0 0 .26458 45.971 35.388)">
|
||||
<path d="m460.66 132.91c-58.7-122.1-212.2-166.5-331.8-104.1-9.4 5.2-13.5 16.6-8.3 27 5.2 9.4 16.6 13.5 27 8.3 99.9-52 227.4-14.9 276.7 86.3 65.4 134.3-19 236.7-87.4 274.6-93.1 51.7-211.2 17.4-267.6-70.7l69.3 14.5c10.4 2.1 21.8-4.2 23.9-15.6 2.1-10.4-4.2-21.8-15.6-23.9l-122.8-25c-20.6-2-25 16.6-23.9 22.9l15.6 123.8c1 10.4 9.4 17.7 19.8 17.7 12.8 0 20.8-12.5 19.8-23.9l-6-50.5c57.4 70.8 170.3 131.2 307.4 68.2 58.1-30 191.5-147.7 103.9-329.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
29
res/webserver/icons/settings.svg
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="54.044mm" height="45.652mm" version="1.1" viewBox="0 0 54.044 45.652" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-47.401 -39.475)" fill="none" stroke="#fff" stroke-linecap="round">
|
||||
<g>
|
||||
<path d="m67.742 44.491h32.687" stroke-width="2.0325"/>
|
||||
<path d="m48.401 62.298h29.287" stroke-width="2"/>
|
||||
<path d="m48.401 80.127h13.985" stroke-width="2"/>
|
||||
</g>
|
||||
<g stroke-dashoffset="37.795" stroke-linejoin="round" stroke-width="1.4823">
|
||||
<ellipse cx="63.092" cy="44.475" rx="4.2589" ry="4.2589" opacity=".998"/>
|
||||
<ellipse cx="82.344" cy="62.301" rx="4.2589" ry="4.2589" opacity=".998"/>
|
||||
<ellipse cx="67.11" cy="80.127" rx="4.2589" ry="4.2589" opacity=".998"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="m48.401 44.468h9.9687" stroke-width="1.9867"/>
|
||||
<path d="m87.044 62.309h13.384" stroke-width="2"/>
|
||||
<path d="m71.877 80.127h28.552" stroke-width="2"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
22
res/webserver/icons/snake.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="50mm" height="50mm" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-115 -3.2567)" display="none">
|
||||
<rect x="-30.238" y="-2.0789" width="265.15" height="146.28" fill="#1b2131" fill-rule="evenodd" opacity=".998"/>
|
||||
</g>
|
||||
<g transform="translate(-156.23 -3.3579)">
|
||||
<path d="m168.2 20.179h14.212v17.105h9.4334" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="2"/>
|
||||
<ellipse cx="191.57" cy="37.27" rx="2.4328" ry="1.89" fill="#fff" fill-rule="evenodd" opacity=".998"/>
|
||||
</g>
|
||||
<g transform="translate(-158.5 -1.487)" stroke="#fff">
|
||||
<rect x="159.51" y="2.487" width="48" height="48" ry="6.8036" fill="none" opacity=".998" stroke="#fff" stroke-dashoffset="37.795" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
19
res/webserver/icons/spiral.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="50mm" height="50mm" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-115.61 -59.289)" display="none">
|
||||
<rect x="-30.238" y="-2.0789" width="265.15" height="146.28" fill="#1b2131" fill-rule="evenodd" opacity=".998"/>
|
||||
</g>
|
||||
<path d="m22.54 25.189c-1.3048 0.6109-1.4672-1.4575-1.0154-2.1687 1.2246-1.9274 4.0313-1.2918 5.3528 0.13803 2.3639 2.5577 1.2898 6.5869-1.2914 8.5369-3.7881 2.8617-9.182 1.3009-11.721-2.4448-3.3841-4.9925-1.3184-11.792 3.5982-14.905 6.187-3.9179 14.408-1.3393 18.089 4.7516 4.0275 6.6647 1.9218 15.404-4.13 20.077" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="2"/>
|
||||
<g transform="translate(-158.51 -1.487)" stroke="#fff">
|
||||
<rect x="159.51" y="2.487" width="48" height="48" ry="6.8036" fill="none" opacity=".998" stroke="#fff" stroke-dashoffset="37.795" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
24
res/webserver/icons/tetris.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="50mm" height="50mm" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-60.99 -59.667)" display="none">
|
||||
<rect x="-30.238" y="-2.0789" width="265.15" height="146.28" fill="#1b2131" fill-rule="evenodd" opacity=".998"/>
|
||||
</g>
|
||||
<g transform="translate(-158.51 -1.487)" stroke="#fff">
|
||||
<rect x="159.51" y="2.487" width="48" height="48" ry="6.8036" fill="none" opacity=".998" stroke="#fff" stroke-dashoffset="37.795" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
|
||||
</g>
|
||||
<g transform="translate(-60.99,-59.667)" fill="none" stroke="#fff" stroke-linejoin="round" stroke-width="2">
|
||||
<path d="m68.266 89.998v9.9999h10.024v-15h-5.0179l-0.0236 4.9765z"/>
|
||||
<path d="m87.908 69.697v5h15v-5z"/>
|
||||
<rect x="73.29" y="69.697" width="5" height="5" opacity=".998" stroke-dashoffset="37.795" stroke-linecap="round"/>
|
||||
<path d="m102.91 89.986 4.1e-4 -4.9886-10.024-3.92e-4 -5.6e-4 15 5.0179 1.9e-4 0.0238-9.9878z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
702
res/webserver/index.html
Normal file
@@ -0,0 +1,702 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="de">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
body {
|
||||
background-color: #222222;
|
||||
font-family: -apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
Oxygen-Sans,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
"Helvetica Neue",
|
||||
sans-serif;
|
||||
color: white;
|
||||
background: linear-gradient(90deg, #ffa9a9, #64a1e0, #ffa9a9, #64a1e0);
|
||||
background-size: 400% 400%;
|
||||
-webkit-animation: gradientBG 360s ease infinite forwards;
|
||||
animation: gradientBG 360s ease infinite forwards;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
/** Animated background: Code By Webdevtrick ( https://webdevtrick.com ) **/
|
||||
@-webkit-keyframes gradientBG {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gradientBG {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: lighter;
|
||||
letter-spacing: .125rem;
|
||||
text-transform: uppercase;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
.buttonClass {
|
||||
font-size: 15px;
|
||||
font-family: Arial;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
color: #fff;
|
||||
font-weight: 200;
|
||||
border-top-left-radius: 14px;
|
||||
border-top-right-radius: 14px;
|
||||
border-bottom-left-radius: 14px;
|
||||
border-bottom-right-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-o-user-select: none;
|
||||
}
|
||||
|
||||
.buttonClass:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
font-size: 15px;
|
||||
font-family: Arial;
|
||||
display: grid;
|
||||
grid-column-gap: 5px;
|
||||
grid-row-gap: 5px;
|
||||
grid-template-columns: auto auto auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dot {
|
||||
border-radius: 20%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
/* align horizontal */
|
||||
align-items: center;
|
||||
/* align vertical */
|
||||
}
|
||||
|
||||
.dot-mode {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
/* align horizontal */
|
||||
align-items: center;
|
||||
/* align vertical */
|
||||
}
|
||||
|
||||
.active {
|
||||
border: 2px solid lightgray;
|
||||
}
|
||||
|
||||
.mode-item {
|
||||
background: rgba(59, 57, 57, 0.308);
|
||||
}
|
||||
|
||||
.mode-item:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.verticalline {
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.356);
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
height: 32px;
|
||||
width: 52px;
|
||||
border-radius: 16px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin: 0;
|
||||
border: 2px solid #474755ab;
|
||||
background: linear-gradient(180deg, #2d2f39ab 0%, #1f2027ab 100%);
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
.toggle:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background: white;
|
||||
box-shadow: 0 1px 2px rgba(44, 44, 44, .2);
|
||||
transition: all .2s cubic-bezier(.5, .1, .75, 1.35);
|
||||
}
|
||||
|
||||
.toggle:checked {
|
||||
border-color: lightgray;
|
||||
}
|
||||
|
||||
.toggle:checked::after {
|
||||
transform: translatex(20px);
|
||||
}
|
||||
|
||||
label {
|
||||
text-align: right;
|
||||
clear: both;
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.checkbox-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.headline {
|
||||
text-align: center;
|
||||
font-weight: 200;
|
||||
font-size: larger;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.control-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wide-button-bottom {
|
||||
width: 80%;
|
||||
height: 40px;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
background-color: rgba(147, 147, 158, 0.4);
|
||||
}
|
||||
|
||||
.arrow-button {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
background-color: rgba(147, 147, 158, 0.4);
|
||||
}
|
||||
|
||||
.tetris-button-bottom {
|
||||
width: 105px;
|
||||
height: 40px;
|
||||
margin: 5px;
|
||||
background-color: rgba(147, 147, 158, 0.4);
|
||||
}
|
||||
|
||||
img {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.setting-button {
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.settings-container {
|
||||
height: 0px;
|
||||
transition: height 1s;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
height: 250px;
|
||||
transition: height 1s;
|
||||
}
|
||||
|
||||
.show-container {
|
||||
display: inline
|
||||
}
|
||||
|
||||
.hide-container {
|
||||
display: none
|
||||
}
|
||||
|
||||
.number-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: left;
|
||||
/* align-items: center; */
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.save-button {
|
||||
height: 30px;
|
||||
margin: 5px;
|
||||
background-color: rgba(147, 147, 158, 0.4);
|
||||
}
|
||||
</style>
|
||||
<title>WORDCLOCK 2.0</title>
|
||||
<link rel="icon" type="image/svg" href="./icons/clock.svg">
|
||||
</head>
|
||||
|
||||
<body oncontextmenu="return false"> <!-- prevent opening of contextmenu -->
|
||||
<div class="setting-button" onclick="toggleSettings()"><img src="./icons/settings.svg" style="height:20px" /></div>
|
||||
|
||||
<h1 id="headline">WORDCLOCK 2.0</h1>
|
||||
|
||||
<div id="settings-container" class="settings-container">
|
||||
<div class="visible-brightness-container" id="static_brightness_container">
|
||||
<div class="number-container">
|
||||
<label for="static_brightness">Static brightness:</label>
|
||||
<input type="range" id="static_brightness" name="static_brightness" min="10" max="255">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden-brightness-container" id="dyn_brightness_container">
|
||||
<div class="number-container">
|
||||
<label for="min_brightness">Min. brightness:</label>
|
||||
<input type="range" id="min_brightness" name="min_brightness" min="10" max="255">
|
||||
</div>
|
||||
<div class="number-container">
|
||||
<label for="max_brightness">Max. brightness:</label>
|
||||
<input type="range" id="max_brightness" name="max_brightness" min="10" max="255">
|
||||
</div>
|
||||
</div>
|
||||
<div class="number-container">
|
||||
<label for="nm_start" style="align-self: flex-start">Nightmode Start Time: </label>
|
||||
<input type="time" id="nm_start" name="nm_start" min="00:00" max="23:59">
|
||||
</div>
|
||||
<div class="number-container">
|
||||
<label for="nm_end" style="align-self: flex-start">Nightmode End Time: </label>
|
||||
<input type="time" id="nm_end" name="nm_end" min="00:00" max="23:59">
|
||||
</div>
|
||||
<div class="checkbox-container">
|
||||
<label for="reset_wifi" style="align-self: flex-start">Reset Wifi Credentials</label>
|
||||
<input name="reset_wifi" id="reset_wifi" type="checkbox" class="toggle">
|
||||
</div>
|
||||
<div class="buttonClass save-button" onclick="saveSettings()">SAVE</div>
|
||||
</div>
|
||||
|
||||
<div class="verticalline">
|
||||
</div>
|
||||
<div class="headline">
|
||||
MODE
|
||||
</div>
|
||||
<div class="grid-container">
|
||||
<div class="grid-item mode-item"><span class="dot-mode" onclick="modechange(this, 0)"><a
|
||||
onclick="sendCommand('./cmd?mode=clock')" class="buttonClass" style="width: 100%;"><img
|
||||
src="./icons/clock.svg" style="height:50px" /></a></span></div>
|
||||
<div class="grid-item mode-item"><span class="dot-mode" onclick="modechange(this, 1)"><a
|
||||
onclick="sendCommand('./cmd?mode=diclock')" class="buttonClass" style="width: 100%;"><img
|
||||
src="./icons/diclock.svg" style="height:50px" /></a></span></div>
|
||||
<div class="grid-item mode-item"><span class="dot-mode" onclick="modechange(this, 2)"><a
|
||||
onclick="sendCommand('./cmd?mode=spiral')" class="buttonClass" style="width: 100%;"><img
|
||||
src="./icons/spiral.svg" style="height:50px" /></a></span></div>
|
||||
<div class="grid-item mode-item"><span class="dot-mode" onclick="modechange(this, 3)"><a
|
||||
onclick="sendCommand('./cmd?mode=tetris')" class="buttonClass" style="width: 100%;"><img
|
||||
src="./icons/tetris.svg" style="height:50px" /></a></span></div>
|
||||
<div class="grid-item mode-item"><span class="dot-mode" onclick="modechange(this, 4)"><a
|
||||
onclick="sendCommand('./cmd?mode=snake')" class="buttonClass" style="width: 100%;"><img
|
||||
src="./icons/snake.svg" style="height:50px" /></a></span></div>
|
||||
<div class="grid-item mode-item"><span class="dot-mode" onclick="modechange(this, 5)"><a
|
||||
onclick="sendCommand('./cmd?mode=pingpong')" class="buttonClass" style="width: 100%;"><img
|
||||
src="./icons/pingpong.svg" style="height:50px" /></a></span></div>
|
||||
<div class="grid-item mode-item"><span class="dot-mode" onclick="modechange(this, 6)"><a
|
||||
onclick="sendCommand('./cmd?mode=hearts')" class="buttonClass" style="width: 100%;"><img
|
||||
src="./icons/hearts.svg" style="height:50px" /></a></span></div>
|
||||
</div>
|
||||
<div class="checkbox-container">
|
||||
<label for="Nightmode" style="align-self: flex-start">Nightmode</label>
|
||||
<div>
|
||||
<input name="Nightmode" id="Nightmode" type="checkbox" class="toggle">
|
||||
</div>
|
||||
</div>
|
||||
<div class="checkbox-container" onclick="toggleBrightnessOptions()">
|
||||
<label for="DynBrightness" style="align-self: flex-start">Dynamic brightness</label>
|
||||
<div>
|
||||
<input name="DynBrightness" id="DynBrightness" type="checkbox" class="toggle">
|
||||
</div>
|
||||
</div>
|
||||
<div class="main-container hidden" id="colorcontainer">
|
||||
<div class="verticalline">
|
||||
</div>
|
||||
<div class="headline">
|
||||
COLOR
|
||||
</div>
|
||||
<div class="control-container">
|
||||
<div class="grid-container">
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=255-0-0')"
|
||||
class="buttonClass" style="background:rgb(255,0,0);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=255-0-128')"
|
||||
class="buttonClass" style="background:rgb(255,0,128);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=255-0-255')"
|
||||
class="buttonClass" style="background:rgb(255,0,255);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=128-0-255')"
|
||||
class="buttonClass" style="background:rgb(128,0,255);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=0-0-255')"
|
||||
class="buttonClass" style="background:rgb(0,0,255);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=0-128-255')"
|
||||
class="buttonClass" style="background:rgb(0,128,255);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=255-255-255')"
|
||||
class="buttonClass" style="background:rgb(255,255,255);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=0-255-128')"
|
||||
class="buttonClass" style="background:rgb(0,255,128);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=0-255-0')"
|
||||
class="buttonClass" style="background:rgb(0,255,0);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=128-255-0')"
|
||||
class="buttonClass" style="background:rgb(128,255,0);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=200-200-0')"
|
||||
class="buttonClass" style="background:rgb(200,200,0);"></a></span></div>
|
||||
<div class="grid-item"><span class="dot"><a onclick="sendCommand('./cmd?led=255-128-0')"
|
||||
class="buttonClass" style="background:rgb(255,128,0);"></a></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="main-container hidden" id="snakecontainer">
|
||||
<div class="verticalline">
|
||||
</div>
|
||||
<div class="headline">
|
||||
SNAKE
|
||||
</div>
|
||||
<div class="control-container">
|
||||
<div class="grid-container">
|
||||
<div class="grid-item" style="grid-column: 2; grid-row: 1;">
|
||||
<div class="buttonClass arrow-button" onclick="sendCommand('./cmd?snake=up')" unselectable="on"><img
|
||||
src="./icons/arrow_left.svg" style="height:30px; transform:rotate(90deg);" /></div>
|
||||
</div>
|
||||
|
||||
<div class="grid-item" style="grid-column: 1; grid-row: 2;">
|
||||
<div class="buttonClass arrow-button" onclick="sendCommand('./cmd?snake=left')" unselectable="on">
|
||||
<img src="./icons/arrow_left.svg" style="height:30px;" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-item" style="grid-column: 2; grid-row: 2;">
|
||||
<div class="buttonClass arrow-button" onclick="sendCommand('./cmd?snake=down')" unselectable="on">
|
||||
<img src="./icons/arrow_left.svg" style="height:30px; transform:rotate(-90deg);" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-item" style="grid-column: 3; grid-row: 2;">
|
||||
<div class="buttonClass arrow-button" onclick="sendCommand('./cmd?snake=right')" unselectable="on">
|
||||
<img src="./icons/arrow_right.svg" style="height:30px;" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-container">
|
||||
<div class="buttonClass wide-button-bottom" onclick="sendCommand('./cmd?snake=new')" unselectable="on"><img
|
||||
src="./icons/refresh.svg" style="height:30px" /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="main-container hidden" id="tetriscontainer">
|
||||
<div class="verticalline">
|
||||
</div>
|
||||
<div class="headline">
|
||||
TETRIS
|
||||
</div>
|
||||
<div class="control-container">
|
||||
<div class="grid-container">
|
||||
<div class="grid-item" style="grid-column: 2; grid-row: 1;">
|
||||
<div class="buttonClass arrow-button" onclick="sendCommand('./cmd?tetris=up')" unselectable="on">
|
||||
<img src="./icons/arrow_left.svg" style="height:30px; transform:rotate(90deg);" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-item" style="grid-column: 1; grid-row: 2;">
|
||||
<div class="buttonClass arrow-button" onclick="sendCommand('./cmd?tetris=left')" unselectable="on">
|
||||
<img src="./icons/arrow_left.svg" style="height:30px;" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-item" style="grid-column: 2; grid-row: 2;">
|
||||
<div class="buttonClass arrow-button" onclick="sendCommand('./cmd?tetris=down')" unselectable="on">
|
||||
<img src="./icons/arrow_left.svg" style="height:30px; transform:rotate(-90deg);" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-item" style="grid-column: 3; grid-row: 2;">
|
||||
<div class="buttonClass arrow-button" onclick="sendCommand('./cmd?tetris=right')" unselectable="on">
|
||||
<img src="./icons/arrow_right.svg" style="height:30px;" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-container">
|
||||
<div class="buttonClass tetris-button-bottom" onclick="sendCommand('./cmd?tetris=play')" unselectable="on">
|
||||
<img src="./icons/refresh.svg" style="height:20px" />
|
||||
</div>
|
||||
<div class="buttonClass tetris-button-bottom" onclick="sendCommand('./cmd?tetris=pause')" unselectable="on">
|
||||
<img src="./icons/playpause.svg" style="height:20px" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main-container hidden" id="pongcontainer">
|
||||
<div class="verticalline">
|
||||
</div>
|
||||
<div class="headline">
|
||||
PONG
|
||||
</div>
|
||||
<div class="control-container">
|
||||
<div class="grid-container">
|
||||
|
||||
<div class="grid-item" style="grid-column: 1; grid-row: 1;">
|
||||
<div class="buttonClass arrow-button" style="width: 140px" onclick="sendCommand('./cmd?pong=up')"
|
||||
unselectable="on"><img src="./icons/arrow_left.svg"
|
||||
style="height:30px; transform:rotate(90deg);" /></div>
|
||||
</div>
|
||||
|
||||
<div class="grid-item" style="grid-column: 1; grid-row: 2;">
|
||||
<div class="buttonClass arrow-button" style="width: 140px" onclick="sendCommand('./cmd?pong=down')"
|
||||
unselectable="on"><img src="./icons/arrow_left.svg"
|
||||
style="height:30px; transform:rotate(-90deg);" /></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-container">
|
||||
<div class="buttonClass wide-button-bottom" onclick="sendCommand('./cmd?pong=new')" unselectable="on"><img
|
||||
src="./icons/refresh.svg" style="height:30px" /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
var url = "./data?key=mode";
|
||||
var myVar = null;
|
||||
|
||||
xmlhttp.onreadystatechange = function () {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
console.log(this.responseText);
|
||||
myVar = JSON.parse(this.responseText);
|
||||
// set mode button state
|
||||
var state = myVar.modeid;
|
||||
var modebuttons = document.getElementsByClassName("dot-mode");
|
||||
for (const element of modebuttons) {
|
||||
element.classList.remove("active");
|
||||
}
|
||||
modebuttons[state].classList.add("active");
|
||||
|
||||
// set Nightmode checkbox states
|
||||
var ckb_nightmode = document.querySelector('input[id="Nightmode"]');
|
||||
if (myVar.night_mode == "1") {
|
||||
console.log("night_mode == 1");
|
||||
ckb_nightmode.checked = true;
|
||||
}
|
||||
else {
|
||||
console.log("night_mode == 0");
|
||||
ckb_nightmode.checked = false;
|
||||
}
|
||||
ckb_nightmode.addEventListener('change', () => {
|
||||
if (ckb_nightmode.checked) {
|
||||
sendCommand("./cmd?night_mode=1");
|
||||
} else {
|
||||
sendCommand("./cmd?night_mode=0");
|
||||
}
|
||||
});
|
||||
|
||||
// set DynBrightness checkbox states
|
||||
var ckb_dynbrightness = document.querySelector('input[id="DynBrightness"]');
|
||||
if (myVar.dyn_brightness == "1") {
|
||||
console.log("dyn_brightness == 1");
|
||||
ckb_dynbrightness.checked = true;
|
||||
}
|
||||
else {
|
||||
console.log("dyn_brightness == 0");
|
||||
ckb_dynbrightness.checked = false;
|
||||
}
|
||||
ckb_dynbrightness.addEventListener('change', () => {
|
||||
if (ckb_dynbrightness.checked) {
|
||||
sendCommand("./cmd?dyn_brightness=1");
|
||||
} else {
|
||||
sendCommand("./cmd?dyn_brightness=0");
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("nm_start").value = myVar.nightModeStart.replace("-", ":");
|
||||
document.getElementById("nm_end").value = myVar.nightModeEnd.replace("-", ":");
|
||||
document.getElementById("static_brightness").value = parseInt(myVar.static_brightness);
|
||||
document.getElementById("min_brightness").value = parseInt(myVar.min_brightness);
|
||||
document.getElementById("max_brightness").value = parseInt(myVar.max_brightness);
|
||||
|
||||
updateDisplay(parseInt(myVar.modeid));
|
||||
console.log(myVar);
|
||||
}
|
||||
};
|
||||
xmlhttp.open("GET", url, true);
|
||||
xmlhttp.send();
|
||||
|
||||
function modechange(element, value) {
|
||||
console.log(element);
|
||||
var modebuttons = document.getElementsByClassName("dot-mode");
|
||||
for (const element of modebuttons) {
|
||||
element.classList.remove("active");
|
||||
}
|
||||
element.classList.add("active");
|
||||
|
||||
updateDisplay(value);
|
||||
}
|
||||
|
||||
function updateDisplay(modeid) {
|
||||
|
||||
var maincontainer = document.getElementsByClassName("main-container");
|
||||
for (const element of maincontainer) {
|
||||
element.classList.add("hidden");
|
||||
}
|
||||
if (myVar != null) {
|
||||
switch (modeid) {
|
||||
case 0: // clock
|
||||
document.getElementById("colorcontainer").classList.remove("hidden");
|
||||
break;
|
||||
case 1: // diclock
|
||||
document.getElementById("colorcontainer").classList.remove("hidden");
|
||||
break;
|
||||
case 2: // spiral
|
||||
break;
|
||||
case 3: // tetris
|
||||
document.getElementById("tetriscontainer").classList.remove("hidden");
|
||||
break;
|
||||
case 4: // snake
|
||||
document.getElementById("snakecontainer").classList.remove("hidden");
|
||||
break;
|
||||
case 5: // pingpong
|
||||
document.getElementById("pongcontainer").classList.remove("hidden");
|
||||
break;
|
||||
case 6: // hearts
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function sendCommand(command) {
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", command, true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
var nmStart = document.getElementById("nm_start");
|
||||
var nmEnd = document.getElementById("nm_end");
|
||||
var staticBrightnessElmt = document.getElementById("static_brightness");
|
||||
var minBrightnessElmt = document.getElementById("min_brightness");
|
||||
var maxBrightnessElmt = document.getElementById("max_brightness");
|
||||
var resetWifi = document.getElementById("reset_wifi");
|
||||
|
||||
var cmdstr = "./cmd?setting=";
|
||||
cmdstr += nmStart.value.replace(":", "-");
|
||||
cmdstr += "-";
|
||||
cmdstr += nmEnd.value.replace(":", "-");
|
||||
cmdstr += "-";
|
||||
cmdstr += staticBrightnessElmt.value;
|
||||
cmdstr += "-";
|
||||
cmdstr += Number(resetWifi.checked);
|
||||
cmdstr += "-";
|
||||
cmdstr += minBrightnessElmt.value;
|
||||
cmdstr += "-";
|
||||
cmdstr += maxBrightnessElmt.value;
|
||||
|
||||
console.log(cmdstr);
|
||||
sendCommand(cmdstr);
|
||||
toggleSettings();
|
||||
}
|
||||
|
||||
function toggleBrightnessOptions() {
|
||||
var static_b = document.getElementById("static_brightness_container");
|
||||
var dyn_b = document.getElementById("dyn_brightness_container");
|
||||
|
||||
var ckb_dynbrightness = document.querySelector('input[id="DynBrightness"]');
|
||||
|
||||
if (ckb_dynbrightness.checked == true) {
|
||||
static_b.classList.remove("show-container");
|
||||
static_b.classList.add("hide-container")
|
||||
dyn_b.classList.remove("hide-container");
|
||||
dyn_b.classList.add("show-container")
|
||||
}
|
||||
else {
|
||||
dyn_b.classList.remove("show-container");
|
||||
dyn_b.classList.add("hide-container");
|
||||
static_b.classList.remove("hide-container");
|
||||
static_b.classList.add("show-container");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSettings() {
|
||||
var container = document.getElementById("settings-container");
|
||||
if (container.classList.contains("show")) {
|
||||
container.classList.remove("show");
|
||||
}
|
||||
else {
|
||||
toggleBrightnessOptions();
|
||||
container.classList.add("show");
|
||||
}
|
||||
}
|
||||
|
||||
function SetMax() {
|
||||
var slider = document.getElementById("mySlider");
|
||||
|
||||
if ("max" in slider) { // Google Chrome, Safari from version 5 and Opera
|
||||
slider.min = 500;
|
||||
} else {
|
||||
// Safari before version 5
|
||||
slider.setAttribute("max", 500);
|
||||
}
|
||||
|
||||
OnSliderChanged(slider);
|
||||
}
|
||||
|
||||
function OnSliderChanged(slider) {
|
||||
var sliderValue = document.getElementById("sliderValue");
|
||||
sliderValue.innerHTML = slider.value;
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
108
res/webserver/style32.css
Normal file
@@ -0,0 +1,108 @@
|
||||
|
||||
/*For more information visit: https://fipsok.de*/
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
background-color: #a9a9a9;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
}
|
||||
h1,h2 {
|
||||
color: #e1e1e1;
|
||||
text-shadow: 2px 2px 2px black;
|
||||
}
|
||||
li {
|
||||
background-color: #7cfc00;
|
||||
list-style-type: none;
|
||||
margin-bottom: 10px;
|
||||
padding-right: 5px;
|
||||
border-top: 3px solid #7cfc00;
|
||||
border-bottom: 3px solid #7cfc00;
|
||||
box-shadow: 5px 5px 5px #000000b3;
|
||||
}
|
||||
li a:first-child, li b {
|
||||
background-color: #ff4500;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 0 5px;
|
||||
border-top: 3.2px solid #ff4500;
|
||||
border-bottom: 3.6px solid #ff4500;
|
||||
text-shadow: 2px 2px 1px black;
|
||||
cursor:pointer;
|
||||
}
|
||||
li strong {
|
||||
color: red;
|
||||
}
|
||||
input {
|
||||
height: 35px;
|
||||
font-size: 13px;
|
||||
}
|
||||
h1+main {
|
||||
display: flex;
|
||||
}
|
||||
aside {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.2em;
|
||||
}
|
||||
#left {
|
||||
align-items: flex-end;
|
||||
text-shadow: 1px 1px 2px #757474;
|
||||
}
|
||||
.note {
|
||||
background-color: salmon;
|
||||
padding: 0.5em;
|
||||
margin-top: 1em;
|
||||
text-align: center;
|
||||
max-width: 320px;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.no {
|
||||
display: none;
|
||||
}
|
||||
#cr {
|
||||
font-weight: bold;
|
||||
cursor:pointer;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
#up {
|
||||
width: auto;
|
||||
}
|
||||
button {
|
||||
width: 130px;
|
||||
height: 40px;
|
||||
font-size: 16px;
|
||||
margin-top: 1em;
|
||||
cursor: pointer;
|
||||
box-shadow: 5px 5px 5px #000000b3;
|
||||
}
|
||||
div button {
|
||||
background-color: #adff2f;
|
||||
}
|
||||
form [title] {
|
||||
background-color: silver;
|
||||
font-size: 16px;
|
||||
width: 125px;
|
||||
}
|
||||
form:nth-of-type(2) {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
[name="group"] {
|
||||
display: none;
|
||||
}
|
||||
[name="group"] + label {
|
||||
font-size: 1.5em;
|
||||
margin-right: 5px;
|
||||
}
|
||||
[name="group"] + label::before {
|
||||
content: "\002610";
|
||||
}
|
||||
[name="group"]:checked + label::before {
|
||||
content: '\002611\0027A5';
|
||||
}
|
||||
13
scripts/http_diagnosis.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import requests
|
||||
|
||||
r = requests.get("http://wordclock.local/cmd?diag=reset_info")
|
||||
print(r.status_code)
|
||||
print(r.text)
|
||||
|
||||
r = requests.get("http://wordclock.local/cmd?diag=sketch_info")
|
||||
print(r.status_code)
|
||||
print(r.text)
|
||||
|
||||
r = requests.get("http://wordclock.local/cmd?diag=device_info")
|
||||
print(r.status_code)
|
||||
print(r.text)
|
||||
52
scripts/multicastUDP_receiver.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from datetime import datetime
|
||||
import logging
|
||||
import queue
|
||||
import socket
|
||||
import struct
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
LOG_PATH = Path("C:/temp/wordclock_log.txt")
|
||||
|
||||
def setup_logging():
|
||||
FORMAT = "%(asctime)s %(message)s"
|
||||
logging.basicConfig(format=FORMAT, level=logging.INFO)
|
||||
logger = logging.getLogger()
|
||||
handler = logging.FileHandler(LOG_PATH)
|
||||
handler.setLevel(logging.INFO)
|
||||
logger.addHandler(handler)
|
||||
return logger
|
||||
|
||||
|
||||
def get_ip_address():
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.connect(("1.1.1.1", 80))
|
||||
return s.getsockname()[0]
|
||||
|
||||
|
||||
logger = setup_logging()
|
||||
|
||||
multicast_group = "230.120.10.2"
|
||||
server_address = ("", 8123)
|
||||
|
||||
# Create the socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
|
||||
# Bind to the server address
|
||||
sock.bind(server_address)
|
||||
|
||||
logging.info("Start")
|
||||
|
||||
# Tell the operating system to add the socket to the multicast group
|
||||
# on all interfaces.
|
||||
group = socket.inet_aton(multicast_group)
|
||||
mreq = struct.pack("4s4s", group, socket.inet_aton(get_ip_address()))
|
||||
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
|
||||
|
||||
logger.info("Ready")
|
||||
|
||||
# Receive/respond loop
|
||||
while True:
|
||||
data, address = sock.recvfrom(1024)
|
||||
data_str = data.decode("utf-8").strip()
|
||||
logger.info(data_str)
|
||||
BIN
scripts/requirements.txt
Normal file
87
src/connectivity/diagnosis.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "diagnosis.h"
|
||||
|
||||
|
||||
Diagnosis::Diagnosis(UDPLogger *logger, LEDMatrix *matrix) // constructor
|
||||
{
|
||||
_logger = logger;
|
||||
_matrix = matrix;
|
||||
}
|
||||
|
||||
String Diagnosis::handle_command(const String &command)
|
||||
{
|
||||
if (command == "device_info")
|
||||
{
|
||||
return print_device_info();
|
||||
}
|
||||
else if (command == "sketch_info")
|
||||
{
|
||||
return print_sketch_info();
|
||||
}
|
||||
else if (command == "reset_info")
|
||||
{
|
||||
return print_last_reset_details();
|
||||
}
|
||||
else if (command == "matrix_fps")
|
||||
{
|
||||
return print_matrix_fps();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle unknown command
|
||||
String unknown_command = "Diagnosis: Unknown command!\n";
|
||||
print(unknown_command);
|
||||
return unknown_command;
|
||||
}
|
||||
}
|
||||
|
||||
String Diagnosis::print_device_info()
|
||||
{
|
||||
// Retrieve and print device information
|
||||
String device_info = "Device Information:\n";
|
||||
device_info += "Chip ID: " + String(ESP.getChipModel()) + "\n";
|
||||
device_info += "Flash Chip Size: " + String(ESP.getFlashChipSize()) + " bytes\n";
|
||||
device_info += "Free Heap Size: " + String(ESP.getFreeHeap()) + " bytes\n";
|
||||
device_info += "Free Sketch Space: " + String(ESP.getFreeSketchSpace()) + " bytes\n";
|
||||
device_info += "SDK Version: " + String(ESP.getSdkVersion()) + "\n";
|
||||
print(device_info);
|
||||
return device_info;
|
||||
}
|
||||
|
||||
String Diagnosis::print_sketch_info()
|
||||
{
|
||||
// Retrieve and print sketch information
|
||||
String sketch_info = "Sketch Information:\n";
|
||||
sketch_info += "Sketch Size: " + String(ESP.getSketchSize()) + " bytes\n";
|
||||
sketch_info += "Sketch MD5: " + String(ESP.getSketchMD5()) + "\n";
|
||||
print(sketch_info);
|
||||
return sketch_info;
|
||||
}
|
||||
|
||||
String Diagnosis::print_last_reset_details()
|
||||
{
|
||||
// Retrieve and print last reset details
|
||||
String reset_info = "Last Reset Details:\n";
|
||||
reset_info += "Reset Reason: " + String(esp_reset_reason()) + "\n";
|
||||
print(reset_info);
|
||||
return reset_info;
|
||||
}
|
||||
|
||||
String Diagnosis::print_matrix_fps()
|
||||
{
|
||||
// Retrieve and print matrix FPS
|
||||
String matrix_fps = "Matrix FPS: " + String(_matrix->get_fps()) + "\n";
|
||||
print(matrix_fps);
|
||||
return matrix_fps;
|
||||
}
|
||||
|
||||
void Diagnosis::print(const String &s)
|
||||
{
|
||||
if (_logger != nullptr)
|
||||
{
|
||||
_logger->log_string(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(s);
|
||||
}
|
||||
}
|
||||
54
src/connectivity/ota_wrapper.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include "ota_wrapper.h"
|
||||
|
||||
// setup Arduino OTA
|
||||
void setupOTA(String hostname)
|
||||
{
|
||||
ArduinoOTA.setHostname(hostname.c_str());
|
||||
|
||||
ArduinoOTA.onStart([]()
|
||||
{
|
||||
String type;
|
||||
if (ArduinoOTA.getCommand() == U_FLASH)
|
||||
{
|
||||
type = "sketch";
|
||||
}
|
||||
else
|
||||
{ // U_FS
|
||||
type = "filesystem";
|
||||
}
|
||||
|
||||
// NOTE: if updating FS this would be the place to unmount FS using FS.end()
|
||||
// Serial.println("Start updating " + type);
|
||||
});
|
||||
ArduinoOTA.onEnd([]()
|
||||
{
|
||||
// Serial.println("\nEnd");
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
|
||||
{
|
||||
// Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error)
|
||||
{
|
||||
//Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) {
|
||||
//Serial.println("Auth Failed");
|
||||
} else if (error == OTA_BEGIN_ERROR) {
|
||||
//Serial.println("Begin Failed");
|
||||
} else if (error == OTA_CONNECT_ERROR) {
|
||||
//Serial.println("Connect Failed");
|
||||
} else if (error == OTA_RECEIVE_ERROR) {
|
||||
//Serial.println("Receive Failed");
|
||||
} else if (error == OTA_END_ERROR) {
|
||||
//Serial.println("End Failed");
|
||||
} });
|
||||
ArduinoOTA.begin();
|
||||
}
|
||||
|
||||
void handleOTA()
|
||||
{
|
||||
// handle OTA
|
||||
ArduinoOTA.handle();
|
||||
}
|
||||
44
src/connectivity/udp_logger.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "udp_logger.h"
|
||||
|
||||
UDPLogger::UDPLogger() {}
|
||||
|
||||
UDPLogger::UDPLogger(IPAddress interface_addr, IPAddress multicast_addr, uint16_t port, String name)
|
||||
{
|
||||
_interfaceAddr = interface_addr;
|
||||
_multicastAddr = multicast_addr;
|
||||
_name = name;
|
||||
_port = port;
|
||||
_udp.beginMulticast(_multicastAddr, _port);
|
||||
}
|
||||
|
||||
void UDPLogger::set_name(String name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
void UDPLogger::log_string(String message)
|
||||
{
|
||||
// wait 5 milliseconds if last send was less than 10 milliseconds before
|
||||
if ((esp_timer_get_time() / 1000) < (_lastSend + 10))
|
||||
{
|
||||
delay(10);
|
||||
}
|
||||
message = _name + ": " + message;
|
||||
#ifdef SERIAL_DEBUG
|
||||
Serial.println(message);
|
||||
delay(10);
|
||||
#endif /* SERIAL_DEBUG */
|
||||
_udp.beginMulticast(_multicastAddr, _port);
|
||||
message.toCharArray(_packetBuffer, 100);
|
||||
_udp.print(_packetBuffer);
|
||||
_udp.endPacket();
|
||||
_lastSend = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
|
||||
void UDPLogger::log_color_24bit(uint32_t color)
|
||||
{
|
||||
uint8_t result_red = color >> 16 & UINT8_MAX;
|
||||
uint8_t result_green = color >> 8 & UINT8_MAX;
|
||||
uint8_t result_blue = color & UINT8_MAX;
|
||||
log_string(String(result_red) + ", " + String(result_green) + ", " + String(result_blue));
|
||||
}
|
||||
332
src/games/pong.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* @file pong.cpp
|
||||
* @author techniccontroller (mail[at]techniccontroller.com)
|
||||
* @brief Class implementation for pong game
|
||||
* @version 0.1
|
||||
* @date 2022-03-06
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
* main code from https://elektro.turanis.de/html/prj041/index.html
|
||||
*
|
||||
*/
|
||||
#include "pong.h"
|
||||
|
||||
/**
|
||||
* @brief Construct a new Pong:: Pong object
|
||||
*
|
||||
*/
|
||||
Pong::Pong()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Pong:: Pong object
|
||||
*
|
||||
* @param myledmatrix pointer to LEDMatrix object, need to provide gridAddPixel(x, y, col), gridFlush()
|
||||
* @param mylogger pointer to UDPLogger object, need to provide a function log_string(message)
|
||||
*/
|
||||
Pong::Pong(LEDMatrix * matrix, UDPLogger * logger)
|
||||
{
|
||||
_ledmatrix = matrix;
|
||||
_logger = logger;
|
||||
_gameState = GAME_STATE_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run main loop for one cycle
|
||||
*
|
||||
*/
|
||||
void Pong::loopCycle()
|
||||
{
|
||||
switch (_gameState)
|
||||
{
|
||||
case GAME_STATE_INIT:
|
||||
initGame(2);
|
||||
break;
|
||||
case GAME_STATE_RUNNING:
|
||||
updateBall();
|
||||
updateGame();
|
||||
break;
|
||||
case GAME_STATE_END:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: UP for given player
|
||||
*
|
||||
* @param playerid id of player {0, 1}
|
||||
*/
|
||||
void Pong::ctrlUp(uint8_t playerid)
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME))
|
||||
{
|
||||
_playerMovement[playerid] = PADDLE_MOVE_DOWN; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: DOWN for given player
|
||||
*
|
||||
* @param playerid id of player {0, 1}
|
||||
*/
|
||||
void Pong::ctrlDown(uint8_t playerid)
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME))
|
||||
{
|
||||
_playerMovement[playerid] = PADDLE_MOVE_UP; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: NONE for given player
|
||||
*
|
||||
* @param playerid id of player {0, 1}
|
||||
*/
|
||||
void Pong::ctrlNone(uint8_t playerid)
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME))
|
||||
{
|
||||
_playerMovement[playerid] = PADDLE_MOVE_NONE;
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize a new game
|
||||
*
|
||||
* @param numBots number of bots {0, 1, 2} -> two bots results in animation
|
||||
*/
|
||||
void Pong::initGame(uint8_t numBots)
|
||||
{
|
||||
_logger->log_string("Pong: init with " + String(numBots) + " Bots");
|
||||
resetLEDs();
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
|
||||
_numBots = numBots;
|
||||
|
||||
_ball.x = 1;
|
||||
_ball.y = (Y_MAX / 2) - (PADDLE_WIDTH / 2) + 1;
|
||||
_ball_old.x = _ball.x;
|
||||
_ball_old.y = _ball.y;
|
||||
_ballMovement[0] = 1;
|
||||
_ballMovement[1] = -1;
|
||||
_ballDelay = BALL_DELAY_MAX;
|
||||
|
||||
for (uint8_t i = 0; i < PADDLE_WIDTH; i++)
|
||||
{
|
||||
_paddles[PLAYER_1][i].x = 0;
|
||||
_paddles[PLAYER_1][i].y = (Y_MAX / 2) - (PADDLE_WIDTH / 2) + i;
|
||||
_paddles[PLAYER_2][i].x = X_MAX - 1;
|
||||
_paddles[PLAYER_2][i].y = _paddles[PLAYER_1][i].y;
|
||||
}
|
||||
|
||||
_gameState = GAME_STATE_RUNNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update ball position
|
||||
*
|
||||
*/
|
||||
void Pong::updateBall()
|
||||
{
|
||||
bool hitBall = false;
|
||||
if (((esp_timer_get_time() / 1000) - _lastBallUpdate) < _ballDelay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_lastBallUpdate = (esp_timer_get_time() / 1000);
|
||||
toggleLed(_ball.x, _ball.y, LED_TYPE_OFF);
|
||||
|
||||
// collision detection for player 1
|
||||
if (_ballMovement[0] == -1 && _ball.x == 1)
|
||||
{
|
||||
for (uint8_t i = 0; i < PADDLE_WIDTH; i++)
|
||||
{
|
||||
if (_paddles[PLAYER_1][i].y == _ball.y)
|
||||
{
|
||||
hitBall = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// collision detection for player 2
|
||||
if (_ballMovement[0] == 1 && _ball.x == X_MAX - 2)
|
||||
{
|
||||
for (uint8_t i = 0; i < PADDLE_WIDTH; i++)
|
||||
{
|
||||
if (_paddles[PLAYER_2][i].y == _ball.y)
|
||||
{
|
||||
hitBall = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hitBall == true)
|
||||
{
|
||||
_ballMovement[0] *= -1;
|
||||
if (_ballDelay > BALL_DELAY_MIN)
|
||||
{
|
||||
_ballDelay -= BALL_DELAY_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
_ball.x += _ballMovement[0];
|
||||
_ball.y += _ballMovement[1];
|
||||
|
||||
if (_ball.x <= 0 || _ball.x >= X_MAX - 1)
|
||||
{
|
||||
endGame();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_ball.y <= 0 || _ball.y >= Y_MAX - 1)
|
||||
{
|
||||
_ballMovement[1] *= -1;
|
||||
}
|
||||
|
||||
toggleLed(_ball.x, _ball.y, LED_TYPE_BALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Game over, draw ball red
|
||||
*
|
||||
*/
|
||||
void Pong::endGame()
|
||||
{
|
||||
_logger->log_string("Pong: Game ended");
|
||||
_gameState = GAME_STATE_END;
|
||||
toggleLed(_ball.x, _ball.y, LED_TYPE_BALL_RED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update paddle position and check for game over
|
||||
*
|
||||
*/
|
||||
void Pong::updateGame()
|
||||
{
|
||||
if (((esp_timer_get_time() / 1000) - _lastDrawUpdate) < GAME_DELAY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_lastDrawUpdate = (esp_timer_get_time() / 1000);
|
||||
|
||||
// turn off paddle LEDs
|
||||
for (uint8_t p = 0; p < PLAYER_AMOUNT; p++)
|
||||
{
|
||||
for (uint8_t i = 0; i < PADDLE_WIDTH; i++)
|
||||
{
|
||||
toggleLed(_paddles[p][i].x, _paddles[p][i].y, LED_TYPE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
// move _paddles
|
||||
for (uint8_t p = 0; p < PLAYER_AMOUNT; p++)
|
||||
{
|
||||
uint8_t movement = getPlayerMovement(p);
|
||||
if (movement == PADDLE_MOVE_UP && _paddles[p][PADDLE_WIDTH - 1].y < (Y_MAX - 1))
|
||||
{
|
||||
for (uint8_t i = 0; i < PADDLE_WIDTH; i++)
|
||||
{
|
||||
_paddles[p][i].y++;
|
||||
}
|
||||
}
|
||||
if (movement == PADDLE_MOVE_DOWN && _paddles[p][0].y > 0)
|
||||
{
|
||||
for (uint8_t i = 0; i < PADDLE_WIDTH; i++)
|
||||
{
|
||||
_paddles[p][i].y--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// show paddle LEDs
|
||||
for (uint8_t p = 0; p < PLAYER_AMOUNT; p++)
|
||||
{
|
||||
for (uint8_t i = 0; i < PADDLE_WIDTH; i++)
|
||||
{
|
||||
toggleLed(_paddles[p][i].x, _paddles[p][i].y, LED_TYPE_PADDLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the next movement of paddle from given player
|
||||
*
|
||||
* @param playerId id of player {0, 1}
|
||||
* @return uint8_t movement {UP, DOWN, NONE}
|
||||
*/
|
||||
uint8_t Pong::getPlayerMovement(uint8_t playerId)
|
||||
{
|
||||
uint8_t action = PADDLE_MOVE_NONE;
|
||||
if (playerId < _numBots)
|
||||
{
|
||||
// bot moves paddle
|
||||
int8_t ydir = _ball_old.y - _ball.y;
|
||||
int8_t diff = _paddles[playerId][PADDLE_WIDTH / 2].y - _ball.y + ydir * 0.5;
|
||||
// no movement if ball moves away from paddle or no difference between ball and paddle
|
||||
if (diff == 0 || (_ballMovement[0] > 0 && playerId == 0) || (_ballMovement[0] < 0 && playerId == 1))
|
||||
{
|
||||
action = PADDLE_MOVE_NONE;
|
||||
}
|
||||
else if (diff > 0)
|
||||
{
|
||||
action = PADDLE_MOVE_DOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
action = PADDLE_MOVE_UP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
action = _playerMovement[playerId];
|
||||
_playerMovement[playerId] = PADDLE_MOVE_NONE;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the led matrix (turn all leds off)
|
||||
*
|
||||
*/
|
||||
void Pong::resetLEDs()
|
||||
{
|
||||
_ledmatrix->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn on LED on matrix
|
||||
*
|
||||
* @param x x position of led
|
||||
* @param y y position of led
|
||||
* @param type type of pixel {PADDLE, BALL_RED, BALL, OFF}
|
||||
*/
|
||||
void Pong::toggleLed(uint8_t x, uint8_t y, uint8_t type)
|
||||
{
|
||||
uint32_t color;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LED_TYPE_PADDLE:
|
||||
color = LEDMatrix::color_24bit(0, 80, 80);
|
||||
break;
|
||||
case LED_TYPE_BALL_RED:
|
||||
color = LEDMatrix::color_24bit(120, 0, 0);
|
||||
break;
|
||||
case LED_TYPE_BALL:
|
||||
color = LEDMatrix::color_24bit(0, 100, 0);
|
||||
break;
|
||||
case LED_TYPE_OFF:
|
||||
default:
|
||||
color = LEDMatrix::color_24bit(0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
_ledmatrix->grid_add_pixel(x, y, color);
|
||||
}
|
||||
315
src/games/snake.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
/**
|
||||
* @file snake.cpp
|
||||
* @author techniccontroller (mail[at]techniccontroller.com)
|
||||
* @brief Class implementation of snake game
|
||||
* @version 0.1
|
||||
* @date 2022-03-05
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
* main code from https://elektro.turanis.de/html/prj099/index.html
|
||||
*
|
||||
*/
|
||||
#include "snake.h"
|
||||
|
||||
/**
|
||||
* @brief Construct a new Snake:: Snake object
|
||||
*
|
||||
*/
|
||||
Snake::Snake()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Snake:: Snake object
|
||||
*
|
||||
* @param myledmatrix pointer to LEDMatrix object, need to provide gridAddPixel(x, y, col), gridFlush()
|
||||
* @param mylogger pointer to UDPLogger object, need to provide a function logString(message)
|
||||
*/
|
||||
Snake::Snake(LEDMatrix *matrix, UDPLogger *logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_ledmatrix = matrix;
|
||||
_gameState = GAME_STATE_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run main loop for one cycle
|
||||
*
|
||||
*/
|
||||
void Snake::loopCycle()
|
||||
{
|
||||
switch (_gameState)
|
||||
{
|
||||
case GAME_STATE_INIT:
|
||||
initGame();
|
||||
break;
|
||||
case GAME_STATE_RUNNING:
|
||||
updateGame();
|
||||
break;
|
||||
case GAME_STATE_END:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: UP
|
||||
*
|
||||
*/
|
||||
void Snake::ctrlUp()
|
||||
{
|
||||
if (((esp_timer_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME)) && (_gameState == GAME_STATE_RUNNING) && (_userDirection != DIRECTION_UP))
|
||||
{
|
||||
_logger->log_string("Snake: UP");
|
||||
_userDirection = DIRECTION_DOWN; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: DOWN
|
||||
*
|
||||
*/
|
||||
void Snake::ctrlDown()
|
||||
{
|
||||
if (((esp_timer_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME)) && (_gameState == GAME_STATE_RUNNING) && (_userDirection != DIRECTION_DOWN))
|
||||
{
|
||||
_logger->log_string("Snake: DOWN");
|
||||
_userDirection = DIRECTION_UP; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: RIGHT
|
||||
*
|
||||
*/
|
||||
void Snake::ctrlRight()
|
||||
{
|
||||
if (((esp_timer_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME)) && (_gameState == GAME_STATE_RUNNING) && (_userDirection != DIRECTION_RIGHT))
|
||||
{
|
||||
_logger->log_string("Snake: RIGHT");
|
||||
_userDirection = DIRECTION_LEFT; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: LEFT
|
||||
*
|
||||
*/
|
||||
void Snake::ctrlLeft()
|
||||
{
|
||||
if (((esp_timer_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME)) && (_gameState == GAME_STATE_RUNNING) && (_userDirection != DIRECTION_LEFT))
|
||||
{
|
||||
_logger->log_string("Snake: LEFT");
|
||||
_userDirection = DIRECTION_RIGHT; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the led matrix (turn all leds off)
|
||||
*
|
||||
*/
|
||||
void Snake::resetLEDs()
|
||||
{
|
||||
_ledmatrix->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize a new game
|
||||
*
|
||||
*/
|
||||
void Snake::initGame()
|
||||
{
|
||||
_logger->log_string("Snake: init");
|
||||
resetLEDs();
|
||||
_head.x = 0;
|
||||
_head.y = 0;
|
||||
_food.x = -1;
|
||||
_food.y = -1;
|
||||
_wormLength = MIN_TAIL_LENGTH;
|
||||
_userDirection = DIRECTION_LEFT;
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
|
||||
for (int i = 0; i < MAX_TAIL_LENGTH; i++)
|
||||
{
|
||||
_tail[i].x = -1;
|
||||
_tail[i].y = -1;
|
||||
}
|
||||
updateFood();
|
||||
_gameState = GAME_STATE_RUNNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update game representation
|
||||
*
|
||||
*/
|
||||
void Snake::updateGame()
|
||||
{
|
||||
if (((esp_timer_get_time() / 1000) - _lastDrawUpdate) > GAME_DELAY)
|
||||
{
|
||||
_logger->log_string("Snake: update game");
|
||||
toggleLed(_tail[_wormLength - 1].x, _tail[_wormLength - 1].y, LED_TYPE_OFF);
|
||||
switch (_userDirection)
|
||||
{
|
||||
case DIRECTION_RIGHT:
|
||||
if (_head.x > 0)
|
||||
{
|
||||
_head.x--;
|
||||
}
|
||||
break;
|
||||
case DIRECTION_LEFT:
|
||||
if (_head.x < X_MAX - 1)
|
||||
{
|
||||
_head.x++;
|
||||
}
|
||||
break;
|
||||
case DIRECTION_DOWN:
|
||||
if (_head.y > 0)
|
||||
{
|
||||
_head.y--;
|
||||
}
|
||||
break;
|
||||
case DIRECTION_UP:
|
||||
if (_head.y < Y_MAX - 1)
|
||||
{
|
||||
_head.y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isCollision() == true)
|
||||
{
|
||||
endGame();
|
||||
return;
|
||||
}
|
||||
|
||||
updateTail();
|
||||
|
||||
if (_head.x == _food.x && _head.y == _food.y)
|
||||
{
|
||||
if (_wormLength < MAX_TAIL_LENGTH)
|
||||
{
|
||||
_wormLength++;
|
||||
}
|
||||
updateFood();
|
||||
}
|
||||
|
||||
_lastDrawUpdate = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Game over, draw _head red
|
||||
*
|
||||
*/
|
||||
void Snake::endGame()
|
||||
{
|
||||
_gameState = GAME_STATE_END;
|
||||
toggleLed(_head.x, _head.y, LED_TYPE_BLOOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update _tail led positions
|
||||
*
|
||||
*/
|
||||
void Snake::updateTail()
|
||||
{
|
||||
for (unsigned int i = _wormLength - 1; i > 0; i--)
|
||||
{
|
||||
_tail[i].x = _tail[i - 1].x;
|
||||
_tail[i].y = _tail[i - 1].y;
|
||||
}
|
||||
_tail[0].x = _head.x;
|
||||
_tail[0].y = _head.y;
|
||||
|
||||
for (unsigned int i = 0; i < _wormLength; i++)
|
||||
{
|
||||
if (_tail[i].x > -1)
|
||||
{
|
||||
toggleLed(_tail[i].x, _tail[i].y, LED_TYPE_SNAKE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update _food position (generate new one if found)
|
||||
*
|
||||
*/
|
||||
void Snake::updateFood()
|
||||
{
|
||||
bool found = true;
|
||||
do
|
||||
{
|
||||
found = true;
|
||||
_food.x = random(0, X_MAX);
|
||||
_food.y = random(0, Y_MAX);
|
||||
for (unsigned int i = 0; i < _wormLength; i++)
|
||||
{
|
||||
if (_tail[i].x == _food.x && _tail[i].y == _food.y)
|
||||
{
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
} while (found == false);
|
||||
toggleLed(_food.x, _food.y, LED_TYPE_FOOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for collisison between snake and border or itself
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool Snake::isCollision()
|
||||
{
|
||||
if (_head.x < 0 || _head.x >= X_MAX)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (_head.y < 0 || _head.y >= Y_MAX)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
for (unsigned int i = 1; i < _wormLength; i++)
|
||||
{
|
||||
if (_tail[i].x == _head.x && _tail[i].y == _head.y)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn on LED on matrix
|
||||
*
|
||||
* @param x x position of led
|
||||
* @param y y position of led
|
||||
* @param type type of pixel {SNAKE, OFF, FOOD, BLOOD}
|
||||
*/
|
||||
void Snake::toggleLed(uint8_t x, uint8_t y, uint8_t type)
|
||||
{
|
||||
uint32_t color;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LED_TYPE_SNAKE:
|
||||
color = LEDMatrix::color_24bit(0, 100, 100);
|
||||
break;
|
||||
case LED_TYPE_OFF:
|
||||
color = LEDMatrix::color_24bit(0, 0, 0);
|
||||
break;
|
||||
case LED_TYPE_FOOD:
|
||||
color = LEDMatrix::color_24bit(0, 150, 0);
|
||||
break;
|
||||
case LED_TYPE_BLOOD:
|
||||
default:
|
||||
color = LEDMatrix::color_24bit(150, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
_ledmatrix->grid_add_pixel(x, y, color);
|
||||
}
|
||||
680
src/games/tetris.cpp
Normal file
@@ -0,0 +1,680 @@
|
||||
/**
|
||||
* @file tetris.cpp
|
||||
* @author techniccontroller (mail[at]techniccontroller.com)
|
||||
* @brief Class implementation for tetris game
|
||||
* @version 0.1
|
||||
* @date 2022-03-05
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
* main tetris code originally written by Klaas De Craemer, Ing. David Hrbaty
|
||||
*
|
||||
*/
|
||||
#include "tetris.h"
|
||||
|
||||
Tetris::Tetris()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Tetris:: Tetris object
|
||||
*
|
||||
* @param myledmatrix pointer to LEDMatrix object, need to provide gridAddPixel(x, y, col), draw_on_matrix(), gridFlush() and printNumber(x,y,n,col)
|
||||
* @param mylogger pointer to UDPLogger object, need to provide a function log_string(message)
|
||||
*/
|
||||
Tetris::Tetris(LEDMatrix *myledmatrix, UDPLogger *mylogger)
|
||||
{
|
||||
_logger = mylogger;
|
||||
_ledmatrix = myledmatrix;
|
||||
_gameState = GAME_STATE_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run main loop for one cycle
|
||||
*
|
||||
*/
|
||||
void Tetris::loopCycle()
|
||||
{
|
||||
switch (_gameState)
|
||||
{
|
||||
case GAME_STATE_READY:
|
||||
|
||||
break;
|
||||
case GAME_STATE_INIT:
|
||||
tetrisInit();
|
||||
|
||||
break;
|
||||
case GAME_STATE_RUNNING:
|
||||
// If brick is still "on the loose", then move it down by one
|
||||
if (_activeBrick.enabled)
|
||||
{
|
||||
// move faster down when allow drop
|
||||
if (_allowdrop)
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > (_droptime + 50))
|
||||
{
|
||||
_droptime = (esp_timer_get_time() / 1000);
|
||||
shiftActiveBrick(DIR_DOWN);
|
||||
printField();
|
||||
}
|
||||
}
|
||||
|
||||
// move down with regular speed
|
||||
if (((esp_timer_get_time() / 1000) - _prevUpdateTime) > (_brickSpeed * _speedtetris / 100))
|
||||
{
|
||||
_prevUpdateTime = (esp_timer_get_time() / 1000);
|
||||
shiftActiveBrick(DIR_DOWN);
|
||||
printField();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_allowdrop = false;
|
||||
// Active brick has "crashed", check for full lines
|
||||
// and create new brick at top of field
|
||||
checkFullLines();
|
||||
newActiveBrick();
|
||||
_prevUpdateTime = (esp_timer_get_time() / 1000); // Reset update time to avoid brick dropping two spaces
|
||||
}
|
||||
break;
|
||||
case GAME_STATE_PAUSED:
|
||||
|
||||
break;
|
||||
case GAME_STATE_END:
|
||||
// at game end show all bricks on field in red color for 1.5 seconds, then show score
|
||||
if (_tetrisGameOver == true)
|
||||
{
|
||||
_tetrisGameOver = false;
|
||||
_logger->log_string("Tetris: end");
|
||||
everythingRed();
|
||||
_tetrisshowscore = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
|
||||
if ((esp_timer_get_time() / 1000) > (_tetrisshowscore + RED_END_TIME))
|
||||
{
|
||||
resetLEDs();
|
||||
_score = _nbRowsTotal;
|
||||
showscore();
|
||||
_gameState = GAME_STATE_READY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: START (& restart)
|
||||
*
|
||||
*/
|
||||
void Tetris::ctrlStart()
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME)
|
||||
{
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
_gameState = GAME_STATE_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: PAUSE/PLAY
|
||||
*
|
||||
*/
|
||||
void Tetris::ctrlPlayPause()
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME)
|
||||
{
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
if (_gameState == GAME_STATE_PAUSED)
|
||||
{
|
||||
_logger->log_string("Tetris: continue");
|
||||
|
||||
_gameState = GAME_STATE_RUNNING;
|
||||
}
|
||||
else if (_gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_logger->log_string("Tetris: pause");
|
||||
|
||||
_gameState = GAME_STATE_PAUSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: RIGHT
|
||||
*
|
||||
*/
|
||||
void Tetris::ctrlRight()
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
shiftActiveBrick(DIR_RIGHT);
|
||||
printField();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: LEFT
|
||||
*
|
||||
*/
|
||||
void Tetris::ctrlLeft()
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
shiftActiveBrick(DIR_LEFT);
|
||||
printField();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: UP (rotate)
|
||||
*
|
||||
*/
|
||||
void Tetris::ctrlUp()
|
||||
{
|
||||
if ((esp_timer_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_lastButtonClick = (esp_timer_get_time() / 1000);
|
||||
rotateActiveBrick();
|
||||
printField();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger control: DOWN (drop)
|
||||
*
|
||||
*/
|
||||
void Tetris::ctrlDown()
|
||||
{
|
||||
// longer debounce time, to prevent immediate drop
|
||||
if ((esp_timer_get_time() / 1000) > _lastButtonClickr + DEBOUNCE_TIME * 5 && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_allowdrop = true;
|
||||
_lastButtonClickr = (esp_timer_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set game speed
|
||||
*
|
||||
* @param i new speed value
|
||||
*/
|
||||
void Tetris::setSpeed(int32_t i)
|
||||
{
|
||||
_logger->log_string("setSpeed: " + String(i));
|
||||
_speedtetris = -10 * i + 150;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the led matrix (turn all leds off)
|
||||
*
|
||||
*/
|
||||
void Tetris::resetLEDs()
|
||||
{
|
||||
_ledmatrix->flush();
|
||||
_ledmatrix->draw_on_matrix_instant();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the tetris game
|
||||
*
|
||||
*/
|
||||
void Tetris::tetrisInit()
|
||||
{
|
||||
_logger->log_string("Tetris: init");
|
||||
|
||||
clearField();
|
||||
_brickSpeed = INIT_SPEED;
|
||||
_nbRowsThisLevel = 0;
|
||||
_nbRowsTotal = 0;
|
||||
_tetrisGameOver = false;
|
||||
|
||||
newActiveBrick();
|
||||
_prevUpdateTime = (esp_timer_get_time() / 1000);
|
||||
|
||||
_gameState = GAME_STATE_RUNNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw current field representation to led matrix
|
||||
*
|
||||
*/
|
||||
void Tetris::printField()
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < MATRIX_WIDTH; x++)
|
||||
{
|
||||
for (y = 0; y < MATRIX_HEIGHT; y++)
|
||||
{
|
||||
uint8_t activeBrickPix = 0;
|
||||
if (_activeBrick.enabled)
|
||||
{ // Only draw brick if it is enabled
|
||||
// Now check if brick is "in view"
|
||||
if ((x >= _activeBrick.xpos) && (x < (_activeBrick.xpos + (_activeBrick.siz))) && (y >= _activeBrick.ypos) && (y < (_activeBrick.ypos + (_activeBrick.siz))))
|
||||
{
|
||||
activeBrickPix = (_activeBrick.pix)[x - _activeBrick.xpos][y - _activeBrick.ypos];
|
||||
}
|
||||
}
|
||||
if (_field.pix[x][y] == 1)
|
||||
{
|
||||
_ledmatrix->grid_add_pixel(x, y, _field.color[x][y]);
|
||||
}
|
||||
else if (activeBrickPix == 1)
|
||||
{
|
||||
_ledmatrix->grid_add_pixel(x, y, _activeBrick.col);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ledmatrix->grid_add_pixel(x, y, 0x000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ledmatrix->draw_on_matrix_instant();
|
||||
}
|
||||
|
||||
/* *** Game functions *** */
|
||||
/**
|
||||
* @brief Spawn new (random) brick
|
||||
*
|
||||
*/
|
||||
void Tetris::newActiveBrick()
|
||||
{
|
||||
uint8_t selectedBrick = 0;
|
||||
static uint8_t lastselectedBrick = 0;
|
||||
|
||||
// choose random next brick, but not the same as before
|
||||
do
|
||||
{
|
||||
selectedBrick = random(7);
|
||||
} while (lastselectedBrick == selectedBrick);
|
||||
|
||||
// Save selected brick for next round
|
||||
lastselectedBrick = selectedBrick;
|
||||
|
||||
// every brick has its color, select corresponding color
|
||||
uint32_t selectedCol = _brickLib[selectedBrick].col;
|
||||
// Set properties of brick
|
||||
_activeBrick.siz = _brickLib[selectedBrick].siz;
|
||||
_activeBrick.yOffset = _brickLib[selectedBrick].yOffset;
|
||||
_activeBrick.xpos = MATRIX_WIDTH / 2 - _activeBrick.siz / 2;
|
||||
_activeBrick.ypos = BRICKOFFSET - _activeBrick.yOffset;
|
||||
_activeBrick.enabled = true;
|
||||
|
||||
// Set color of brick
|
||||
_activeBrick.col = selectedCol;
|
||||
// _activeBrick.color = _colorLib[1];
|
||||
|
||||
// Copy pix array of selected Brick
|
||||
uint8_t x, y;
|
||||
for (y = 0; y < MAX_BRICK_SIZE; y++)
|
||||
{
|
||||
for (x = 0; x < MAX_BRICK_SIZE; x++)
|
||||
{
|
||||
_activeBrick.pix[x][y] = (_brickLib[selectedBrick]).pix[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
// Check collision, if already, then game is over
|
||||
if (checkFieldCollision(&_activeBrick))
|
||||
{
|
||||
_tetrisGameOver = true;
|
||||
_gameState = GAME_STATE_END;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check collision between bricks in the field and the specified brick
|
||||
*
|
||||
* @param brick brick to be checked for collision
|
||||
* @return boolean true if collision occured
|
||||
*/
|
||||
boolean Tetris::checkFieldCollision(struct Brick *brick)
|
||||
{
|
||||
uint8_t bx, by;
|
||||
uint8_t fx, fy;
|
||||
for (by = 0; by < MAX_BRICK_SIZE; by++)
|
||||
{
|
||||
for (bx = 0; bx < MAX_BRICK_SIZE; bx++)
|
||||
{
|
||||
fx = brick->xpos + bx;
|
||||
fy = brick->ypos + by;
|
||||
if ((brick->pix[bx][by] == 1) && (_field.pix[fx][fy] == 1))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check collision between specified brick and all sides of the playing field
|
||||
*
|
||||
* @param brick brick to be checked for collision
|
||||
* @return boolean true if collision occured
|
||||
*/
|
||||
boolean Tetris::checkSidesCollision(struct Brick *brick)
|
||||
{
|
||||
// Check vertical collision with sides of field
|
||||
uint8_t bx, by;
|
||||
uint8_t fx; //, fy; /* Patch */
|
||||
for (by = 0; by < MAX_BRICK_SIZE; by++)
|
||||
{
|
||||
for (bx = 0; bx < MAX_BRICK_SIZE; bx++)
|
||||
{
|
||||
if (brick->pix[bx][by] == 1)
|
||||
{
|
||||
fx = brick->xpos + bx; // Determine actual position in the field of the current pix of the brick
|
||||
// fy = brick->ypos + by; /* Patch */
|
||||
if (fx < 0 || fx >= MATRIX_WIDTH)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rotate current active brick
|
||||
*
|
||||
*/
|
||||
void Tetris::rotateActiveBrick()
|
||||
{
|
||||
// Copy active brick pix array to temporary pix array
|
||||
uint8_t x, y;
|
||||
Brick tmpBrick;
|
||||
for (y = 0; y < MAX_BRICK_SIZE; y++)
|
||||
{
|
||||
for (x = 0; x < MAX_BRICK_SIZE; x++)
|
||||
{
|
||||
tmpBrick.pix[x][y] = _activeBrick.pix[x][y];
|
||||
}
|
||||
}
|
||||
tmpBrick.xpos = _activeBrick.xpos;
|
||||
tmpBrick.ypos = _activeBrick.ypos;
|
||||
tmpBrick.siz = _activeBrick.siz;
|
||||
|
||||
// Depending on size of the active brick, we will rotate differently
|
||||
if (_activeBrick.siz == 3)
|
||||
{
|
||||
// Perform rotation around center pix
|
||||
tmpBrick.pix[0][0] = _activeBrick.pix[0][2];
|
||||
tmpBrick.pix[0][1] = _activeBrick.pix[1][2];
|
||||
tmpBrick.pix[0][2] = _activeBrick.pix[2][2];
|
||||
tmpBrick.pix[1][0] = _activeBrick.pix[0][1];
|
||||
tmpBrick.pix[1][1] = _activeBrick.pix[1][1];
|
||||
tmpBrick.pix[1][2] = _activeBrick.pix[2][1];
|
||||
tmpBrick.pix[2][0] = _activeBrick.pix[0][0];
|
||||
tmpBrick.pix[2][1] = _activeBrick.pix[1][0];
|
||||
tmpBrick.pix[2][2] = _activeBrick.pix[2][0];
|
||||
// Keep other parts of temporary block clear
|
||||
tmpBrick.pix[0][3] = 0;
|
||||
tmpBrick.pix[1][3] = 0;
|
||||
tmpBrick.pix[2][3] = 0;
|
||||
tmpBrick.pix[3][3] = 0;
|
||||
tmpBrick.pix[3][2] = 0;
|
||||
tmpBrick.pix[3][1] = 0;
|
||||
tmpBrick.pix[3][0] = 0;
|
||||
}
|
||||
else if (_activeBrick.siz == 4)
|
||||
{
|
||||
// Perform rotation around center "cross"
|
||||
tmpBrick.pix[0][0] = _activeBrick.pix[0][3];
|
||||
tmpBrick.pix[0][1] = _activeBrick.pix[1][3];
|
||||
tmpBrick.pix[0][2] = _activeBrick.pix[2][3];
|
||||
tmpBrick.pix[0][3] = _activeBrick.pix[3][3];
|
||||
tmpBrick.pix[1][0] = _activeBrick.pix[0][2];
|
||||
tmpBrick.pix[1][1] = _activeBrick.pix[1][2];
|
||||
tmpBrick.pix[1][2] = _activeBrick.pix[2][2];
|
||||
tmpBrick.pix[1][3] = _activeBrick.pix[3][2];
|
||||
tmpBrick.pix[2][0] = _activeBrick.pix[0][1];
|
||||
tmpBrick.pix[2][1] = _activeBrick.pix[1][1];
|
||||
tmpBrick.pix[2][2] = _activeBrick.pix[2][1];
|
||||
tmpBrick.pix[2][3] = _activeBrick.pix[3][1];
|
||||
tmpBrick.pix[3][0] = _activeBrick.pix[0][0];
|
||||
tmpBrick.pix[3][1] = _activeBrick.pix[1][0];
|
||||
tmpBrick.pix[3][2] = _activeBrick.pix[2][0];
|
||||
tmpBrick.pix[3][3] = _activeBrick.pix[3][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger->log_string("Tetris: Brick size error");
|
||||
}
|
||||
|
||||
// Now validate by checking collision.
|
||||
// Collision possibilities:
|
||||
// - Brick now sticks outside field
|
||||
// - Brick now sticks inside fixed bricks of field
|
||||
// In case of collision, we just discard the rotated temporary brick
|
||||
if ((!checkSidesCollision(&tmpBrick)) && (!checkFieldCollision(&tmpBrick)))
|
||||
{
|
||||
// Copy temporary brick pix array to active pix array
|
||||
for (y = 0; y < MAX_BRICK_SIZE; y++)
|
||||
{
|
||||
for (x = 0; x < MAX_BRICK_SIZE; x++)
|
||||
{
|
||||
_activeBrick.pix[x][y] = tmpBrick.pix[x][y];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shift brick left/right/down by one if possible
|
||||
*
|
||||
* @param dir direction to be shifted
|
||||
*/
|
||||
void Tetris::shiftActiveBrick(int dir)
|
||||
{
|
||||
// Change position of active brick (no copy to temporary needed)
|
||||
if (dir == DIR_LEFT)
|
||||
{
|
||||
_activeBrick.xpos--;
|
||||
}
|
||||
else if (dir == DIR_RIGHT)
|
||||
{
|
||||
_activeBrick.xpos++;
|
||||
}
|
||||
else if (dir == DIR_DOWN)
|
||||
{
|
||||
_activeBrick.ypos++;
|
||||
}
|
||||
|
||||
// Check position of active brick
|
||||
// Two possibilities when collision is detected:
|
||||
// - Direction was LEFT/RIGHT, just revert position back
|
||||
// - Direction was DOWN, revert position and fix block to field on collision
|
||||
// When no collision, keep _activeBrick coordinates
|
||||
if ((checkSidesCollision(&_activeBrick)) || (checkFieldCollision(&_activeBrick)))
|
||||
{
|
||||
if (dir == DIR_LEFT)
|
||||
{
|
||||
_activeBrick.xpos++;
|
||||
}
|
||||
else if (dir == DIR_RIGHT)
|
||||
{
|
||||
_activeBrick.xpos--;
|
||||
}
|
||||
else if (dir == DIR_DOWN)
|
||||
{
|
||||
_activeBrick.ypos--; // Go back up one
|
||||
addActiveBrickToField();
|
||||
_activeBrick.enabled = false; // Disable brick, it is no longer moving
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy active pixels to field, including color
|
||||
*
|
||||
*/
|
||||
void Tetris::addActiveBrickToField()
|
||||
{
|
||||
uint8_t bx, by;
|
||||
uint8_t fx, fy;
|
||||
for (by = 0; by < MAX_BRICK_SIZE; by++)
|
||||
{
|
||||
for (bx = 0; bx < MAX_BRICK_SIZE; bx++)
|
||||
{
|
||||
fx = _activeBrick.xpos + bx;
|
||||
fy = _activeBrick.ypos + by;
|
||||
|
||||
if (fx >= 0 && fy >= 0 && fx < MATRIX_WIDTH && fy < MATRIX_HEIGHT && _activeBrick.pix[bx][by])
|
||||
{ // Check if inside playing field
|
||||
// _field.pix[fx][fy] = _field.pix[fx][fy] || _activeBrick.pix[bx][by];
|
||||
_field.pix[fx][fy] = _activeBrick.pix[bx][by];
|
||||
_field.color[fx][fy] = _activeBrick.col;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move all pix from the field above startRow down by one. startRow is overwritten
|
||||
*
|
||||
* @param startRow
|
||||
*/
|
||||
void Tetris::moveFieldDownOne(uint8_t startRow)
|
||||
{
|
||||
if (startRow == 0)
|
||||
{ // Topmost row has nothing on top to move...
|
||||
return;
|
||||
}
|
||||
uint8_t x, y;
|
||||
for (y = startRow - 1; y > 0; y--)
|
||||
{
|
||||
for (x = 0; x < MATRIX_WIDTH; x++)
|
||||
{
|
||||
_field.pix[x][y + 1] = _field.pix[x][y];
|
||||
_field.color[x][y + 1] = _field.color[x][y];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if a line is complete
|
||||
*
|
||||
*/
|
||||
void Tetris::checkFullLines()
|
||||
{
|
||||
int x, y;
|
||||
int minY = 0;
|
||||
for (y = (MATRIX_HEIGHT - 1); y >= minY; y--)
|
||||
{
|
||||
uint8_t rowSum = 0;
|
||||
for (x = 0; x < MATRIX_WIDTH; x++)
|
||||
{
|
||||
rowSum = rowSum + (_field.pix[x][y]);
|
||||
}
|
||||
if (rowSum >= MATRIX_WIDTH)
|
||||
{
|
||||
// Found full row, animate its removal
|
||||
_activeBrick.enabled = false;
|
||||
|
||||
for (x = 0; x < MATRIX_WIDTH; x++)
|
||||
{
|
||||
_field.pix[x][y] = 0;
|
||||
printField();
|
||||
delay(100);
|
||||
}
|
||||
// Move all upper rows down by one
|
||||
moveFieldDownOne(y);
|
||||
y++;
|
||||
minY++;
|
||||
printField();
|
||||
delay(100);
|
||||
|
||||
_nbRowsThisLevel++;
|
||||
_nbRowsTotal++;
|
||||
if (_nbRowsThisLevel >= LEVELUP)
|
||||
{
|
||||
_nbRowsThisLevel = 0;
|
||||
_brickSpeed = _brickSpeed - SPEED_STEP;
|
||||
if (_brickSpeed < 200)
|
||||
{
|
||||
_brickSpeed = 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear field
|
||||
*
|
||||
*/
|
||||
void Tetris::clearField()
|
||||
{
|
||||
uint8_t x, y;
|
||||
for (y = 0; y < MATRIX_HEIGHT; y++)
|
||||
{
|
||||
for (x = 0; x < MATRIX_WIDTH; x++)
|
||||
{
|
||||
_field.pix[x][y] = 0;
|
||||
_field.color[x][y] = 0;
|
||||
}
|
||||
}
|
||||
for (x = 0; x < MATRIX_WIDTH; x++)
|
||||
{ // This last row is invisible to the player and only used for the collision detection routine
|
||||
_field.pix[x][MATRIX_HEIGHT] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Color all bricks on the field red
|
||||
*
|
||||
*/
|
||||
void Tetris::everythingRed()
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < MATRIX_WIDTH; x++)
|
||||
{
|
||||
for (y = 0; y < MATRIX_HEIGHT; y++)
|
||||
{
|
||||
uint8_t activeBrickPix = 0;
|
||||
if (_activeBrick.enabled)
|
||||
{ // Only draw brick if it is enabled
|
||||
// Now check if brick is "in view"
|
||||
if ((x >= _activeBrick.xpos) && (x < (_activeBrick.xpos + (_activeBrick.siz))) && (y >= _activeBrick.ypos) && (y < (_activeBrick.ypos + (_activeBrick.siz))))
|
||||
{
|
||||
activeBrickPix = (_activeBrick.pix)[x - _activeBrick.xpos][y - _activeBrick.ypos];
|
||||
}
|
||||
}
|
||||
if (_field.pix[x][y] == 1)
|
||||
{
|
||||
_ledmatrix->grid_add_pixel(x, y, RED);
|
||||
}
|
||||
else if (activeBrickPix == 1)
|
||||
{
|
||||
_ledmatrix->grid_add_pixel(x, y, RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ledmatrix->grid_add_pixel(x, y, 0x000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ledmatrix->draw_on_matrix_instant();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw score to led matrix
|
||||
*
|
||||
*/
|
||||
void Tetris::showscore()
|
||||
{
|
||||
uint32_t color = LEDMatrix::color_24bit(255, 170, 0);
|
||||
_ledmatrix->flush();
|
||||
if (_score > 9)
|
||||
{
|
||||
_ledmatrix->print_number(2, 3, _score / 10, color);
|
||||
_ledmatrix->print_number(6, 3, _score % 10, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ledmatrix->print_number(4, 3, _score, color);
|
||||
}
|
||||
_ledmatrix->draw_on_matrix_instant();
|
||||
}
|
||||
1192
src/matrix/animation_functions.cpp
Normal file
344
src/matrix/led_matrix.cpp
Normal file
@@ -0,0 +1,344 @@
|
||||
#include "led_matrix.h"
|
||||
#include "own_font.h"
|
||||
#include "wordclock_constants.h"
|
||||
|
||||
#define MAX_LED_CURRENT_MA 20 // 20mA for full brightness per LED
|
||||
|
||||
// seven predefined colors24bit (green, red, yellow, purple, orange, lightgreen, blue)
|
||||
const uint32_t colors_24bit[NUM_COLORS] = {
|
||||
LEDMatrix::color_24bit(0, 255, 0),
|
||||
LEDMatrix::color_24bit(255, 0, 0),
|
||||
LEDMatrix::color_24bit(200, 200, 0),
|
||||
LEDMatrix::color_24bit(255, 0, 200),
|
||||
LEDMatrix::color_24bit(255, 128, 0),
|
||||
LEDMatrix::color_24bit(0, 128, 0),
|
||||
LEDMatrix::color_24bit(0, 0, 255)};
|
||||
|
||||
/**
|
||||
* @brief Construct a new LEDMatrix::LEDMatrix object
|
||||
*
|
||||
* @param mymatrix pointer to Adafruit_NeoMatrix object
|
||||
* @param mybrightness the initial brightness of the leds
|
||||
* @param mylogger pointer to the UDPLogger object
|
||||
*/
|
||||
LEDMatrix::LEDMatrix(FastLED_NeoMatrix *matrix, uint8_t brightness, UDPLogger *logger)
|
||||
{
|
||||
_neomatrix = matrix;
|
||||
_brightness = brightness;
|
||||
_logger = logger;
|
||||
_current_limit = DEFAULT_CURRENT_LIMIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert RGB value to 24bit color value
|
||||
*
|
||||
* @param r red value (0-255)
|
||||
* @param g green value (0-255)
|
||||
* @param b blue value (0-255)
|
||||
* @return uint32_t 24bit color value
|
||||
*/
|
||||
uint32_t LEDMatrix::color_24bit(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert 24bit color to 16bit color
|
||||
*
|
||||
* @param color24bit 24bit color value
|
||||
* @return uint16_t 16bit color value
|
||||
*/
|
||||
uint16_t LEDMatrix::color_24_to_16bit(uint32_t color_24bit)
|
||||
{
|
||||
uint8_t r = color_24bit >> 16 & UINT8_MAX;
|
||||
uint8_t g = color_24bit >> 8 & UINT8_MAX;
|
||||
uint8_t b = color_24bit & UINT8_MAX;
|
||||
return ((uint16_t)(r & 0xF8) << 8) |
|
||||
((uint16_t)(g & 0xFC) << 3) |
|
||||
(b >> 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Input a value 0 to 255 to get a color value. The colors are a transition r - g - b - back to r.
|
||||
*
|
||||
* @param WheelPos Value between 0 and 255
|
||||
* @return uint32_t return 24bit color of colorwheel
|
||||
*/
|
||||
uint32_t LEDMatrix::wheel(uint8_t WheelPos)
|
||||
{
|
||||
WheelPos = UINT8_MAX - WheelPos;
|
||||
if (WheelPos < 85)
|
||||
{
|
||||
return color_24bit(UINT8_MAX - WheelPos * 3, 0, WheelPos * 3);
|
||||
}
|
||||
if (WheelPos < 170)
|
||||
{
|
||||
WheelPos -= 85;
|
||||
return color_24bit(0, WheelPos * 3, UINT8_MAX - WheelPos * 3);
|
||||
}
|
||||
WheelPos -= 170;
|
||||
return color_24bit(WheelPos * 3, UINT8_MAX - WheelPos * 3, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Interpolates two colors24bit and returns an color of the result
|
||||
*
|
||||
* @param color1 startcolor for interpolation
|
||||
* @param color2 endcolor for interpolatio
|
||||
* @param factor which color is wanted on the path from start to end color
|
||||
* @return uint32_t interpolated color
|
||||
*/
|
||||
uint32_t LEDMatrix::interpolate_color_24bit(uint32_t color1, uint32_t color2, float factor)
|
||||
{
|
||||
uint8_t result_R = color1 >> 16 & UINT8_MAX;
|
||||
uint8_t result_G = color1 >> 8 & UINT8_MAX;
|
||||
uint8_t result_B = color1 & UINT8_MAX;
|
||||
result_R = (uint8_t)(result_R + (int16_t)(factor * ((int16_t)(color2 >> 16 & UINT8_MAX) - (int16_t)result_R)));
|
||||
result_G = (uint8_t)(result_G + (int16_t)(factor * ((int16_t)(color2 >> 8 & UINT8_MAX) - (int16_t)result_G)));
|
||||
result_B = (uint8_t)(result_B + (int16_t)(factor * ((int16_t)(color2 & UINT8_MAX) - (int16_t)result_B)));
|
||||
return color_24bit(result_R, result_G, result_B);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup function for LED matrix
|
||||
*
|
||||
*/
|
||||
void LEDMatrix::setup_matrix()
|
||||
{
|
||||
_neomatrix->begin();
|
||||
_neomatrix->setTextWrap(false);
|
||||
_neomatrix->setBrightness(_brightness);
|
||||
randomSeed(analogRead(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn on the minutes indicator leds with the provided pattern (binary encoded)
|
||||
*
|
||||
* @param pattern the binary encoded pattern of the minute indicator
|
||||
* @param color color to be displayed
|
||||
*/
|
||||
void LEDMatrix::set_min_indicator(uint8_t pattern, uint32_t color)
|
||||
{
|
||||
// pattern:
|
||||
// 15 -> 1111
|
||||
// 14 -> 1110
|
||||
// (...)
|
||||
// 2 -> 0010
|
||||
// 1 -> 0001
|
||||
// 0 -> 0000
|
||||
if (pattern & 1)
|
||||
{
|
||||
_target_minute_indicators[0] = color;
|
||||
}
|
||||
if (pattern >> 1 & 1)
|
||||
{
|
||||
_target_minute_indicators[1] = color;
|
||||
}
|
||||
if (pattern >> 2 & 1)
|
||||
{
|
||||
_target_minute_indicators[2] = color;
|
||||
}
|
||||
if (pattern >> 3 & 1)
|
||||
{
|
||||
_target_minute_indicators[3] = color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief "Activates" a pixel in targetgrid with color
|
||||
*
|
||||
* @param x x-position of pixel
|
||||
* @param y y-position of pixel
|
||||
* @param color color of pixel
|
||||
*/
|
||||
void LEDMatrix::grid_add_pixel(uint8_t x, uint8_t y, uint32_t color)
|
||||
{
|
||||
// limit ranges of x and y
|
||||
if (x >= 0 && x < MATRIX_WIDTH && y >= 0 && y < MATRIX_HEIGHT)
|
||||
{
|
||||
_target_grid[y][x] = color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief "Deactivates" all pixels in targetgrid
|
||||
*
|
||||
*/
|
||||
void LEDMatrix::flush(void)
|
||||
{
|
||||
// set a zero to each pixel
|
||||
for (uint8_t i = 0; i < MATRIX_HEIGHT; i++)
|
||||
{
|
||||
for (uint8_t j = 0; j < MATRIX_WIDTH; j++)
|
||||
{
|
||||
_target_grid[i][j] = 0;
|
||||
}
|
||||
}
|
||||
// set every minutes indicator led to 0
|
||||
_target_minute_indicators[0] = 0;
|
||||
_target_minute_indicators[1] = 0;
|
||||
_target_minute_indicators[2] = 0;
|
||||
_target_minute_indicators[3] = 0;
|
||||
}
|
||||
|
||||
uint16_t LEDMatrix::get_fps(void)
|
||||
{
|
||||
return FastLED.getFPS();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write target pixels directly to leds
|
||||
*
|
||||
*/
|
||||
void LEDMatrix::draw_on_matrix_instant()
|
||||
{
|
||||
_draw_on_matrix(1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write target pixels with low pass filter to leds
|
||||
*
|
||||
* @param factor factor between 0 and 1 (1.0 = hard, 0.1 = smooth)
|
||||
*/
|
||||
void LEDMatrix::draw_on_matrix_smooth(float factor)
|
||||
{
|
||||
_draw_on_matrix(factor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draws the targetgrid to the ledmatrix
|
||||
*
|
||||
* @param factor factor between 0 and 1 (1.0 = hard, 0.1 = smooth)
|
||||
*/
|
||||
void LEDMatrix::_draw_on_matrix(float factor)
|
||||
{
|
||||
uint16_t total_current = 0;
|
||||
uint32_t filtered_color = 0;
|
||||
|
||||
// loop over all leds in matrix
|
||||
for (uint8_t col = 0; col < MATRIX_WIDTH; col++)
|
||||
{
|
||||
for (uint8_t row = 0; row < MATRIX_HEIGHT; row++)
|
||||
{
|
||||
// implement momentum as smooth transistion function
|
||||
filtered_color = interpolate_color_24bit(_current_grid[row][col], _target_grid[row][col], factor);
|
||||
_neomatrix->drawPixel(col, row, color_24_to_16bit(filtered_color));
|
||||
_current_grid[row][col] = filtered_color;
|
||||
total_current += _calc_estimated_led_current(filtered_color);
|
||||
}
|
||||
}
|
||||
|
||||
// loop over all minute indicator leds
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
filtered_color = interpolate_color_24bit(_current_minute_indicators[i], _target_minute_indicators[i], factor);
|
||||
_neomatrix->drawPixel(MATRIX_WIDTH - (1 + i), MATRIX_HEIGHT, color_24_to_16bit(filtered_color));
|
||||
_current_minute_indicators[i] = filtered_color;
|
||||
total_current += _calc_estimated_led_current(filtered_color);
|
||||
}
|
||||
|
||||
// Check if totalCurrent reaches _current_limit -> if yes reduce brightness
|
||||
if (total_current > _current_limit)
|
||||
{
|
||||
uint8_t new_brightness = (uint8_t)(_brightness * (float(_current_limit) / float(total_current)));
|
||||
_neomatrix->setBrightness(new_brightness);
|
||||
}
|
||||
_neomatrix->show();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shows a 1-digit number on LED matrix (5x3)
|
||||
*
|
||||
* @param xpos x of left top corner of digit
|
||||
* @param ypos y of left top corner of digit
|
||||
* @param number number to display
|
||||
* @param color color to display (24bit)
|
||||
*/
|
||||
void LEDMatrix::print_number(uint8_t xpos, uint8_t ypos, uint8_t number, uint32_t color)
|
||||
{
|
||||
for (int y = ypos, i = 0; y < (ypos + 5); y++, i++)
|
||||
{
|
||||
for (int x = xpos, k = 2; x < (xpos + 3); x++, k--)
|
||||
{
|
||||
if ((numbers_font[number][i] >> k) & 0x1)
|
||||
{
|
||||
grid_add_pixel(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shows a character on LED matrix (5x3), supports currently only 'I' and 'P'
|
||||
*
|
||||
* @param xpos x of left top corner of character
|
||||
* @param ypos y of left top corner of character
|
||||
* @param character character to display
|
||||
* @param color color to display (24bit)
|
||||
*/
|
||||
void LEDMatrix::print_char(uint8_t xpos, uint8_t ypos, char character, uint32_t color)
|
||||
{
|
||||
int id = 0;
|
||||
if (character == 'I')
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
else if (character == 'P')
|
||||
{
|
||||
id = 1;
|
||||
}
|
||||
|
||||
for (int y = ypos, i = 0; y < (ypos + 5); y++, i++)
|
||||
{
|
||||
for (int x = xpos, k = 2; x < (xpos + 3); x++, k--)
|
||||
{
|
||||
if ((chars_font[id][i] >> k) & 0x1)
|
||||
{
|
||||
grid_add_pixel(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Brightness
|
||||
*
|
||||
* @param mybrightness brightness to be set [0..255]
|
||||
*/
|
||||
void LEDMatrix::set_brightness(uint8_t brightness)
|
||||
{
|
||||
_brightness = brightness;
|
||||
_neomatrix->setBrightness(_brightness);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calc estimated current (mA) for one pixel with the given color and brightness
|
||||
*
|
||||
* @param color 24bit color value of the pixel for which the current should be calculated
|
||||
* @return the current in mA
|
||||
*/
|
||||
uint16_t LEDMatrix::_calc_estimated_led_current(uint32_t color)
|
||||
{
|
||||
// extract rgb values
|
||||
uint8_t red = color >> 16 & UINT8_MAX;
|
||||
uint8_t green = color >> 8 & UINT8_MAX;
|
||||
uint8_t blue = color & UINT8_MAX;
|
||||
|
||||
// Linear estimation: 20mA for full brightness per LED
|
||||
// (calculation avoids float numbers)
|
||||
uint32_t estimated_current = (MAX_LED_CURRENT_MA * red) + (MAX_LED_CURRENT_MA * green) + (MAX_LED_CURRENT_MA * blue);
|
||||
estimated_current /= UINT8_MAX;
|
||||
estimated_current = (estimated_current * _brightness) / UINT8_MAX;
|
||||
|
||||
return estimated_current;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the current limit
|
||||
*
|
||||
* @param new_current_limit the total current limit for whole matrix
|
||||
*/
|
||||
void LEDMatrix::set_current_limit(uint16_t new_current_limit)
|
||||
{
|
||||
_current_limit = new_current_limit;
|
||||
}
|
||||
296
src/matrix/render_functions.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
#include <Arduino.h>
|
||||
#include "render_functions.h"
|
||||
#include "led_matrix.h"
|
||||
#include "udp_logger.h"
|
||||
|
||||
extern LEDMatrix led_matrix;
|
||||
|
||||
const String clock_chars_as_string = "ESRISTNFUNFVIERTELZEHNZWANZIGHVORPIKACHUNACHHALBMELFUNFMITTERNACHTEINSUWUZWEIDREIFUNVIERSECHSOBACHTSIEBENZWOLFZEHNEUNEUHR";
|
||||
|
||||
/**
|
||||
* @brief control the four minute indicator LEDs
|
||||
*
|
||||
* @param minutes minutes to be displayed [0 ... 59]
|
||||
* @param color 24bit color value
|
||||
*/
|
||||
void draw_minute_indicator(uint8_t minutes, uint32_t color)
|
||||
{
|
||||
// separate LEDs for minutes in an additional row
|
||||
switch (minutes % 5)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1000, color);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1100, color);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1110, color);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1111, color);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw the given sentence to the word clock
|
||||
*
|
||||
* @param message sentence to be displayed
|
||||
* @param color 24bit color value
|
||||
* @return int: 0 if successful, -1 if sentence not possible to display
|
||||
*/
|
||||
int show_string_on_clock(String message, uint32_t color)
|
||||
{
|
||||
String word = "";
|
||||
int last_letter_clock = 0;
|
||||
int word_position = 0;
|
||||
int idx = 0;
|
||||
|
||||
// add space on the end of message for splitting
|
||||
message = message + " ";
|
||||
|
||||
// empty the target grid
|
||||
led_matrix.flush();
|
||||
|
||||
while (true)
|
||||
{
|
||||
// extract next word from message
|
||||
word = split(message, ' ', idx);
|
||||
idx++;
|
||||
|
||||
if (word.length() > 0)
|
||||
{
|
||||
// find word in clock string
|
||||
word_position = clock_chars_as_string.indexOf(word, last_letter_clock);
|
||||
|
||||
if (word_position >= 0)
|
||||
{
|
||||
// word found on clock -> enable leds in targetgrid
|
||||
for (unsigned int i = 0; i < word.length(); i++)
|
||||
{
|
||||
unsigned int x = (word_position + i) % MATRIX_WIDTH;
|
||||
unsigned int y = (word_position + i) / MATRIX_WIDTH;
|
||||
led_matrix.grid_add_pixel(x, y, color);
|
||||
}
|
||||
// remember end of the word on clock
|
||||
last_letter_clock = word_position + word.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
// word is not possible to show on clock
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else // end - no more word in message
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // return success
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts the given time as sentence (String)
|
||||
*
|
||||
* @param hours hours of the time value
|
||||
* @param minutes minutes of the time value
|
||||
* @return String time as sentence
|
||||
*/
|
||||
String time_to_string(uint8_t hours, uint8_t minutes)
|
||||
{
|
||||
String message = "ES IST "; // first two words
|
||||
|
||||
// show minutes
|
||||
if (minutes >= 5 && minutes < 10)
|
||||
{
|
||||
message += "FUNF NACH ";
|
||||
}
|
||||
else if (minutes >= 10 && minutes < 15)
|
||||
{
|
||||
message += "ZEHN NACH ";
|
||||
}
|
||||
else if (minutes >= 15 && minutes < 20)
|
||||
{
|
||||
message += "VIERTEL NACH ";
|
||||
}
|
||||
else if (minutes >= 20 && minutes < 25)
|
||||
{
|
||||
message += "ZWANZIG NACH ";
|
||||
}
|
||||
else if (minutes >= 25 && minutes < 30)
|
||||
{
|
||||
message += "FUNF VOR HALB ";
|
||||
}
|
||||
else if (minutes >= 30 && minutes < 35)
|
||||
{
|
||||
message += "HALB ";
|
||||
}
|
||||
else if (minutes >= 35 && minutes < 40)
|
||||
{
|
||||
message += "FUNF NACH HALB ";
|
||||
}
|
||||
else if (minutes >= 40 && minutes < 45)
|
||||
{
|
||||
message += "ZWANZIG VOR ";
|
||||
}
|
||||
else if (minutes >= 45 && minutes < 50)
|
||||
{
|
||||
message += "VIERTEL VOR ";
|
||||
}
|
||||
else if (minutes >= 50 && minutes < 55)
|
||||
{
|
||||
message += "ZEHN VOR ";
|
||||
}
|
||||
else if (minutes >= 55 && minutes < 60)
|
||||
{
|
||||
message += "FUNF VOR ";
|
||||
}
|
||||
|
||||
// increment hour when 25 minutes of an hour have passed
|
||||
if (minutes >= 25)
|
||||
{
|
||||
hours++;
|
||||
}
|
||||
|
||||
// convert hours to 12h format
|
||||
if (hours > 12) // 24h -> 12h, except 12h
|
||||
{
|
||||
hours -= 12;
|
||||
}
|
||||
|
||||
// show hours
|
||||
switch (hours)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (minutes >= 0 && minutes < 5)
|
||||
{
|
||||
message += "MITTERNACHT ";
|
||||
}
|
||||
else
|
||||
{
|
||||
message += "ZWOLF ";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
message += "EIN";
|
||||
message += (minutes > 4) ? "S " : " "; // add "S" if needed
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
message += "ZWEI ";
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
message += "DREI ";
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
message += "VIER ";
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
message += "FUNF ";
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
message += "SECHS ";
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
message += "SIEBEN ";
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
message += "ACHT ";
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
message += "NEUN ";
|
||||
break;
|
||||
}
|
||||
case 10:
|
||||
{
|
||||
message += "ZEHN ";
|
||||
break;
|
||||
}
|
||||
case 11:
|
||||
{
|
||||
message += "ELF ";
|
||||
break;
|
||||
}
|
||||
case 12:
|
||||
{
|
||||
message += "ZWOLF ";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((minutes < 5) && (hours != 0))
|
||||
{
|
||||
message += "UHR ";
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Splits a string at given character and return specified element
|
||||
*
|
||||
* @param s string to split
|
||||
* @param parser separating character
|
||||
* @param index index of the element to return
|
||||
* @return String
|
||||
*/
|
||||
String split(String s, char parser, int index)
|
||||
{
|
||||
String rs = "";
|
||||
int parser_cnt = 0;
|
||||
int r_from_index = 0, r_to_index = -1;
|
||||
|
||||
while (index >= parser_cnt)
|
||||
{
|
||||
r_from_index = r_to_index + 1;
|
||||
r_to_index = s.indexOf(parser, r_from_index);
|
||||
if (index == parser_cnt)
|
||||
{
|
||||
if (r_to_index == 0 || r_to_index == -1)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return s.substring(r_from_index, r_to_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
parser_cnt++;
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
1094
src/wordclock_esp32.cpp
Normal file
230
src/wrapper/littlefs_wrapper.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
// ****************************************************************
|
||||
// Arduino IDE Tab Esp32 Filesystem Manager spezifisch sortiert Modular
|
||||
// created: Jens Fleischer, 2023-03-26
|
||||
// last mod: Jens Fleischer, 2024-06-03
|
||||
// For more information visit: https://fipsok.de
|
||||
// ****************************************************************
|
||||
// Hardware: Esp32
|
||||
// Software: Esp32 Arduino Core 2.0.6 - 3.0.0
|
||||
// Getestet auf: ESP32 NodeMCU-32s
|
||||
/******************************************************************
|
||||
Copyright (c) 2023 Jens Fleischer. All rights reserved.
|
||||
|
||||
This file is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
*******************************************************************/
|
||||
// Diese Version von LittleFS sollte als Tab eingebunden werden.
|
||||
// #include <LittleFS.h> #include <WebServer.h> müssen im Haupttab aufgerufen werden
|
||||
// Die Funktionalität des ESP32 Webservers ist erforderlich.
|
||||
// "webserver.onNotFound()" darf nicht im Setup des ESP32 Webserver stehen.
|
||||
// Die Funktion "setupFS();" muss im Setup aufgerufen werden.
|
||||
/**************************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "littlefs_wrapper.h"
|
||||
#include <WebServer.h>
|
||||
#ifdef USE_LittleFS
|
||||
#define SPIFFS LittleFS
|
||||
#include <LittleFS.h>
|
||||
#else
|
||||
#include <SPIFFS.h>
|
||||
#endif
|
||||
#include <detail/RequestHandlersImpl.h>
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
|
||||
extern WebServer webserver;
|
||||
|
||||
const char WARNING[] PROGMEM = R"(<h2>LittleFS konnte nicht initialisiert werden!)";
|
||||
const char HELPER[] PROGMEM = R"(<form method="POST" action="/upload" enctype="multipart/form-data">
|
||||
<input type="file" name="[]" multiple><button>Upload</button></form>Lade die fs.html hoch.)";
|
||||
|
||||
void format_fs()
|
||||
{ // Formatiert das Filesystem
|
||||
LittleFS.format();
|
||||
send_response();
|
||||
}
|
||||
|
||||
void send_response()
|
||||
{
|
||||
webserver.sendHeader("Location", "fs.html");
|
||||
webserver.send(303, "message/http");
|
||||
}
|
||||
|
||||
const String format_bytes(size_t const &bytes)
|
||||
{ // lesbare Anzeige der Speichergrößen
|
||||
return bytes < 1024 ? static_cast<String>(bytes) + " Byte" : bytes < 1048576 ? static_cast<String>(bytes / 1024.0) + " KB"
|
||||
: static_cast<String>(bytes / 1048576.0) + " MB";
|
||||
}
|
||||
|
||||
bool handle_list()
|
||||
{ // Senden aller Daten an den Client
|
||||
File root = LittleFS.open("/");
|
||||
using namespace std;
|
||||
using records = tuple<String, String, size_t, time_t>;
|
||||
list<records> dirList;
|
||||
while (File f = root.openNextFile())
|
||||
{ // Ordner und Dateien zur Liste hinzufügen
|
||||
if (f.isDirectory())
|
||||
{
|
||||
uint8_t ran{0};
|
||||
File fold = LittleFS.open(static_cast<String>("/") + f.name());
|
||||
while (File f = fold.openNextFile())
|
||||
{
|
||||
ran++;
|
||||
dirList.emplace_back(fold.name(), f.name(), f.size(), f.getLastWrite());
|
||||
}
|
||||
if (!ran)
|
||||
dirList.emplace_back(fold.name(), "", 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dirList.emplace_back("", f.name(), f.size(), f.getLastWrite());
|
||||
}
|
||||
}
|
||||
dirList.sort([](const records &f, const records &l) { // Dateien sortieren
|
||||
if (webserver.arg(0) == "1")
|
||||
{ // nach Größe
|
||||
return get<2>(f) > get<2>(l);
|
||||
}
|
||||
else if (webserver.arg(0) == "2")
|
||||
{ // nach Zeit
|
||||
return get<3>(f) > get<3>(l);
|
||||
}
|
||||
else
|
||||
{ // nach Name
|
||||
for (uint8_t i = 0; i < 31; i++)
|
||||
{
|
||||
if (tolower(get<1>(f)[i]) < tolower(get<1>(l)[i]))
|
||||
return true;
|
||||
else if (tolower(get<1>(f)[i]) > tolower(get<1>(l)[i]))
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
dirList.sort([](const records &f, const records &l) { // Ordner sortieren
|
||||
if (get<0>(f)[0] != 0x00 || get<0>(l)[0] != 0x00)
|
||||
{
|
||||
for (uint8_t i = 0; i < 31; i++)
|
||||
{
|
||||
if (tolower(get<0>(f)[i]) < tolower(get<0>(l)[i]))
|
||||
return true;
|
||||
else if (tolower(get<0>(f)[i]) > tolower(get<0>(l)[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
String temp = "[";
|
||||
for (auto &t : dirList)
|
||||
{
|
||||
if (temp != "[")
|
||||
temp += ',';
|
||||
temp += "{\"folder\":\"" + get<0>(t) + "\",\"name\":\"" + get<1>(t) + "\",\"size\":\"" + format_bytes(get<2>(t)) + "\",\"time\":\"" + get<3>(t) + "\"}";
|
||||
}
|
||||
temp += ",{\"usedBytes\":\"" + format_bytes(LittleFS.usedBytes()) + // Berechnet den verwendeten Speicherplatz
|
||||
"\",\"totalBytes\":\"" + format_bytes(LittleFS.totalBytes()) + // Zeigt die Größe des Speichers
|
||||
"\",\"freeBytes\":\"" + (LittleFS.totalBytes() - LittleFS.usedBytes()) + "\"}]"; // Berechnet den freien Speicherplatz
|
||||
webserver.send(200, "application/json", temp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void delete_files(const String &path)
|
||||
{
|
||||
DEBUG_F("delete: %s\n", path.c_str());
|
||||
if (!LittleFS.remove("/" + path))
|
||||
{
|
||||
File root = LittleFS.open(path);
|
||||
while (String filename = root.getNextFileName())
|
||||
{
|
||||
LittleFS.remove(filename);
|
||||
LittleFS.rmdir(path);
|
||||
if (filename.length() < 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool handle_file(String &path)
|
||||
{
|
||||
if (webserver.hasArg("new"))
|
||||
{
|
||||
String folderName{webserver.arg("new")};
|
||||
for (auto &c : {34, 37, 38, 47, 58, 59, 92})
|
||||
for (auto &e : folderName)
|
||||
if (e == c)
|
||||
e = 95; // Ersetzen der nicht erlaubten Zeichen
|
||||
DEBUG_F("Creating Dir: %s\n", folderName.c_str());
|
||||
LittleFS.mkdir("/" + folderName);
|
||||
}
|
||||
if (webserver.hasArg("sort"))
|
||||
return handle_list();
|
||||
if (webserver.hasArg("delete"))
|
||||
{
|
||||
delete_files(webserver.arg("delete"));
|
||||
send_response();
|
||||
return true;
|
||||
}
|
||||
if (!LittleFS.exists("/fs.html"))
|
||||
webserver.send(200, "text/html", LittleFS.begin(true) ? HELPER : WARNING); // ermöglicht das hochladen der fs.html
|
||||
if (path.endsWith("/"))
|
||||
path += "index.html";
|
||||
if (path == "/spiffs.html")
|
||||
send_response(); // Umleitung für den Admin Tab
|
||||
File f = LittleFS.open(path, "r");
|
||||
String eTag = String(f.getLastWrite(), HEX); // Verwendet den Zeitstempel der Dateiänderung, um den ETag zu erstellen.
|
||||
if (webserver.header("If-None-Match") == eTag)
|
||||
{
|
||||
webserver.send(304);
|
||||
return true;
|
||||
}
|
||||
webserver.sendHeader("ETag", eTag);
|
||||
return LittleFS.exists(path) ? webserver.streamFile(f, StaticRequestHandler::getContentType(path)) : false;
|
||||
}
|
||||
|
||||
void setup_fs()
|
||||
{ // Funktionsaufruf "setupFS();" muss im Setup eingebunden werden
|
||||
LittleFS.begin(true);
|
||||
webserver.on("/format", format_fs);
|
||||
webserver.on("/upload", HTTP_POST, send_response, handle_upload);
|
||||
String path = webserver.urlDecode(webserver.uri());
|
||||
webserver.onNotFound([&path]()
|
||||
{
|
||||
if (!handle_file(path)) {
|
||||
webserver.send(404, "text/html", "Page Not Found: " + path);
|
||||
} });
|
||||
const char *headerkeys[] = {"If-None-Match"}; // "If-None-Match" HTTP-Anfrage-Header einfügen
|
||||
webserver.collectHeaders(headerkeys, static_cast<size_t>(1)); // für ETag Unterstüzung: vor Core Version 3.x.x.
|
||||
}
|
||||
|
||||
void handle_upload()
|
||||
{ // Dateien ins Filesystem schreiben
|
||||
static File fsUploadFile;
|
||||
HTTPUpload &upload = webserver.upload();
|
||||
if (upload.status == UPLOAD_FILE_START)
|
||||
{
|
||||
if (upload.filename.length() > 31)
|
||||
{ // Dateinamen kürzen
|
||||
upload.filename = upload.filename.substring(upload.filename.length() - 31, upload.filename.length());
|
||||
}
|
||||
DEBUG_F("handleFileUpload Name: /%s\n", upload.filename.c_str());
|
||||
fsUploadFile = LittleFS.open("/" + webserver.arg(0) + "/" + webserver.urlDecode(upload.filename), "w");
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_WRITE)
|
||||
{
|
||||
DEBUG_F("handleFileUpload Data: %u\n", upload.currentSize);
|
||||
fsUploadFile.write(upload.buf, upload.currentSize);
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_END)
|
||||
{
|
||||
DEBUG_F("handleFileUpload Size: %u\n", upload.totalSize);
|
||||
fsUploadFile.close();
|
||||
}
|
||||
}
|
||||
11
test/README
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||