[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-mdb] branch master updated: add images for errors
From: |
gnunet |
Subject: |
[taler-taler-mdb] branch master updated: add images for errors |
Date: |
Sat, 13 Jan 2024 19:24:56 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository taler-mdb.
The following commit(s) were added to refs/heads/master by this push:
new b31d2af add images for errors
b31d2af is described below
commit b31d2af5910632ac5d845df24abfe278d50bdf6f
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Sat Jan 13 19:24:52 2024 +0100
add images for errors
---
contrib/Makefile.am | 23 ++
contrib/png/backend-auth-failure.png | Bin 0 -> 214380 bytes
contrib/png/backend-dns-resolution-failure.png | Bin 0 -> 39978 bytes
contrib/png/backend-no-webserver.png | Bin 0 -> 36708 bytes
contrib/png/backend-unreachable.png | Bin 0 -> 35611 bytes
contrib/png/backend-x509-cert-bad.png | Bin 0 -> 30694 bytes
contrib/png/child-died.png | Bin 0 -> 29994 bytes
contrib/png/err-num-read-fail.png | Bin 0 -> 27458 bytes
contrib/png/maintenance.png | Bin 0 -> 28329 bytes
contrib/png/no-ip.png | Bin 0 -> 26469 bytes
contrib/svg/backend-auth-failure.svg | 71 ++++++
contrib/svg/backend-dns-resolution-failure.svg | 71 ++++++
contrib/svg/backend-no-webserver.svg | 71 ++++++
contrib/svg/backend-unreachable.svg | 126 ++++++++++
contrib/svg/backend-x509-cert-bad.svg | 71 ++++++
contrib/svg/child-died.svg | 71 ++++++
contrib/svg/err-num-read-fail.svg | 71 ++++++
contrib/svg/maintenance.svg | 71 ++++++
contrib/svg/no-ip.svg | 71 ++++++
contrib/taler-mdb-show.sh | 41 ++++
debian/taler-mdb.postrm.debhelper | 2 +-
debian/taler-mdb.service | 2 +-
debian/taler-mdb.substvars | 2 +-
src/Makefile.am | 10 +-
src/taler-mdb-display.c | 312 +++++++++++++++++++++++++
25 files changed, 1082 insertions(+), 4 deletions(-)
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index ade84a2..01065de 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1,9 +1,32 @@
SUBDIRS = .
+imgdir=$(datadir)/taler/mdb
+imgdir_DATA = \
+ png/backend-auth-failure.png \
+ png/backend-no-webserver.png \
+ png/backend-x509-cert-bad.png \
+ png/err-num-read-fail.png \
+ png/no-ip.png \
+ png/backend-dns-resolution-failure.png \
+ png/backend-unreachable.png \
+ png/child-died.png \
+ png/maintenance.png
+
bin_SCRIPTS = \
taler-mdb-network-check.sh
EXTRA_DIST = \
$(bin_SCRIPTS) \
+ $(imgdir_DATA) \
+ svg/backend-auth-failure.svg \
+ svg/backend-no-webserver.svg \
+ svg/backend-x509-cert-bad.svg \
+ svg/err-num-read-fail.svg \
+ svg/no-ip.svg \
+ svg/backend-dns-resolution-failure.svg \
+ svg/backend-unreachable.svg \
+ svg/child-died.svg \
+ svg/maintenance.svg \
+ taler-machine.penpot \
uncrustify.cfg \
uncrustify_precommit
diff --git a/contrib/png/backend-auth-failure.png
b/contrib/png/backend-auth-failure.png
new file mode 100644
index 0000000..bacb351
Binary files /dev/null and b/contrib/png/backend-auth-failure.png differ
diff --git a/contrib/png/backend-dns-resolution-failure.png
b/contrib/png/backend-dns-resolution-failure.png
new file mode 100644
index 0000000..7cb510e
Binary files /dev/null and b/contrib/png/backend-dns-resolution-failure.png
differ
diff --git a/contrib/png/backend-no-webserver.png
b/contrib/png/backend-no-webserver.png
new file mode 100644
index 0000000..9d31220
Binary files /dev/null and b/contrib/png/backend-no-webserver.png differ
diff --git a/contrib/png/backend-unreachable.png
b/contrib/png/backend-unreachable.png
new file mode 100644
index 0000000..8e3494c
Binary files /dev/null and b/contrib/png/backend-unreachable.png differ
diff --git a/contrib/png/backend-x509-cert-bad.png
b/contrib/png/backend-x509-cert-bad.png
new file mode 100644
index 0000000..41fc0f4
Binary files /dev/null and b/contrib/png/backend-x509-cert-bad.png differ
diff --git a/contrib/png/child-died.png b/contrib/png/child-died.png
new file mode 100644
index 0000000..95ff3e3
Binary files /dev/null and b/contrib/png/child-died.png differ
diff --git a/contrib/png/err-num-read-fail.png
b/contrib/png/err-num-read-fail.png
new file mode 100644
index 0000000..0cc11bb
Binary files /dev/null and b/contrib/png/err-num-read-fail.png differ
diff --git a/contrib/png/maintenance.png b/contrib/png/maintenance.png
new file mode 100644
index 0000000..b2005c7
Binary files /dev/null and b/contrib/png/maintenance.png differ
diff --git a/contrib/png/no-ip.png b/contrib/png/no-ip.png
new file mode 100644
index 0000000..cb09b4b
Binary files /dev/null and b/contrib/png/no-ip.png differ
diff --git a/contrib/svg/backend-auth-failure.svg
b/contrib/svg/backend-auth-failure.svg
new file mode 100644
index 0000000..12140c7
--- /dev/null
+++ b/contrib/svg/backend-auth-failure.svg
@@ -0,0 +1,71 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-2d5b5ebd-d89e-8002-8003-bc36eb0be5d7" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-2d5b5ebd-d89e-8002-8003-bc36eb0be5d7"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d89e-8002-8003-bc36eb0be5d7-rumext-id-12"><rect rx="0"
ry="0" x="0" y="0" width="480" height="360" transform="matrix(1.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-2d5b5ebd-d89e-8002-8003-bc36eb0be5d7-rumext-id-12)"
fill="none"><clipPath class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd- [...]
\ No newline at end of file
diff --git a/contrib/svg/backend-dns-resolution-failure.svg
b/contrib/svg/backend-dns-resolution-failure.svg
new file mode 100644
index 0000000..8f44ed4
--- /dev/null
+++ b/contrib/svg/backend-dns-resolution-failure.svg
@@ -0,0 +1,71 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-2d5b5ebd-d89e-8002-8003-bc3b31c430c8" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-2d5b5ebd-d89e-8002-8003-bc3b31c430c8"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d89e-8002-8003-bc3b31c430c8-rumext-id-1"><rect rx="0"
ry="0" x="0" y="0" width="480" height="360" transform="matrix(1.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-2d5b5ebd-d89e-8002-8003-bc3b31c430c8-rumext-id-1)"
fill="none"><clipPath class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d8 [...]
\ No newline at end of file
diff --git a/contrib/svg/backend-no-webserver.svg
b/contrib/svg/backend-no-webserver.svg
new file mode 100644
index 0000000..0283a3e
--- /dev/null
+++ b/contrib/svg/backend-no-webserver.svg
@@ -0,0 +1,71 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-2d5b5ebd-d89e-8002-8003-bc35b0c36344" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-2d5b5ebd-d89e-8002-8003-bc35b0c36344"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d89e-8002-8003-bc35b0c36344-rumext-id-21"><rect rx="0"
ry="0" x="0" y="0" width="480" height="360" transform="matrix(1.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-2d5b5ebd-d89e-8002-8003-bc35b0c36344-rumext-id-21)"
fill="none"><clipPath class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd- [...]
\ No newline at end of file
diff --git a/contrib/svg/backend-unreachable.svg
b/contrib/svg/backend-unreachable.svg
new file mode 100644
index 0000000..95ccfb8
--- /dev/null
+++ b/contrib/svg/backend-unreachable.svg
@@ -0,0 +1,126 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-2d5b5ebd-d89e-8002-8003-bc3446c736f9" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* cyrillic-ext */
+@font-face {
+ font-family: 'JetBrains Mono';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAARsABAAAAAACMwAAAQRAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoBmA/U1RBVF4AXBEICoRkg3oLGgABNgIkAy4EIAWFAAeBAwwHGy8HyI7Cca8UYSlFWGJzMUTEQ/1+r2f33Q+oAgAFVkiO0LMiG92pzNTWmEogIUHV6LrA3+vU9yUZFWCUyyYpAGzHxMo5cgl5YpzSCUM8NWtp6sXT3zttbOqD96hLoIAijvawNWhs2hMogzEXBdQFssAy6shdkO6VPDXsvEGgCwihJoRAvaBtQgx0vqymBYQK7HoBasgsSYO9G/Rcy7nAD9pML9mFjgKPfId1ALiW9o7HQAUNkLR49NmAP3T1LIDvcKYsVP8XB0G1hXJmAH2cGQG5lOOYwRNCU2IAjgXYW7OFQ8CTV1oH8oewJAxfJWQEAAQqZBDoKEB+BpBwZj
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'JetBrains Mono';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABSoABAAAAAALZwAABRHAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoEUG4JCHIFaBmA/U1RBVF4AgjQRCAq6aK19C4IEAAE2AiQDg3gEIAWFAAeIdgwHGxUlFeOYJbBxAI/ZefqIqs3iiv8/Jchx1MK1Hj6QCjtsqbzREj7Uu8Vx4pSRrqjmog/tOGN3PfRXFIaNPCUhbk3yIME013ZitMnf2OPLamGnvJSoHMue4TQeqDV+b/f2ixpqiWQm3a2TaXSGZBIKQzTpane0ls7s7gPdE1EA4QKMMiqqbEyFrGs1kCcjOjxu6582F5E4AxChZTD2BkxKGCX4gI1UsRK9DL0of1R4P9u7+5HGfrX3OwbnhVDfo1ShNOG0//9r5nsDbebe/2ezwChUT4Wa4SIYk9iMLSXbsgQUHjkAHhu73EgVO0u+qBHYhiz4TghZsf
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek */
+@font-face {
+ font-family: 'JetBrains Mono';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABB4ABAAAAAAI2AAABAXAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGnwbHhyBWgZgP1NUQVReAIFKEQgKq3yjDQuBYAABNgIkA4M4BCAFhQAHhzAMBxv5HLOiTpNW7pD9lwvchIG1Lpgw0C5JhmaFsVEsKmGKMewlOrSU5cmvTnzOOQPGOx3KexV+GN3p0I93joDyL/qeeXt0BDFUBEagIjOEkEIR5Ojui1s7f69T3/syhYBMCpCJ5SQmUGyd8w2SCwhTeSzfDivgXB4L/dP9b+aefZ9fu0QhJFwc6AOwtOFxW/+0uWv0fyuJlkEvihEWc/aATS4ygqvW30H808Xe/L0SjiMo4e2gXehKDiTXjI87mldKHlwBxMd4sEhn7sqnhxmdzQoANgUVjcjWIxZVSG6lNuT/AECddMg+31pq79/clMEFyEa4pCpOV83szt
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'JetBrains Mono';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAA8AABAAAAAALJAAAA6fAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGnYbhWocghYGYD9TVEFUXgCCbBEICrBAp2wLgjIAATYCJAOEHAQgBYUAB4w9DAcb7SUzo3aUk7oOwf/hwBQZJp2w6h8GxJG6TTswGCNFVinYG8lm36Y5Wwrq620Hiodu88UWwvRjNBxCLu1AUZ8j17L3P6mDsd5az9cxHp7f339r7/M+PEpkgpHMPJOUXX+bSVOSEAGEJN6fp23fn2EMdGmjoA1kUAQbELhUiyI8TGy0iTdWYLId4d/gRxfCGJMpWvToat1c/ZQ+xAAoS9OhRa/Y4//zpbk3ubZ/W16va0fs5+wHACEzOtuzGztAp6kDhqyuUIjnnxQIGiktsqW1oS8KpLTtPHrpuOaMT619aaen+x1P7s+xCh/JFa53Wd4aH3Wqfw/0QP
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'JetBrains Mono';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABukABAAAAAAS6AAABtCAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoIkG4ksHIMyBmA/U1RBVF4AhGYRCArddMwQC4NuAAE2AiQDhx4EIAWFAAeQVwwHG7M/BdzxsHHAYHB5TVFULQLJ/9fkxhhag2p1D3qSvMiMZHVWrza7ig2lYchKm4FzGC/zgrUkjl1wOOguDsaFfM0Py8lyv5LAwHlihZv4JDR+r8HtyMosTVjuERr7JJeHf8bx3ve+lYgGaHJy/XlLC2VVdYvLO0twSVJUg3+e31Z/Llhg1ZQYCComCP14vPcQRUDBpyg+icHGKKadaSed2Wknqp2K7WbbmXV3/X8zBen/xCR3XrC+0kS1QsPtL81VyXS6kMwcIap7i4VdPmL9z63t2kdUqAA1q0P+n+dk920jiTTjmDo+DjiMvPP//3sXdeJEY0yzAG
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'JetBrains Mono';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAFJgABAAAAAA4hAAAFH8AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoEUG4ZQHIGacgZgP1NUQVReAIUqEQgKgdxkgaxNC4YYAAE2AiQDjB4EIAWFAAejFgwHG8fFB8Tb90hAdwCkblfXTo1ECBsHAbDjs2cGgo0TQOB5yP7/vyeoMYbwbgcoNqtpIlQEYUlYElazCmph0RVdm7qIwk/shy9ruey0yhG+ZKISeRi+GSzGzpPpeIHb7aD8PEtS/nHRORqGOrrXBlt2Uv13SNhhl6tnqYhoMTMZfDVYKOxRfM2jMIYO7kb//JsujEx5ydtdvhfQdr9rlu+SEwkSHZ881orhYxO3PlFyNWC3YEvozY2nxfNzNvt+jBQ8Ff8ED3gFPUowOcRyXDAJIlJTpS5GoO/b763q9o9mzSoLJByQMKtzolbptQ6NB9TAM68f8f
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-2d5b5ebd-d89e-8002-8003-bc3446c736f9"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d89e-8002-8003-bc3446c736f9-rumext-id-46"><rect rx="0"
ry="0" x="0" y="0" width="480" height="360" transform="matrix(1.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-2d5b5ebd-d89e-8002-8003-bc3446c736f9-rumext-id-46)"
fill="none"><clipPath class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd- [...]
\ No newline at end of file
diff --git a/contrib/svg/backend-x509-cert-bad.svg
b/contrib/svg/backend-x509-cert-bad.svg
new file mode 100644
index 0000000..bf9ee2b
--- /dev/null
+++ b/contrib/svg/backend-x509-cert-bad.svg
@@ -0,0 +1,71 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-2d5b5ebd-d89e-8002-8003-bc361a39c911" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-2d5b5ebd-d89e-8002-8003-bc361a39c911"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d89e-8002-8003-bc361a39c911-rumext-id-64"><rect rx="0"
ry="0" x="0" y="0" width="480" height="360" transform="matrix(1.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-2d5b5ebd-d89e-8002-8003-bc361a39c911-rumext-id-64)"
fill="none"><clipPath class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd- [...]
\ No newline at end of file
diff --git a/contrib/svg/child-died.svg b/contrib/svg/child-died.svg
new file mode 100644
index 0000000..5f7fe50
--- /dev/null
+++ b/contrib/svg/child-died.svg
@@ -0,0 +1,71 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-2d5b5ebd-d89e-8002-8003-bc3908030f86" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-2d5b5ebd-d89e-8002-8003-bc3908030f86"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d89e-8002-8003-bc3908030f86-rumext-id-55"><rect rx="0"
ry="0" x="0" y="0" width="480" height="360" transform="matrix(1.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-2d5b5ebd-d89e-8002-8003-bc3908030f86-rumext-id-55)"
fill="none"><clipPath class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd- [...]
\ No newline at end of file
diff --git a/contrib/svg/err-num-read-fail.svg
b/contrib/svg/err-num-read-fail.svg
new file mode 100644
index 0000000..2e4f52b
--- /dev/null
+++ b/contrib/svg/err-num-read-fail.svg
@@ -0,0 +1,71 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-7abbe548-0101-8074-8003-bc3c29bacfd3" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-7abbe548-0101-8074-8003-bc3c29bacfd3"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-7abbe548-0101-8074-8003-bc3c29bacfd3-rumext-id-73"><rect rx="0"
ry="0" x="0" y="0" width="480" height="360" transform="matrix(1.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-7abbe548-0101-8074-8003-bc3c29bacfd3-rumext-id-73)"
fill="none"><clipPath class="frame-clip-def frame-clip"
id="frame-clip-7abbe548- [...]
\ No newline at end of file
diff --git a/contrib/svg/maintenance.svg b/contrib/svg/maintenance.svg
new file mode 100644
index 0000000..c9899d1
--- /dev/null
+++ b/contrib/svg/maintenance.svg
@@ -0,0 +1,71 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-2d5b5ebd-d89e-8002-8003-bc38a7b7f398" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-2d5b5ebd-d89e-8002-8003-bc38a7b7f398"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d89e-8002-8003-bc38a7b7f398-rumext-id-29"><rect rx="0"
ry="0" x="0" y="0" width="480" height="360" transform="matrix(1.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-2d5b5ebd-d89e-8002-8003-bc38a7b7f398-rumext-id-29)"
fill="none"><clipPath class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd- [...]
\ No newline at end of file
diff --git a/contrib/svg/no-ip.svg b/contrib/svg/no-ip.svg
new file mode 100644
index 0000000..dd87818
--- /dev/null
+++ b/contrib/svg/no-ip.svg
@@ -0,0 +1,71 @@
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="480"
xmlns="http://www.w3.org/2000/svg" height="360"
id="screenshot-2d5b5ebd-d89e-8002-8003-bc3b4c5926e8" viewBox="0 0 480 360"
style="-webkit-print-color-adjust: exact;" fill="none" version="1.1"><style
data-loading="false">@font-face {
+ font-family: 'sourcesanspro';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff;base64,d09GRgABAAAAAHSMABQAAAABDCAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABvAAAAD4AAABQinOTf0ZGVE0AAAH8AAAAHAAAABxwkYDFR0RFRgAAAhgAAAAiAAAAJgAnARBHUE9TAAACPAAACzwAADXwmf/bv0dTVUIAAA14AAAA+gAAAa7khdupT1MvMgAADnQAAABXAAAAYGdamnRjbWFwAAAOzAAAAYkAAAHiSESmoGN2dCAAABBYAAAAVgAAAFYUww7lZnBnbQAAELAAAAGxAAACZVO0L6dnYXNwAAASZAAAAAgAAAAIAAAAEGdseWYAABJsAABQOgAAm1B0O5TbaGVhZAAAYqgAAAAxAAAANgkVq9doaGVhAABi3AAAAB8AAAAkDmAFi2htdHgAAGL8AAACOgAAA6h47lnNbG9jYQAAZTgAAAHIAAAB1smHp
[...]
+ }
+/* cyrillic-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAADvwABIAAAAAjVwAADuKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoFOG5JCHDYGYACCWAhUCYM8EQwKgegwgdA5C4NaABKBeAE2AiQDhzAEIAWCdAcgDIJJG1F+FdwYN3AeQFB+677abITtcRB8qCaK0k06uOD/rwlqyNg/1gG4OUtEGEGmirCEmqCnVGr8zsRmprTwyRyCfbliCOmQx9q6Mj5be/suy4CgRfxSwkp8rM+rmfWO0aAxlI/2bxhtsYiy9ZR3ZZiGPUfJ5eLCH0Og40B+5lS4+JZbREd3WtkRGvskl+f/s3v+f1b32tUPREaEUgQoBBjJsfAljRyMLk4N8XP7extjgFQJkkYTgjWLlAqleiNzwEBCpAY4YhuwTVIYgoyRGyKbgIgB0iHoB8XA+OZ8Ou2bGY00gAJL9liSUY6TeDNLnPx/QJA9Ln
[...]
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAACWcABIAAAAAWLAAACU5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobllYcNgZgAIIECFQJgzwRDAqBgWzzRAuCEAASgRQBNgIkA4QcBCAFgnQHIAyCSRtATxVsXGWGjQMMs+lnUBRVo81EUaPVpDXB/1+TmzJwD1T/qiCyZNisrEoqJdLUU4XdGFQhjzBlqe+erlaQaExxJzlQcKB465SpoPV52dI8GZeWGJIUaZVuemk76uNVowWj6Dl7XlNSpinpy1R//+CHMHBkVqDYZD5CSx/xEkR2/Fe927Mz/wxHZgogFOLL3jllJCU50T//nvXnJqmmwkDFJoWYDqR2oHRFf+0+Gd/y12qA5tatRDKsgSA2VhxVNl2DFql2TqkeY8jIjTIP+o4HxoNBSIVEjciRBq+PVWu2e4RzCU8YpmLECyEJFPCpR2O2y4d/ni
[...]
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+/* greek-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAAXMABIAAAAACeAAAAVwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiYbIBw2BmAANAhUCYM8EQwKg2iDSgsQABIUATYCJAMcBCAFgnQHIAyCSRt8CAieB2WbnmbLuYAwwpK8+iIe4P3r89wHDZaakNWCmB8R66SEWr+ILhpijnTqf6QAyyF8GVAOAPOWtmNg6llFXANTaQXCgXMubThOj6JRPCJsEWW3o1/4wX411uruvta/9FF8Zz50qenu3hVxmf4QIi1dRSzhkcR0SqA1QoiwzI2uAUbffgtBpA0YCssEQRChiaaAgMpAFvDsmKQshIEEer1l/u1J0Sbi8P6OJsQc3VHd6N0nlHe1MAhFbvPNcXJVWKNNekPqCYVx/lj8nqMi5BY4Pd6hectSY5E2Lll8SMf/HJXfEKEOfCtEMjEFBEHtpSkbjBK4aB1MIE
[...]
+ unicode-range: U+1F00-1FFF;
+}
+/* greek */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABvIABIAAAAAOYgAABtmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbjEocNgZgAIFkCFQJgzwRDArPdMcZC4FIABJwATYCJAODDAQgBYJ0ByAMgkkbLzMV3Bg3cB5AgtL+dFGUC8ojwf9fE9SQsQftHoablcBAJCnZiWWrVQuV5mlVJ2ZKaJa1O4xgpZOeStdtJqxoMWTv3rvjdJiEUBrhQCzjWKrrzr+v3IEvgtjCHD1r8RMqj2DUbHUyl4hbe5lIDkAEEv7BTsC+xxGuHLLDJzwiHqGlj3jhedKj/3NHyYLOPksVyBbSB1V0wvzv2n/ewGQCNDPJ4CNcyi6XXCtkT9WCK7lfZQjUdwVhSH0hX5Qr6naI5na/NTmQyDBHdEm3iAEoMEJG1gSjB2IwqiywRvWIHoLRPK+/h3l+b/sICQgQDouxxGMEJJh57K
[...]
+ unicode-range: U+0370-03FF;
+}
+/* vietnamese */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAABW4ABIAAAAANeQAABVYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjQbhlocNgZgAIEACFQJgzwRDArNRMZyC4IWABKBFAE2AiQDhCgEIAWCdAcgDIJJG0QwsxE2bBxAgN2rQPJ/ODCHzPnAWwWN2o42Fh2ljaWNtCCX3HjNpZ/jxeLZb4tm/kHiZ77mziCxZzy0cd8wTRJCiqDsSRqOR0gyC8+j3ffnZpLMGvMWRPfZ/87uBFagisZuqfzAb7P3+QVYiFknMxMjYpGImbB2t2HH1kadsmRrWXFGrkqX5TLxP6cqy2soa6trO4GdCmCmXToDmCtuKXj/ZyBcBEwQ3fvOvtv7qRSwgAQ4mq6lFACOaaw0uy1ldv9zuuKQSO46+Dl0Do9Oylz/M5dCGNyOU6+ueMEx1eTggIMuIVsO8utrIbVMv07ZhkxjhvHZUs
[...]
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323,
U+0329, U+1EA0-1EF9, U+20AB;
+}
+/* latin-ext */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAC5gABIAAAAAcywAAC36AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAbjgwcgTAGYACDFAhUCYM8EQwKgbckgaVCC4N6ABKCCAE2AiQDh3AEIAWCdAcgDIJJGxxnJWybRvHgPADRiPpto6hJe1QiimDjIEDErxz8/+fkZAyBOmNq3n64RJGVYTsuMvUITcoKDzKbnypbeOMbTMui6C1taW9RKNHcVufFfHmORoTFgPXPgSnw9b5+VMOftv6L4lsP7Nfim5v2Fg/56vZtj9Xi2X1oL6wcCiUVkSRoowcKbqtiCxv72hEa+ySXh8iOvlc9XT27H+cQIKJzkEqRldoRFJE77dfP5dv9SY4YVAl4fHV0YXyVAjauylb1hue32fuUFViBOF1ahVEzCqsHioGKGBg5nZvTKYoJ6sSq6UQbF4o9l+mqzt3O2voMgP//fv
[...]
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src:
url(data:font/woff2;base64,d09GMgABAAAAAD2AABIAAAAAjnQAAD0aAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmQbmWQchV4GYACDIAhUCYM8EQwKgdx8gcR7C4QKABKCEAE2AiQDiBAEIAWCdAcgDIJJGzN/JezYiwK6AzihqSaqkQj7NFrlfHQg9jiQuO4X/P/nBM1EBrn5JK11TkWFUIRFnUFrFNvrPcp4DjlYevVgA0nxppzrUq2UwfojRitCYK27fdpSUHxF/dDCWlx/V1u8Guv6n+CPBeCi/9HtCEOUiBJRQoED6JkYbb+j7GNtuz+jRvSEZ/S00A7a2OhRipW6qzPAnRzRiJOHcO0f/0wy2b1bAsXMrrbsmBUhK0BVxx9efp7f5p/73qPEAETsPwy00f6KxdJqDIyKVRq5FmPZzFW5bKs2e9nKAG2zQ0Rdq2ivdNPVuxmRGFE4CwsLG8FAULHABE
[...]
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+</style><g id="shape-2d5b5ebd-d89e-8002-8003-bc3b4c5926e8"><defs><clipPath
class="frame-clip-def frame-clip"
id="frame-clip-2d5b5ebd-d89e-8002-8003-bc3b4c5926e8-rumext-id-38"><rect rx="0"
ry="0" x="0" y="0" width="479.9999999999999" height="360"
transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000,
0.000000)"/></clipPath></defs><g
clip-path="url(#frame-clip-2d5b5ebd-d89e-8002-8003-bc3b4c5926e8-rumext-id-38)"
fill="none"><clipPath class="frame-clip-def frame-clip" id="frame- [...]
\ No newline at end of file
diff --git a/contrib/taler-mdb-show.sh b/contrib/taler-mdb-show.sh
new file mode 100644
index 0000000..a050002
--- /dev/null
+++ b/contrib/taler-mdb-show.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+set -eu
+
+function cleanup()
+{
+ taler-mdb-display-off -c "$CONF" -i
+ exit 0
+}
+
+trap cleanup EXIT
+
+CONF="$HOME/.config/taler.conf"
+
+# Parse command-line options
+while getopts ':c:h' OPTION; do
+ case "$OPTION" in
+ c)
+ CONF="$OPTARG"
+ ;;
+ h)
+ echo 'Supported options:'
+ # shellcheck disable=SC2016
+ echo ' -c $CONF -- set configuration'
+ ;;
+ ?)
+ exit_fail "Unrecognized command line option"
+ ;;
+ esac
+done
+
+taler-mdb-display-on -c "$CONF"
+
+FBDEV=$(taler-config -c "$CONF" -s taler-mdb -o FRAMEBUFFER_DEVICE)
+
+fbi -d "$FBDEV" -a -m "768x576-75" -vt 2 -nocomments -noverbose "$1.png"
+
+while true
+do
+ sleep 10
+done
diff --git a/debian/taler-mdb.postrm.debhelper
b/debian/taler-mdb.postrm.debhelper
index 5d2556c..0847f23 100644
--- a/debian/taler-mdb.postrm.debhelper
+++ b/debian/taler-mdb.postrm.debhelper
@@ -1,4 +1,4 @@
-# Automatically added by dh_installdebconf/13.3
+# Automatically added by dh_installdebconf/13.11.4ubuntu3
if [ "$1" = purge ] && [ -e /usr/share/debconf/confmodule ]; then
. /usr/share/debconf/confmodule
db_purge
diff --git a/debian/taler-mdb.service b/debian/taler-mdb.service
index 4946e41..ec2c8cb 100644
--- a/debian/taler-mdb.service
+++ b/debian/taler-mdb.service
@@ -5,7 +5,7 @@ Description=GNU Taler Multi-Drop-Bus application
User=root
Type=simple
Restart=on-failure
-ExecStart=/usr/bin/taler-mdb-network-check.sh -c /etc/taler-mdb.conf -f
"FIXME-show-message-cmd" /usr/bin/taler-mdb -c /etc/taler-mdb.conf
+ExecStart=/usr/bin/taler-mdb-network-check.sh -c /etc/taler-mdb.conf -f
'/usr/bin/taler-mdb-show.sh -c /etc/taler-mdb.conf' /usr/bin/taler-mdb -c
/etc/taler-mdb.conf
StandardOutput=inherit
StandardError=inherit
Restart=always
diff --git a/debian/taler-mdb.substvars b/debian/taler-mdb.substvars
index 0248013..1c0d4e3 100644
--- a/debian/taler-mdb.substvars
+++ b/debian/taler-mdb.substvars
@@ -1,3 +1,3 @@
misc:Depends=debconf (>= 0.5) | debconf-2.0
-shlibs:Depends=libc6 (>= 2.14), libgnunet (>= 0.14.0), libjansson4 (>= 2.0.1),
libnfc5 (>= 1.7.0~rc2), libqrencode4 (>= 3.2.0), libtalerexchange (>= 0.9.0),
libtalermerchant (>= 0.9.0)
+shlibs:Depends=libc6 (>= 2.34), libgnunet (>= 0.20.0), libjansson4 (>= 2.14),
libnfc6 (>= 1.7.0~rc2), libqrencode4 (>= 3.2.0), libtalerexchange (>= 0.9.3),
libtalermerchant (>= 0.9.3)
misc:Pre-Depends=
diff --git a/src/Makefile.am b/src/Makefile.am
index c48d4bb..42463c2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,8 @@
# This Makefile.am is in the public domain
bin_PROGRAMS = \
taler-coin-acceptor \
- taler-mdb
+ taler-mdb \
+ taler-mdb-display
if HAVE_QR
bin_PROGRAMS += qr-show
@@ -43,3 +44,10 @@ qr_show_LDADD = \
@QR_LIBS@ \
$(XLIB)
+
+taler-mdb-display_SOURCES = \
+ taler-mdb-display.c
+taler-mdb-display_LDADD = \
+ -lgnunetutil \
+ $(XLIB)
+
diff --git a/src/taler-mdb-display.c b/src/taler-mdb-display.c
new file mode 100644
index 0000000..d486427
--- /dev/null
+++ b/src/taler-mdb-display.c
@@ -0,0 +1,312 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER 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 General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+* @file taler-mdb-display-on.c
+* @brief turn on the display back light
+* @author Boss Marco
+* @author Christian Grothoff
+*/
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IP_H
+#include <netinet/ip.h> /* superset of previous */
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <termios.h>
+#include <microhttpd.h>
+#include <gnunet/gnunet_util_lib.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+/* for adafruit pitft display */
+#include <linux/fb.h>
+
+/**
+ * Disable i18n support.
+ */
+#define _(s) (s)
+
+/**
+ * Handle for the Framebuffer device
+ */
+struct Display
+{
+ /**
+ * File descriptor for the screen
+ */
+ int devicefd;
+
+ /**
+ * File descriptor to set backlight information
+ */
+ int backlightfd;
+
+ /**
+ * The display memory to set the pixel information
+ */
+ uint16_t *memory;
+
+ /**
+ * Original screen information
+ */
+ struct fb_var_screeninfo orig_vinfo;
+
+ /**
+ * Variable screen information (color depth ...)
+ */
+ struct fb_var_screeninfo var_info;
+
+ /**
+ * Fixed screen informtaion
+ */
+ struct fb_fix_screeninfo fix_info;
+};
+
+
+/**
+ * Next program to launch.
+ */
+static char *const *arg_next;
+
+/**
+ * Name of the framebuffer device (i.e. /dev/fb1).
+ */
+static char *framebuffer_device_filename;
+
+/**
+ * Name of the backlight file of @e framebuffer_device_filename (i.e.
/sys/class/backlight/soc:backlight/brightness).
+ */
+static char *framebuffer_backlight_filename;
+
+/**
+ * Global option '-i' to invert backlight on/off values
+ */
+static int backlight_invert;
+
+/**
+ * Standard backlight on value
+ */
+static char backlight_on = '1';
+
+/**
+ * Standard backlight off value
+ */
+static char backlight_off = '0';
+
+/**
+ * Handle for the framebuffer device
+ */
+static struct Display qrDisplay;
+
+
+static void
+shutdown_task (void *cls)
+{
+ (void) cls;
+ if (NULL != qrDisplay.memory)
+ memset (qrDisplay.memory,
+ 0xFF,
+ qrDisplay.var_info.xres * qrDisplay.var_info.yres
+ * sizeof (uint16_t));
+ if (NULL != qrDisplay.memory)
+ {
+ /* free the display data */
+ munmap (qrDisplay.memory,
+ qrDisplay.fix_info.smem_len);
+ qrDisplay.memory = NULL;
+ /* close device */
+ GNUNET_break (0 == close (qrDisplay.devicefd));
+ qrDisplay.devicefd = -1;
+ if (0 < qrDisplay.backlightfd)
+ GNUNET_break (0 == close (qrDisplay.backlightfd));
+ qrDisplay.backlightfd = -1;
+ }
+}
+
+
+/**
+ * @brief Start the application
+ *
+ * @param cls closure
+ * @param args arguments left
+ * @param cfgfile config file name
+ * @param cfg handle for the configuration file
+ */
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ (void) cls;
+ (void) cfgfile;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (cfg,
+ "taler-mdb",
+ "FRAMEBUFFER_DEVICE",
+ &framebuffer_device_filename))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler-mdb",
+ "FRAMEBUFFER_DEVICE");
+ framebuffer_device_filename = GNUNET_strdup ("/dev/fb1");
+ }
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (cfg,
+ "taler-mdb",
+ "FRAMEBUFFER_BACKLIGHT",
+
&framebuffer_backlight_filename))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler-mdb",
+ "FRAMEBUFFER_BACKLIGHT");
+ framebuffer_backlight_filename = GNUNET_strdup (
+ "/sys/class/backlight/soc:backlight/brightness");
+ }
+ /* open the framebuffer device */
+ qrDisplay.devicefd = open (framebuffer_device_filename,
+ O_RDWR);
+ if (0 < qrDisplay.devicefd)
+ {
+ /* read information about the screen */
+ ioctl (qrDisplay.devicefd,
+ FBIOGET_VSCREENINFO,
+ &qrDisplay.var_info);
+
+ /* store current screeninfo for reset */
+ qrDisplay.orig_vinfo = qrDisplay.var_info;
+
+ if (16 != qrDisplay.var_info.bits_per_pixel)
+ {
+ /* Change variable info to 16 bit per pixel */
+ qrDisplay.var_info.bits_per_pixel = 16;
+ if (0 > ioctl (qrDisplay.devicefd,
+ FBIOPUT_VSCREENINFO,
+ &qrDisplay.var_info))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "ioctl(FBIOPUT_VSCREENINFO)");
+ return;
+ }
+ }
+
+ /* Get fixed screen information */
+ if (0 > ioctl (qrDisplay.devicefd,
+ FBIOGET_FSCREENINFO,
+ &qrDisplay.fix_info))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "ioctl(FBIOGET_FSCREENINFO)");
+ return;
+ }
+
+ /* get pointer onto frame buffer */
+ qrDisplay.memory = mmap (NULL,
+ qrDisplay.fix_info.smem_len,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ qrDisplay.devicefd,
+ 0);
+
+ /* open backlight file to turn display backlight on and off */
+ if (0 > qrDisplay.devicefd)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "mmap");
+ return;
+ }
+
+ memset (qrDisplay.memory,
+ 0xFF,
+ qrDisplay.var_info.xres * qrDisplay.var_info.yres
+ * sizeof (uint16_t));
+
+ qrDisplay.backlightfd = open (
+ framebuffer_backlight_filename, O_WRONLY);
+ if (0 > qrDisplay.backlightfd)
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "open",
+ framebuffer_backlight_filename);
+ }
+ else
+ {
+ if (backlight_invert)
+ {
+ backlight_on = '0';
+ backlight_off = '1';
+ }
+ (void) ! write (qrDisplay.backlightfd,
+ &backlight_off,
+ 1);
+ }
+ }
+ else
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "open",
+ framebuffer_device_filename);
+ }
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+ NULL);
+
+ if (0 < qrDisplay.backlightfd)
+ (void) ! write (qrDisplay.backlightfd,
+ &backlight_on,
+ 1);
+}
+
+
+int
+main (int argc,
+ char*const*argv)
+{
+ int ret;
+ /* the available command line options */
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_option_flag ('i',
+ "backlight-invert",
+ "invert the backlight on/off values (standard
on = 1)",
+ &backlight_invert),
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ ret = GNUNET_PROGRAM_run (argc,
+ argv,
+ "taler-mdb-display-on",
+ "Turn on display.\n",
+ options,
+ &run,
+ NULL);
+ if (GNUNET_OK != ret)
+ return 1;
+ return 0;
+}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-taler-mdb] branch master updated: add images for errors,
gnunet <=