Initial commit

This commit is contained in:
Pascal Engélibert 2022-09-19 18:41:09 +02:00
commit 05cd190c53
Signed by: tuxmain
GPG key ID: 3504BC6D362F7DCA
155 changed files with 49378 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/public

7
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,7 @@
{
"spellright.language": [],
"spellright.documentTypes": [
"latex",
"plaintext"
]
}

13
README.md Normal file
View file

@ -0,0 +1,13 @@
# txmn.tk website
Sources for my personal website [txmn.tk](https://txmn.tk).
## Build
Use [zola](https://getzola.org).
## License
CopyLeft 2022 Pascal Engélibert
This work (website's source code and content, except some contents, logos and libraries) is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/). (CC BY-SA)

43
config.toml Normal file
View file

@ -0,0 +1,43 @@
base_url = "/"
compile_sass = true
build_search_index = false
default_language = "en"
minify_html = false
[slugify]
paths = "off"
taxonomies = "off"
[markdown]
highlight_code = true
[extra]
sitename = "tuxmain's homepage"
[languages.eo]
generate_feed = true
taxonomies = [
{name = "tags"},
]
[languages.eo.translations]
[languages.en]
generate_feed = true
taxonomies = [
{name = "tags"},
]
[languages.en.translations]
[languages.fr]
generate_feed = true
taxonomies = [
{name = "tags"},
]
[languages.fr.translations]

123
content/_index.eo.md Normal file
View file

@ -0,0 +1,123 @@
+++
title = "Hejmo"
insert_anchor_links = "left"
+++
<div class="service_boxes">
{{ service_box(href="https://flim.txmn.tk", title="PeerTube", img="/img/peertube.svg", img_alt="Logotipo PeerTube") }}
{{ service_box(href="/framadate", title="Framadate", img="/img/framadate.png", img_alt="Logotipo Framadate") }}
{{ service_box(href="/element", title="Matrix / Element", img="/img/element.svg", img_alt="Logotipo Element") }}
{{ service_box(href="https://forum.progaccess.net", title="Forumo ProgAccess", img="/img/progaccess.png", img_alt="Logotipo ProgAccess") }}
{{ service_box(href="https://cloud.txmn.tk", title="NextCloud", img="/img/nextcloud.svg", img_alt="Logotipo NextCloud") }}
{{ service_box(href="/lufi", title="Lufi", img="/img/lufi.svg", img_alt="Logotipo Lufi") }}
{{ service_box(href="/lutim", title="Lutim", img="/img/lutim.png", img_alt="Logotipo Lutim") }}
{{ service_box(href="/l", title="LSTU", img="/img/lstu.svg", img_alt="Logotipo LSTU") }}
{{ service_box(href="https://pad.txmn.tk", title="Etherpad", img="/img/etherpad.png", img_alt="Logotipo Etherpad") }}
{{ service_box(href="/mumble", title="Mumble", img="/img/mumble.svg", img_alt="Logotipo Mumble") }}
</div>
**[Artikoloj de blogo](blog)**
## Kiu li estas? {#kiu}
* Homo ĝis pruvita alie;
* Pascal Engélibert;
* Programisto liberecista, studento de matematiko;
* Rust, Python, PHP, web, franca, angla, hispana, esperanta;
* Preferas tabojn;
* Preferas [GNU AGPL](https://www.gnu.org/licenses/licenses.html#AGPL) kaj [CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0/).
## Projektoj {#projektoj}
<div class="service_boxes">
{{ service_box(href="https://progaccess.net", title="ProgAccess", img="/img/progaccess.png", img_alt="Logotipo ProgAccess") }}
{{ service_box(href="//zettascript.org/projects/gmixer/", title="ĞMixer", img="/img/gmixer.svg", img_alt="Logotipo ĞMixer") }}
{{ service_box(href="https://framagit.org/ZettaScript/syeve", title="Syeve", img="/img/syeve.svg", img_alt="Logotipo Syeve") }}
{{ service_box(href="https://framagit.org/ZettaScript/forceatlas2-rs", title="ForceAtlas2-rs", img="/img/forceatlas2.png", img_alt="Grafo") }}
{{ service_box(href="//worldwotmap.duniter.org", title="WorldWotMap", img="/img/gbreve.svg", img_alt="Ğ") }}
</div>
### Projektoj kreitaj aŭ kunkreitaj {#projektoj2}
* [ProgAccess](https://www.progaccess.net) kaj la retejoj [NVDA-FR](https://www.nvda-fr.org), [AccessiKey](https://accessikey.nvda-fr.org), por alirebligi la komputiko al ĉiu
* [ĞMixer](//zettascript.org/projects/gmixer/), por anonimigi viajn kriptomonajn spezojn tra unu cepa reto
* [WorldWotMap](//worldwotmap.duniter.org), geografia mapo de la reto de fido Duniter
* [ForceAtlas2-rs](https://framagit.org/ZettaScript/forceatlas2-rs), realigo de la algoritmo de grafspacigo ForceAtlas2 en Rust
* [Ğ1force](https://git.duniter.org/tools/g1force), brutfortilo Scrypt+Ed25519 en Rust
* [Syeve](https://framagit.org/ZettaScript/syeve) (Simple yet efficient video encoding), kodeko de video senperda
* [matrix_bridge](https://git.p2p.legal/tuxmain/minetest-matrix_bridge), mod Minetest por diskuti kun Matrix
* [ğexplore](https://git.duniter.org/tools/gexplore), tridimensia esplorilo de reto de fido Duniter
* [Telefono Diskogurdo](https://git.txmn.tk/tuxmain/telephone-jukebox), diska telefono kiu muzikas
### Kontribuoj {#kontribuoj}
* [Libera Mono](https://monnaie-libre.fr): variitaj kontribuoj
* [Wotmap](https://wotmap.duniter.org), bildigi grafon de unu reto de fido Duniter (backend)
* [Duniter](https://git.duniter.org/nodes/rust/duniter-v2s), blokĉeno por libera mono (Rust)
### Etaj kontribuoj {#etaj-kontribuoj}
* GParted: [alirebleco al ekranlegiloj](https://gitlab.gnome.org/GNOME/gparted/-/commit/f31fbb986fab551a4db8c05e9a45720b35bc5385)
* Tera: [multlingva filtrilo `date`](https://github.com/Keats/tera/pull/742)
### Kuriozaj projektoj {#kuriozaj-projektoj}
* [Perkomputile ciferece stirata (CNC) artikigita brako](https://framagit.org/ZettaScript/cnc-arm)
* [Pervarma lasera printilo kun Arduino](https://framagit.org/ZettaScript/laserprinter) (por printi sur papero sen konsumi inkon)
* Multfunkcia sistemo por videkunveno aŭ datumfluo en Rust
* Transformilo de sono al MIDI
## Servoj {#servoj}
* [NextCloud](https://cloud.txmn.tk) à louer en Ğ1 ([plus d'infos](https://www.gchange.fr/#/app/market/view/AW6aQfpXzeWXAkHvSFwJ/compte-nextcloud-stockage-de-fichiers))
* 🗓 [Framadate](/framadate)
* 🎞 [PeerTube Flim](https://flim.txmn.tk)
* 🎧 Servilo Mumble publika: `txmn.tk:64738` &#8211; [Interfaco Mumble TTT](/mumble)
* 🎮 [Juneland](https://juneland.fr): serviloj MineTest por la libera mono
* 🏷 [Viğnette](/g1/vignette): printu etikedojn por viaj ğbazaroj
* [Forumo ProgAccess](https://forum.progaccess.net): interhelpo por la alirebleco de komputiko
* 📁 [Lufi](/lufi): sendu dosierojn ĝis 2GB
* 📷 [Lutim](/lutim): sendu bilgojn ĝis 10MB (ideala por forumoj)
* 🗩 [Servilo Matrix](/element): messagerie instantanée fédérée Matrix (interface Element, chiffrement de bout-en-bout, groupes, etc.)
* [Ğ.ML](//xn--tea.ml): sous-domaines gratuits pour la monnaie libre
* Servilo STUN publika: `stun:txmn.tk:3478`
* [Historique des données géographiques Cesium+ de la Ğ1](/g1/history/cesiumplusmap)
* Hébergement/installation de site/blog/boutique Odoo, WordPress, ou autres. Payable en Ğ1, me contacter par e-mail.
* 🗒 [Etherpad](https://pad.txmn.tk): document partagé de prise de notes en temps réel
## Ankaŭ gastigas {#gastigas}
<div class="service_boxes">
{{ service_box(href="//dubitaristes.fr", title="Les Dubitaristes Girondins", img="/img/dubitaristes.png", img_alt="Logotipo Dubitaristes") }}
{{ service_box(href="https://collectifsources.fr", title="Collectif Sources", img="/img/collectifsources.png", img_alt="Logo Collectif Sources") }}
{{ service_box(href="//juneland.fr", title="Juneland", img="/img/minetest.svg", img_alt="Logotipo MineTest") }}
</div>
## La kamaradoj {#kamaradoj}
* [Librezo](https://librezo.com) helpas la profesiulojn liberiĝi de la GAFAM per instali siajn proprajn komputikajn servojn.
## Kontaktoj {#kontaktoj}
* Retpoŝto: `t ĉe txmn punkto tk` _aŭ_ `tuxmain ĉe zettascript punkto org`
* [Publika ŝlosilo GPG](/tuxmain.asc)
* <a rel="author" href="https://toot.aquilenet.fr/@tuxmain">Mastodon</a>
* [Kontaktformularo ZettaScript](//zettascript.org/contact.php)
* [Libera Mono Ğ1](https://demo.cesium.app/#/app/wot/45GfjkWCWQhJ3epJVGC2NSg1Rcu4Ue1vDD3kk9eLs5TQ/) (publika ŝlosilo: `45GfjkWCWQhJ3epJVGC2NSg1Rcu4Ue1vDD3kk9eLs5TQ:CUw`)
* [GitLab Framagit](https://framagit.org/ZettaScript) (projektoj)
* [GitLab Duniter](https://git.duniter.org/tuxmain) (projektoj pri la libera mono)
* [Gitea P2P.legal](https://git.p2p.legal/tuxmain) (aliaj projektoj pri la libera mono)
* [Gitea JSB](https://gitea.jeunes-science.asso.fr/tuxmain) (projektoj [Jeunes-Science Bordeaux](https://jeunes-science.asso.fr))
* [Gitxmn](https://git.txmn.tk/tuxmain) (etaj projektoj kiuj mi ne sciis kien publikigi)
* [GitLab Gnome](https://gitlab.gnome.org/tuxmain)
* [GitHub](https://github.com/ZettaScript) (malpreferata)
<a href="https://liberapay.com/tuxmain/donate" title="Doni kun Liberapay"><img alt="Doni kun Liberapay" src="/img/liberapay-donate.svg"/></a>
## Pri {#pri}
🦀 Retejo generita kun [zola](https://www.getzola.org/).
🧮 Gastigata sur unu Raspberry Pi en Bègles, apud Bordeaux, en Franco.
📜 Ĉi tiu retejo estas publikigita laŭ la permesilo <a rel="license" href="//creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>. ([Fontkodo](https://git.txmn.tk/tuxmain/website)) [Kondiĉoj de uzo](@/eula.eo.md)

123
content/_index.fr.md Normal file
View file

@ -0,0 +1,123 @@
+++
title = "Accueil"
insert_anchor_links = "left"
+++
<div class="service_boxes">
{{ service_box(href="https://flim.txmn.tk", title="PeerTube", img="/img/peertube.svg", img_alt="Logo PeerTube") }}
{{ service_box(href="/framadate", title="Framadate", img="/img/framadate.png", img_alt="Logo Framadate") }}
{{ service_box(href="/element", title="Matrix / Element", img="/img/element.svg", img_alt="Logo Element") }}
{{ service_box(href="https://forum.progaccess.net", title="Forum ProgAccess", img="/img/progaccess.png", img_alt="Logo ProgAccess") }}
{{ service_box(href="https://cloud.txmn.tk", title="NextCloud", img="/img/nextcloud.svg", img_alt="Logo NextCloud") }}
{{ service_box(href="/lufi", title="Lufi", img="/img/lufi.svg", img_alt="Logo Lufi") }}
{{ service_box(href="/lutim", title="Lutim", img="/img/lutim.png", img_alt="Logo Lutim") }}
{{ service_box(href="/l", title="LSTU", img="/img/lstu.svg", img_alt="Logo LSTU") }}
{{ service_box(href="https://pad.txmn.tk", title="Etherpad", img="/img/etherpad.png", img_alt="Logo Etherpad") }}
{{ service_box(href="/mumble", title="Mumble", img="/img/mumble.svg", img_alt="Logo Mumble") }}
</div>
**[Articles de blog](blog)**
## Qui est-ce&#8239;? {#qui}
* Être humain jusqu'à preuve du contraire&#8239;;
* Pascal Engélibert&#8239;;
* Développeur libriste, étudiant en mathématiques&#8239;;
* Rust, Python, PHP, web, français, anglais, espagnol, espéranto&#8239;;
* Préfère les tabulations&#8239;;
* Préfère [GNU AGPL](https://www.gnu.org/licenses/licenses.html#AGPL) et [CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0/).
## Projets {#projets}
<div class="service_boxes">
{{ service_box(href="https://progaccess.net", title="ProgAccess", img="/img/progaccess.png", img_alt="Logo ProgAccess") }}
{{ service_box(href="//zettascript.org/projects/gmixer/", title="ĞMixer", img="/img/gmixer.svg", img_alt="Logo ĞMixer") }}
{{ service_box(href="https://framagit.org/ZettaScript/syeve", title="Syeve", img="/img/syeve.svg", img_alt="Logo Syeve") }}
{{ service_box(href="https://framagit.org/ZettaScript/forceatlas2-rs", title="ForceAtlas2-rs", img="/img/forceatlas2.png", img_alt="Graphe") }}
{{ service_box(href="//worldwotmap.duniter.org", title="WorldWotMap", img="/img/gbreve.svg", img_alt="Ğ") }}
</div>
### Projets créés ou cocréés {#projets2}
* [ProgAccess](https://www.progaccess.net) et les sites [NVDA-FR](https://www.nvda-fr.org), [AccessiKey](https://accessikey.nvda-fr.org), pour rendre l'informatique accessible aux mal ou non voyant·es
* [ĞMixer](//zettascript.org/projects/gmixer/), pour anonymiser vos transactions de cryptomonnaie à travers un réseau en oignons
* [WorldWotMap](//worldwotmap.duniter.org), pour voir la carte géographique d'une Toile de Confiance Duniter
* [ForceAtlas2-rs](https://framagit.org/ZettaScript/forceatlas2-rs), implémentation de l'algo de positionnement de graphe ForceAtlas2 en Rust
* [Ğ1force](https://git.duniter.org/tools/g1force), outil de bruteforce Scrypt+Ed25519 en Rust
* [Syeve](https://framagit.org/ZettaScript/syeve) (Simple yet efficient video encoding), codec lossless en Rust
* [matrix_bridge](https://git.p2p.legal/tuxmain/minetest-matrix_bridge), mod Minetest pour l'interaction avec Matrix
* [ğexplore](https://git.duniter.org/tools/gexplore), un explorateur en 3D de toile de confiance Duniter
* [Téléphone Jukebox](https://git.txmn.tk/tuxmain/telephone-jukebox), un téléphone à cadran jouant des sons
### Contributions {#contributions}
* [Monnaie Libre](https://monnaie-libre.fr)&nbsp;: contributions éparses et variées
* [Wotmap](https://wotmap.duniter.org), représenter le graphe d'une toile de confiance Duniter (développement du backend)
* [Duniter](https://git.duniter.org/nodes/rust/duniter-v2s), blockchain pour monnaie libre (Rust)
### Micro-contributions {#micro-contributions}
* GParted&nbsp;: [accessibilité aux lecteurs d'écran](https://gitlab.gnome.org/GNOME/gparted/-/commit/f31fbb986fab551a4db8c05e9a45720b35bc5385)
* Tera&nbsp;: [support de la langue pour le filtre `date`](https://github.com/Keats/tera/pull/742)
### Bidouillages en cours {#bidouillages}
* [Bras articulé CNC modulaire imprimé en 3D, contrôlé par Arduino](https://framagit.org/ZettaScript/cnc-arm)
* [Imprimante thermique LASER Arduino](https://framagit.org/ZettaScript/laserprinter) (pour imprimer sur papier sans consommer d'encre)
* Système super-modulaire de visioconférence/stream/live en Rust
* Convertisseur audio vers MIDI
## Services {#services}
* [NextCloud](https://cloud.txmn.tk) à louer en Ğ1 ([plus d'infos](https://www.gchange.fr/#/app/market/view/AW6aQfpXzeWXAkHvSFwJ/compte-nextcloud-stockage-de-fichiers))
* 🗓 [Framadate](/framadate)
* 🎞 [PeerTube Flim](https://flim.txmn.tk)
* 🎧 Serveur Mumble public&nbsp;: `txmn.tk:64738` &#8211; [Interface Mumble web](/mumble)
* 🎮 [Juneland](https://juneland.fr)&nbsp;: serveurs MineTest pour la monnaie libre
* 🏷 [Viğnette](/g1/vignette) à imprimer pour vos ğmarchés
* [Forum ProgAccess](https://forum.progaccess.net)&nbsp;: entraide pour l'accessibilité de l'informatique
* 📁 [Lufi](/lufi)&nbsp;: envoi de fichiers gratuit jusqu'à 2Go
* 📷 [Lutim](/lutim)&nbsp;: envoi d'images gratuit jusqu'à 10Mo (pratique pour les forums)
* 🗩 [Serveur Matrix](/element)&nbsp;: Messagerie instantanée fédérée Matrix (interface Element, chiffrement de bout-en-bout, groupes, etc.)
* [Ğ.ML](//xn--tea.ml)&nbsp;: sous-domaines gratuits pour la monnaie libre
* Serveur STUN public&nbsp;: `stun:txmn.tk:3478`
* [Historique des données géographiques Cesium+ de la Ğ1](/g1/history/cesiumplusmap)
* Hébergement/installation de site/blog/boutique Odoo, WordPress, ou autres. Payable en Ğ1, me contacter par e-mail.
* 🗒 [Etherpad](https://pad.txmn.tk)&nbsp;: document partagé de prise de notes en temps réel
## Héberge aussi {#heberge}
<div class="service_boxes">
{{ service_box(href="//dubitaristes.fr", title="Les Dubitaristes Girondins", img="/img/dubitaristes.png", img_alt="Logo Dubitaristes") }}
{{ service_box(href="https://collectifsources.fr", title="Collectif Sources", img="/img/collectifsources.png", img_alt="Logo Collectif Sources") }}
{{ service_box(href="//juneland.fr", title="Juneland", img="/img/minetest.svg", img_alt="Logo MineTest") }}
</div>
## Les camarades {#camarades}
* [Librezo](https://librezo.com) aide les pros à se libérer des GAFAM en installant chez vous votre infrastructure informatique.
## Contacts {#contacts}
* Courrier électronique&nbsp;: `t chez txmn point tk` _ou_ `tuxmain chez zettascript point org`
* [Clé publique GPG](/tuxmain.asc)
* <a rel="author" href="https://toot.aquilenet.fr/@tuxmain">Mastodon</a>
* [Formulaire de contact ZettaScript](//zettascript.org/contact.php)
* [Monnaie Libre Ğ1](https://demo.cesium.app/#/app/wot/45GfjkWCWQhJ3epJVGC2NSg1Rcu4Ue1vDD3kk9eLs5TQ/) (clé publique&nbsp;: `45GfjkWCWQhJ3epJVGC2NSg1Rcu4Ue1vDD3kk9eLs5TQ:CUw`)
* [GitLab Framagit](https://framagit.org/ZettaScript) (projets en général)
* [GitLab Duniter](https://git.duniter.org/tuxmain) (projets pour la monnaie libre)
* [Gitea P2P.legal](https://git.p2p.legal/tuxmain) (autres projets pour la monnaie libre)
* [Gitea JSB](https://gitea.jeunes-science.asso.fr/tuxmain) (projets [Jeunes-Science Bordeaux](https://jeunes-science.asso.fr))
* [Gitxmn](https://git.txmn.tk/tuxmain) (petits projets que je ne savais pas où mettre)
* [GitLab Gnome](https://gitlab.gnome.org/tuxmain)
* [GitHub](https://github.com/ZettaScript) (déprécié, conservé pour la rétrocompatibilité seulement)
<a href="https://liberapay.com/tuxmain/donate" title="Donner avec Liberapay"><img alt="Donner avec Liberapay" src="/img/liberapay-donate.svg"/></a>
## À propos {#a-propos}
🦀 Site généré avec [zola](https://www.getzola.org/).
🧮 Hébergé sur un Raspberry Pi à Bègles, près de Bordeaux, en France.
📜 Ce site est mis à disposition selon les termes de la licence <a rel="license" href="//creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>. ([Code source](https://git.txmn.tk/tuxmain/website)) [CGU](@/eula.fr.md)

125
content/_index.md Normal file
View file

@ -0,0 +1,125 @@
+++
title = "Home"
insert_anchor_links = "left"
+++
<div class="service_boxes">
{{ service_box(href="https://flim.txmn.tk", title="PeerTube", img="/img/peertube.svg", img_alt="Logo PeerTube") }}
{{ service_box(href="/framadate", title="Framadate", img="/img/framadate.png", img_alt="Logo Framadate") }}
{{ service_box(href="/element", title="Matrix / Element", img="/img/element.svg", img_alt="Logo Element") }}
{{ service_box(href="https://forum.progaccess.net", title="Forum ProgAccess", img="/img/progaccess.png", img_alt="Logo ProgAccess") }}
{{ service_box(href="https://cloud.txmn.tk", title="NextCloud", img="/img/nextcloud.svg", img_alt="Logo NextCloud") }}
{{ service_box(href="/lufi", title="Lufi", img="/img/lufi.svg", img_alt="Logo Lufi") }}
{{ service_box(href="/lutim", title="Lutim", img="/img/lutim.png", img_alt="Logo Lutim") }}
{{ service_box(href="/l", title="LSTU", img="/img/lstu.svg", img_alt="Logo LSTU") }}
{{ service_box(href="https://pad.txmn.tk", title="Etherpad", img="/img/etherpad.png", img_alt="Logo Etherpad") }}
{{ service_box(href="/mumble", title="Mumble", img="/img/mumble.svg", img_alt="Logo Mumble") }}
</div>
**[Blog articles](blog)**
## Who is that? {#who}
* Human being until proven otherwise;
* Pascal Engélibert;
* Libre developper, student of mathematics;
* Rust, Python, PHP, web, French, English, Spanish, Esperanto;
* Prefers tabulations;
* Prefers [GNU AGPL](https://www.gnu.org/licenses/licenses.html#AGPL) and [CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0/).
## Projects {#projects}
<div class="service_boxes">
{{ service_box(href="https://progaccess.net", title="ProgAccess", img="/img/progaccess.png", img_alt="Logo ProgAccess") }}
{{ service_box(href="//zettascript.org/projects/gmixer/", title="ĞMixer", img="/img/gmixer.svg", img_alt="Logo ĞMixer") }}
{{ service_box(href="https://framagit.org/ZettaScript/syeve", title="Syeve", img="/img/syeve.svg", img_alt="Logo Syeve") }}
{{ service_box(href="https://framagit.org/ZettaScript/forceatlas2-rs", title="ForceAtlas2-rs", img="/img/forceatlas2.png", img_alt="Graph") }}
{{ service_box(href="//worldwotmap.duniter.org", title="WorldWotMap", img="/img/gbreve.svg", img_alt="Ğ") }}
</div>
### Projects created or cocreated {#projects2}
* [ProgAccess](https://www.progaccess.net) and the sites [NVDA-FR](https://www.nvda-fr.org), [AccessiKey](https://accessikey.nvda-fr.org), to make computers accessible to the visually impaired
* [ĞMixer](//zettascript.org/projects/gmixer/), to anonymize your cryptocurrency transactions through an onion network
* [WorldWotMap](//worldwotmap.duniter.org), a geographical map of a Duniter web of trust
* [ForceAtlas2-rs](https://framagit.org/ZettaScript/forceatlas2-rs), implementation of the graph layout ForceAtlas2 in Rust
* [Ğ1force](https://git.duniter.org/tools/g1force), Scrypt+Ed25519 bruteforce tool in Rust
* [Syeve](https://framagit.org/ZettaScript/syeve) (Simple yet efficient video encoding), lossless codec in Rust
* [matrix_bridge](https://git.p2p.legal/tuxmain/minetest-matrix_bridge), Minetest mod for Matrix messaging interaction
* [ğexplore](https://git.duniter.org/tools/gexplore), a 3D web of trust history explorer for Duniter
* [Jukebox Telephone](https://git.txmn.tk/tuxmain/telephone-jukebox), a dial phone that plays sounds
### Contributions {#contributions}
* [Libre Currency](https://monnaie-libre.fr): sparse and various contributions
* [Wotmap](https://wotmap.duniter.org), represent the graph of a Duniter web of trust (backend development)
* [Duniter](https://git.duniter.org/nodes/rust/duniter-v2s), blockchain for libre currency (Rust)
### Micro-contributions {#micro-contributions}
* GParted: [screen reader accessibility](https://gitlab.gnome.org/GNOME/gparted/-/commit/f31fbb986fab551a4db8c05e9a45720b35bc5385)
* Tera: [`date` filter supports localization](https://github.com/Keats/tera/pull/742)
### WiP Hacks {#hacks}
* [Modular articulated arm CNC, 3D-printed, controled by Arduino](https://framagit.org/ZettaScript/cnc-arm)
* [LASER thermal printer with Arduino](https://framagit.org/ZettaScript/laserprinter) (for printing on paper without consuming ink)
* Super-modular visioconference/stream/live system in Rust
* Audio to MIDI converter
## Services {#services}
* [NextCloud](https://cloud.txmn.tk) to rent in Ğ1 ([more info](https://www.gchange.fr/#/app/market/view/AW6aQfpXzeWXAkHvSFwJ/compte-nextcloud-stockage-de-fichiers))
* 🗓 [Framadate](/framadate)
* 🎞 [PeerTube Flim](https://flim.txmn.tk)
* 🎧 Public Mumble server: `txmn.tk:64738` &#8211; [Mumble web interface](/mumble)
* 🎮 [Juneland](https://juneland.fr): MineTest servers for the libre currency
* 🏷 [Viğnette](/g1/vignette) to print labels for your ğmarkets
* [Forum ProgAccess](https://forum.progaccess.net): mutual aid for computer accessibility
* 📁 [Lufi](/lufi): free file sharing up to 2GB
* 📷 [Lutim](/lutim): free image sharing up to 10MB (convenient for forums)
* 🗩 [Matrix server](/element): Federated instant messaging Matrix (Element interface, end-to-end encryption, groups, etc.)
* [Ğ.ML](//xn--tea.ml): free subdomains for the libre currency
* Public STUN server: `stun:txmn.tk:3478`
* [Cesium+ geographical data history of Ğ1](/g1/history/cesiumplusmap)
* Hosting/installation of site/blog/shop Odoo, WordPress, or other. Paid in Ğ1, contact me by email.
* 🗒 [Etherpad](https://pad.txmn.tk): Real time shared document for note taking
## Also hosting {#host}
<div class="service_boxes">
{{ service_box(href="//dubitaristes.fr", title="Les Dubitaristes Girondins", img="/img/dubitaristes.png", img_alt="Logo Dubitaristes") }}
{{ service_box(href="https://collectifsources.fr", title="Collectif Sources", img="/img/collectifsources.png", img_alt="Logo Collectif Sources") }}
{{ service_box(href="//juneland.fr", title="Juneland", img="/img/minetest.svg", img_alt="Logo MineTest") }}
</div>
## The camarades {#camarades}
* [Librezo](https://librezo.com) helps the professionals to liberate themselves from the GAFAM by installing your own computing services.
## Contacts {#contacts}
* Electronic missive: `t åt txmn døt tk` _or_ `tuxmain åt zettascript døt org`
* [GPG public key](/tuxmain.asc)
* <a rel="author" href="https://toot.aquilenet.fr/@tuxmain">Mastodon</a>
* [ZettaScript contact form](//zettascript.org/contact.php)
* [Libre Currency Ğ1](https://demo.cesium.app/#/app/wot/45GfjkWCWQhJ3epJVGC2NSg1Rcu4Ue1vDD3kk9eLs5TQ/) (pubkey: `45GfjkWCWQhJ3epJVGC2NSg1Rcu4Ue1vDD3kk9eLs5TQ:CUw`)
* [GitLab Framagit](https://framagit.org/ZettaScript) (projects in general)
* [GitLab Duniter](https://git.duniter.org/tuxmain) (projects about libre currency)
* [Gitea P2P.legal](https://git.p2p.legal/tuxmain) (also projects about libre currency)
* [Gitea JSB](https://gitea.jeunes-science.asso.fr/tuxmain) (projects about [Jeunes-Science Bordeaux](https://jeunes-science.asso.fr))
* [Gitxmn](https://git.txmn.tk/tuxmain) (small projects I didn't know where to publish)
* [GitLab Gnome](https://gitlab.gnome.org/tuxmain)
* [GitHub](https://github.com/ZettaScript) (deprecated, used for backward compatibility only)
<a href="https://liberapay.com/tuxmain/donate" title="Donate with Liberapay"><img alt="Donate with Liberapay" src="/img/liberapay-donate.svg"/></a>
## About {#about}
🦀 Site generated with [zola](https://www.getzola.org/).
🧮 Hosted on a Raspberry Pi in Bègles, near Bordeaux, France.
📜 This website is published under the terms of the <a rel="license" href="//creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a> license. ([Source code](https://git.txmn.tk/tuxmain/website)) ([EULA](@/eula.md))
<a class="hidden" href="/admin">admin</a>

View file

@ -0,0 +1,6 @@
+++
page_template = "blog.html"
title = "Blogo"
sort_by = "date"
insert_anchors = "right"
+++

View file

@ -0,0 +1,6 @@
+++
page_template = "blog.html"
title = "Blog"
sort_by = "date"
insert_anchors = "right"
+++

6
content/blog/_index.md Normal file
View file

@ -0,0 +1,6 @@
+++
page_template = "blog.html"
title = "Blog"
sort_by = "date"
insert_anchors = "right"
+++

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,64 @@
+++
title = "Aŭtonoma Atmega328P, paŝ-paŝe"
date = 2022-09-12
description = "Facila gvido por programi aŭtonoman Atmega328P-on kun Arduino."
[taxonomies]
tags = ["elektroniko", "Arduino"]
+++
Ĉi tiu gvido priskribas kiel programi aŭtonoman mikrokontrolilon Atmega328P uzante karton Arduino, kaj exteran oscilatoron je 16MHz. Ĝi rezultas el mia frustro kaŭzita de ĉiuj miaj malsukcesaj provoj, kaj de legoj de malkompletaj instruiloj. Nun mi trovis funkciantan metodon, mi ĝin publikigas tie por ne perdi ĝin.
## Necesa aparataro
* Atmega328P (la "P" gravas)
* karto Arduino (mi uzis unu Arduino Micro)
* oscilatoro 16MHz
* 2× kondensiloj 22pF
* rezistilo 10kΩ
* kondensilo 100µF
### Komento
Se vi ne havas kondensilon je 22pF, vi povas trovi iujn en malnovaj aparatoj (ekzemple, videosurbendigiloj enhavas multan). Malfeliĉe la trairantaj kondensiloj je tiu valoro ŝajne malabundas, do vi eble devos malveldi multajn surfacajn kondensilojn kaj trovi la bonaj uzante unu [simpla ]
Si vous n'avez aucun condensateur de 22pF, vous pouvez en récupérer dans un vieil appareil (par exemple il y en a plein dans les magnétoscopes). Malheureusement les condensateurs traversants de cette valeur ont l'air assez rares, donc vous devrez peut-être récupérer plein de condensateurs montés en surface et trouver les bons en fabriquant un [capacimètre tout simple avec une Arduino](https://www.instructables.com/Capacitance-Meter/).
## Circuit
{{ float_img(alt="Circuit for programming the Atmega using an Arduino.", src="circuit.png", style="max-height:100vh;max-width:100%;") }}
La description des broches de l'Atmega328P peut être trouvée dans [sa fiche technique](atmega328p.pdf).
* Connectez les broches MOSI, MISO, SCK(=SCLK) de l'Arduino aux broches correspondantes de l'Atmega. (sur l'Arduino Uno, ce sont respectivement les broches 11, 12, 13)
* Connectez la broche 10 de l'Arduino à la broche Reset de l'Atmega.
* Connectez les deux pôles de l'oscillateur aux broches XTAL/TOSC de l'Atmega, et placez un condensateur de 22pF entre ces pôles et le GND.
* Connectez les GNDs. Connectez les VCC de l'Atmega, AVCC de l'Atmega et +5V de l'Arduino.
Vérifiez bien les branchements. Le MOSI va sur le MOSI et le MISO sur le MISO, ils ne sont pas échangés.
### En production
Les branchements suivants sont nécessaires seulement quand le microcontrôleur n'est pas connecté à l'Arduino.
* Placez une résistance pull-up sur Reset (une résistance de 10kΩ entre Reset et VCC).
* Placez un condensateur de 100µF entre GND et VCC.
* L'oscillateur et les petits condensateurs sont toujours nécessaires.
* VCC et AVCC doivent toujours être reliés.
## Programmation
J'utilise l'IDE Arduino.
D'abord, programmons l'Arduino pour en faire une sorte de relais entre l'ordinateur et le microcontrôleur&nbsp;:
1. Ouvrez le programme d'exemple `ArduinoISP`.
1. Si vous utilisez une Arduino Uno, décommentez la ligne `#define USE_OLD_STYLE_WIRING`.
1. Choisissez votre carte dans le _Type de carte_ (_Arduino Micro_ pour moi).
1. Choisissez votre programmateur habituel (en général _AVR ISP_).
1. Envoyez le programme normalement.
Nous pouvons enfin programmer le microcontrôleur&nbsp;:
1. Ouvrez le programme voulu. (ou testez avec l'exemple `Blink`)
1. Choisissez le type de carte _Arduino Uno_. (même si vous utilisez une autre carte comme programmateur&#8239;; c'est parce qu'un Atmega328P seul avec un oscillateur 16MHz se comporte comme une Arduino Uno)
1. Choisissez le programmateur _Arduino as ISP_.
1. Si le microcontrôleur ne contient pas encore de bootloader, faites _Outils -> Graver la séquence d'initialisation_.
1. Envoyez le programme avec _Croquis -> Téléverser avec un programmateur_.

View file

@ -0,0 +1,62 @@
+++
title = "Atmega328P indépendant, pas à pas"
date = 2022-09-12
description = "Guide simple pour programmer un Atmega328P indépendant avec une Arduino"
[taxonomies]
tags = ["électronique", "Arduino"]
+++
Ce guide décrit comment programmer un microcontrôleur Atmega328P en utilisant une carte Arduino comme programmateur, et un oscillateur 16MHz externe. Il est le résultat de la frustration qu'ont provoqué chez moi toutes les tentatives infructueuses et les lectures de tutoriels incomplets. Maintenant que j'ai trouvé une méthode qui marche, je la publie ici afin de ne pas la perdre.
## Matériel nécessaire
* Atmega328P (le P change tout)
* Arduino board (j'ai utilisé une Arduino Micro)
* oscillateur 16MHz
* 2× condensateur 22pF
* résistance 10kΩ
* condensateur 100µF
### Note
Si vous n'avez aucun condensateur de 22pF, vous pouvez en récupérer dans un vieil appareil (par exemple il y en a plein dans les magnétoscopes). Malheureusement les condensateurs traversants de cette valeur ont l'air assez rares, donc vous devrez peut-être récupérer plein de condensateurs montés en surface et trouver les bons en fabriquant un [capacimètre tout simple avec une Arduino](https://www.instructables.com/Capacitance-Meter/).
## Circuit
{{ float_img(alt="Circuit for programming the Atmega using an Arduino.", src="circuit.png", style="max-height:100vh;max-width:100%;") }}
La description des broches de l'Atmega328P peut être trouvée dans [sa fiche technique](atmega328p.pdf).
* Connectez les broches MOSI, MISO, SCK(=SCLK) de l'Arduino aux broches correspondantes de l'Atmega. (sur l'Arduino Uno, ce sont respectivement les broches 11, 12, 13)
* Connectez la broche 10 de l'Arduino à la broche Reset de l'Atmega.
* Connectez les deux pôles de l'oscillateur aux broches XTAL/TOSC de l'Atmega, et placez un condensateur de 22pF entre ces pôles et le GND.
* Connectez les GNDs. Connectez les VCC de l'Atmega, AVCC de l'Atmega et +5V de l'Arduino.
Vérifiez bien les branchements. Le MOSI va sur le MOSI et le MISO sur le MISO, ils ne sont pas échangés.
### En production
Les branchements suivants sont nécessaires seulement quand le microcontrôleur n'est pas connecté à l'Arduino.
* Placez une résistance pull-up sur Reset (une résistance de 10kΩ entre Reset et VCC).
* Placez un condensateur de 100µF entre GND et VCC.
* L'oscillateur et les petits condensateurs sont toujours nécessaires.
* VCC et AVCC doivent toujours être reliés.
## Programmation
J'utilise l'IDE Arduino.
D'abord, programmons l'Arduino pour en faire une sorte de relais entre l'ordinateur et le microcontrôleur&nbsp;:
1. Ouvrez le programme d'exemple `ArduinoISP`.
1. Si vous utilisez une Arduino Uno, décommentez la ligne `#define USE_OLD_STYLE_WIRING`.
1. Choisissez votre carte dans le _Type de carte_ (_Arduino Micro_ pour moi).
1. Choisissez votre programmateur habituel (en général _AVR ISP_).
1. Envoyez le programme normalement.
Nous pouvons enfin programmer le microcontrôleur&nbsp;:
1. Ouvrez le programme voulu. (ou testez avec l'exemple `Blink`)
1. Choisissez le type de carte _Arduino Uno_. (même si vous utilisez une autre carte comme programmateur&#8239;; c'est parce qu'un Atmega328P seul avec un oscillateur 16MHz se comporte comme une Arduino Uno)
1. Choisissez le programmateur _Arduino as ISP_.
1. Si le microcontrôleur ne contient pas encore de bootloader, faites _Outils -> Graver la séquence d'initialisation_.
1. Envoyez le programme avec _Croquis -> Téléverser avec un programmateur_.

View file

@ -0,0 +1,62 @@
+++
title = "Standalone Atmega328P guide"
date = 2022-09-12
description = "Simple guide to program a standalone Atmega328P using an Arduino."
[taxonomies]
tags = ["electronics", "Arduino"]
+++
This guide describes how to burn a program into an Atmega328P microcontroller, using an Arduino board as programmer and an external 16MHz oscillator. It's the result of the frustration that every single time I wanted to to this, it was a struggle because I couldn't find any _complete_ tutorial. At least, the following works for me.
## Materials needed
* Atmega328P (the P matters)
* Arduino board (I used an Arduino Micro)
* 16MHz oscillator
* 2× 22pF capacitors
* 10kΩ resistor
* 100µF capacitor
### Notes
If you don't have any 22pF capacitor, you can salvage some capacitors from an old device (e.g. there are plenty in videotape readers). Unfortunately through-hole capacitors with this value look pretty rare, so you may need to salvage a bunch of unmarked surface-mounted ones and [build a simple Arduino-based capacitance meter](https://www.instructables.com/Capacitance-Meter/) to find the wanted ones.
## Circuit
{{ float_img(alt="Circuit for programming the Atmega using an Arduino.", src="circuit.png", style="max-height:100vh;max-width:100%;") }}
Check Atmega328P's pinout [in the datasheet](atmega328p.pdf).
* Connect the MOSI, MISO, SCK(=SCLK) pins on the Arduino to the corresponding ones on the Atmega. (on Arduino Uno, they are respectively on pins 11, 12, 13)
* Connect Arduino pin 10 to Atmega's Reset pin.
* Connect each pin on the oscillator to the XTAL/TOSC pins on the Atmega, and place a 22pF capacitor between each of these two pins and the GND.
* Connect the GNDs together. Connect Atmega's VCC, Atmega's AVCC and Arduino's +5V together.
Triple-check the wiring. MOSI goes on MOSI and MISO goes on MISO, they are not swapped.
### For normal operation
The following connections are only needed when the microcontroller is disconnected from the Arduino.
* Place a pull-up resistor on the Reset pin (10kΩ resistor between Reset and VCC).
* Place a 100µF capacitor between GND and VCC.
* The oscillator and ceramic capacitors are still needed.
* VCC and AVCC still have to be connected.
## Program
I'm using the Arduino IDE.
First, we program the Arduino board to make it operating as a relay between the computer and the microcontroller:
1. Open the example sketch `ArduinoISP`.
1. If using an Arduino Uno, uncomment the line `#define USE_OLD_STYLE_WIRING`.
1. Choose your programmer board as board type (_Arduino Micro_ in my case).
1. Choose a regular programmer (typically _AVR ISP_).
1. Upload the sketch normally.
Now we can program the microcontroller:
1. Open the wanted sketch. (or start with the `Blink` example)
1. Choose _Arduino Uno_ as board type. (even if you're using another board as a programmer; it's because a standalone Atmega328P with a 16MHz oscillator behaves like an Arduino Uno)
1. Choose _Arduino as ISP_ as programmer.
1. If your microcontroller doesn't contain a bootloader yet, upload the bootloader using _Tools -> Burn bootloader_.
1. Upload the sketch using _Sketch -> Upload using programmer_.

View file

@ -0,0 +1,15 @@
+++
title = "Homomorfia kriptografio"
date = 2022-03-04
description = "Kurta prezento de la homomorfia kriptografio, kun ekzemploj kaj uzadoj (franca)"
[taxonomies]
tags = ["kriptografio", "matematiko"]
[extra]
katex = true
+++
$$f:(G,*)\longrightarrow (G',\star)\quad|\quad\forall (g,h)\in G^2,~f(g *h)=f(g)\star f(h)$$
Ĉi tiu dokumento estas komprenebla per studentoj en unua yaro de matematiko. Ĝi rapide prezentas homomorfian kriptografion, iom ekzemplojn kaj uzadojn.
[Legi PDF (franca)](//cloud.txmn.tk/index.php/s/EygkDWqCsZLiTaL/download?path=&files=mss.pdf)

View file

@ -0,0 +1,15 @@
+++
title = "Chiffrement homomorphe"
date = 2022-03-04
description = "Une présentation rapide du chiffrement homomorphe, de quelques exemples et de ses applications."
[taxonomies]
tags = ["cryptographie", "mathématiques"]
[extra]
katex = true
+++
$$f:(G,*)\longrightarrow (G',\star)\quad|\quad\forall (g,h)\in G^2,~f(g *h)=f(g)\star f(h)$$
Ce document de niveau troisième semestre de mathématiques (prérequis&nbsp;: bases d'algèbre linéaire et d'arithmétique) présente rapidement le chiffrement homomorphe, quelques exemples et applications.
[Lire au format PDF](//cloud.txmn.tk/index.php/s/EygkDWqCsZLiTaL/download?path=&files=mss.pdf)

View file

@ -0,0 +1,15 @@
+++
title = "Homomorphic encryption"
date = 2022-03-04
description = "A quick overview of homomorphic encryption, examples and applications (French)"
[taxonomies]
tags = ["cryptography", "mathematics"]
[extra]
katex = true
+++
$$f:(G,*)\longrightarrow (G',\star)\quad|\quad\forall (g,h)\in G^2,~f(g *h)=f(g)\star f(h)$$
This document is accessible to a student in first year of mathematics. It briefly introduces homomorphic encryption, some examples and its applications.
[Read PDF (French)](//cloud.txmn.tk/index.php/s/EygkDWqCsZLiTaL/download?path=&files=mss.pdf)

View file

@ -0,0 +1,59 @@
+++
title = "Minitel kiel terminalo GNU/Linux"
date = 2022-05-15
description = "Ankoraŭ provo uzi Minitel kiel terminalo."
draft=true
[taxonomies]
tags = ["Minitel", "retro", "Arduino"]
+++
**Celo: uzi unu [Minitel](https://eo.wikipedia.org/wiki/Minitel) kiel terminalo de sistemo GNU/Linux.**
{{ float_img(alt="Minitel elmontranta la logotipon de Rust.", src="minitel_rust.jpg", style="max-height:100vh;max-width:min(800px,100%)") }}
Ĉi tio artikolo publikiĝis en la franclingva revuo [_Programmez!_ #256](https://www.programmez.com/magazine/programmez-253-pdf), kio enhavas multajn artikolojn pri la Minitel kaj sia interfacaĵo.
## 😎 La erao de la ĉirkaŭ-komputiko {#ĉirkaŭ-komputiko}
La Minitel enhavas ĉirkaŭ-komputikan kontaktilon (france "prise péri-informatique"), kiu estas eneligo. Por komuniki kun ĝi, sufiĉas seria interfaco. Do mi uzis Arduinon kiel ponto inter Minitel kaj komputilo. Zorgu tamen, necesas Arduino kun multaj seriaj interfacoj (ekzemple la Mega). Ĉi tio evitas al ni programi serian pelilon. La normo ĉirkaŭ-komputiko uzas preskaŭ ASCII 7-bitoj en bitokoj. La fortpeza bito estas la kontrolsumo.
## 🔌 Elektroniko {#elektroniko}
{{ float_img(alt="Konektoskemo", src="minitel_wiring.svg", style="width:300px;background-color:#fff") }}
* Konektu la GND de la Minitel (stifto 2, en la medio) al GND de la Arduino;
* Konektu la RX de la Minitel (stifto 1, en la tute maldekstro de GND) al TX1 de la Arduino;
* Konektu la RX1 de la Arduino al TX de la Minitel (stifto 3, en la tute dekstro de GND) tra 220Ω rezistilo, kaj al +5V tra _pull-up_ 2200Ω rezistilo (ĉiu valoro inter 1kΩ kaj 20kΩ devus funkcii). La rezistilo necesas ĉar la eligo de la Minitel estas +8,5V.
## 💻️ Programaro {#programaro}
Unue mi programis kontrolilon en Python. Ĝi simulas terminalon, kun USB kiel eneligo. Ĝi legas komandan linion, kaj ĝin efektivigas kiam la klavo "Sendo" frapiĝas.
{{ float_img(alt="Minitel ekmontranta la logotipon de Rust.", src="minitel_fortune.jpg", style="max-height:100vh;max-width:min(800px,100%)") }}
Tio sola malfaciligis:
* Ne estas klavo "Novan Linion". Nur klavo "Ĉaretrevenigo". Sed feliĉe estas la bitoko "Novan Linion", ni do povas uzi CRLF.
* Il n'y a pas de touche Nouvelle Ligne. Seulement une touche Retour Chariot. Mais par miracle le caractère Nouvelle Ligne existe, on peut donc utiliser du CRLF. Ça veut dire qu'il faut interpréter la touche Envoi (qui a un code sur deux octets) comme LF, et transformer les LF venant de Linux en CRLF.
* Les accents ne sont pas standard. Une lettre accentuée fait trois octets&nbsp;: un qui indique un caractère spécial, un qui spécifie l'accent, et la lettre. Et attention&#8239;! On a droit aux majuscules accentuées (coucou Windows, le Minitel fait une chose mieux que toi), mais seulement les accents franchouillards. La piñata et le glacier [würmien](https://fr.wiktionary.org/wiki/würmien) n'ont pas la nationalité.
* Le clavier est en majuscule, et les minuscules demandent l'appui de Maj. Si on veut inverser ce comportement, on doit pour chaque lettre arrivant au contrôleur, renvoyer un retour arrière puis la lettre en casse inversée. On voit le clignotement à l'écran et ça oblige à taper assez lentement pour que la réécriture ait le temps de s'opérer.
* Le port péri-informatique supporte 1200 bit/s, soit un rafraîchissement complet de l'écran en plus de 6 secondes. Certains modèles sont plus rapides, jusqu'à 9600 bit/s. Cette lenteur oblige à optimiser l'affichage pour plus d'immédiateté. On ne peut pas rafraîchir tout l'écran en permanence, il faut envoyer uniquement les caractères qui changent. Donc s'il y a un bug (un imprévu dans le programme, un problème de signal, un utilisateur qui tape trop vite), l'écran ne sera pas dans l'état attendu, et le programme, qui n'a aucun moyen de le savoir, continuera même s'il écrit n'importe quoi.
* En mode semi-graphique, les caractères sont remplacés par une grille de 2×3 pixels. On peut alors dessiner, en convertissant les images correctement. On a même quelques nuances de gris&#8239;! (pas 50 mais c'est déjà bien) L'inconvénient, c'est que le changement de couleur agit sur le caractère entier, soit 6 pixels, et non sur chaque pixel individuellement. La gestion de la couleur est donc un peu délicate.
* Si l'affichage est modifié en permanence, par exemple dans un jeu de Snake pour déplacer le serpent, l'appui de n'importe quelle touche peut interférer avec un caractère spécial de plusieurs octets envoyé par le contrôleur. Il en résulte un comportement imprévisible, et souvent un caractère aléatoire qui s'affiche. C'est pourquoi dans le Snake et dans le Tetris que j'ai faits, l'écran se retrouve vite constellé de caractères. J'ai essayé de nettoyer des petites parties différentes de l'écran en permanence, par exemple ligne par ligne, mais cela prend trop de temps, réduit la réactivité du jeu et n'est pas très efficace.
* L'écran est très petit, 40×24 caractères seulement. Aussi, il ne défile pas mais reboucle en haut quand le curseur arrive en bas. Il n'est donc pas vraiment adapté à un terminal de type Unix. Il faut soit créer un système de pagination, qui nettoie l'écran à chaque page, soit accepter de reboucler et nettoyer la fin de la ligne.
* Certains caractères manquent, comme la barre verticale `|`. Cette dernière étant indispensable dans un terminal, j'ai décidé de la substituer aux accents circonflexes `^` qui sont bizarrement affichés `↑` sur le Minitel.
* Côté Linux ce n'est pas facile non plus... Il faut pouvoir indiquer aux programmes la taille du terminal, qu'ils comprennent qu'ils sont dans un terminal et non dans un script, pour que par exemple bash écrive son invite de commande (_prompt_), gérer le retour arrière (qui n'est pas géré directement par bash), etc.
Toutes ces contraintes rendent la conception d'un terminal générique compliquée. Il faut que chaque programme adapte sa gestion du clavier et de l'affichage, car les besoins sont différents pour un utilitaire en ligne de commande, un éditeur de texte, une messagerie instantanée ou un jeu en temps réel.
On m'a donc donné l'idée d'une approche différente&nbsp;: plutôt que d'envoyer la sortie des programmes au Minitel, on garde un tampon de l'écran du Minitel en mémoire. C'est un tableau de l'état de chaque caractère, dont le mode texte ou semi-graphique, la couleur, le clignotement, le code du caractère, etc. Les programmes écrivent dedans, puis demandent au contrôleur de l'envoyer. Au prix de calculs plus lents (ce qui reste négligeable), l'algorithme cherche alors à envoyer le moins de données possibles. Les caractères inchangés ne sont pas renvoyés, on profite de l'instruction plaçant le curseur à la position donnée et de celle permettant de répéter les N derniers caractères.
J'ai implémenté ce nouveau contrôleur en [Rust](https://www.rust-lang.org/) (un langage bas-niveau offrant des abstractions haut-niveau sans coût et la sécurité de la mémoire), ce qui permet un code plus propre, sûr et rapide qu'en Python. C'est une bibliothèque réutilisable (publiée sous licence libre GNU AGPL), que j'ai pu utiliser pour faire un terminal, un Tetris et un Snake.
Au prix de [quelques nanosieverts](https://en.wikipedia.org/w/index.php?title=Cathode-ray_tube&oldid=1087446467#Ionizing_radiation) et d'un ultrason désagréable, cette petite aventure rétro m'a plongé dans une époque que je n'ai pas connue, [quoique j'y vis peut-être encore](https://framatube.org/w/9a8642c0-62f0-4060-95e4-088de9c5db00).
Ressources utiles&nbsp;:
* [Dépôt Git du code du projet](https://git.jeunes-science.asso.fr/tuxmain/Minitel)
* [Notice du Minitel 1 Bistandard (PDF)](https://wiki.labomedia.org/images/c/c7/Minitel1BAlcatel1.pdf)
* [Table des codes de programmation du Minitel](http://millevaches.hydraule.org/info/minitel/specs/codes.htm)
* [Jeunes-Science Bordeaux](https://www.jeunes-science.asso.fr/), club de loisirs scientifiques, disposant entre autres de pièces de collection telles que le Minitel qui a été utilisé pour réaliser ce projet.

View file

@ -0,0 +1,57 @@
+++
title = "Le Minitel comme terminal GNU/Linux"
date = 2022-07-02
description = "Encore une tentative d'utilisation d'un Minitel comme terminal."
[taxonomies]
tags = ["Minitel", "rétro", "Arduino"]
+++
**Objectif&nbsp;: utiliser un [Minitel](https://fr.wikipedia.org/wiki/Minitel) comme terminal d'un système GNU/Linux.**
{{ float_img(alt="Minitel affichant le logo de Rust.", src="minitel_rust.jpg", style="max-height:100vh;max-width:min(800px,100%)") }}
Cet article est paru dans le magazine [_Programmez!_ #256](https://www.programmez.com/magazine/programmez-253-pdf), qui contient plusieurs autres articles concernant le Minitel et son interfaçage.
## 😎 L'ère de la péri-informatique {#péri-informatique}
Le Minitel dispose d'une prise "péri-informatique", qui est un port série d'entrée-sortie. Il suffit pour communiquer avec d'une interface série. J'ai donc utilisé une Arduino comme pont entre le Minitel et l'ordinateur. Mais attention, il faut un Arduino possédant plusieurs interfaces série (comme le Mega). Cela nous évite d'avoir à coder un pilote série logiciel. Le standard péri-informatique utilise à peu près de l'ASCII 7 bits et un découpage en octets. Le bit de poids fort est la somme de contrôle des 7 autres.
## 🔌 Électronique {#électronique}
{{ float_img(alt="Schéma du branchement", src="minitel_wiring.svg", style="width:300px;background-color:#fff") }}
* Connectez le GND du Minitel (pin 2, celui du milieu) au GND de l'Arduino&#8239;;
* Connectez le RX du Minitel (pin 1, tout à gauche du GND) au TX1 de l'Arduino&#8239;;
* Connectez le RX1 de l'Arduino au TX du Minitel (pin 3, tout à droite du GND) à travers une résistance de 220Ω, et au +5V à travers une résistance pull-up de 2200Ω (toute valeur entre 1kΩ et 20kΩ devrait marcher). La résistance est nécessaire car la sortie du Minitel est en +8,5V.
## 💻️ Logiciel {#logiciel}
J'ai d'abord codé un contrôleur en Python. C'est une sorte d'émulateur de terminal, avec le port USB comme entrée-sortie. Il prend une ligne de commande et l'exécute à l'appui de la touche Envoi.
{{ float_img(alt="Minitel affichant le logo de Rust.", src="minitel_fortune.jpg", style="max-height:100vh;max-width:min(800px,100%)") }}
Rien que ça demandait de surmonter plusieurs difficultés&nbsp;:
* Il n'y a pas de touche Nouvelle Ligne. Seulement une touche Retour Chariot. Mais par miracle le caractère Nouvelle Ligne existe, on peut donc utiliser du CRLF. Ça veut dire qu'il faut interpréter la touche Envoi (qui a un code sur deux octets) comme LF, et transformer les LF venant de Linux en CRLF.
* Les accents ne sont pas standard. Une lettre accentuée fait trois octets&nbsp;: un qui indique un caractère spécial, un qui spécifie l'accent, et la lettre. Et attention&#8239;! On a droit aux majuscules accentuées (coucou Windows, le Minitel te surpasse), mais seulement les accents franchouillards. La piñata et le glacier [würmien](https://fr.wiktionary.org/wiki/würmien) n'ont pas la nationalité.
* Le clavier est en majuscule, et les minuscules demandent l'appui de Maj. Si on veut inverser ce comportement, on doit pour chaque lettre arrivant au contrôleur, renvoyer un retour arrière puis la lettre en casse inversée. On voit le clignotement à l'écran et ça oblige à taper assez lentement pour que la réécriture ait le temps de s'opérer.
* Le port péri-informatique supporte 1200 bit/s, soit un rafraîchissement complet de l'écran en plus de 6 secondes. Certains modèles sont plus rapides, jusqu'à 9600 bit/s. Cette lenteur oblige à optimiser l'affichage pour plus d'immédiateté. On ne peut pas rafraîchir tout l'écran en permanence, il faut envoyer uniquement les caractères qui changent. Donc s'il y a un bug (un imprévu dans le programme, un problème de signal, un utilisateur qui tape trop vite), l'écran ne sera pas dans l'état attendu, et le programme, qui n'a aucun moyen de le savoir, continuera même s'il écrit n'importe quoi.
* En mode semi-graphique, les caractères sont remplacés par une grille de 2×3 pixels. On peut alors dessiner, en convertissant les images correctement. On a même quelques nuances de gris&#8239;! (pas 50 mais c'est déjà bien) L'inconvénient, c'est que le changement de couleur agit sur le caractère entier, soit 6 pixels, et non sur chaque pixel individuellement. La gestion de la couleur est donc un peu délicate.
* Si l'affichage est modifié en permanence, par exemple dans un jeu de Snake pour déplacer le serpent, l'appui de n'importe quelle touche peut interférer avec un caractère spécial de plusieurs octets envoyé par le contrôleur. Il en résulte un comportement imprévisible, et souvent un caractère aléatoire qui s'affiche. C'est pourquoi dans le Snake et dans le Tetris que j'ai faits, l'écran se retrouve vite constellé de caractères. J'ai essayé de nettoyer des petites parties différentes de l'écran en permanence, par exemple ligne par ligne, mais cela prend trop de temps, réduit la réactivité du jeu et n'est pas très efficace.
* L'écran est très petit, 40×24 caractères seulement. Aussi, il ne défile pas mais reboucle en haut quand le curseur arrive en bas. Il n'est donc pas vraiment adapté à un terminal de type Unix. Il faut soit créer un système de pagination, qui nettoie l'écran à chaque page, soit accepter de reboucler et nettoyer la fin de la ligne.
* Certains caractères manquent, comme la barre verticale `|`. Cette dernière étant indispensable dans un terminal, j'ai décidé de la substituer aux accents circonflexes `^` qui sont bizarrement affichés `↑` sur le Minitel.
* Côté Linux ce n'est pas facile non plus... Il faut pouvoir indiquer aux programmes la taille du terminal, qu'ils comprennent qu'ils sont dans un terminal et non dans un script, pour que par exemple bash écrive son invite de commande (_prompt_), gérer le retour arrière (qui n'est pas géré directement par bash), etc.
Toutes ces contraintes rendent la conception d'un terminal générique compliquée. Il faut que chaque programme adapte sa gestion du clavier et de l'affichage, car les besoins sont différents pour un utilitaire en ligne de commande, un éditeur de texte, une messagerie instantanée ou un jeu en temps réel.
On m'a donc donné l'idée d'une approche différente&nbsp;: plutôt que d'envoyer la sortie des programmes au Minitel, on garde un tampon de l'écran du Minitel en mémoire. C'est un tableau de l'état de chaque caractère, dont le mode texte ou semi-graphique, la couleur, le clignotement, le code du caractère, etc. Les programmes écrivent dedans, puis demandent au contrôleur de l'envoyer. Au prix de calculs plus lents (ce qui reste négligeable), l'algorithme cherche alors à envoyer le moins de données possibles. Les caractères inchangés ne sont pas renvoyés, on profite de l'instruction plaçant le curseur à la position donnée et de celle permettant de répéter les N derniers caractères.
J'ai implémenté ce nouveau contrôleur en [Rust](https://www.rust-lang.org/) (un langage bas-niveau offrant des abstractions haut-niveau sans coût et la sécurité de la mémoire), ce qui permet un code plus propre, sûr et rapide qu'en Python. C'est une bibliothèque réutilisable (publiée sous licence libre GNU AGPL), que j'ai pu utiliser pour faire un terminal, un Tetris et un Snake.
Au prix de [quelques nanosieverts](https://en.wikipedia.org/w/index.php?title=Cathode-ray_tube&oldid=1087446467#Ionizing_radiation) et d'un ultrason désagréable, cette petite aventure rétro m'a plongé dans une époque que je n'ai pas connue, [quoique j'y vis peut-être encore](https://framatube.org/w/9a8642c0-62f0-4060-95e4-088de9c5db00).
Ressources utiles&nbsp;:
* [Dépôt Git du code du projet](https://git.jeunes-science.asso.fr/tuxmain/Minitel)
* [Notice du Minitel 1 Bistandard (PDF)](https://wiki.labomedia.org/images/c/c7/Minitel1BAlcatel1.pdf)
* [Table des codes de programmation du Minitel](http://millevaches.hydraule.org/info/minitel/specs/codes.htm)
* [Jeunes-Science Bordeaux](https://www.jeunes-science.asso.fr/), club de loisirs scientifiques, disposant entre autres de pièces de collection telles que le Minitel qui a été utilisé pour réaliser ce projet.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

View file

@ -0,0 +1,749 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="4.000500cm" height="4.000500cm" viewBox="0 0 15750 15750">
<title>SVG Picture created as minitel_wiring.svg date 2022/05/09 20:38:52 </title>
<desc>Picture generated by Eeschema-SVG </desc>
<g style="fill:#000000; fill-opacity:1.000000;stroke:#000000; stroke-opacity:1.000000;
stroke-linecap:round; stroke-linejoin:round;"
transform="translate(0 0) scale(1 1)">
</g>
<g style="fill:#000000; fill-opacity:0.0;
stroke:#000000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<g >
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:100.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M4000.012296 10499.962942 A2018.228346 2018.228346 0.0 0 0 5699.029252 12499.834408" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<circle cx="4800.000000" cy="10500.000000" r="200.000000" />
<circle cx="5100.000000" cy="9600.000000" r="200.000000" />
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 4000.000000,10500.000000
4600.000000,10500.000000
" />
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 6000.000000,8500.000000
6000.000000,9000.000000
" />
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 8000.000000,10500.000000
7400.000000,10500.000000
" />
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 4000.000000,9500.000000
4300.000000,9500.000000
4900.000000,9600.000000
" />
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 8000.000000,9500.000000
7700.000000,9500.000000
7100.000000,9600.000000
" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:100.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:100.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 5700.000000,12450.000000
5700.000000,12150.000000
6300.000000,12150.000000
6300.000000,12450.000000
" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<circle cx="6000.000000" cy="9200.000000" r="200.000000" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:100.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M6301.115055 12499.813369 A2005.826772 2005.826772 0.0 0 0 8000.002364 10500.094507" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<circle cx="6900.000000" cy="9600.000000" r="200.000000" />
<circle cx="7200.000000" cy="10500.000000" r="200.000000" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:100.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M7999.996954 10496.509343 A2000.000000 2000.000000 0.0 0 0 4000.003046 10496.509343" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M4000 10500
L3000 10500
" />
<text x="3500.000000" y="10400.000000"
textLength="606.181102" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">1</text>
<g class="stroked-text"><desc>1</desc>
<path d="M3642 10376
L3357 10376
" />
<path d="M3500 10376
L3500 9876
L3452 9947
L3404 9995
L3357 10019
" />
</g><path d="M6000 8500
L6000 7500
" />
<g transform="rotate(-90.000000 5900.000000 8000.000000)">
<text x="5900.000000" y="8000.000000"
textLength="536.181102" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">2</text>
</g>
<g class="stroked-text"><desc>2</desc>
<path d="M5423 8142
L5400 8119
L5376 8071
L5376 7952
L5400 7904
L5423 7880
L5471 7857
L5519 7857
L5590 7880
L5876 8166
L5876 7857
" />
</g><path d="M8000 10500
L9000 10500
" />
<text x="8500.000000" y="10400.000000"
textLength="536.181102" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">3</text>
<g class="stroked-text"><desc>3</desc>
<path d="M8333 9876
L8642 9876
L8476 10066
L8547 10066
L8595 10090
L8619 10114
L8642 10161
L8642 10280
L8619 10328
L8595 10352
L8547 10376
L8404 10376
L8357 10352
L8333 10328
" />
</g><path d="M4000 9500
L3000 9500
" />
<text x="3500.000000" y="9400.000000"
textLength="536.181102" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">4</text>
<g class="stroked-text"><desc>4</desc>
<path d="M3595 9042
L3595 9376
" />
<path d="M3476 8852
L3357 9209
L3666 9209
" />
</g><path d="M8000 9500
L9000 9500
" />
<text x="8500.000000" y="9400.000000"
textLength="536.181102" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">5</text>
<g class="stroked-text"><desc>5</desc>
<path d="M8619 8876
L8380 8876
L8357 9114
L8380 9090
L8428 9066
L8547 9066
L8595 9090
L8619 9114
L8642 9161
L8642 9280
L8619 9328
L8595 9352
L8547 9376
L8428 9376
L8380 9352
L8357 9328
" />
</g></g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<text x="6000.039370" y="13749.960630"
textLength="2536.181102" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">Minitel</text>
<g class="stroked-text"><desc>Minitel</desc>
<path d="M4880 13726
L4880 13226
L5047 13583
L5214 13226
L5214 13726
" />
<path d="M5452 13726
L5452 13392
" />
<path d="M5452 13226
L5428 13249
L5452 13273
L5476 13249
L5452 13226
L5452 13273
" />
<path d="M5690 13392
L5690 13726
" />
<path d="M5690 13440
L5714 13416
L5761 13392
L5833 13392
L5880 13416
L5904 13464
L5904 13726
" />
<path d="M6142 13726
L6142 13392
" />
<path d="M6142 13226
L6119 13249
L6142 13273
L6166 13249
L6142 13226
L6142 13273
" />
<path d="M6309 13392
L6500 13392
" />
<path d="M6380 13226
L6380 13654
L6404 13702
L6452 13726
L6500 13726
" />
<path d="M6857 13702
L6809 13726
L6714 13726
L6666 13702
L6642 13654
L6642 13464
L6666 13416
L6714 13392
L6809 13392
L6857 13416
L6880 13464
L6880 13511
L6642 13559
" />
<path d="M7166 13726
L7119 13702
L7095 13654
L7095 13226
" />
</g></g>
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<g >
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 9700.000000,4000.000000
10000.000000,3500.000000
" />
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 10000.000000,4500.000000
10000.000000,3500.000000
" />
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 10000.000000,3500.000000
10300.000000,4000.000000
" />
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<text x="10000.000000" y="2749.960630"
textLength="1583.818898" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">+5V</text>
<g class="stroked-text"><desc>+5V</desc>
<path d="M9357 2535
L9738 2535
" />
<path d="M9547 2726
L9547 2345
" />
<path d="M10214 2226
L9976 2226
L9952 2464
L9976 2440
L10023 2416
L10142 2416
L10190 2440
L10214 2464
L10238 2511
L10238 2630
L10214 2678
L10190 2702
L10142 2726
L10023 2726
L9976 2702
L9952 2678
" />
<path d="M10380 2226
L10547 2726
L10714 2226
" />
</g></g>
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<g >
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:100.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<rect x="9600.000000" y="5000.000000" width="800.000000" height="2000.000000" rx="0.000000" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M10000 5000
L10000 4500
" />
<path d="M10000 7000
L10000 7500
" />
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<text x="11519.330709" y="5749.921260"
textLength="1036.181102" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">R2</text>
<g class="stroked-text"><desc>R2</desc>
<path d="M11435 5726
L11269 5487
" />
<path d="M11150 5726
L11150 5226
L11340 5226
L11388 5249
L11412 5273
L11435 5321
L11435 5392
L11412 5440
L11388 5464
L11340 5487
L11150 5487
" />
<path d="M11626 5273
L11650 5249
L11697 5226
L11816 5226
L11864 5249
L11888 5273
L11912 5321
L11912 5368
L11888 5440
L11602 5726
L11912 5726
" />
</g><text x="11983.622047" y="6749.921260"
textLength="1964.763780" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">2200</text>
<g class="stroked-text"><desc>2200</desc>
<path d="M11126 6273
L11150 6249
L11197 6226
L11316 6226
L11364 6249
L11388 6273
L11412 6321
L11412 6368
L11388 6440
L11102 6726
L11412 6726
" />
<path d="M11602 6273
L11626 6249
L11674 6226
L11793 6226
L11840 6249
L11864 6273
L11888 6321
L11888 6368
L11864 6440
L11578 6726
L11888 6726
" />
<path d="M12197 6226
L12245 6226
L12293 6249
L12316 6273
L12340 6321
L12364 6416
L12364 6535
L12340 6630
L12316 6678
L12293 6702
L12245 6726
L12197 6726
L12150 6702
L12126 6678
L12102 6630
L12078 6535
L12078 6416
L12102 6321
L12126 6273
L12150 6249
L12197 6226
" />
<path d="M12674 6226
L12721 6226
L12769 6249
L12793 6273
L12816 6321
L12840 6416
L12840 6535
L12816 6630
L12793 6678
L12769 6702
L12721 6726
L12674 6726
L12626 6702
L12602 6678
L12578 6630
L12555 6535
L12555 6416
L12578 6321
L12602 6273
L12626 6249
L12674 6226
" />
</g></g>
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<g >
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;fill:none"
d="M 7500.000000,4500.000000
7500.000000,5000.000000
8000.000000,5000.000000
7500.000000,5500.000000
7000.000000,5000.000000
7500.000000,5000.000000
" />
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<text x="7500.000000" y="6749.960630"
textLength="1583.818898" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">GND</text>
<g class="stroked-text"><desc>GND</desc>
<path d="M7119 6249
L7071 6226
L7000 6226
L6928 6249
L6880 6297
L6857 6345
L6833 6440
L6833 6511
L6857 6607
L6880 6654
L6928 6702
L7000 6726
L7047 6726
L7119 6702
L7142 6678
L7142 6511
L7047 6511
" />
<path d="M7357 6726
L7357 6226
L7642 6726
L7642 6226
" />
<path d="M7880 6726
L7880 6226
L8000 6226
L8071 6249
L8119 6297
L8142 6345
L8166 6440
L8166 6511
L8142 6607
L8119 6654
L8071 6702
L8000 6726
L7880 6726
" />
</g></g>
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<g >
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:100.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<rect x="9600.000000" y="8000.000000" width="800.000000" height="2000.000000" rx="0.000000" />
</g>
<g style="fill:#840000; fill-opacity:0.0;
stroke:#840000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M10000 8000
L10000 7500
" />
<path d="M10000 10000
L10000 10500
" />
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<text x="11519.330709" y="8749.921260"
textLength="1036.181102" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">R1</text>
<g class="stroked-text"><desc>R1</desc>
<path d="M11435 8726
L11269 8487
" />
<path d="M11150 8726
L11150 8226
L11340 8226
L11388 8249
L11412 8273
L11435 8321
L11435 8392
L11412 8440
L11388 8464
L11340 8487
L11150 8487
" />
<path d="M11912 8726
L11626 8726
" />
<path d="M11769 8726
L11769 8226
L11721 8297
L11674 8345
L11626 8368
" />
</g><text x="11745.551181" y="9749.921260"
textLength="1488.582677" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="middle" opacity="0">220</text>
<g class="stroked-text"><desc>220</desc>
<path d="M11126 9273
L11150 9249
L11197 9226
L11316 9226
L11364 9249
L11388 9273
L11412 9321
L11412 9368
L11388 9440
L11102 9726
L11412 9726
" />
<path d="M11602 9273
L11626 9249
L11674 9226
L11793 9226
L11840 9249
L11864 9273
L11888 9321
L11888 9368
L11864 9440
L11578 9726
L11888 9726
" />
<path d="M12197 9226
L12245 9226
L12293 9249
L12316 9273
L12340 9321
L12364 9416
L12364 9535
L12340 9630
L12316 9678
L12293 9702
L12245 9726
L12197 9726
L12150 9702
L12126 9678
L12102 9630
L12078 9535
L12078 9416
L12102 9321
L12126 9273
L12150 9249
L12197 9226
" />
</g></g>
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:62.519685; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
</g>
<g style="fill:#008484; fill-opacity:0.0;
stroke:#008484; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
</g>
<g style="fill:#000000; fill-opacity:0.0;
stroke:#000000; stroke-width:60.000000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<text x="2000.000000" y="6862.480315"
textLength="1393.346457" font-size="666.653543" lengthAdjust="spacingAndGlyphs"
text-anchor="start" opacity="0">TX1</text>
<g class="stroked-text"><desc>TX1</desc>
<path d="M2077 6338
L2363 6338
" />
<path d="M2220 6838
L2220 6338
" />
<path d="M2482 6338
L2815 6838
" />
<path d="M2815 6338
L2482 6838
" />
<path d="M3268 6838
L2982 6838
" />
<path d="M3125 6838
L3125 6338
L3077 6410
L3030 6457
L2982 6481
" />
</g></g>
<g style="fill:#000000; fill-opacity:0.0;
stroke:#000000; stroke-wi