From 15df3ac5b2135acf91310cfd888455b0f6c2fb4a Mon Sep 17 00:00:00 2001
From: Pierre Jarriges <pierre.jarriges@tutanota.com>
Date: Fri, 5 Nov 2021 16:09:30 +0100
Subject: [PATCH] switch server to Actix

---
 .gitignore                                    |    2 +-
 Cargo.lock                                    | 2079 +++++++++++++++++
 Cargo.toml                                    |   16 +
 Dockerfile                                    |   20 +-
 LICENSE.md => LICENSE                         |    2 +-
 Makefile                                      |   38 +-
 README.md                                     |   72 +
 data/nginx/app.conf                           |   26 -
 dev.Dockerfile                                |    4 +
 dev.docker-compose.yml                        |   19 +
 docker-compose.yml                            |   28 +-
 init-letsencrypt.sh                           |   80 -
 public/education/education.js                 |    7 +
 public/education/index.html                   |   64 +-
 public/favicon.ico                            |  Bin 7758 -> 0 bytes
 public/games/games.js                         |    7 +
 public/games/index.html                       |   64 +-
 public/index.html                             |   78 +-
 public/main.js                                |    7 +
 public/robots.txt                             |    4 -
 public/sitemap.xml                            |   19 -
 public/software-development/index.html        |   64 +-
 .../software-development.js                   |    7 +
 readme.md                                     |    2 -
 src/env.rs                                    |   27 +
 src/main.rs                                   |   60 +
 src/standard_static_files.rs                  |   28 +
 src/tls.rs                                    |   43 +
 build.js => website/build.js                  |   10 +-
 config.js => website/config.js                |    0
 constants.js => website/constants.js          |    0
 .../package-lock.json                         |   61 +-
 package.json => website/package.json          |    4 +-
 .../src}/generic-components/image-carousel.js |    0
 .../home-page-components/kuadrado-values.js   |    0
 .../home-page-components/news-articles.js     |    0
 .../home-page-components/news-articles.scss   |    0
 .../src}/home-page-components/theme-card.js   |    0
 .../src}/home-page-components/whoami.js       |    0
 .../src}/home-page-components/whoami.scss     |    0
 {src => website/src}/homepage.js              |    0
 {src => website/src}/homepage.scss            |    0
 {src => website/src}/lib/article-utils.js     |    0
 {src => website/src}/lib/fetch.js             |    0
 {src => website/src}/lib/web-page.js          |    0
 {src => website/src}/main.js                  |    0
 .../src}/pages/education/education.js         |    0
 .../src}/pages/education/education.scss       |    0
 {src => website/src}/pages/education/index.js |    0
 .../src}/pages/education/meta.json            |    0
 .../pages/games/components/game-article.js    |    0
 .../pages/games/components/game-articles.js   |    0
 {src => website/src}/pages/games/games.js     |    0
 {src => website/src}/pages/games/games.scss   |    0
 {src => website/src}/pages/games/index.js     |    0
 {src => website/src}/pages/games/meta.json    |    0
 .../components/software-articles.js           |    0
 .../src}/pages/software-development/index.js  |    0
 .../src}/pages/software-development/meta.json |    0
 .../software-development.js                   |    0
 .../software-development.scss                 |    0
 {src => website/src}/run-page.js              |    0
 {src => website/src}/style.scss               |    0
 .../src}/template/components/navbar.js        |    0
 {src => website/src}/template/template.js     |    7 +
 {src => website/src}/theme.scss               |    0
 66 files changed, 2608 insertions(+), 341 deletions(-)
 create mode 100644 Cargo.lock
 create mode 100644 Cargo.toml
 rename LICENSE.md => LICENSE (99%)
 create mode 100644 README.md
 delete mode 100644 data/nginx/app.conf
 create mode 100644 dev.Dockerfile
 create mode 100644 dev.docker-compose.yml
 delete mode 100755 init-letsencrypt.sh
 delete mode 100644 public/favicon.ico
 delete mode 100644 public/robots.txt
 delete mode 100644 public/sitemap.xml
 delete mode 100644 readme.md
 create mode 100644 src/env.rs
 create mode 100644 src/main.rs
 create mode 100644 src/standard_static_files.rs
 create mode 100644 src/tls.rs
 rename build.js => website/build.js (94%)
 rename config.js => website/config.js (100%)
 rename constants.js => website/constants.js (100%)
 rename package-lock.json => website/package-lock.json (98%)
 rename package.json => website/package.json (90%)
 rename {src => website/src}/generic-components/image-carousel.js (100%)
 rename {src => website/src}/home-page-components/kuadrado-values.js (100%)
 rename {src => website/src}/home-page-components/news-articles.js (100%)
 rename {src => website/src}/home-page-components/news-articles.scss (100%)
 rename {src => website/src}/home-page-components/theme-card.js (100%)
 rename {src => website/src}/home-page-components/whoami.js (100%)
 rename {src => website/src}/home-page-components/whoami.scss (100%)
 rename {src => website/src}/homepage.js (100%)
 rename {src => website/src}/homepage.scss (100%)
 rename {src => website/src}/lib/article-utils.js (100%)
 rename {src => website/src}/lib/fetch.js (100%)
 rename {src => website/src}/lib/web-page.js (100%)
 rename {src => website/src}/main.js (100%)
 rename {src => website/src}/pages/education/education.js (100%)
 rename {src => website/src}/pages/education/education.scss (100%)
 rename {src => website/src}/pages/education/index.js (100%)
 rename {src => website/src}/pages/education/meta.json (100%)
 rename {src => website/src}/pages/games/components/game-article.js (100%)
 rename {src => website/src}/pages/games/components/game-articles.js (100%)
 rename {src => website/src}/pages/games/games.js (100%)
 rename {src => website/src}/pages/games/games.scss (100%)
 rename {src => website/src}/pages/games/index.js (100%)
 rename {src => website/src}/pages/games/meta.json (100%)
 rename {src => website/src}/pages/software-development/components/software-articles.js (100%)
 rename {src => website/src}/pages/software-development/index.js (100%)
 rename {src => website/src}/pages/software-development/meta.json (100%)
 rename {src => website/src}/pages/software-development/software-development.js (100%)
 rename {src => website/src}/pages/software-development/software-development.scss (100%)
 rename {src => website/src}/run-page.js (100%)
 rename {src => website/src}/style.scss (100%)
 rename {src => website/src}/template/components/navbar.js (100%)
 rename {src => website/src}/template/template.js (91%)
 rename {src => website/src}/theme.scss (100%)

diff --git a/.gitignore b/.gitignore
index 4bd38e2..25423e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,4 @@ bundle.js
 *.css.map
 src/**/*.css
 node_modules
-/data/certbot
\ No newline at end of file
+target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..6188139
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,2079 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "actix-codec"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570"
+dependencies = [
+ "bitflags",
+ "bytes 0.5.6",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project 0.4.28",
+ "tokio",
+ "tokio-util",
+]
+
+[[package]]
+name = "actix-connect"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc"
+dependencies = [
+ "actix-codec",
+ "actix-rt",
+ "actix-service",
+ "actix-utils",
+ "derive_more",
+ "either",
+ "futures-util",
+ "http",
+ "log",
+ "rustls",
+ "tokio-rustls",
+ "trust-dns-proto",
+ "trust-dns-resolver",
+ "webpki",
+]
+
+[[package]]
+name = "actix-files"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c51e8a9146c12fce92a6e4c24b8c4d9b05268130bfd8d61bc587e822c32ce689"
+dependencies = [
+ "actix-service",
+ "actix-web",
+ "bitflags",
+ "bytes 0.5.6",
+ "derive_more",
+ "futures-core",
+ "futures-util",
+ "log",
+ "mime",
+ "mime_guess",
+ "percent-encoding",
+ "v_htmlescape",
+]
+
+[[package]]
+name = "actix-http"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cb8958da437716f3f31b0e76f8daf36554128517d7df37ceba7df00f09622ee"
+dependencies = [
+ "actix-codec",
+ "actix-connect",
+ "actix-rt",
+ "actix-service",
+ "actix-threadpool",
+ "actix-tls",
+ "actix-utils",
+ "base64 0.13.0",
+ "bitflags",
+ "brotli2",
+ "bytes 0.5.6",
+ "cookie",
+ "copyless",
+ "derive_more",
+ "either",
+ "encoding_rs",
+ "flate2",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "fxhash",
+ "h2",
+ "http",
+ "httparse",
+ "indexmap",
+ "itoa",
+ "language-tags",
+ "lazy_static",
+ "log",
+ "mime",
+ "percent-encoding",
+ "pin-project 1.0.8",
+ "rand",
+ "regex",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sha-1",
+ "slab",
+ "time",
+]
+
+[[package]]
+name = "actix-macros"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "actix-router"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ad299af73649e1fc893e333ccf86f377751eb95ff875d095131574c6f43452c"
+dependencies = [
+ "bytestring",
+ "http",
+ "log",
+ "regex",
+ "serde",
+]
+
+[[package]]
+name = "actix-rt"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227"
+dependencies = [
+ "actix-macros",
+ "actix-threadpool",
+ "copyless",
+ "futures-channel",
+ "futures-util",
+ "smallvec",
+ "tokio",
+]
+
+[[package]]
+name = "actix-server"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e"
+dependencies = [
+ "actix-codec",
+ "actix-rt",
+ "actix-service",
+ "actix-utils",
+ "futures-channel",
+ "futures-util",
+ "log",
+ "mio",
+ "mio-uds",
+ "num_cpus",
+ "slab",
+ "socket2",
+]
+
+[[package]]
+name = "actix-service"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb"
+dependencies = [
+ "futures-util",
+ "pin-project 0.4.28",
+]
+
+[[package]]
+name = "actix-testing"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c"
+dependencies = [
+ "actix-macros",
+ "actix-rt",
+ "actix-server",
+ "actix-service",
+ "log",
+ "socket2",
+]
+
+[[package]]
+name = "actix-threadpool"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30"
+dependencies = [
+ "derive_more",
+ "futures-channel",
+ "lazy_static",
+ "log",
+ "num_cpus",
+ "parking_lot",
+ "threadpool",
+]
+
+[[package]]
+name = "actix-tls"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb"
+dependencies = [
+ "actix-codec",
+ "actix-service",
+ "actix-utils",
+ "futures-util",
+ "rustls",
+ "tokio-rustls",
+ "webpki",
+ "webpki-roots",
+]
+
+[[package]]
+name = "actix-utils"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a"
+dependencies = [
+ "actix-codec",
+ "actix-rt",
+ "actix-service",
+ "bitflags",
+ "bytes 0.5.6",
+ "either",
+ "futures-channel",
+ "futures-sink",
+ "futures-util",
+ "log",
+ "pin-project 0.4.28",
+ "slab",
+]
+
+[[package]]
+name = "actix-web"
+version = "3.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86"
+dependencies = [
+ "actix-codec",
+ "actix-http",
+ "actix-macros",
+ "actix-router",
+ "actix-rt",
+ "actix-server",
+ "actix-service",
+ "actix-testing",
+ "actix-threadpool",
+ "actix-tls",
+ "actix-utils",
+ "actix-web-codegen",
+ "awc",
+ "bytes 0.5.6",
+ "derive_more",
+ "encoding_rs",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "fxhash",
+ "log",
+ "mime",
+ "pin-project 1.0.8",
+ "regex",
+ "rustls",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "socket2",
+ "time",
+ "tinyvec",
+ "url",
+]
+
+[[package]]
+name = "actix-web-codegen"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "actix-web-middleware-redirect-https"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ce1464786203c29120f6d1e4dcdc9c3975506e70b89c3a56c5389f265256dc6"
+dependencies = [
+ "actix-service",
+ "actix-web",
+ "futures",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.51"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+
+[[package]]
+name = "awc"
+version = "2.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691"
+dependencies = [
+ "actix-codec",
+ "actix-http",
+ "actix-rt",
+ "actix-service",
+ "base64 0.13.0",
+ "bytes 0.5.6",
+ "cfg-if 1.0.0",
+ "derive_more",
+ "futures-core",
+ "log",
+ "mime",
+ "percent-encoding",
+ "rand",
+ "rustls",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+]
+
+[[package]]
+name = "base-x"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
+
+[[package]]
+name = "base64"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
+
+[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "brotli-sys"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "brotli2"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e"
+dependencies = [
+ "brotli-sys",
+ "libc",
+]
+
+[[package]]
+name = "buf-min"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa17aa1cf56bdd6bb30518767d00e58019d326f3f05d8c3e0730b549d332ea83"
+dependencies = [
+ "bytes 0.5.6",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "bytes"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
+
+[[package]]
+name = "bytes"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
+
+[[package]]
+name = "bytestring"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d"
+dependencies = [
+ "bytes 1.1.0",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.70"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "const_fn"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7"
+
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
+name = "cookie"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951"
+dependencies = [
+ "percent-encoding",
+ "time",
+ "version_check 0.9.3",
+]
+
+[[package]]
+name = "copyless"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "derive_more"
+version = "0.99.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df"
+dependencies = [
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "rustc_version 0.3.3",
+ "syn",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "discard"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
+
+[[package]]
+name = "dotenv"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
+
+[[package]]
+name = "either"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "enum-as-inner"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crc32fast",
+ "libc",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
+dependencies = [
+ "matches",
+ "percent-encoding",
+]
+
+[[package]]
+name = "fuchsia-zircon"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+dependencies = [
+ "bitflags",
+ "fuchsia-zircon-sys",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+
+[[package]]
+name = "futures"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
+dependencies = [
+ "autocfg",
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
+
+[[package]]
+name = "futures-task"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
+
+[[package]]
+name = "futures-util"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
+dependencies = [
+ "autocfg",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite 0.2.7",
+ "pin-utils",
+ "proc-macro-hack",
+ "proc-macro-nested",
+ "slab",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+dependencies = [
+ "typenum",
+ "version_check 0.9.3",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "h2"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
+dependencies = [
+ "bytes 0.5.6",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+
+[[package]]
+name = "heck"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hostname"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
+dependencies = [
+ "libc",
+ "match_cfg",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "http"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
+dependencies = [
+ "bytes 1.1.0",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "httparse"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
+
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
+name = "idna"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
+dependencies = [
+ "matches",
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "iovec"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "ipconfig"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
+dependencies = [
+ "socket2",
+ "widestring",
+ "winapi 0.3.9",
+ "winreg",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+
+[[package]]
+name = "js-sys"
+version = "0.3.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "kernel32-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+dependencies = [
+ "winapi 0.2.8",
+ "winapi-build",
+]
+
+[[package]]
+name = "kuadrado_server"
+version = "2.0.0"
+dependencies = [
+ "actix-files",
+ "actix-web",
+ "actix-web-middleware-redirect-https",
+ "dotenv",
+ "env_logger",
+ "rustls",
+]
+
+[[package]]
+name = "language-tags"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.102"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
+
+[[package]]
+name = "linked-hash-map"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
+
+[[package]]
+name = "lock_api"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "lru-cache"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
+dependencies = [
+ "linked-hash-map",
+]
+
+[[package]]
+name = "match_cfg"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
+
+[[package]]
+name = "matches"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
+
+[[package]]
+name = "memchr"
+version = "2.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+
+[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "mime_guess"
+version = "2.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
+dependencies = [
+ "mime",
+ "unicase",
+]
+
+[[package]]
+name = "miniz_oxide"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
+dependencies = [
+ "adler",
+ "autocfg",
+]
+
+[[package]]
+name = "mio"
+version = "0.6.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
+dependencies = [
+ "cfg-if 0.1.10",
+ "fuchsia-zircon",
+ "fuchsia-zircon-sys",
+ "iovec",
+ "kernel32-sys",
+ "libc",
+ "log",
+ "miow",
+ "net2",
+ "slab",
+ "winapi 0.2.8",
+]
+
+[[package]]
+name = "mio-uds"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
+dependencies = [
+ "iovec",
+ "libc",
+ "mio",
+]
+
+[[package]]
+name = "miow"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
+dependencies = [
+ "kernel32-sys",
+ "net2",
+ "winapi 0.2.8",
+ "ws2_32-sys",
+]
+
+[[package]]
+name = "net2"
+version = "0.2.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
+dependencies = [
+ "cfg-if 0.1.10",
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "nom"
+version = "4.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
+dependencies = [
+ "memchr",
+ "version_check 0.1.5",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
+name = "parking_lot"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
+dependencies = [
+ "instant",
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
+dependencies = [
+ "cfg-if 1.0.0",
+ "instant",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+
+[[package]]
+name = "pest"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
+dependencies = [
+ "ucd-trie",
+]
+
+[[package]]
+name = "pin-project"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f"
+dependencies = [
+ "pin-project-internal 0.4.28",
+]
+
+[[package]]
+name = "pin-project"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
+dependencies = [
+ "pin-project-internal 1.0.8",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
+
+[[package]]
+name = "proc-macro-nested"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
+[[package]]
+name = "quote"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom",
+ "libc",
+ "rand_chacha",
+ "rand_core",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
+name = "resolv-conf"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
+dependencies = [
+ "hostname",
+ "quick-error",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted",
+ "web-sys",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+dependencies = [
+ "semver 0.9.0",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
+dependencies = [
+ "semver 0.11.0",
+]
+
+[[package]]
+name = "rustls"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81"
+dependencies = [
+ "base64 0.12.3",
+ "log",
+ "ring",
+ "sct",
+ "webpki",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "sct"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+dependencies = [
+ "semver-parser 0.7.0",
+]
+
+[[package]]
+name = "semver"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
+dependencies = [
+ "semver-parser 0.10.2",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
+[[package]]
+name = "semver-parser"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
+dependencies = [
+ "pest",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.130"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.130"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha-1"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
+dependencies = [
+ "block-buffer",
+ "cfg-if 1.0.0",
+ "cpufeatures",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sha1"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
+
+[[package]]
+name = "smallvec"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
+
+[[package]]
+name = "socket2"
+version = "0.3.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "standback"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
+dependencies = [
+ "version_check 0.9.3",
+]
+
+[[package]]
+name = "stdweb"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
+dependencies = [
+ "discard",
+ "rustc_version 0.2.3",
+ "stdweb-derive",
+ "stdweb-internal-macros",
+ "stdweb-internal-runtime",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "stdweb-derive"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_derive",
+ "syn",
+]
+
+[[package]]
+name = "stdweb-internal-macros"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
+dependencies = [
+ "base-x",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "sha1",
+ "syn",
+]
+
+[[package]]
+name = "stdweb-internal-runtime"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
+
+[[package]]
+name = "syn"
+version = "1.0.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "threadpool"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
+dependencies = [
+ "num_cpus",
+]
+
+[[package]]
+name = "time"
+version = "0.2.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242"
+dependencies = [
+ "const_fn",
+ "libc",
+ "standback",
+ "stdweb",
+ "time-macros",
+ "version_check 0.9.3",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "time-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1"
+dependencies = [
+ "proc-macro-hack",
+ "time-macros-impl",
+]
+
+[[package]]
+name = "time-macros-impl"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f"
+dependencies = [
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "standback",
+ "syn",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5241dd6f21443a3606b432718b166d3cedc962fd4b8bea54a8bc7f514ebda986"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+
+[[package]]
+name = "tokio"
+version = "0.2.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092"
+dependencies = [
+ "bytes 0.5.6",
+ "futures-core",
+ "iovec",
+ "lazy_static",
+ "libc",
+ "memchr",
+ "mio",
+ "mio-uds",
+ "pin-project-lite 0.1.12",
+ "signal-hook-registry",
+ "slab",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
+dependencies = [
+ "futures-core",
+ "rustls",
+ "tokio",
+ "webpki",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
+dependencies = [
+ "bytes 0.5.6",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project-lite 0.1.12",
+ "tokio",
+]
+
+[[package]]
+name = "tracing"
+version = "0.1.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8"
+dependencies = [
+ "cfg-if 1.0.0",
+ "log",
+ "pin-project-lite 0.2.7",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "tracing-futures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
+dependencies = [
+ "pin-project 1.0.8",
+ "tracing",
+]
+
+[[package]]
+name = "trust-dns-proto"
+version = "0.19.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cad71a0c0d68ab9941d2fb6e82f8fb2e86d9945b94e1661dd0aaea2b88215a9"
+dependencies = [
+ "async-trait",
+ "cfg-if 1.0.0",
+ "enum-as-inner",
+ "futures",
+ "idna",
+ "lazy_static",
+ "log",
+ "rand",
+ "smallvec",
+ "thiserror",
+ "tokio",
+ "url",
+]
+
+[[package]]
+name = "trust-dns-resolver"
+version = "0.19.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "710f593b371175db53a26d0b38ed2978fafb9e9e8d3868b1acd753ea18df0ceb"
+dependencies = [
+ "cfg-if 0.1.10",
+ "futures",
+ "ipconfig",
+ "lazy_static",
+ "log",
+ "lru-cache",
+ "resolv-conf",
+ "smallvec",
+ "thiserror",
+ "tokio",
+ "trust-dns-proto",
+]
+
+[[package]]
+name = "typenum"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
+
+[[package]]
+name = "ucd-trie"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
+
+[[package]]
+name = "unicase"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+dependencies = [
+ "version_check 0.9.3",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "url"
+version = "2.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "matches",
+ "percent-encoding",
+]
+
+[[package]]
+name = "v_escape"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3e0ab5fab1db278a9413d2ea794cb66f471f898c5b020c3c394f6447625d9d4"
+dependencies = [
+ "buf-min",
+ "v_escape_derive",
+]
+
+[[package]]
+name = "v_escape_derive"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c860ad1273f4eee7006cee05db20c9e60e5d24cba024a32e1094aa8e574f3668"
+dependencies = [
+ "nom",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "v_htmlescape"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f9a8af610ad6f7fc9989c9d2590d9764bc61f294884e9ee93baa58795174572"
+dependencies = [
+ "cfg-if 1.0.0",
+ "v_escape",
+]
+
+[[package]]
+name = "version_check"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
+
+[[package]]
+name = "version_check"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
+dependencies = [
+ "cfg-if 1.0.0",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
+dependencies = [
+ "bumpalo",
+ "lazy_static",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
+
+[[package]]
+name = "web-sys"
+version = "0.3.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.21.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f"
+dependencies = [
+ "webpki",
+]
+
+[[package]]
+name = "widestring"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
+
+[[package]]
+name = "winapi"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-build"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "winreg"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "ws2_32-sys"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
+dependencies = [
+ "winapi 0.2.8",
+ "winapi-build",
+]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..2f390d4
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "kuadrado_server"
+version = "2.0.0"
+authors = ["Pierre Jarriges <pierre.jarriges@tutanota.com>"]
+edition = "2018"
+license-file = "LICENSE"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+actix-web = { version = "3", features=["rustls"] }
+actix-web-middleware-redirect-https = "3.0.1"
+rustls="0.18.1"
+actix-files="0.5"
+env_logger="0.9"
+dotenv="0.15"
diff --git a/Dockerfile b/Dockerfile
index 819d2b9..0429e59 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,11 +1,9 @@
-FROM nginx
-
-## Remove default nginx index page
-RUN rm -rf /usr/share/nginx/html/*
-
-RUN apt-get update \
-    && apt-get install nodejs npm -y
-
-WORKDIR /usr/share/nginx/html
-
-COPY . .
\ No newline at end of file
+FROM kuadsoft/rust-openssl:latest as builder
+
+WORKDIR /usr/src/kuadrado_server
+COPY . .
+RUN cargo install --path .
+ 
+FROM kuadsoft/debian-openssl:buster-slim
+COPY --from=builder /usr/local/cargo/bin/kuadrado_server /usr/local/bin/kuadrado_server
+CMD ["kuadrado_server"]
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE
similarity index 99%
rename from LICENSE.md
rename to LICENSE
index 5d4367c..9c3fcf7 100644
--- a/LICENSE.md
+++ b/LICENSE
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
+SOFTWARE.
diff --git a/Makefile b/Makefile
index 131229b..22fccea 100644
--- a/Makefile
+++ b/Makefile
@@ -1,26 +1,32 @@
 run:
-	docker-compose up -d
-
-run-log:
 	docker-compose up
 
+run-dev:
+	docker-compose -f ./dev.docker-compose.yml up
+
 build:
-	docker-compose up --build -d
+	docker-compose up --build
+
+build-dev:
+	docker-compose -f ./dev.docker-compose.yml up  --build 
+
+reload-api:
+	docker-compose restart kuadrado_server
 
-stop:
-	docker-compose down
+test:
+	RESOURCES_DIR="./" cargo test -- --test-threads=1
 
-bash: 
-	docker exec -it kuadrado bash
+doc:
+	cargo doc --no-deps
 
-open:
-	firefox http://localhost/
+bash-api:
+	docker exec -it kuadrado_server bash
 
-push:
-	git add . && git commit -m "$(msg)" && git push origin HEAD
+build-front:
+	npm run --prefix ./website build
 
-update-prod:
-	git checkout . && git pull origin master && npm install && npm run build-prod
+build-front-debug:
+	npm run --prefix ./website build debug
 
-reload:
-	docker exec -it kuadrado nginx -s reload
\ No newline at end of file
+logs:
+	docker-compose logs -f
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..82dc5d4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,72 @@
+# Kuadrado Software Website
+
+## install
+
+### Prerequisite
+
+-   docker
+-   docker-compose
+-   certbot for prod or mkcert for dev
+
+---
+
+### TLS CERTS
+
+-   ### Localhost
+
+    With mkcert
+
+    ```sh
+    $ sudo mkdir -p /etc/letsencrypt/live/localhost
+    $ sudo chmod 777 -R /etc/letsencryt/live/localhost
+    $ mkcert -key-file privkey.pem -cert-file fullchain.pem localhost
+    ```
+
+-   ### Real server
+
+    Install snapd and certbot at system level. https://certbot.eff.org/lets-encrypt/debianbuster-other
+
+    Then run
+
+    ```sh
+    $ sudo certbot certonly --standalone
+    ```
+
+---
+
+## Build
+
+```sh
+$ git clone https://gitlab.com/kuadrado-software/kuadrado-website.git
+$ cd kuadrado-website
+
+$ touch ./.env
+# Fill .env file with the required variables described below
+
+# Build the website
+$ cd website
+$ npm install
+$ npm run build
+# or
+$ npm run build-debug
+
+$ cd ..
+
+# build the image and run the container
+$ docker-compose up --build
+# Or
+$ docker-compose -f ./dev.docker-compose.yml up --build
+```
+
+---
+
+## Expected environment variables
+
+_Env vars may be defined in a .env file at the root of the project_
+
+-   `RELEASE_MODE`: Can be either "debug", "test" or "prod". It's used to define the log level. Not required. Default is "prod"
+-   `SERVER_PORT`: The port bound the Actix server
+-   `SERVER_PORT_TLS`: The tls port bound the Actix server
+-   `SERVER_HOST`: IP address or domain name hosting the API.
+-   `SERVER_PROTOCOL`: http or https regarding the protocol used to connect the server
+-   `RESOURCES_DIR`: A linux directory that will be used to mount static resources like certs and html files
diff --git a/data/nginx/app.conf b/data/nginx/app.conf
deleted file mode 100644
index e26671f..0000000
--- a/data/nginx/app.conf
+++ /dev/null
@@ -1,26 +0,0 @@
-server {
-    listen 80;  
-    server_name kuadrado-software.fr www.kuadrado-software.fr;
-    root   /usr/share/nginx/html;
-    index  index.html index.htm;
-    server_tokens off;
-    location /.well-known/acme-challenge/ {
-        root /var/www/certbot;
-    }
-
-    location / {
-        return 301 https://$host$request_uri;
-    }
-}
-
-server {
-    server_name kuadrado-software.fr www.kuadrado-software.fr;
-    listen 443 ssl;
-    root   /usr/share/nginx/html;
-    index  index.html index.htm;
-    server_tokens off;
-    ssl_certificate /etc/letsencrypt/live/kuadrado-software.fr/fullchain.pem;
-    ssl_certificate_key /etc/letsencrypt/live/kuadrado-software.fr/privkey.pem;
-    include /etc/letsencrypt/options-ssl-nginx.conf;
-    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
-}
\ No newline at end of file
diff --git a/dev.Dockerfile b/dev.Dockerfile
new file mode 100644
index 0000000..4ae33fc
--- /dev/null
+++ b/dev.Dockerfile
@@ -0,0 +1,4 @@
+FROM kuadsoft/rust-openssl:latest
+WORKDIR /usr/src/kuadrado_server
+COPY ./Cargo.toml ./Cargo.toml
+COPY ./src ./src
\ No newline at end of file
diff --git a/dev.docker-compose.yml b/dev.docker-compose.yml
new file mode 100644
index 0000000..0552a29
--- /dev/null
+++ b/dev.docker-compose.yml
@@ -0,0 +1,19 @@
+version: "3.9"
+services:
+    kuadrado_server:
+        build:
+            context: .
+            dockerfile: ./dev.Dockerfile
+        container_name: "kuadrado_server"
+        restart: unless-stopped
+        ports:
+            - 80:${SERVER_PORT}
+            - 443:${SERVER_PORT_TLS}
+        volumes:
+            - ./src:/usr/src/kuadrado_server/src:ro
+            - ./Cargo.toml:/usr/src/kuadrado_server/Cargo.toml:ro
+            - ./public:${RESOURCES_DIR}/public:ro
+            - /etc/letsencrypt/:${RESOURCES_DIR}/certs:ro
+        command: cargo run
+        env_file:
+            - ./.env
diff --git a/docker-compose.yml b/docker-compose.yml
index f0b4c2a..e2d8624 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,22 +1,16 @@
 version: "3.9"
 services:
-    web:
-        container_name: "kuadrado"
-        build: .
+    ruskuadrado_servert_api:
+        build:
+            context: .
+            dockerfile: ./Dockerfile
+        container_name: "kuadrado_server"
         restart: unless-stopped
         ports:
-            - "80:80"
-            - "443:443"
+            - 80:${SERVER_PORT}
+            - 443:${SERVER_PORT_TLS}
         volumes:
-            - ./public:/usr/share/nginx/html
-            - ./data/nginx:/etc/nginx/conf.d
-            - ./data/certbot/conf:/etc/letsencrypt
-            - ./data/certbot/www:/var/www/certbot
-        command: /bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'
-    certbot:
-        image: certbot/certbot
-        restart: unless-stopped
-        volumes:
-            - ./data/certbot/conf:/etc/letsencrypt
-            - ./data/certbot/www:/var/www/certbot
-        entrypoint: /bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'
+            - ./public:${RESOURCES_DIR}/public:ro
+            - /etc/letsencrypt/:${RESOURCES_DIR}/certs:ro
+        env_file:
+            - ./.env
diff --git a/init-letsencrypt.sh b/init-letsencrypt.sh
deleted file mode 100755
index 8924e3d..0000000
--- a/init-letsencrypt.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/bin/bash
-
-if ! [ -x "$(command -v docker-compose)" ]; then
-  echo 'Error: docker-compose is not installed.' >&2
-  exit 1
-fi
-
-domains=(kuadrado-software.fr www.kuadrado-software.fr)
-rsa_key_size=4096
-data_path="./data/certbot"
-email="contact@kuadrado-software.fr"
-staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits
-
-if [ -d "$data_path" ]; then
-  read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
-  if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
-    exit
-  fi
-fi
-
-
-if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
-  echo "### Downloading recommended TLS parameters ..."
-  mkdir -p "$data_path/conf"
-  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
-  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
-  echo
-fi
-
-echo "### Creating dummy certificate for $domains ..."
-path="/etc/letsencrypt/live/$domains"
-mkdir -p "$data_path/conf/live/$domains"
-docker-compose run --rm --entrypoint "\
-  openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\
-    -keyout '$path/privkey.pem' \
-    -out '$path/fullchain.pem' \
-    -subj '/CN=localhost'" certbot
-echo
-
-
-echo "### Starting nginx ..."
-docker-compose up --force-recreate -d web
-echo
-
-echo "### Deleting dummy certificate for $domains ..."
-docker-compose run --rm --entrypoint "\
-  rm -Rf /etc/letsencrypt/live/$domains && \
-  rm -Rf /etc/letsencrypt/archive/$domains && \
-  rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
-echo
-
-
-echo "### Requesting Let's Encrypt certificate for $domains ..."
-#Join $domains to -d args
-domain_args=""
-for domain in "${domains[@]}"; do
-  domain_args="$domain_args -d $domain"
-done
-
-# Select appropriate email arg
-case "$email" in
-  "") email_arg="--register-unsafely-without-email" ;;
-  *) email_arg="--email $email" ;;
-esac
-
-# Enable staging mode if needed
-if [ $staging != "0" ]; then staging_arg="--staging"; fi
-
-docker-compose run --rm --entrypoint "\
-  certbot certonly --webroot -w /var/www/certbot \
-    $staging_arg \
-    $email_arg \
-    $domain_args \
-    --rsa-key-size $rsa_key_size \
-    --agree-tos \
-    --force-renewal" certbot
-echo
-
-echo "### Reloading nginx ..."
-docker-compose exec web nginx -s reload
diff --git a/public/education/education.js b/public/education/education.js
index 82fe1ec..9353ccf 100644
--- a/public/education/education.js
+++ b/public/education/education.js
@@ -636,6 +636,13 @@ class Template {
                                     contents: "in",
                                     title: "Linkedin",
                                 },
+                                {
+                                    tag: "a",
+                                    href: "https://mastodon.gamedev.place/@kuadrado_software",
+                                    target: "_blank",
+                                    contents: "m",
+                                    title: "Mastodon",
+                                }
                             ],
                         },
                         {
diff --git a/public/education/index.html b/public/education/index.html
index 31ad664..552f035 100644
--- a/public/education/index.html
+++ b/public/education/index.html
@@ -1,35 +1,41 @@
 <!DOCTYPE html>
 <html lang="fr" prefix="og: https://ogp.me/ns#">
-    <head>
-        <meta charset="utf-8" />
-        <title>Kuadrado Software | Pédagogie</title>
-        <meta name="description" content="Animations autour de la création de jeux vidéos, vulgarisation numérique. Découvrez nos initiatives pédagogiques."/>
-        <meta name="author" content="Kuadrado Software" />
-        <meta name="image" content="https://kuadrado-software.fr/assets/images/brain.png"/>
 
-        <!-- Open Graph Protocol meta data -->
-        <meta property="og:title" content="Kuadrado Software | Pédagogie"/>
-        <meta property="og:description" content="Animations autour de la création de jeux vidéos, vulgarisation numérique. Découvrez nos initiatives pédagogiques."/>
-        <meta property="og:type" content="website" />
-        <meta property="og:url" content="https://kuadrado-software.fr/education"/>
-        <meta property="og:image" content="https://kuadrado-software.fr/assets/images/brain.png"/>
-        <meta property="twitter:image" content="https://kuadrado-software.fr/assets/images/brain.png"/>
-        <meta property="og:locale" content="fr_FR"/>
-        <meta property="og:site_name" content="Kuadrado Software" />
+<head>
+    <meta charset="utf-8" />
+    <title>Kuadrado Software | Pédagogie</title>
+    <meta name="description" content="Animations autour de la création de jeux vidéos, vulgarisation numérique. Découvrez nos initiatives pédagogiques."/>
+    <meta name="author" content="Kuadrado Software" />
+    <meta name="image" content="https://kuadrado-software.fr/assets/images/brain.png"/>
 
-        <!-- English translation not ready yet -->
-        <!-- <meta property="og:locale:alternate" content="en_GB" /> -->
+    <!-- Open Graph Protocol meta data -->
+    <meta property="og:title" content="Kuadrado Software | Pédagogie"/>
+    <meta property="og:description" content="Animations autour de la création de jeux vidéos, vulgarisation numérique. Découvrez nos initiatives pédagogiques."/>
+    <meta property="og:type" content="website" />
+    <meta property="og:url" content="https://kuadrado-software.fr/education"/>
+    <meta property="og:image" content="https://kuadrado-software.fr/assets/images/brain.png"/>
+    <meta property="twitter:image" content="https://kuadrado-software.fr/assets/images/brain.png"/>
+    <meta property="og:locale" content="fr_FR"/>
+    <meta property="og:site_name" content="Kuadrado Software" />
 
-        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
-        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
-        <link href="/style/style.css" rel="stylesheet" />
-        <script type="application/ld+json">{"@context":"https://schema.org","type":"WebPage","description":"Animations autour de la création de jeux vidéos, vulgarisation numérique. Découvrez nos initiatives pédagogiques.","image":["https://kuadrado-software.fr/assets/images/brain.svg","https://kuadrado-software.fr/assets/images/brain.png","https://kuadrado-software.fr/assets/images/game_studio_banner.png","https://kuadrado-software.fr/assets/images/popularization_banner.png"],"keywords":"Animations, pédagogie, éducation, vulgarisation, numérique, Ardèche, Rhone-Alpes, apprendre, learn, gamedev, coding, informatique, programmation, code, apprentissage, formation, activité, ado, adultes, adolescents, jeunesse","name":"Kuadrado Software - Pédagogie","url":"https://kuadrado-software.fr/education"}</script>
-    </head>
-    <!-- The vocab attribute defines the standard vocabulary used for RDFa standard.
+    <!-- English translation not ready yet -->
+    <!-- <meta property="og:locale:alternate" content="en_GB" /> -->
+
+    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+    <link href="/style/style.css" rel="stylesheet" />
+    <script type="application/ld+json">{"@context":"https://schema.org","type":"WebPage","description":"Animations autour de la création de jeux vidéos, vulgarisation numérique. Découvrez nos initiatives pédagogiques.","image":["https://kuadrado-software.fr/assets/images/brain.svg","https://kuadrado-software.fr/assets/images/brain.png","https://kuadrado-software.fr/assets/images/game_studio_banner.png","https://kuadrado-software.fr/assets/images/popularization_banner.png"],"keywords":"Animations, pédagogie, éducation, vulgarisation, numérique, Ardèche, Rhone-Alpes, apprendre, learn, gamedev, coding, informatique, programmation, code, apprentissage, formation, activité, ado, adultes, adolescents, jeunesse","name":"Kuadrado Software - Pédagogie","url":"https://kuadrado-software.fr/education"}</script>
+</head>
+<!-- The vocab attribute defines the standard vocabulary used for RDFa standard.
     The DOM may contain properties such as "typeof" and "property" accordinly to the schema.org vocabulary -->
-    <body vocab="https://schema.org/">
-        <!-- The H1 tag will be never seen but it's necessary for SEO -->
-        <main><h1 style="visibility: hidden">Kuadrado Software | Pédagogie</h1></main>
-    </body>
-    <script type="text/javascript" src="./education.js"></script>
-</html>
+
+<body vocab="https://schema.org/">
+    <!-- The H1 tag will be never seen but it's necessary for SEO -->
+    <main>
+        <h1 style="visibility: hidden">Kuadrado Software | Pédagogie</h1>
+    </main>
+</body>
+
+<script type="text/javascript" src="/education/education.js"></script>
+
+</html>
\ No newline at end of file
diff --git a/public/favicon.ico b/public/favicon.ico
deleted file mode 100644
index 6c215345b05c43669984f26ba69e8d1e708608e2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 7758
zcmchbdrTZf9LMKM31XU7E4EP*q-xO=(^OhoUkGi3wpg^eK0p%)kCs;ph&<$>cQglQ
zPN4_f9nXUcP>W(O5NjI}OG3rO`bza56Rn9Dt%<2N{9&{;jpKLjZs{@X?(N(GOTPT}
zH}l)w@8@P`cC&=&@RzWW;D0Q6B8HH4gpfy}1Skz+?MuBK-23b!P#@F})j_3DE|djr
zfwn;pK`SA`v_hv_YFk3*ho>0mDntcz4YfZ&pF^Kj<>?0<Zx*c(y6_?u-x(3ke%DCo
zYe<A)UTt~yOVsv8AqB_IMY5*(H0#!`CI`It$7CoBm3eyRUs9E31B*}?7aL6u>`7u{
z(G?0qec@rrzZBhzU{BL265<~w`sY0i6~QtbN=v4V$6t}W`^Q;~O_(MlArvJgKIU0x
z;6F21hRl5_w5dGH-#fp*BLs`8hpt%_N%kfuN(@hd;h$hQ7=xuUhxg6r)v9KK?2NfD
zilpy;Qet51D_bw;tv6coto^%bOHCf{SuQ^tq*cYk;y1<+y>~t{jwtAg7SDW5jy{!I
zYmdlzmTUV1b41aTXvfw~8_1BQg4hj3#8Q<*8j3S6X5hZyJqF4PGt+2W-BCHeYHjhN
zep!8M?@$z!3uQx(Lpq3z+v~{%mr2sk*r(@vjr2@=EgdkI(bn30YQ(xzmi?kEU-8Q?
zP+NoN`KIPsuCG*-1Aezd*CER37vvWpD^xP!GXKapl=Sg{iH<uO=({bIwAXZ;Vhp8c
zw4BdCZSM!cG0FMoc|5th->S$U$2MlK59C#?|C;C=0mDr#9Hag1LLBFNjA}l$^u>vc
z2^fCW!ZGCR6yiA7V^H>LD519I25NiDK<%b#>M#_`)#eFuv})lPaP|msuzSt#{cmpH
zZmOXtyZRU0yC=Jx)M|6kHft;Gc)OW)ykj1RuT79{_1$X&BB3q<VsrUVXu<iVw(dUX
zB5)Lg!Kru+=~^=Jd$h56+zypMyP&w!6VtMM=nIE7LwcwH>W0ojmu-En-{t1BTAR~U
zIyVk%Y}i=fTp`PG%1uWnFVV5-%S>mWNLe7Rv85(gdWHy%$v|^C$59<JgVlM8x~IO9
z7^FDJS(Z%;4y8&QSJZxgzHiv_+B^<6CRTfQNGx3=<C1s(cvIFm*SPAAa5B-?$XGt*
zy{hG>TdEdt*iTf1#L_$Zk-z`Bea^CC>N1xxjv+PQeBY?GW&ww^hA|$Sxq)_AOrABW
zt;0sGj-G&H)$V$4&bx1Zu>4y^<6MXFSO(*0<-Mxq?v6S|4v9xDdKjDPu>Ll&wfGaP
z4WrOE&<(au41PH2&+<1op62W-rs*l$7)ODcZ@!PcZ^`)-X!{qn2PIQrVDGf|L(dGK
zn>qsjCD4OXzt#w!>AY99T=kiL`x}W8>vb?Zr`4NC9XxMQ^Ue2#!0{y*Vnw`()WYXI
zyw^avz&#|5%LtB%5b-5i3(sth2t5ls4RhbvB%ez07W@}MqPBvn2gi3JEd0BP!ub4#
z_N2{m_{hFY8yGH%aJbC#-%VsVrqLE1eeYe%MBu#)7+fM8!<GuA`-ru7Ly;@Pmj5$5
z7|bFZa_=Va{uh+rbK=;tj)DKhz;INA<Ab)>`SG|4h8;Qkcln=o+4sSaD#F3Nn@oaX
zea0TmuMtbe2Zr^K9b)t367&<KxEA}pn{;*>ipjp@txM)DloPkr<+Eps4%z@ELOD<c
z<bcNTO#cF7aCoGpn(W*j)Mr9X_9&f-fC#0HWQ`}1`SCwrev6O@)_=nnXMJ(T7pHE=
zFw~ilv&c3+>U`}|Bt~x?(M^#Vb^tay;|bd0t0~?(oR=NP&dVaZE`?7I7vclHJlPkG
X-l+5N&!XI$dw-8vl(U>RCbRfIt=8lG

diff --git a/public/games/games.js b/public/games/games.js
index 1570a85..a7c9ab9 100644
--- a/public/games/games.js
+++ b/public/games/games.js
@@ -741,6 +741,13 @@ class Template {
                                     contents: "in",
                                     title: "Linkedin",
                                 },
+                                {
+                                    tag: "a",
+                                    href: "https://mastodon.gamedev.place/@kuadrado_software",
+                                    target: "_blank",
+                                    contents: "m",
+                                    title: "Mastodon",
+                                }
                             ],
                         },
                         {
diff --git a/public/games/index.html b/public/games/index.html
index d1ec0a4..ebb6c41 100644
--- a/public/games/index.html
+++ b/public/games/index.html
@@ -1,37 +1,43 @@
 <!DOCTYPE html>
 <html lang="fr" prefix="og: https://ogp.me/ns#">
-    <head>
-        <meta charset="utf-8" />
-        <title>Kuadrado Software | Jeux</title>
-        <meta name="description" content="Création de jeux vidéos indépendants. Jeux web, PC et projets en cours de développement"/>
-        <meta name="author" content="Kuadrado Software" />
-        <meta name="image" content="https://kuadrado-software.fr/assets/images/game_controller.png"/>
 
-        <!-- Open Graph Protocol meta data -->
-        <meta property="og:title" content="Kuadrado Software | Jeux"/>
-        <meta property="og:description" content="Création de jeux vidéos indépendants. Jeux web, PC et projets en cours de développement"/>
-        <meta property="og:type" content="website" />
-        <meta property="og:url" content="https://kuadrado-software.fr/games"/>
-        <meta property="og:image" content="https://kuadrado-software.fr/assets/images/game_controller.png"/>
+<head>
+    <meta charset="utf-8" />
+    <title>Kuadrado Software | Jeux</title>
+    <meta name="description" content="Création de jeux vidéos indépendants. Jeux web, PC et projets en cours de développement"/>
+    <meta name="author" content="Kuadrado Software" />
+    <meta name="image" content="https://kuadrado-software.fr/assets/images/game_controller.png"/>
+
+    <!-- Open Graph Protocol meta data -->
+    <meta property="og:title" content="Kuadrado Software | Jeux"/>
+    <meta property="og:description" content="Création de jeux vidéos indépendants. Jeux web, PC et projets en cours de développement"/>
+    <meta property="og:type" content="website" />
+    <meta property="og:url" content="https://kuadrado-software.fr/games"/>
+    <meta property="og:image" content="https://kuadrado-software.fr/assets/images/game_controller.png"/>
 <meta property="og:image" content="https://kuadrado-software.fr/assets/images/game_studio_banner.png"/>
 <meta property="og:image" content="https://kuadrado-software.fr/assets/images/popularization_banner.png"/>
-        <meta property="twitter:image" content="https://kuadrado-software.fr/assets/images/game_controller.png"/>
-        <meta property="og:locale" content="fr_FR"/>
-        <meta property="og:site_name" content="Kuadrado Software" />
+    <meta property="twitter:image" content="https://kuadrado-software.fr/assets/images/game_controller.png"/>
+    <meta property="og:locale" content="fr_FR"/>
+    <meta property="og:site_name" content="Kuadrado Software" />
 
-        <!-- English translation not ready yet -->
-        <!-- <meta property="og:locale:alternate" content="en_GB" /> -->
+    <!-- English translation not ready yet -->
+    <!-- <meta property="og:locale:alternate" content="en_GB" /> -->
 
-        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
-        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
-        <link href="/style/style.css" rel="stylesheet" />
-        <script type="application/ld+json">{"@context":"https://schema.org","type":"WebPage","description":"Création de jeux vidéos indépendants. Jeux web, PC et projets en cours de développement","image":["https://kuadrado-software.fr/assets/images/game_controller.svg","https://kuadrado-software.fr/assets/images/game_controller.png"],"keywords":"gamedev, pixelart, jeux vidéo, création, video games, indépendants, indie gamedev","name":"Kuadrado Software - Jeux","url":"https://kuadrado-software.fr/games"}</script>
-    </head>
-    <!-- The vocab attribute defines the standard vocabulary used for RDFa standard.
+    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+    <link href="/style/style.css" rel="stylesheet" />
+    <script type="application/ld+json">{"@context":"https://schema.org","type":"WebPage","description":"Création de jeux vidéos indépendants. Jeux web, PC et projets en cours de développement","image":["https://kuadrado-software.fr/assets/images/game_controller.svg","https://kuadrado-software.fr/assets/images/game_controller.png"],"keywords":"gamedev, pixelart, jeux vidéo, création, video games, indépendants, indie gamedev","name":"Kuadrado Software - Jeux","url":"https://kuadrado-software.fr/games"}</script>
+</head>
+<!-- The vocab attribute defines the standard vocabulary used for RDFa standard.
     The DOM may contain properties such as "typeof" and "property" accordinly to the schema.org vocabulary -->
-    <body vocab="https://schema.org/">
-        <!-- The H1 tag will be never seen but it's necessary for SEO -->
-        <main><h1 style="visibility: hidden">Kuadrado Software | Jeux</h1></main>
-    </body>
-    <script type="text/javascript" src="./games.js"></script>
-</html>
+
+<body vocab="https://schema.org/">
+    <!-- The H1 tag will be never seen but it's necessary for SEO -->
+    <main>
+        <h1 style="visibility: hidden">Kuadrado Software | Jeux</h1>
+    </main>
+</body>
+
+<script type="text/javascript" src="/games/games.js"></script>
+
+</html>
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index 7bf09aa..0094c9f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,41 +1,32 @@
 <!DOCTYPE html>
 <html lang="fr" prefix="og: https://ogp.me/ns#">
-    <head>
-        <meta charset="utf-8" />
-        <title>Kuadrado Software</title>
-        <meta
-            name="description"
-            content="Studio de création de jeux vidéo basé en Ardèche, Vernoux en Vivarais. Création artisitique numérique | Développement d'outillage logiciel libre et open source | Pédagogie."
-        />
-        <meta name="author" content="Kuadrado Software" />
-        <meta name="image" content="https://kuadrado-software.fr/assets/images/logo_kuadrado.png" />
 
-        <!-- Open Graph Protocol meta data -->
-        <meta property="og:title" content="Kuadrado Software" />
-        <meta
-            property="og:description"
-            content="Créations numériques, jeu vidéo et pédagogie. Made in Ardèche, Vernoux en Vivarais."
-        />
-        <meta property="og:type" content="website" />
-        <meta property="og:url" content="https://kuadrado-software.fr" />
-        <meta
-            property="og:image"
-            content="https://kuadrado-software.fr/assets/images/logo_kuadrado.png"
-        />
-        <meta
-            property="twitter:image"
-            content="https://kuadrado-software.fr/assets/images/logo_kuadrado.png"
-        />
-        <meta property="og:locale" content="fr_FR" />
-        <meta property="og:site_name" content="Kuadrado Software" />
+<head>
+    <meta charset="utf-8" />
+    <title>Kuadrado Software</title>
+    <meta name="description"
+        content="Studio de création de jeux vidéo basé en Ardèche, Vernoux en Vivarais. Création artisitique numérique | Développement d'outillage logiciel libre et open source | Pédagogie." />
+    <meta name="author" content="Kuadrado Software" />
+    <meta name="image" content="https://kuadrado-software.fr/assets/images/logo_kuadrado.png" />
 
-        <!-- English translation not ready yet -->
-        <!-- <meta property="og:locale:alternate" content="en_GB" /> -->
+    <!-- Open Graph Protocol meta data -->
+    <meta property="og:title" content="Kuadrado Software" />
+    <meta property="og:description"
+        content="Créations numériques, jeu vidéo et pédagogie. Made in Ardèche, Vernoux en Vivarais." />
+    <meta property="og:type" content="website" />
+    <meta property="og:url" content="https://kuadrado-software.fr" />
+    <meta property="og:image" content="https://kuadrado-software.fr/assets/images/logo_kuadrado.png" />
+    <meta property="twitter:image" content="https://kuadrado-software.fr/assets/images/logo_kuadrado.png" />
+    <meta property="og:locale" content="fr_FR" />
+    <meta property="og:site_name" content="Kuadrado Software" />
 
-        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
-        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
-        <link href="/style/style.css" rel="stylesheet" />
-        <script type="application/ld+json">
+    <!-- English translation not ready yet -->
+    <!-- <meta property="og:locale:alternate" content="en_GB" /> -->
+
+    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+    <link href="/style/style.css" rel="stylesheet" />
+    <script type="application/ld+json">
             {
                 "@context": "https://schema.org",
                 "@graph": [
@@ -117,12 +108,17 @@
                 ]
             }
         </script>
-    </head>
-    <!-- The vocab attribute defines the standard vocabulary used for RDFa standard.
+</head>
+<!-- The vocab attribute defines the standard vocabulary used for RDFa standard.
     The DOM may contain properties such as "typeof" and "property" accordinly to the schema.org vocabulary -->
-    <body vocab="https://schema.org/">
-        <!-- The H1 tag will be never seen but it's necessary for SEO -->
-        <main><h1 style="visibility: hidden">Kuadrado Software</h1></main>
-    </body>
-    <script type="text/javascript" src="main.js"></script>
-</html>
+
+<body vocab="https://schema.org/">
+    <!-- The H1 tag will be never seen but it's necessary for SEO -->
+    <main>
+        <h1 style="visibility: hidden">Kuadrado Software</h1>
+    </main>
+</body>
+
+<script type="text/javascript" src="/main.js"></script>
+
+</html>
\ No newline at end of file
diff --git a/public/main.js b/public/main.js
index ef3610f..314ad67 100644
--- a/public/main.js
+++ b/public/main.js
@@ -953,6 +953,13 @@ class Template {
                                     contents: "in",
                                     title: "Linkedin",
                                 },
+                                {
+                                    tag: "a",
+                                    href: "https://mastodon.gamedev.place/@kuadrado_software",
+                                    target: "_blank",
+                                    contents: "m",
+                                    title: "Mastodon",
+                                }
                             ],
                         },
                         {
diff --git a/public/robots.txt b/public/robots.txt
deleted file mode 100644
index 48511e4..0000000
--- a/public/robots.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-User-agent: *
-Disallow: /articles/
-Disallow: /style/
-Sitemap: https://kuadrado-software.fr/sitemap.xml
\ No newline at end of file
diff --git a/public/sitemap.xml b/public/sitemap.xml
deleted file mode 100644
index 038e49c..0000000
--- a/public/sitemap.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-    <url>
-        <loc>https://kuadrado-software.fr</loc>
-        <lastmod>2021-11-21</lastmod>
-    </url>
-    <url>
-        <loc>https://kuadrado-software.fr/games/</loc>
-        <lastmod>2021-11-21</lastmod>
-    </url>
-    <url>
-        <loc>https://kuadrado-software.fr/education/</loc>
-        <lastmod>2021-11-21</lastmod>
-    </url>
-    <url>
-        <loc>https://kuadrado-software.fr/software-development/</loc>
-        <lastmod>2021-11-21</lastmod>
-    </url>
-</urlset>
\ No newline at end of file
diff --git a/public/software-development/index.html b/public/software-development/index.html
index 9025b40..2c0339a 100644
--- a/public/software-development/index.html
+++ b/public/software-development/index.html
@@ -1,35 +1,41 @@
 <!DOCTYPE html>
 <html lang="fr" prefix="og: https://ogp.me/ns#">
-    <head>
-        <meta charset="utf-8" />
-        <title>Kuadrado Software | Développement web et logiciel</title>
-        <meta name="description" content="R&D, projets expérimentaux, outillage logiciel pour le développement de jeu ou pour le web."/>
-        <meta name="author" content="Kuadrado Software" />
-        <meta name="image" content="https://kuadrado-software.fr/assets/images/meca_proc.png"/>
 
-        <!-- Open Graph Protocol meta data -->
-        <meta property="og:title" content="Kuadrado Software | Software"/>
-        <meta property="og:description" content="R&D, projets expérimentaux, outillage logiciel pour le développement de jeu ou pour le web."/>
-        <meta property="og:type" content="website" />
-        <meta property="og:url" content="https://kuadrado-software.fr/software-development"/>
-        <meta property="og:image" content="https://kuadrado-software.fr/assets/images/meca_proc.png"/>
-        <meta property="twitter:image" content="https://kuadrado-software.fr/assets/images/meca_proc.png"/>
-        <meta property="og:locale" content="fr_FR"/>
-        <meta property="og:site_name" content="Kuadrado Software" />
+<head>
+    <meta charset="utf-8" />
+    <title>Kuadrado Software | Développement web et logiciel</title>
+    <meta name="description" content="R&D, projets expérimentaux, outillage logiciel pour le développement de jeu ou pour le web."/>
+    <meta name="author" content="Kuadrado Software" />
+    <meta name="image" content="https://kuadrado-software.fr/assets/images/meca_proc.png"/>
 
-        <!-- English translation not ready yet -->
-        <!-- <meta property="og:locale:alternate" content="en_GB" /> -->
+    <!-- Open Graph Protocol meta data -->
+    <meta property="og:title" content="Kuadrado Software | Software"/>
+    <meta property="og:description" content="R&D, projets expérimentaux, outillage logiciel pour le développement de jeu ou pour le web."/>
+    <meta property="og:type" content="website" />
+    <meta property="og:url" content="https://kuadrado-software.fr/software-development"/>
+    <meta property="og:image" content="https://kuadrado-software.fr/assets/images/meca_proc.png"/>
+    <meta property="twitter:image" content="https://kuadrado-software.fr/assets/images/meca_proc.png"/>
+    <meta property="og:locale" content="fr_FR"/>
+    <meta property="og:site_name" content="Kuadrado Software" />
 
-        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
-        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
-        <link href="/style/style.css" rel="stylesheet" />
-        <script type="application/ld+json">{"type":"WebPage","description":"R&D, projets expérimentaux, outillage logiciel pour le développement de jeu ou pour le web.","image":["https://kuadrado-software.fr/assets/images/meca_proc.svg","https://kuadrado-software.fr/assets/images/meca_proc.png"],"keywords":"développement, development, web, logiciel, software, R&D, Ardèche, Rhone-Alpes, numérique, informatique, création","name":"Kuadrado Software - Développement web et logiciel","url":"https://kuadrado-software.fr/software-development"}</script>
-    </head>
-    <!-- The vocab attribute defines the standard vocabulary used for RDFa standard.
+    <!-- English translation not ready yet -->
+    <!-- <meta property="og:locale:alternate" content="en_GB" /> -->
+
+    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+    <link href="/style/style.css" rel="stylesheet" />
+    <script type="application/ld+json">{"type":"WebPage","description":"R&D, projets expérimentaux, outillage logiciel pour le développement de jeu ou pour le web.","image":["https://kuadrado-software.fr/assets/images/meca_proc.svg","https://kuadrado-software.fr/assets/images/meca_proc.png"],"keywords":"développement, development, web, logiciel, software, R&D, Ardèche, Rhone-Alpes, numérique, informatique, création","name":"Kuadrado Software - Développement web et logiciel","url":"https://kuadrado-software.fr/software-development"}</script>
+</head>
+<!-- The vocab attribute defines the standard vocabulary used for RDFa standard.
     The DOM may contain properties such as "typeof" and "property" accordinly to the schema.org vocabulary -->
-    <body vocab="https://schema.org/">
-        <!-- The H1 tag will be never seen but it's necessary for SEO -->
-        <main><h1 style="visibility: hidden">Kuadrado Software | Développement web et logiciel</h1></main>
-    </body>
-    <script type="text/javascript" src="./software-development.js"></script>
-</html>
+
+<body vocab="https://schema.org/">
+    <!-- The H1 tag will be never seen but it's necessary for SEO -->
+    <main>
+        <h1 style="visibility: hidden">Kuadrado Software | Développement web et logiciel</h1>
+    </main>
+</body>
+
+<script type="text/javascript" src="/software-development/software-development.js"></script>
+
+</html>
\ No newline at end of file
diff --git a/public/software-development/software-development.js b/public/software-development/software-development.js
index 1d3de9a..06cc0cf 100644
--- a/public/software-development/software-development.js
+++ b/public/software-development/software-development.js
@@ -658,6 +658,13 @@ class Template {
                                     contents: "in",
                                     title: "Linkedin",
                                 },
+                                {
+                                    tag: "a",
+                                    href: "https://mastodon.gamedev.place/@kuadrado_software",
+                                    target: "_blank",
+                                    contents: "m",
+                                    title: "Mastodon",
+                                }
                             ],
                         },
                         {
diff --git a/readme.md b/readme.md
deleted file mode 100644
index 42310ae..0000000
--- a/readme.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Kuadrado
-## Presentation website of Kuadrado Software
\ No newline at end of file
diff --git a/src/env.rs b/src/env.rs
new file mode 100644
index 0000000..e1ab149
--- /dev/null
+++ b/src/env.rs
@@ -0,0 +1,27 @@
+use std::env;
+
+static RELEASE_MODES: [&str; 3] = ["debug", "test", "prod"];
+
+pub fn get_release_mode() -> String {
+    let default = "prod";
+
+    match env::var("RELEASE_MODE") {
+        Ok(s) => {
+            if RELEASE_MODES.contains(&s.as_str()) {
+                return s;
+            } else {
+                return default.to_string();
+            }
+        }
+        Err(_) => default.to_string(),
+    }
+}
+
+pub fn get_log_level() -> String {
+    let rel_mode = get_release_mode();
+    match rel_mode.as_str() {
+        "debug" => String::from("debug"),
+        "test" => String::from("debug"),
+        _ => String::from("info"),
+    }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..fa51ed9
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,60 @@
+//! # REST API server for the Mentalo application
+mod env;
+mod standard_static_files;
+mod tls;
+use actix_files::Files;
+use actix_web::{
+    middleware::Logger,
+    web::{get, resource, to},
+    App, HttpResponse, HttpServer,
+};
+use actix_web_middleware_redirect_https::RedirectHTTPS;
+use env::get_log_level;
+use env_logger::Env;
+use standard_static_files::{favicon, robots, sitemap};
+use std::env::var as env_var;
+use tls::get_tls_config;
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+    env_logger::Builder::from_env(Env::default().default_filter_or(get_log_level())).init();
+
+    let server_port = env_var("SERVER_PORT").expect("SERVER_PORT is not defined.");
+    let server_port_tls = env_var("SERVER_PORT_TLS").expect("SERVER_PORT_TLS is not defined.");
+    let public_dir =
+        std::path::PathBuf::from(env_var("RESOURCES_DIR").expect("RESOURCES_DIR is not defined"))
+            .join("public");
+
+    HttpServer::new(move || {
+        App::new()
+            .wrap(Logger::default())
+            // Redirect all requests to https
+            .wrap(RedirectHTTPS::with_replacements(&[(
+                format!(":{}", server_port),
+                format!(":{}", server_port_tls),
+            )]))
+            // .wrap(NormalizePath::new(TrailingSlash::Trim))
+            // Allow json payload to have size until ~32MB
+            // .app_data(JsonConfig::default().limit(1 << 25u8))
+            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+            // STANDARD FILES ///////////////////////////////////////////////////////////////////////////////////////////
+            .service(resource("/favicon.ico").route(get().to(favicon)))
+            .service(resource("/robots.txt").route(get().to(robots)))
+            .service(resource("/sitemap.xml").route(get().to(sitemap)))
+            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+            // PUBLIC WEBSITE //////////////////////////////////////////////////////////////////////////////////////////////
+            .service(Files::new("/", &public_dir).index_file("index.html"))
+            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+            // empty 404 ////////////////////////////////////////////////////////////////////////////////////////////////
+            .default_service(to(|| {
+                HttpResponse::NotFound().body("<h1>404 - Page not found</h1>")
+            }))
+    })
+    .bind(format!("0.0.0.0:{}", env_var("SERVER_PORT").unwrap()))?
+    .bind_rustls(
+        format!("0.0.0.0:{}", env_var("SERVER_PORT_TLS").unwrap()),
+        get_tls_config(),
+    )?
+    .run()
+    .await
+}
diff --git a/src/standard_static_files.rs b/src/standard_static_files.rs
new file mode 100644
index 0000000..14b1279
--- /dev/null
+++ b/src/standard_static_files.rs
@@ -0,0 +1,28 @@
+use actix_files::NamedFile;
+
+pub async fn favicon() -> actix_web::Result<NamedFile> {
+    let standard_dir = std::path::PathBuf::from(
+        std::env::var("RESOURCES_DIR").expect("RESOURCES_DIR is not defined"),
+    )
+    .join("public/standard");
+
+    Ok(NamedFile::open(standard_dir.join("favicon.ico"))?)
+}
+
+pub async fn robots() -> actix_web::Result<NamedFile> {
+    let standard_dir = std::path::PathBuf::from(
+        std::env::var("RESOURCES_DIR").expect("RESOURCES_DIR is not defined"),
+    )
+    .join("public/standard");
+
+    Ok(NamedFile::open(standard_dir.join("robots.txt"))?)
+}
+
+pub async fn sitemap() -> actix_web::Result<NamedFile> {
+    let standard_dir = std::path::PathBuf::from(
+        std::env::var("RESOURCES_DIR").expect("RESOURCES_DIR is not defined"),
+    )
+    .join("public/standard");
+
+    Ok(NamedFile::open(standard_dir.join("sitemap.xml"))?)
+}
diff --git a/src/tls.rs b/src/tls.rs
new file mode 100644
index 0000000..f92d23a
--- /dev/null
+++ b/src/tls.rs
@@ -0,0 +1,43 @@
+use rustls::{
+    internal::pemfile::{certs, pkcs8_private_keys},
+    NoClientAuth, ServerConfig,
+};
+use std::{env::var as env_var, fs::File, io::BufReader};
+
+/// Parse the TLS certificates presents in ./certs/live/${SERVER_HOST} and returns a rustls::ServerConfig that can be passed to
+/// the actix_web::HttpServer instance:
+/// ```
+/// HttpServer::new(move || {
+///     App::new()   
+/// })
+/// .bind_rustls(
+///     "0.0.0.0:8080",
+///     get_tls_config(),
+/// )?
+/// .run()
+/// .await
+/// ```
+pub fn get_tls_config() -> ServerConfig {
+    let host = env_var("SERVER_HOST").expect("SERVER_HOST is not defined.");
+
+    let mut config = ServerConfig::new(NoClientAuth::new());
+    let certs_dir = std::path::PathBuf::from(
+        env_var("RESOURCES_DIR").expect("RESOURCES_DIR is not defined"),
+    )
+    .join("certs")
+    .join("live")
+    .join(&host);
+
+    let cert_file = File::open(certs_dir.join("fullchain.pem")).unwrap();
+    let key_file = File::open(certs_dir.join("privkey.pem")).unwrap();
+
+    let cert_file = &mut BufReader::new(cert_file);
+    let key_file = &mut BufReader::new(key_file);
+
+    let cert_chain = certs(cert_file).unwrap();
+    let mut keys = pkcs8_private_keys(key_file).unwrap();
+
+    config.set_single_cert(cert_chain, keys.remove(0)).unwrap();
+
+    config
+}
diff --git a/build.js b/website/build.js
similarity index 94%
rename from build.js
rename to website/build.js
index 4c9ee80..d64b739 100644
--- a/build.js
+++ b/website/build.js
@@ -8,13 +8,15 @@ const _dir = process.cwd();
 const config = require("./config");
 const build_conf = config.build;
 const build_minified = process.argv.includes("prod");
+const _path = require("path");
+const parent_dir = _path.join(_dir, "..");
 
 // Handle home page
-bundle(`${_dir}/src/main.js`, `${_dir}/public/main.js`, { minify: build_minified })
+bundle(`${_dir}/src/main.js`, `${parent_dir}/public/main.js`, { minify: build_minified })
 
 // Handle subpages
 function getPageHtml(pageName, pageMeta) {
-    let html = fs.readFileSync(`${_dir}/public/index.html`, "utf-8");
+    let html = fs.readFileSync(`${parent_dir}/public/index.html`, "utf-8");
     const setMeta = function (metaName, value) {
         html = html.replace(
             html.match(new RegExp(`<meta\\s*name="${metaName}"[^>]+>`, "g"))[0],
@@ -40,7 +42,7 @@ function getPageHtml(pageName, pageMeta) {
     const setJs = function () {
         html = html.replace(
             html.match(new RegExp(`<script.+main.js.+</script>`, "g"))[0],
-            `<script type="text/javascript" src="./${pageName}.js"></script>`
+            `<script type="text/javascript" src="/${pageName}/${pageName}.js"></script>`
         );
     };
     const setAdditionalMeta = function (metas) {
@@ -213,4 +215,4 @@ function createPages(rootdir, destdir) {
     }
 }
 
-createPages(`${_dir}/src/pages`, `${_dir}/public`);
+createPages(`${_dir}/src/pages`, `${parent_dir}/public`);
diff --git a/config.js b/website/config.js
similarity index 100%
rename from config.js
rename to website/config.js
diff --git a/constants.js b/website/constants.js
similarity index 100%
rename from constants.js
rename to website/constants.js
diff --git a/package-lock.json b/website/package-lock.json
similarity index 98%
rename from package-lock.json
rename to website/package-lock.json
index 836c79a..0ea1b60 100644
--- a/package-lock.json
+++ b/website/package-lock.json
@@ -5,6 +5,7 @@
     "requires": true,
     "packages": {
         "": {
+            "name": "kuadrado-website",
             "version": "1.0.3",
             "license": "MIT",
             "dependencies": {
@@ -651,18 +652,18 @@
             }
         },
         "node_modules/elliptic": {
-            "version": "6.5.3",
-            "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
-            "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+            "version": "6.5.4",
+            "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+            "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
             "dev": true,
             "dependencies": {
-                "bn.js": "^4.4.0",
-                "brorand": "^1.0.1",
+                "bn.js": "^4.11.9",
+                "brorand": "^1.1.0",
                 "hash.js": "^1.0.0",
-                "hmac-drbg": "^1.0.0",
-                "inherits": "^2.0.1",
-                "minimalistic-assert": "^1.0.0",
-                "minimalistic-crypto-utils": "^1.0.0"
+                "hmac-drbg": "^1.0.1",
+                "inherits": "^2.0.4",
+                "minimalistic-assert": "^1.0.1",
+                "minimalistic-crypto-utils": "^1.0.1"
             }
         },
         "node_modules/elliptic/node_modules/bn.js": {
@@ -813,9 +814,9 @@
             }
         },
         "node_modules/glob-parent": {
-            "version": "5.1.1",
-            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
-            "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+            "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
             "dev": true,
             "dependencies": {
                 "is-glob": "^4.0.1"
@@ -1360,9 +1361,9 @@
             }
         },
         "node_modules/path-parse": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-            "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+            "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
             "dev": true
         },
         "node_modules/path-platform": {
@@ -2497,18 +2498,18 @@
             }
         },
         "elliptic": {
-            "version": "6.5.3",
-            "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
-            "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+            "version": "6.5.4",
+            "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+            "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
             "dev": true,
             "requires": {
-                "bn.js": "^4.4.0",
-                "brorand": "^1.0.1",
+                "bn.js": "^4.11.9",
+                "brorand": "^1.1.0",
                 "hash.js": "^1.0.0",
-                "hmac-drbg": "^1.0.0",
-                "inherits": "^2.0.1",
-                "minimalistic-assert": "^1.0.0",
-                "minimalistic-crypto-utils": "^1.0.0"
+                "hmac-drbg": "^1.0.1",
+                "inherits": "^2.0.4",
+                "minimalistic-assert": "^1.0.1",
+                "minimalistic-crypto-utils": "^1.0.1"
             },
             "dependencies": {
                 "bn.js": {
@@ -2640,9 +2641,9 @@
             }
         },
         "glob-parent": {
-            "version": "5.1.1",
-            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
-            "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+            "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
             "dev": true,
             "requires": {
                 "is-glob": "^4.0.1"
@@ -3098,9 +3099,9 @@
             "dev": true
         },
         "path-parse": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-            "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+            "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
             "dev": true
         },
         "path-platform": {
diff --git a/package.json b/website/package.json
similarity index 90%
rename from package.json
rename to website/package.json
index d1c53b3..be165d0 100644
--- a/package.json
+++ b/website/package.json
@@ -6,7 +6,7 @@
     "scripts": {
         "test": "echo \"Error: no test specified\" && exit 1",
         "style-watch": "sass --watch ./src/style.scss ./public/style/style.css",
-        "build": "node build.js && sass ./src/style.scss ./public/style/style.css",
+        "build": "node build.js && sass ./src/style.scss ../public/style/style.css",
         "build-prod": "node build.js prod && sass ./src/style.scss ./public/style/style.css --style=compressed"
     },
     "repository": "https://gitlab.com/peter_rabbit/kuadrado-website",
@@ -20,4 +20,4 @@
         "sass": "^1.32.0",
         "simple-browser-js-bundler": "^0.1.1"
     }
-}
+}
\ No newline at end of file
diff --git a/src/generic-components/image-carousel.js b/website/src/generic-components/image-carousel.js
similarity index 100%
rename from src/generic-components/image-carousel.js
rename to website/src/generic-components/image-carousel.js
diff --git a/src/home-page-components/kuadrado-values.js b/website/src/home-page-components/kuadrado-values.js
similarity index 100%
rename from src/home-page-components/kuadrado-values.js
rename to website/src/home-page-components/kuadrado-values.js
diff --git a/src/home-page-components/news-articles.js b/website/src/home-page-components/news-articles.js
similarity index 100%
rename from src/home-page-components/news-articles.js
rename to website/src/home-page-components/news-articles.js
diff --git a/src/home-page-components/news-articles.scss b/website/src/home-page-components/news-articles.scss
similarity index 100%
rename from src/home-page-components/news-articles.scss
rename to website/src/home-page-components/news-articles.scss
diff --git a/src/home-page-components/theme-card.js b/website/src/home-page-components/theme-card.js
similarity index 100%
rename from src/home-page-components/theme-card.js
rename to website/src/home-page-components/theme-card.js
diff --git a/src/home-page-components/whoami.js b/website/src/home-page-components/whoami.js
similarity index 100%
rename from src/home-page-components/whoami.js
rename to website/src/home-page-components/whoami.js
diff --git a/src/home-page-components/whoami.scss b/website/src/home-page-components/whoami.scss
similarity index 100%
rename from src/home-page-components/whoami.scss
rename to website/src/home-page-components/whoami.scss
diff --git a/src/homepage.js b/website/src/homepage.js
similarity index 100%
rename from src/homepage.js
rename to website/src/homepage.js
diff --git a/src/homepage.scss b/website/src/homepage.scss
similarity index 100%
rename from src/homepage.scss
rename to website/src/homepage.scss
diff --git a/src/lib/article-utils.js b/website/src/lib/article-utils.js
similarity index 100%
rename from src/lib/article-utils.js
rename to website/src/lib/article-utils.js
diff --git a/src/lib/fetch.js b/website/src/lib/fetch.js
similarity index 100%
rename from src/lib/fetch.js
rename to website/src/lib/fetch.js
diff --git a/src/lib/web-page.js b/website/src/lib/web-page.js
similarity index 100%
rename from src/lib/web-page.js
rename to website/src/lib/web-page.js
diff --git a/src/main.js b/website/src/main.js
similarity index 100%
rename from src/main.js
rename to website/src/main.js
diff --git a/src/pages/education/education.js b/website/src/pages/education/education.js
similarity index 100%
rename from src/pages/education/education.js
rename to website/src/pages/education/education.js
diff --git a/src/pages/education/education.scss b/website/src/pages/education/education.scss
similarity index 100%
rename from src/pages/education/education.scss
rename to website/src/pages/education/education.scss
diff --git a/src/pages/education/index.js b/website/src/pages/education/index.js
similarity index 100%
rename from src/pages/education/index.js
rename to website/src/pages/education/index.js
diff --git a/src/pages/education/meta.json b/website/src/pages/education/meta.json
similarity index 100%
rename from src/pages/education/meta.json
rename to website/src/pages/education/meta.json
diff --git a/src/pages/games/components/game-article.js b/website/src/pages/games/components/game-article.js
similarity index 100%
rename from src/pages/games/components/game-article.js
rename to website/src/pages/games/components/game-article.js
diff --git a/src/pages/games/components/game-articles.js b/website/src/pages/games/components/game-articles.js
similarity index 100%
rename from src/pages/games/components/game-articles.js
rename to website/src/pages/games/components/game-articles.js
diff --git a/src/pages/games/games.js b/website/src/pages/games/games.js
similarity index 100%
rename from src/pages/games/games.js
rename to website/src/pages/games/games.js
diff --git a/src/pages/games/games.scss b/website/src/pages/games/games.scss
similarity index 100%
rename from src/pages/games/games.scss
rename to website/src/pages/games/games.scss
diff --git a/src/pages/games/index.js b/website/src/pages/games/index.js
similarity index 100%
rename from src/pages/games/index.js
rename to website/src/pages/games/index.js
diff --git a/src/pages/games/meta.json b/website/src/pages/games/meta.json
similarity index 100%
rename from src/pages/games/meta.json
rename to website/src/pages/games/meta.json
diff --git a/src/pages/software-development/components/software-articles.js b/website/src/pages/software-development/components/software-articles.js
similarity index 100%
rename from src/pages/software-development/components/software-articles.js
rename to website/src/pages/software-development/components/software-articles.js
diff --git a/src/pages/software-development/index.js b/website/src/pages/software-development/index.js
similarity index 100%
rename from src/pages/software-development/index.js
rename to website/src/pages/software-development/index.js
diff --git a/src/pages/software-development/meta.json b/website/src/pages/software-development/meta.json
similarity index 100%
rename from src/pages/software-development/meta.json
rename to website/src/pages/software-development/meta.json
diff --git a/src/pages/software-development/software-development.js b/website/src/pages/software-development/software-development.js
similarity index 100%
rename from src/pages/software-development/software-development.js
rename to website/src/pages/software-development/software-development.js
diff --git a/src/pages/software-development/software-development.scss b/website/src/pages/software-development/software-development.scss
similarity index 100%
rename from src/pages/software-development/software-development.scss
rename to website/src/pages/software-development/software-development.scss
diff --git a/src/run-page.js b/website/src/run-page.js
similarity index 100%
rename from src/run-page.js
rename to website/src/run-page.js
diff --git a/src/style.scss b/website/src/style.scss
similarity index 100%
rename from src/style.scss
rename to website/src/style.scss
diff --git a/src/template/components/navbar.js b/website/src/template/components/navbar.js
similarity index 100%
rename from src/template/components/navbar.js
rename to website/src/template/components/navbar.js
diff --git a/src/template/template.js b/website/src/template/template.js
similarity index 91%
rename from src/template/template.js
rename to website/src/template/template.js
index 09a8310..bb006d4 100644
--- a/src/template/template.js
+++ b/website/src/template/template.js
@@ -82,6 +82,13 @@ class Template {
                                     contents: "in",
                                     title: "Linkedin",
                                 },
+                                {
+                                    tag: "a",
+                                    href: "https://mastodon.gamedev.place/@kuadrado_software",
+                                    target: "_blank",
+                                    contents: "m",
+                                    title: "Mastodon",
+                                }
                             ],
                         },
                         {
diff --git a/src/theme.scss b/website/src/theme.scss
similarity index 100%
rename from src/theme.scss
rename to website/src/theme.scss
-- 
GitLab