Spelling fixes...
This commit is contained in:
parent
a5161afd72
commit
1af6779b0a
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||||
|
|
||||||
= Cargo
|
= Cargo
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ Bibliothek. +
|
|||||||
Es wird auch gleich `main.rs`, ein `.git`-Ordner (inkl. `.gitignore`)
|
Es wird auch gleich `main.rs`, ein `.git`-Ordner (inkl. `.gitignore`)
|
||||||
und `Cargo.toml` erstellt.
|
und `Cargo.toml` erstellt.
|
||||||
|
|
||||||
== Angelegte Datein
|
== Angelegte Dateien
|
||||||
|
|
||||||
=== Cargo.toml
|
=== Cargo.toml
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||||
|
|
||||||
= Erstes Spiel
|
= Erstes Spiel
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ CLI-Eingabe
|
|||||||
** ohne die ``use'' Anweisung oben, müsste es `std::io::stdin()` sein
|
** ohne die ``use'' Anweisung oben, müsste es `std::io::stdin()` sein
|
||||||
* `.read_line(&mut guess)` ließt eine Zeile und speichert sie in guess
|
* `.read_line(&mut guess)` ließt eine Zeile und speichert sie in guess
|
||||||
** `&` erstellt dabei eine Referenz (wie in C)
|
** `&` erstellt dabei eine Referenz (wie in C)
|
||||||
** Referenzen sind standardmäßig imutable - deshalb `&mut`
|
** Referenzen sind standardmäßig immutable - deshalb `&mut`
|
||||||
** `read_line()` gibt ein `Result`-Objekt zurück, dieser kann `Ok` oder
|
** `read_line()` gibt ein `Result`-Objekt zurück, dieser kann `Ok` oder
|
||||||
`Err` enthalten
|
`Err` enthalten
|
||||||
* `.expect("Fehlermeldung")` entpackt das `Result`-Objekt
|
* `.expect("Fehlermeldung")` entpackt das `Result`-Objekt
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||||
|
|
||||||
= Konzepte
|
= Konzepte
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ fn main() {
|
|||||||
|
|
||||||
Die Ausgabe des Programms ist dabei der letztere Wert, hier also 10.
|
Die Ausgabe des Programms ist dabei der letztere Wert, hier also 10.
|
||||||
Es ist also mehr eine neue Variable unter dem selben Namen wie die alte.
|
Es ist also mehr eine neue Variable unter dem selben Namen wie die alte.
|
||||||
Sogar der Datentyp kann sich dabei ändern, man muss sich also nicht ständig neue Namen für Variabeln ausdenken, nur weil man sie casted (Juchuu!).
|
Sogar der Datentyp kann sich dabei ändern, man muss sich also nicht ständig neue Namen für Variablen ausdenken, nur weil man sie casted (Juchuu!).
|
||||||
|
|
||||||
Da Variablen immer Block-Scope-basiert (?) sind, kann dies natürlich auch in einem eingebetteten Block genutzt werden.
|
Da Variablen immer Block-Scope-basiert (?) sind, kann dies natürlich auch in einem eingebetteten Block genutzt werden.
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ Chars werden mit single-quotes geschrieben (Strings mit doppelten quotes).
|
|||||||
|
|
||||||
Allerdings scheint es noch ein wenig komplizierter zu sein, das kommt aber erst später.
|
Allerdings scheint es noch ein wenig komplizierter zu sein, das kommt aber erst später.
|
||||||
|
|
||||||
=== Combound Types
|
=== Compound Types
|
||||||
Gruppierung von mehreren Werten in einem Typ.
|
Gruppierung von mehreren Werten in einem Typ.
|
||||||
|
|
||||||
==== Tupel
|
==== Tupel
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||||
|
|
||||||
= Ownership
|
= Ownership
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html[Link zum Buc
|
|||||||
== Was ist das?
|
== Was ist das?
|
||||||
|
|
||||||
Jeder Wert hat eine Variable, die ihn "besitzt".
|
Jeder Wert hat eine Variable, die ihn "besitzt".
|
||||||
Jeder Wert kann zu einem Zeitpunkt nur von _einer_ Variable bessessen werden.
|
Jeder Wert kann zu einem Zeitpunkt nur von _einer_ Variable besessen werden.
|
||||||
Sollte die Variable aus dem Scope verschwinden, wird der Wert ungültig und aus dem Speicher entfernt.
|
Sollte die Variable aus dem Scope verschwinden, wird der Wert ungültig und aus dem Speicher entfernt.
|
||||||
|
|
||||||
== Warum?
|
== Warum?
|
||||||
@ -148,4 +148,4 @@ Fun fact: String Literale sind auch Slices und damit Referenzen von Strings.
|
|||||||
Noch mehr fun fact: Da dynamische String und String Literale damit quasi den selben Typ beschreiben, haben sie auch den gemeinsamen Typ `&str`.
|
Noch mehr fun fact: Da dynamische String und String Literale damit quasi den selben Typ beschreiben, haben sie auch den gemeinsamen Typ `&str`.
|
||||||
Für Leseoperationen kann also im Allgemeinen dieser benutzt werden.
|
Für Leseoperationen kann also im Allgemeinen dieser benutzt werden.
|
||||||
|
|
||||||
Slices können auch mutable sein, dafür muss aber das ursprüngliche Array mmutable sein und es kann immer nur ein mutable Slice gleichzetig existieren (also genauso wie beim Ownership).
|
Slices können auch mutable sein, dafür muss aber das ursprüngliche Array mutable sein und es kann immer nur ein mutable Slice gleichzeitig existieren (also genauso wie beim Ownership).
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||||
|
|
||||||
= Enums und Pattern Matching
|
= Enums und Pattern Matching
|
||||||
|
|
||||||
@ -73,13 +73,13 @@ Es gibt zwar keine Attribute, aber da ja auch die internen Structs Methoden habe
|
|||||||
|
|
||||||
Options hab ich oben schonmal kurz beschrieben.
|
Options hab ich oben schonmal kurz beschrieben.
|
||||||
In Rust ist dieser Datentyp sehr wichtig.
|
In Rust ist dieser Datentyp sehr wichtig.
|
||||||
Die Dokumentation dazu ist https://doc.rust-lang.org/std/option/enum.Option.html[hier zu finden] und enthält sehr viel Wichtiges und Interesantes.
|
Die Dokumentation dazu ist https://doc.rust-lang.org/std/option/enum.Option.html[hier zu finden] und enthält sehr viel Wichtiges und Interessantes.
|
||||||
|
|
||||||
== `match`
|
== `match`
|
||||||
|
|
||||||
`match` ist quasi das `switch` von Rust.
|
`match` ist quasi das `switch` von Rust.
|
||||||
Nur kann es auch prüfen, ob eine Variable einem Enum-Typen angehört.
|
Nur kann es auch prüfen, ob eine Variable einem Enum-Typen angehört.
|
||||||
So wie Rust bis jetzt klang, kann wahrscheinlich jedem Datentypen ein "match-Trait" gegeben werden, der dann eine "Zugehörigkeit" (Gleicheit stimmt ja irgendwie nicht) prüfen kann.
|
So wie Rust bis jetzt klang, kann wahrscheinlich jedem Datentypen ein "match-Trait" gegeben werden, der dann eine "Zugehörigkeit" (Gleichheit stimmt ja irgendwie nicht) prüfen kann.
|
||||||
|
|
||||||
Aber ganz einfach: Angenommen wir wollen die Methode `to_css_string` von oben implementieren.
|
Aber ganz einfach: Angenommen wir wollen die Methode `to_css_string` von oben implementieren.
|
||||||
Diese Methode muss ja, je nach Typ, völlig unterschiedlich funktionieren.
|
Diese Methode muss ja, je nach Typ, völlig unterschiedlich funktionieren.
|
||||||
@ -124,7 +124,7 @@ Der Unterschied ist, dass bei `other` noch der Inhalt genutzt werden kann, bei `
|
|||||||
=== `if let`
|
=== `if let`
|
||||||
|
|
||||||
Dieses if-Konstrukt nutzt man am besten, wenn man nur auf eine einzelne Variante eines Enums prüfen möchte.
|
Dieses if-Konstrukt nutzt man am besten, wenn man nur auf eine einzelne Variante eines Enums prüfen möchte.
|
||||||
Letzendlich ist es ganz simpel:
|
Letztendlich ist es ganz simpel:
|
||||||
|
|
||||||
[source, rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-22T14:29:34+02:00
|
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||||
|
|
||||||
= How to: Projektmanagement
|
= How to: Projektmanagement
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-c
|
|||||||
|
|
||||||
== Packages, Crates, Modules, was?
|
== Packages, Crates, Modules, was?
|
||||||
|
|
||||||
Rust hat ein sehr hierachisches Konzept, was die Strukturierung von Projekten angeht.
|
Rust hat ein sehr hierarchisches Konzept, was die Strukturierung von Projekten angeht.
|
||||||
|
|
||||||
Fangen wir mal von oben an:
|
Fangen wir mal von oben an:
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ Ihr Merkmal ist vor allem, dass eine `main`-Funktion existiert, die der Einstieg
|
|||||||
|
|
||||||
==== Library Crate
|
==== Library Crate
|
||||||
|
|
||||||
Wie der Name schon sagt, stellt diese Art Crate nur Funktionen zur verfügung wie eine Bibliothek.
|
Wie der Name schon sagt, stellt diese Art Crate nur Funktionen zur Verfügung wie eine Bibliothek.
|
||||||
|
|
||||||
=== Modules
|
=== Modules
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ fn main() {
|
|||||||
|
|
||||||
Dagegen gilt für Enums: Wenn der Enum public ist, sind auch alle Varianten public.
|
Dagegen gilt für Enums: Wenn der Enum public ist, sind auch alle Varianten public.
|
||||||
|
|
||||||
==== Abürzungen mit `use`
|
==== Abkürzungen mit `use`
|
||||||
|
|
||||||
Angenommen, wir haben eine Mediathek mit Filmen, Serien, Spielen, etc. und brauchen immer lange Zugriffspfade (also z.B. `crate::medien::spiele::liste::add()`), obwohl wir nur Spiele brauchen, kann `use` benutzt werden.
|
Angenommen, wir haben eine Mediathek mit Filmen, Serien, Spielen, etc. und brauchen immer lange Zugriffspfade (also z.B. `crate::medien::spiele::liste::add()`), obwohl wir nur Spiele brauchen, kann `use` benutzt werden.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-22T14:29:34+02:00
|
:docdatetime: 2022-10-18T17:56:27+02:00
|
||||||
|
|
||||||
= Standard Collections
|
= Standard Collections
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ Das macht das ganze ordentlich schwierig.
|
|||||||
|
|
||||||
Ist immer eine schlechte Idee, außer man weiß exakt wie lang die einzelnen Zeichen (in Byte) des Strings sind.
|
Ist immer eine schlechte Idee, außer man weiß exakt wie lang die einzelnen Zeichen (in Byte) des Strings sind.
|
||||||
Im Englischen ist es normalerweise 1 Byte pro Zeichen, Umlaute sind schon 2, und so weiter.
|
Im Englischen ist es normalerweise 1 Byte pro Zeichen, Umlaute sind schon 2, und so weiter.
|
||||||
Sollte man außversehen ein Zeichen "durchschneiden" (also nur 1 Byte eines "ü" im Slice haben), gibt es eine Runtime Panic.
|
Sollte man aus Versehen ein Zeichen "durchschneiden" (also nur 1 Byte eines "ü" im Slice haben), gibt es eine Runtime Panic.
|
||||||
|
|
||||||
=== Iterieren
|
=== Iterieren
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ for b in "hallo".bytes() {
|
|||||||
// Wirft eben die einzelnen u8 raus.
|
// Wirft eben die einzelnen u8 raus.
|
||||||
----
|
----
|
||||||
|
|
||||||
Wenn wir "grapheme" haben wollen (Was anscheinend sowas wie "volle Zeichen" sind, mehr als nur char), gibt es keine eingebaute Funktion aber crates, die das lösen.
|
Wenn wir "grapheme" haben wollen (Was anscheinend so etwas wie "volle Zeichen" sind, mehr als nur char), gibt es keine eingebaute Funktion aber crates, die das lösen.
|
||||||
|
|
||||||
== HashMaps
|
== HashMaps
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
// -- Erstellen --
|
// -- Erstellen --
|
||||||
// iter(), zip() und collect()
|
// iter(), zip() und collect()
|
||||||
// collect() kann in alles mögliche wandeln, deshalb muss der Typ anggeben werden.
|
// collect() kann in alles mögliche wandeln, deshalb muss der Typ angegeben werden.
|
||||||
let woerter = vec![String::from("eins"), String::from("zwei"), String::from("drei")];
|
let woerter = vec![String::from("eins"), String::from("zwei"), String::from("drei")];
|
||||||
let zahlen = vec![1, 2, 3];
|
let zahlen = vec![1, 2, 3];
|
||||||
let mut zahlwort: HashMap<_, _> = woerter.into_iter().zip(zahlen.into_iter()).collect();
|
let mut zahlwort: HashMap<_, _> = woerter.into_iter().zip(zahlen.into_iter()).collect();
|
||||||
|
15
list.json
15
list.json
@ -5,11 +5,11 @@
|
|||||||
"short_desc": "The terminal on my website.",
|
"short_desc": "The terminal on my website.",
|
||||||
"desc": [
|
"desc": [
|
||||||
"This is part of my homepage.",
|
"This is part of my homepage.",
|
||||||
"What you see here should resemble an CLI. If you ever used Linux this should be pretty easy for you.",
|
"What you see on the page resembles an CLI. You just type in commands and some output is shown or it does something on the website.",
|
||||||
"Everyone else: Have no fear. It is pretty simple. You just type in commands and the output is shown here or it does something on the webite.",
|
"To find out which commands are available, you can just type %{help}.",
|
||||||
"To find out, which commands are available, you can type just %{help}.",
|
|
||||||
"",
|
"",
|
||||||
"Currently everything is still in development. So if you come back in a few days/weeks/months/years something could have been changed!",
|
"Everything is always in development. So if you come back in a few days/weeks/months/years something could have been changed!",
|
||||||
|
"You can also check out the #%{dev version|https://dev.c0ntroller.de} if you haven't already.",
|
||||||
"",
|
"",
|
||||||
"Have fun!"
|
"Have fun!"
|
||||||
],
|
],
|
||||||
@ -33,7 +33,7 @@
|
|||||||
"name": "rust",
|
"name": "rust",
|
||||||
"short_desc": "Me learning Rust (German).",
|
"short_desc": "Me learning Rust (German).",
|
||||||
"desc": [
|
"desc": [
|
||||||
"I documented my progress to lern the Rust programming language.",
|
"I documented my progress to learn the Rust programming language.",
|
||||||
"It follows the #%{Rust book|https://doc.rust-lang.org/book/} with my own annotations.",
|
"It follows the #%{Rust book|https://doc.rust-lang.org/book/} with my own annotations.",
|
||||||
"Everything is in German as these notes are mostly meant for me."
|
"Everything is in German as these notes are mostly meant for me."
|
||||||
],
|
],
|
||||||
@ -57,7 +57,8 @@
|
|||||||
"short_desc": "TUfast is a browser extension that is used by multiple thousand users of the TU Dresden.",
|
"short_desc": "TUfast is a browser extension that is used by multiple thousand users of the TU Dresden.",
|
||||||
"desc": [
|
"desc": [
|
||||||
"TUfast is a browser extension that is used by multiple thousand users of the TU Dresden.",
|
"TUfast is a browser extension that is used by multiple thousand users of the TU Dresden.",
|
||||||
"It provides autologin to the most used portals, shortcuts, redirects, and more."
|
"It provides autologin to the most used portals, shortcuts, redirects, and more.",
|
||||||
|
"I'm one of the developers."
|
||||||
],
|
],
|
||||||
"repo": "https://github.com/TUfast-TUD/TUfast_TUD",
|
"repo": "https://github.com/TUfast-TUD/TUfast_TUD",
|
||||||
"more": "https://tu-fast.de/",
|
"more": "https://tu-fast.de/",
|
||||||
@ -94,7 +95,7 @@
|
|||||||
"short_desc": "A script that syncs a Google Photos album to your drive.",
|
"short_desc": "A script that syncs a Google Photos album to your drive.",
|
||||||
"desc": [
|
"desc": [
|
||||||
"Giving random apps access to your Google Photos can be bad.",
|
"Giving random apps access to your Google Photos can be bad.",
|
||||||
"To still use an album as screenaver etc. I wrote this script.",
|
"To still use an album as screensaver etc. I wrote this script.",
|
||||||
"It syncs all your photos to your drive while giving you maximum privacy."
|
"It syncs all your photos to your drive while giving you maximum privacy."
|
||||||
],
|
],
|
||||||
"repo": "https://git.c0ntroller.de/c0ntroller/simple-callback-server",
|
"repo": "https://git.c0ntroller.de/c0ntroller/simple-callback-server",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-07-29T11:27:37+02:00
|
:docdatetime: 2022-10-18T17:56:27+02:00
|
||||||
|
|
||||||
= Overleaf Sync with Git
|
= Overleaf Sync with Git
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ But how to use them?
|
|||||||
|
|
||||||
== Access granted
|
== Access granted
|
||||||
|
|
||||||
I noticed the front end uses session IDs for user authentification.
|
I noticed the front end uses session IDs for user authentication.
|
||||||
You get an ID, you POST valid credentials (and a CSRF token) to `/login` and your session ID get's "verified".
|
You get an ID, you POST valid credentials (and a CSRF token) to `/login` and your session ID get's "verified".
|
||||||
|
|
||||||
Using their repository, it was easy to find other routes that are useable.
|
Using their repository, it was easy to find other routes that are useable.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-08T12:19:20+02:00
|
:docdatetime: 2022-10-18T17:56:27+02:00
|
||||||
|
|
||||||
= Simple Callback Server
|
= Simple Callback Server
|
||||||
|
|
||||||
@ -12,12 +12,12 @@ Still, I needed it sometimes and I didn't want to rewrite it every time I use it
|
|||||||
|
|
||||||
== What can it be used for?
|
== What can it be used for?
|
||||||
|
|
||||||
When creating a dev application on Google, Spotify, or other services you often have some heavy authentification flow to get access.
|
When creating a dev application on Google, Spotify, or other services you often have some heavy authentication flow to get access.
|
||||||
But normally I want to use the API for private projects and it's _my_ account that gets authenticated every time.
|
But normally I want to use the API for private projects and it's _my_ account that gets authenticated every time.
|
||||||
|
|
||||||
To make reauthentication easier these OAuth protocols often provide a "refresh token" which can be used to get a valid new token.
|
To make reauthentication easier these OAuth protocols often provide a "refresh token" which can be used to get a valid new token.
|
||||||
|
|
||||||
To get the initial authentification token and to get such a refresh token you provide a callback address where you get redirected after the user logs in.
|
To get the initial authentication token and to get such a refresh token you provide a callback address where you get redirected after the user logs in.
|
||||||
The tokens and meta information normally are sent in a `POST` body.
|
The tokens and meta information normally are sent in a `POST` body.
|
||||||
And this is where this small application is necessary.
|
And this is where this small application is necessary.
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-08-10T17:09:32+02:00
|
:docdatetime: 2022-10-18T17:56:27+02:00
|
||||||
|
|
||||||
= c0ntroller.de
|
= Terminal
|
||||||
|
|
||||||
Hello and welcome to my website.
|
Hello and welcome to my CLI website.
|
||||||
|
|
||||||
== Why did I do this?
|
== Why did I do this?
|
||||||
Mainly because of boredom and because I like to code.
|
Mainly because of boredom and because I like to code.
|
||||||
@ -62,12 +62,12 @@ I talked about shortcuts before, but here's a list of which shortcuts are possib
|
|||||||
|kbd:[▲] / kbd:[▼]
|
|kbd:[▲] / kbd:[▼]
|
||||||
|Scroll through last commands.
|
|Scroll through last commands.
|
||||||
|
|
||||||
|kbd:[Strg+L]
|
|kbd:[Ctrl+L]
|
||||||
|Clears the history. +
|
|Clears the history. +
|
||||||
Similar to `clear`.
|
Similar to `clear`.
|
||||||
|
|
||||||
|kbd:[Strg+D]
|
|kbd:[Ctrl+D]
|
||||||
|Exits the page. Don't work in (most?) cases because of a https://developer.mozilla.org/en-US/docs/Web/API/Window/close[JavaScript restriction]. +
|
|Exits the page. Doesn't work in (most?) cases because of a https://developer.mozilla.org/en-US/docs/Web/API/Window/close[JavaScript restriction]. +
|
||||||
Similar to `exit`.
|
Similar to `exit`.
|
||||||
|
|
||||||
|kbd:[Ctrl+U]/ +
|
|kbd:[Ctrl+U]/ +
|
||||||
@ -82,8 +82,8 @@ kbd:[Ctrl+C]
|
|||||||
- Every line in the history window is parsed in a custom format.
|
- Every line in the history window is parsed in a custom format.
|
||||||
* `%{command}` is parsed to a clickable command
|
* `%{command}` is parsed to a clickable command
|
||||||
* `#{link text|url}` is parsed to a link
|
* `#{link text|url}` is parsed to a link
|
||||||
- Project logs are loaded dynamicly. They can be updated at any time.
|
- Project logs are loaded dynamically. They can be updated at any time.
|
||||||
- There are lots of eastereggs. Some are for specfic people, some for me and some for fun.
|
- There are lots of eastereggs. Some are for specific people, some for me and some for fun.
|
||||||
- I made some custom annotations for code blocks show faulty code (wrong syntax/will not compile/etc.).
|
- I made some custom annotations for code blocks show faulty code (wrong syntax/will not compile/etc.).
|
||||||
|
|
||||||
[source.notCompiling, rust]
|
[source.notCompiling, rust]
|
||||||
|
Loading…
Reference in New Issue
Block a user