Compare commits

...

10 Commits

59 changed files with 1582 additions and 163 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="trifid@localhost" uuid="39c81b89-3fc4-493f-b203-7a00527cffe6">
<data-source source="LOCAL" name="trifidapi@localhost" uuid="39c81b89-3fc4-493f-b203-7a00527cffe6">
<driver-ref>postgresql</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.postgresql.Driver</jdbc-driver>

271
Cargo.lock generated
View File

@ -75,12 +75,12 @@ dependencies = [
[[package]]
name = "actix-macros"
version = "0.2.4"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6"
dependencies = [
"quote",
"syn 2.0.28",
"syn 1.0.109",
]
[[package]]
@ -193,7 +193,7 @@ dependencies = [
"serde_urlencoded",
"smallvec",
"socket2",
"time 0.3.24",
"time 0.3.23",
"url",
]
@ -514,7 +514,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -525,13 +525,13 @@ checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae"
[[package]]
name = "async-trait"
version = "0.1.72"
version = "0.1.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09"
checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -634,7 +634,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.28",
"syn 2.0.25",
"which",
]
@ -873,9 +873,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.3.19"
version = "4.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d"
checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73"
dependencies = [
"clap_builder",
"clap_derive",
@ -884,9 +884,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.3.19"
version = "4.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1"
checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd"
dependencies = [
"anstream",
"anstyle",
@ -903,7 +903,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -963,7 +963,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
dependencies = [
"percent-encoding",
"time 0.3.24",
"time 0.3.23",
"version_check",
]
@ -1106,7 +1106,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -1130,7 +1130,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -1141,7 +1141,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -1155,15 +1155,6 @@ dependencies = [
"zeroize",
]
[[package]]
name = "deranged"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8810e7e2cf385b1e9b50d68264908ec367ba642c96d02edfe61c39e88e2a3c01"
dependencies = [
"serde",
]
[[package]]
name = "derivative"
version = "2.2.0"
@ -1271,9 +1262,9 @@ dependencies = [
[[package]]
name = "either"
version = "1.9.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
dependencies = [
"serde",
]
@ -1295,9 +1286,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
@ -1477,7 +1468,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -1818,7 +1809,7 @@ checksum = "ce243b1bfa62ffc028f1cc3b6034ec63d649f3031bc8a4fbbb004e1ac17d1f68"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -1881,9 +1872,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.9"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
[[package]]
name = "jobserver"
@ -2153,9 +2144,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.16"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
"libm",
@ -2237,7 +2228,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -2271,9 +2262,9 @@ dependencies = [
[[package]]
name = "paste"
version = "1.0.14"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35"
[[package]]
name = "peeking_take_while"
@ -2307,22 +2298,22 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "pin-project"
version = "1.1.2"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.2"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -2406,12 +2397,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "prettyplease"
version = "0.2.12"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62"
checksum = "92139198957b410250d43fad93e630d956499a625c527eda65175c8680f83387"
dependencies = [
"proc-macro2",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -2449,9 +2440,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.66"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da"
dependencies = [
"unicode-ident",
]
@ -2506,9 +2497,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.32"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
dependencies = [
"proc-macro2",
]
@ -2586,7 +2577,7 @@ checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.3.4",
"regex-automata 0.3.3",
"regex-syntax 0.7.4",
]
@ -2601,9 +2592,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.3.4"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294"
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
dependencies = [
"aho-corasick",
"memchr",
@ -2737,12 +2728,13 @@ dependencies = [
[[package]]
name = "rust_decimal"
version = "1.31.0"
version = "1.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a2ab0025103a60ecaaf3abf24db1db240a4e1c15837090d2c32f625ac98abea"
checksum = "d0446843641c69436765a35a5a77088e28c2e6a12da93e84aa3ab1cd4aa5a042"
dependencies = [
"arrayvec",
"borsh",
"bytecheck",
"byteorder",
"bytes",
"num-traits",
@ -2823,9 +2815,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
version = "0.101.2"
version = "0.101.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59"
checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e"
dependencies = [
"ring",
"untrusted",
@ -2833,15 +2825,15 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.15"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
[[package]]
name = "scopeguard"
version = "1.2.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sct"
@ -2863,14 +2855,14 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
name = "sea-orm"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90b508f060b689cd91abd76973ba4f1b0f416bb09915e2177fd3c6f853be76bc"
checksum = "61f6c7daef05dde3476d97001e11fca7a52b655aa3bf4fd610ab2da1176a2ed5"
dependencies = [
"async-stream",
"async-trait",
@ -2888,7 +2880,7 @@ dependencies = [
"sqlx",
"strum",
"thiserror",
"time 0.3.24",
"time 0.3.23",
"tracing",
"url",
"uuid",
@ -2896,9 +2888,9 @@ dependencies = [
[[package]]
name = "sea-orm-cli"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d3b389690bccc6565e6a6af367599957b196288c4f556a7b4157a8c5086eb8d"
checksum = "3e3f0ff2fa5672e2e7314d107c6498a18e469beeb340a0ed84e3075fce73c2cd"
dependencies = [
"chrono",
"clap",
@ -2913,23 +2905,23 @@ dependencies = [
[[package]]
name = "sea-orm-macros"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d49560a5a1bbd57f82fa1a622a8deefa51e44ce3a0b27f012f50bb6092a914f"
checksum = "cd90e73d5f5b184bad525767da29fbfec132b4e62ebd6f60d2f2737ec6468f62"
dependencies = [
"heck",
"proc-macro2",
"quote",
"sea-bae",
"syn 2.0.28",
"syn 2.0.25",
"unicode-ident",
]
[[package]]
name = "sea-orm-migration"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdccbb31e93d1a426a0df84f5f36d0b84d302444c3156e3a4fedb0b8da64ae87"
checksum = "21f673fcefb3a7e7b89a12b6c0e854ec0be14367635ac3435369c8ad7f11e09e"
dependencies = [
"async-trait",
"clap",
@ -2956,7 +2948,7 @@ dependencies = [
"rust_decimal",
"sea-query-derive",
"serde_json",
"time 0.3.24",
"time 0.3.23",
"uuid",
]
@ -2972,7 +2964,7 @@ dependencies = [
"sea-query",
"serde_json",
"sqlx",
"time 0.3.24",
"time 0.3.23",
"uuid",
]
@ -3020,35 +3012,35 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "semver"
version = "1.0.18"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
[[package]]
name = "serde"
version = "1.0.179"
version = "1.0.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0"
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.179"
version = "1.0.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c"
checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
name = "serde_json"
version = "1.0.104"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed"
dependencies = [
"itoa",
"ryu",
@ -3078,9 +3070,9 @@ dependencies = [
[[package]]
name = "serde_with"
version = "3.1.0"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3"
checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513"
dependencies = [
"base64 0.21.2",
"chrono",
@ -3089,26 +3081,26 @@ dependencies = [
"serde",
"serde_json",
"serde_with_macros",
"time 0.3.24",
"time 0.3.23",
]
[[package]]
name = "serde_with_macros"
version = "3.1.0"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65"
checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
name = "serde_yaml"
version = "0.9.25"
version = "0.9.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574"
checksum = "452e67b9c20c37fa79df53201dc03839651086ed9bbe92b3ca585ca9fdaa7d85"
dependencies = [
"indexmap 2.0.0",
"itoa",
@ -3156,9 +3148,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "signal-hook"
version = "0.3.17"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
dependencies = [
"libc",
"signal-hook-registry",
@ -3208,7 +3200,7 @@ checksum = "2230cd5c29b815c9b699fb610b49a5ed65588f3509d9f0108be3a885da629333"
dependencies = [
"colored",
"log",
"time 0.3.24",
"time 0.3.23",
"windows-sys 0.42.0",
]
@ -3325,7 +3317,7 @@ dependencies = [
"smallvec",
"sqlformat",
"thiserror",
"time 0.3.24",
"time 0.3.23",
"tokio",
"tokio-stream",
"tracing",
@ -3414,7 +3406,7 @@ dependencies = [
"sqlx-core",
"stringprep",
"thiserror",
"time 0.3.24",
"time 0.3.23",
"tracing",
"uuid",
"whoami",
@ -3459,7 +3451,7 @@ dependencies = [
"sqlx-core",
"stringprep",
"thiserror",
"time 0.3.24",
"time 0.3.23",
"tracing",
"uuid",
"whoami",
@ -3484,7 +3476,7 @@ dependencies = [
"percent-encoding",
"serde",
"sqlx-core",
"time 0.3.24",
"time 0.3.23",
"tracing",
"url",
"uuid",
@ -3498,9 +3490,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "stringprep"
version = "0.1.3"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da"
checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
dependencies = [
"unicode-bidi",
"unicode-normalization",
@ -3537,9 +3529,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.28"
version = "2.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2"
dependencies = [
"proc-macro2",
"quote",
@ -3554,9 +3546,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
version = "3.7.0"
version = "3.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998"
checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651"
dependencies = [
"cfg-if",
"fastrand 2.0.0",
@ -3608,22 +3600,22 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.44"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.44"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -3649,11 +3641,10 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.24"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b79eabcd964882a646b3584543ccabeae7869e9ac32a46f6f22b7a5bd405308b"
checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446"
dependencies = [
"deranged",
"itoa",
"libc",
"num_threads",
@ -3670,9 +3661,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
[[package]]
name = "time-macros"
version = "0.2.11"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd"
checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4"
dependencies = [
"time-core",
]
@ -3720,7 +3711,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -3803,9 +3794,9 @@ dependencies = [
[[package]]
name = "totp-rs"
version = "5.1.0"
version = "5.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f7b277d6c2a9dc06b706aa35156ea7b6958793c444f1f1e911b6273fc7e67c1"
checksum = "0ad5e73765ff14ae797c1a61ee0c7beaf21b4e4a0047844300e332c6c24df1fc"
dependencies = [
"base32",
"constant_time_eq",
@ -3844,7 +3835,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
@ -3873,7 +3864,7 @@ dependencies = [
[[package]]
name = "trifid-api"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"actix-cors",
"actix-request-identifier",
@ -3937,14 +3928,14 @@ dependencies = [
[[package]]
name = "trifid_api_entities"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"sea-orm",
]
[[package]]
name = "trifid_api_migration"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"async-std",
"async-trait",
@ -3971,9 +3962,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]]
name = "unicode-ident"
version = "1.0.11"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
[[package]]
name = "unicode-normalization"
@ -4008,9 +3999,9 @@ dependencies = [
[[package]]
name = "unsafe-libyaml"
version = "0.2.9"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa"
checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6"
[[package]]
name = "untrusted"
@ -4031,9 +4022,9 @@ dependencies = [
[[package]]
name = "urlencoding"
version = "2.1.3"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
[[package]]
name = "utf8parse"
@ -4043,9 +4034,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.4.1"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be"
dependencies = [
"getrandom",
"serde",
@ -4117,7 +4108,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
"wasm-bindgen-shared",
]
@ -4151,7 +4142,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -4373,9 +4364,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]]
name = "winnow"
version = "0.5.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bd122eb777186e60c3fdf765a58ac76e41c582f1f535fbf3314434c6b58f3f7"
checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
dependencies = [
"memchr",
]
@ -4427,23 +4418,23 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.25",
]
[[package]]
name = "zstd"
version = "0.12.4"
version = "0.12.3+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c"
checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "6.0.6"
version = "6.0.5+zstd.1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581"
checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b"
dependencies = [
"libc",
"zstd-sys",

View File

@ -3,6 +3,7 @@ module main
go 1.20
require (
dario.cat/mergo v1.0.0 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@ -14,26 +15,27 @@ require (
github.com/google/gopacket v1.1.19 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/dns v1.1.54 // indirect
github.com/miekg/dns v1.1.55 // indirect
github.com/nbrownus/go-metrics-prometheus v0.0.0-20210712211119-974a6260965f // indirect
github.com/prometheus/client_golang v1.15.1 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/slackhq/nebula v1.7.2 // indirect
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect
github.com/vishvananda/netlink v1.1.0 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
golang.org/x/crypto v0.8.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/term v0.8.0 // indirect
golang.org/x/net v0.13.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/protobuf v1.30.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

View File

@ -1,4 +1,6 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -76,6 +78,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@ -95,6 +99,8 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@ -111,6 +117,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@ -118,8 +126,12 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/slackhq/nebula v1.7.2 h1:Rko1Mlksz/nC0c919xjGpB8uOSrTJ5e6KPgZx+lVfYw=
github.com/slackhq/nebula v1.7.2/go.mod h1:cnaoahkUipDs1vrNoIszyp0QPRIQN9Pm68ppQEW1Fhg=
github.com/slackhq/nebula v1.7.3-0.20230802182832-83b6dc7b16e5 h1:NWU3xgmHAWA10Io2a20RFOVC0raucO+ZBohow3Am3H0=
github.com/slackhq/nebula v1.7.3-0.20230802182832-83b6dc7b16e5/go.mod h1:gpXidU9u3Nf0nfkwmM4nnjxhEiV/Z+8MEumGo4wVuyI=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -142,6 +154,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@ -160,6 +174,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -184,12 +200,17 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@ -203,6 +224,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b h1:J1CaxgLerRR5lgx3wnr6L04cJFbWoceSK9JWBdglINo=
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b/go.mod h1:tqur9LnfstdR9ep2LaJT4lFUl0EjlHtge+gAjmsHUG4=
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -216,6 +239,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -1,4 +1,20 @@
//! # nebula-ffi
//! nebula-ffi is a crate for interacting with the Nebula project via a CGo compatability layer.
//! It provides support for running a Nebula VPN directly from a Rust binary, liken to how the default
//! `nebula` binary functions.
//! ## Versioning
//! `nebula-ffi` is automatically updated for every single release or commit made on the slackhq/nebula repository.
//! To build against a **specific release:**
//! ```toml
//! [dependencies]
//! nebula-ffi = { version = "1.7.2" } # for Nebula 1.7.2
//! ```
//! To build against a **specific commit:**
//! ```toml
//! [dependencies]
//! nebula-ffi = { version = "1.7.2+83b6dc7" } # for commit 83b6dc7, which happened *after* the 1.7.2 release
//! ```
//! This versioning is an artifact of the build process for nebula-ffi and how Cargo versioning works.
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]

43
nebula-ffi/update.py Normal file
View File

@ -0,0 +1,43 @@
import os
import re
import subprocess
import shutil
# Super cursed python script to update nebula and rewrite the cargo version so we can have Ultra Up-To-Date nebula versions
# clone the repository to /tmp/nebula-clone-checkout
#if os.path.exists('/tmp/nebula-clone-checkout'):
# shutil.rmtree('/tmp/nebula-clone-checkout')
#subprocess.check_output(['git', 'clone', 'https://github.com/slackhq/nebula', '/tmp/nebula-clone-checkout', '--bare'])
describe = subprocess.check_output(['git', '-C', '/tmp/nebula-clone-checkout', 'describe']).decode('ascii').strip()
print(f'Repository version: {describe}')
on_tag_re = re.compile('v(\\d+.)+(\\d+)')
on_commit_re = re.compile('v(\d+.)+(\d+)-(\d+)-g[a-f0-9]+')
if on_commit_re.match(describe):
print('Repository is on-commit (no tag on this commit)')
split = describe.split('-')
version_splits = len(split) - 2
version = split[:version_splits][0].split('v')[1]
commit = split[-1].split('g')[1]
print('Base version:', version)
print('Commit:', commit)
print(f'Go package specifier: github.com/slackhq/nebula@{commit}')
print(f'Cargo package version: {version}+{commit}')
gopkg = f'github.com/slackhq/nebula@{commit}'
cargo = f'{version}+{commit}'
print('Updating gopkg')
subprocess.check_output(['go', 'get', gopkg])
print('Updating cargo (todo)')
elif on_tag_re.match(describe):
print('Repository is on-tag (this commit is tagged)')

View File

@ -1,6 +1,6 @@
[package]
name = "trifid-api"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
description = "Pure-rust Defined Networking compatible management server"
license = "GPL-3.0-or-later"
@ -26,8 +26,8 @@ log = "0.4" # Logging
simple_logger = "4" # Logging
sea-orm = { version = "0.12", features = [ "sqlx-postgres", "runtime-actix-rustls", "macros" ]} # Database
trifid_api_migration = { version = "0.1.0", path = "trifid_api_migration" } # Database
trifid_api_entities = { version = "0.1.0", path = "trifid_api_entities" } # Database
trifid_api_migration = { version = "0.1", path = "trifid_api_migration" } # Database
trifid_api_entities = { version = "0.1", path = "trifid_api_entities" } # Database
rand = "0.8" # Misc.
hex = "0.4" # Misc.

View File

@ -78,6 +78,11 @@ url = "your-database-url-here"
# SocketAddr. Optional. Default = 0.0.0.0:8080 (all IPs, port 8080)
# bind = "0.0.0.0:8080"
# The number of worker threads to create.
# Increase this number if your server is timing out requests.
# usize. Optional. Default = 32
# workers = 32
#### [tokens] ####
# Configure options related to the various tokens that may be issued by the trifid-api server.
[tokens]

View File

@ -76,6 +76,8 @@ pub struct TrifidConfigDatabase {
pub struct TrifidConfigServer {
#[serde(default = "socketaddr_8080")]
pub bind: SocketAddr,
#[serde(default = "default_workers")]
pub workers: usize
}
#[derive(Serialize, Deserialize, Debug)]
@ -730,3 +732,5 @@ fn none<T>() -> Option<T> {
fn is_none<T>(o: &Option<T>) -> bool {
o.is_none()
}
fn default_workers() -> usize { 32 }

View File

@ -88,7 +88,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
errors: vec![api_error],
}),
)
.into()
.into()
}),
)
.wrap(RequestIdentifier::with_generator(random_id_no_id))
@ -121,9 +121,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
.service(routes::v1::hosts::get_host_overrides)
.service(routes::v1::hosts::update_host_overrides)
})
.bind(CONFIG.server.bind)?
.run()
.await?;
.workers(CONFIG.server.workers)
.bind(CONFIG.server.bind)?
.run()
.await?;
Ok(())
}

View File

@ -74,7 +74,7 @@ pub async fn dnclient(
let client_keys_2 = host_in_ks
.client_keys
.iter()
.find(|u| u.id == host_in_ks.current_client_key);;
.find(|u| u.id == host_in_ks.current_client_key);
let signature = match Signature::from_slice(&req.signature) {
Ok(sig) => sig,
@ -91,18 +91,25 @@ pub async fn dnclient(
};
let mut valid = false;
let mut valid_key = None;
if let Some(client_keys) = client_keys {
if client_keys.ed_pub.verify(req.message.as_bytes(), &signature).is_ok() {
valid = true;
valid_key = Some(client_keys);
}
}
if let Some(client_keys_2) = client_keys_2 {
if client_keys_2.ed_pub.verify(req.message.as_bytes(), &signature).is_ok() {
valid = true;
valid_key = Some(client_keys_2);
}
}
if client_keys.is_none() && client_keys_2.is_none() {
panic!("No valid keys for host {}", host);
}
if !valid {
// Be intentionally vague as the message is invalid.
warn!("! invalid signature from {}", host);
@ -114,6 +121,8 @@ pub async fn dnclient(
}]);
}
let client_keys = valid_key.unwrap();
// Sig OK
// Decode the message from base64

View File

@ -1,6 +1,6 @@
[package]
name = "trifid_api_entities"
version = "0.1.0"
version = "0.1.2"
edition = "2021"
description = "Database entities for trifid-api"
license = "GPL-3.0-or-later"

View File

@ -31,6 +31,8 @@ pub enum Relation {
HostEnrollmentCode,
#[sea_orm(has_many = "super::host_static_address::Entity")]
HostStaticAddress,
#[sea_orm(has_many = "super::keystore_entry::Entity")]
KeystoreEntry,
#[sea_orm(
belongs_to = "super::network::Entity",
from = "Column::Network",
@ -67,6 +69,12 @@ impl Related<super::host_static_address::Entity> for Entity {
}
}
impl Related<super::keystore_entry::Entity> for Entity {
fn to() -> RelationDef {
Relation::KeystoreEntry.def()
}
}
impl Related<super::network::Entity> for Entity {
fn to() -> RelationDef {
Relation::Network.def()

View File

@ -10,6 +10,8 @@ pub mod host;
pub mod host_config_override;
pub mod host_enrollment_code;
pub mod host_static_address;
pub mod keystore_entry;
pub mod keystore_host;
pub mod magic_link;
pub mod network;
pub mod organization;

View File

@ -8,6 +8,8 @@ pub use super::host::Entity as Host;
pub use super::host_config_override::Entity as HostConfigOverride;
pub use super::host_enrollment_code::Entity as HostEnrollmentCode;
pub use super::host_static_address::Entity as HostStaticAddress;
pub use super::keystore_entry::Entity as KeystoreEntry;
pub use super::keystore_host::Entity as KeystoreHost;
pub use super::magic_link::Entity as MagicLink;
pub use super::network::Entity as Network;
pub use super::organization::Entity as Organization;

View File

@ -1,6 +1,6 @@
[package]
name = "trifid_api_migration"
version = "0.1.0"
version = "0.1.2"
edition = "2021"
description = "Database migrations for trifid-api"
license = "GPL-3.0-or-later"
@ -14,7 +14,7 @@ path = "src/lib.rs"
[dependencies]
async-std = { version = "1", features = ["attributes", "tokio1"] }
async-trait = "0.1.68"
async-trait = "0.1"
[dependencies.sea-orm-migration]
version = "0.12"

View File

@ -18,6 +18,8 @@ mod m20230427_170037_create_table_hosts;
mod m20230427_171517_create_table_hosts_static_addresses;
mod m20230427_171529_create_table_hosts_config_overrides;
mod m20230511_120511_create_table_host_enrollment_codes;
mod m20230815_225520_create_table_keystore_hosts;
mod m20230815_230218_create_table_keystore_entries;
#[async_trait::async_trait]
impl MigratorTrait for Migrator {
@ -39,6 +41,8 @@ impl MigratorTrait for Migrator {
Box::new(m20230427_171517_create_table_hosts_static_addresses::Migration),
Box::new(m20230427_171529_create_table_hosts_config_overrides::Migration),
Box::new(m20230511_120511_create_table_host_enrollment_codes::Migration),
Box::new(m20230815_225520_create_table_keystore_hosts::Migration),
Box::new(m20230815_230218_create_table_keystore_entries::Migration),
]
}
}

1
website/docs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
book

16
website/docs/book.toml Normal file
View File

@ -0,0 +1,16 @@
[book]
authors = ["core"]
language = "en"
multilingual = false
src = "src"
title = "Trifid Documentation"
[preprocessor]
[preprocessor.catppuccin]
assets_version = "0.2.1" # DO NOT EDIT: Managed by `mdbook-catppuccin install`
[output]
[output.html]
additional-css = ["./theme/catppuccin.css", "./theme/catppuccin-highlight.css"]

View File

@ -0,0 +1,49 @@
# Summary
[Introduction](./index.md)
# tfclient User's Guide
- [About tfclient](./tfclient/index.md)
- [Platform Support](./tfclient/platform_support.md)
- [Why can't tfclient support XXXX?](./tfclient/why_not_this_os.md)
- [Testing tfclient on new platforms](./tfclient/untested_os.md)
- [Installation](./tfclient/install/index.md)
- [Windows](./tfclient/install/windows.md)
- [macOS](./tfclient/install/macos.md)
- [Linux](./tfclient/install/linux.md)
- [NetBSD](./tfclient/install/netbsd.md)
- [Usage](./tfclient/usage.md)
# trifid-api User's Guide
- [About trifid-api (for users)](./trifid-api/users/index.md)
- [Supported Clients/Platforms](./trifid-api/users/supported_clients.md)
- [How to configure your client](./trifid-api/users/client_setup.md)
- [Why doesn't trifid support mobile devices?](./trifid-api/users/mobile.md)
# trifid-api Administrator's Guide
- [About trifid-api](./trifid-api/index.md)
- [Installation](./trifid-api/install/index.md)
- [Windows](./trifid-api/install/windows.md)
- [macOS](./trifid-api/install/macos.md)
- [Linux](./trifid-api/install/linux.md)
- [Docker](./trifid-api/install/docker.md)
- [Setup Guide](./trifid-api/guide/index.md)
- [Installing trifid-api](./trifid-api/guide/installing.md)
- [Setting up your database](./trifid-api/guide/database.md)
- [Installing tfcli](./trifid-api/guide/tfcli.md)
- [Configuring trifid-api](./trifid-api/guide/config.md)
- [Creating an organization](./trifid-api/guide/firstorg.md)
- [Enrolling a lighthouse](./trifid-api/guide/enroll.md)
- [Troubleshooting](./trifid-api/troubleshooting.md)
- [Config Reference](./trifid-api/config.md)
# tfcli User's Guide
- [About tfcli](./tfcli/index.md)
- [Installation](./tfcli/install/index.md)
- [Windows](./tfcli/install/windows.md)
- [macOS](./tfcli/install/macos.md)
- [Linux](./tfclient/install/linux.md)

19
website/docs/src/index.md Normal file
View File

@ -0,0 +1,19 @@
# Introduction
**trifid** is a complete open-source reimplementation of the [Defined Networking](https://defined.net) management protocol for [Nebula](https://github.com/slackhq/nebula) networks.
It makes it easy to run a completley self-hosted mesh VPN with very little effort.
In addition to the API server reimplementation and custom client, we include a command-line tool for interacting with the [Management API](https://docs.defined.net), fully compatible with the upstream API or any custom API server like trifid.
We also include a Rust library for interacting with keys and certificates in the Nebula PKI. Find it on crates.rs as trifid-pki. This library is an implementation of the Nebula PKI system that is mostly feature-complete, with the exception of non-Curve25519 cryptography, which is currently unsupported.
This set of pages contains complete documentation on how to use the various parts of the trifid project, with the exception of the library crates, `dnapi-rs` and `trifid-pki`, as those are self-documented Rust libraries with good documentation available through docs.rs.
If you are looking for documentation on **tfclient**, the trifid implementation of dnclient, see [it's documentation index](./tfclient/index.md).
If you are a *user* on a trifid-api instance (you are part of an organization on the instance), see [the trifid-api user guide](./trifid-api/users/index.md).
If you are an administrator on a trifid-api instance or are looking to set one up, see [the trifid-api administrator guide](./trifid-api/index.md).
If you are looking for documentation on **tfcli**, the management CLI, see [it's documentation index](./tfcli/index.md).

View File

@ -0,0 +1 @@
# About tfcli

View File

@ -0,0 +1 @@
# Installation

View File

@ -0,0 +1 @@
# macOS

View File

@ -0,0 +1 @@
# Windows

View File

@ -0,0 +1,7 @@
# About tfclient
**tfclient** is an open-source VPN client for the Defined Networking management protocol. It is built around the Nebula mesh vpn originally created by Slack, and now maintained by Defined Networking.
tfclient is written in Rust, and can run on most platforms. For more information on platform support, see [Platform Support](./platform_support.md).
To learn how to install or use tfclient, visit the respective pages for [Installation](./install/index.md) or [Usage](./usage.md).

View File

@ -0,0 +1,5 @@
# Installation
For now, tfclient needs to be compiled from source. Packaged binaries are planned but will come later as the project matures.
Please refer to the relavent page for your system in the sidebar for instructions on how to compile and install tfclient.

View File

@ -0,0 +1,97 @@
# Linux Installation
## 1. Set up your compiler toolchain
In order to compile tfclient, you will need a functional Rust compiler and a functional C compiler suite. You will also need a copy of the `git` command-line tools.
If you don't have Rust installed, we highly recommend you use `rustup`:
```
curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
Follow the instructions on-screen.
Before continuing, ensure you have a Rust compiler:
```
$ cargo -V
```
This command should display `cargo`'s version. If it does not, ensure Rust is installed properly.
You will also need a functioning Go compiler, with CGo support, and `libclang` installed.
Ensure you have:
- a functioning Rust compiler
- a functioning Go compiler, with CGo support
- libclang installed
## 2. Acquire a copy of the tfclient source code
First, determine the most recent release of tfclient. Visit [the refs page](https://git.e3t.cc/~core/trifid/refs), and find the most recent tfclient release.
For example, if you see `tfclient-v0.2.3`, the latest version of tfclient is `0.2.3`.
Next, download the tfclient source code:
```
$ git clone https://git.e3t.cc/~core/trifid --depth 0 -b [desired tfclient version]
$ cd tfclient
```
## 3. Compile tfclient
Finally, compile the tfclient binary with:
```
$ cargo build --release --bin tfclient
```
This can take a very long time depending on your computer specs, and requires an internet connection.
## 4. Install tfclient system-wide
Once the build finishes, the resulting binary will be `target/release/tfclient`. Copy this to a location in the system PATH, such as `/bin` or `/usr/bin`.
## (Optional) 5. Create a system service
The following section assumes you have installed tfclient to `/usr/bin/tfclient`, and you wish to use the upstream DN API, `https://api.defined.net`. You will need to change these values in the
This will vary depending on your system. See the below sections for examples.
### SystemD
```
[Unit]
Description=A client for Defined Networking mesh networks
Wants=basic.target network.target
After=basic.target network.target network-online.target
[Service]
SyslogIdentifier=tfclient
ExecStart=/usr/bin/tfclient run --server https://api.defined.net --name tfclient
Restart=always
[Install]
WantedBy=multi-user.target
```
Place this file in `/usr/lib/systemd/system/tfclient.service`, and start and enable it with `systemctl enable --now tfclient`.
### runit
Create a new folder named `tfclient` in your service directory. For example, on Void Linux, this is `/etc/sv/`.
Create a new **executable** file named `run` in this directory (Void Linux Example: `/etc/sv/tfclient/run`), with the following contents:
```
#!/bin/bash
exec 2>&1 /usr/bin/tfclient --server https://api.defined.net --name tfclient > /var/log/tfclient.log
```
Link the service folder to the runsvdir. For Void Linux, this is `/var/service`:
```
$ ln -s /etc/sv/tfclient /var/service/
```

View File

@ -0,0 +1 @@
# macOS

View File

@ -0,0 +1 @@
# NetBSD

View File

@ -0,0 +1 @@
# Windows

View File

@ -0,0 +1,22 @@
# Platform Support
tfclient is supported on most platforms. tfclient is broken up into two "support tiers":
- 'Tier 1' platforms have full support, including linking to and managing the nebula binary. No extra work is required on these platforms - just install tfclient and run!
- 'Tier 2' platforms cannot link to the nebula-ffi CGo binary due to platform limitations. On these platforms, tfclient must be compiled in Tier 2 mode, and the user is responsible for managing the Nebula binary and ensuring it points to the tfclient-managed config file. Documentation on how to use tfclient on Tier 2 platforms can be found [here](docs/tfclient/tier-2-building.md)
| Operating System / Architecture | tfclient support tier |
|---------------------------------|---------------------------------------|
| Windows (all architectures ) | Tier 2 |
| Darwin (OSX, macOS) | Tier 2 - [untested](./untested_os.md) |
| FreeBSD (amd64) | Tier 1 - [untested](./untested_os.md) |
| NetBSD | Tier 2 |
| Linux | Tier 1 |
On platforms marked 'untested', the trifid maintainers were unable to test tfclient on that platform. Help is wanted to test tfclient on as many platforms as possible!
tfclient should work on most platforms, but the authors of tfclient don't have every device and OS combo in the world.
If you are willing to run untested software on your machine to contribute to trifid, consider testing tfclient on your device and [reporting your findings back to us](https://lists.e3t.cc/~core/trifid-devel). This is super helpful to us and helps us maintain trifid for more platforms when we have users willing to test the latest versions and report bugs to us. If you are interested, please see [this page](./untested_os.md).
Unfortunately, [tfclient won't work everywhere](./why_not_this_os.md). See [here](./why_not_this_os.md) for details.

View File

@ -0,0 +1,13 @@
# Help us out - test tfclient on new platforms
There are [lots](index.md#where-does-trifid-work) of operating systems in which `tfclient` *should* work, but due to a lack of devices, it cannot be tested. If you have a system running one of these devices and want to help out the project, please test tfclient for functionality on your device!
| **Notice**: While tfclient is almost always perfectly safe, there are always risks to running untested software on production machines. Be careful out there! |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
If you aren't able to get tfclient to compile with nebula-ffi, consider trying it as a [Tier 2 platform](docs/tfclient/tier-2-building.md). Documentation on how to do this can be found [here](docs/tfclient/tier-2-building.md).
Any findings, positive or negative, can be posted straight to [trifid-devel](https://lists.e3t.cc/~core/trifid-devel).
Thanks! We really appreciate it.

View File

@ -0,0 +1 @@
# Usage

View File

@ -0,0 +1 @@
# Why can't tfclient support XXXX?

View File

@ -0,0 +1 @@
# How to configure your client

View File

@ -0,0 +1 @@
# Config Reference

View File

@ -0,0 +1 @@
# Configuring trifid-api

View File

@ -0,0 +1 @@
# Setting up your database

View File

@ -0,0 +1 @@
# Enrolling a lighthouse

View File

@ -0,0 +1 @@
# Creating an organization

View File

@ -0,0 +1 @@
# Setup Guide

View File

@ -0,0 +1 @@
# Installing trifid-api

View File

@ -0,0 +1 @@
# Installing tfcli

View File

@ -0,0 +1 @@
# About trifid-api

View File

@ -0,0 +1 @@
# Docker

View File

@ -0,0 +1 @@
# Installation

View File

@ -0,0 +1 @@
# Linux

View File

@ -0,0 +1 @@
# macOS

View File

@ -0,0 +1 @@
# Windows

View File

@ -0,0 +1 @@
# Supported Clients/Platforms

View File

@ -0,0 +1 @@
# Troubleshooting

View File

@ -0,0 +1 @@
# How to configure your client

View File

@ -0,0 +1 @@
# About trifid-api (for users)

View File

@ -0,0 +1 @@
# Why doesn't trifid support mobile devices?

View File

@ -0,0 +1 @@
# Supported Clients/Platforms

View File

@ -0,0 +1,607 @@
.mocha code .hljs-keyword {
color: #cba6f7;
}
.mocha code .hljs-built_in {
color: #f38ba8;
}
.mocha code .hljs-type {
color: #f9e2af;
}
.mocha code .hljs-literal {
color: #fab387;
}
.mocha code .hljs-number {
color: #fab387;
}
.mocha code .hljs-operator {
color: #94e2d5;
}
.mocha code .hljs-punctuation {
color: #bac2de;
}
.mocha code .hljs-property {
color: #94e2d5;
}
.mocha code .hljs-regexp {
color: #f5c2e7;
}
.mocha code .hljs-string {
color: #a6e3a1;
}
.mocha code .hljs-char.escape_ {
color: #a6e3a1;
}
.mocha code .hljs-subst {
color: #a6adc8;
}
.mocha code .hljs-symbol {
color: #f2cdcd;
}
.mocha code .hljs-variable {
color: #cba6f7;
}
.mocha code .hljs-variable.language_ {
color: #cba6f7;
}
.mocha code .hljs-variable.constant_ {
color: #fab387;
}
.mocha code .hljs-title {
color: #89b4fa;
}
.mocha code .hljs-title.class_ {
color: #f9e2af;
}
.mocha code .hljs-title.function_ {
color: #89b4fa;
}
.mocha code .hljs-params {
color: #cdd6f4;
}
.mocha code .hljs-comment {
color: #585b70;
}
.mocha code .hljs-doctag {
color: #f38ba8;
}
.mocha code .hljs-meta {
color: #fab387;
}
.mocha code .hljs-section {
color: #89b4fa;
}
.mocha code .hljs-tag {
color: #a6adc8;
}
.mocha code .hljs-name {
color: #cba6f7;
}
.mocha code .hljs-attr {
color: #89b4fa;
}
.mocha code .hljs-attribute {
color: #a6e3a1;
}
.mocha code .hljs-bullet {
color: #94e2d5;
}
.mocha code .hljs-code {
color: #a6e3a1;
}
.mocha code .hljs-emphasis {
color: #f38ba8;
font-style: italic;
}
.mocha code .hljs-strong {
color: #f38ba8;
font-weight: bold;
}
.mocha code .hljs-formula {
color: #94e2d5;
}
.mocha code .hljs-link {
color: #74c7ec;
font-style: italic;
}
.mocha code .hljs-quote {
color: #a6e3a1;
font-style: italic;
}
.mocha code .hljs-selector-tag {
color: #f9e2af;
}
.mocha code .hljs-selector-id {
color: #89b4fa;
}
.mocha code .hljs-selector-class {
color: #94e2d5;
}
.mocha code .hljs-selector-attr {
color: #cba6f7;
}
.mocha code .hljs-selector-pseudo {
color: #94e2d5;
}
.mocha code .hljs-template-tag {
color: #f2cdcd;
}
.mocha code .hljs-template-variable {
color: #f2cdcd;
}
.mocha code .hljs-diff-addition {
color: #a6e3a1;
background: rgba(166, 227, 161, 0.15);
}
.mocha code .hljs-diff-deletion {
color: #f38ba8;
background: rgba(243, 139, 168, 0.15);
}
.macchiato code .hljs-keyword {
color: #c6a0f6;
}
.macchiato code .hljs-built_in {
color: #ed8796;
}
.macchiato code .hljs-type {
color: #eed49f;
}
.macchiato code .hljs-literal {
color: #f5a97f;
}
.macchiato code .hljs-number {
color: #f5a97f;
}
.macchiato code .hljs-operator {
color: #8bd5ca;
}
.macchiato code .hljs-punctuation {
color: #b8c0e0;
}
.macchiato code .hljs-property {
color: #8bd5ca;
}
.macchiato code .hljs-regexp {
color: #f5bde6;
}
.macchiato code .hljs-string {
color: #a6da95;
}
.macchiato code .hljs-char.escape_ {
color: #a6da95;
}
.macchiato code .hljs-subst {
color: #a5adcb;
}
.macchiato code .hljs-symbol {
color: #f0c6c6;
}
.macchiato code .hljs-variable {
color: #c6a0f6;
}
.macchiato code .hljs-variable.language_ {
color: #c6a0f6;
}
.macchiato code .hljs-variable.constant_ {
color: #f5a97f;
}
.macchiato code .hljs-title {
color: #8aadf4;
}
.macchiato code .hljs-title.class_ {
color: #eed49f;
}
.macchiato code .hljs-title.function_ {
color: #8aadf4;
}
.macchiato code .hljs-params {
color: #cad3f5;
}
.macchiato code .hljs-comment {
color: #5b6078;
}
.macchiato code .hljs-doctag {
color: #ed8796;
}
.macchiato code .hljs-meta {
color: #f5a97f;
}
.macchiato code .hljs-section {
color: #8aadf4;
}
.macchiato code .hljs-tag {
color: #a5adcb;
}
.macchiato code .hljs-name {
color: #c6a0f6;
}
.macchiato code .hljs-attr {
color: #8aadf4;
}
.macchiato code .hljs-attribute {
color: #a6da95;
}
.macchiato code .hljs-bullet {
color: #8bd5ca;
}
.macchiato code .hljs-code {
color: #a6da95;
}
.macchiato code .hljs-emphasis {
color: #ed8796;
font-style: italic;
}
.macchiato code .hljs-strong {
color: #ed8796;
font-weight: bold;
}
.macchiato code .hljs-formula {
color: #8bd5ca;
}
.macchiato code .hljs-link {
color: #7dc4e4;
font-style: italic;
}
.macchiato code .hljs-quote {
color: #a6da95;
font-style: italic;
}
.macchiato code .hljs-selector-tag {
color: #eed49f;
}
.macchiato code .hljs-selector-id {
color: #8aadf4;
}
.macchiato code .hljs-selector-class {
color: #8bd5ca;
}
.macchiato code .hljs-selector-attr {
color: #c6a0f6;
}
.macchiato code .hljs-selector-pseudo {
color: #8bd5ca;
}
.macchiato code .hljs-template-tag {
color: #f0c6c6;
}
.macchiato code .hljs-template-variable {
color: #f0c6c6;
}
.macchiato code .hljs-diff-addition {
color: #a6da95;
background: rgba(166, 218, 149, 0.15);
}
.macchiato code .hljs-diff-deletion {
color: #ed8796;
background: rgba(237, 135, 150, 0.15);
}
.frappe code .hljs-keyword {
color: #ca9ee6;
}
.frappe code .hljs-built_in {
color: #e78284;
}
.frappe code .hljs-type {
color: #e5c890;
}
.frappe code .hljs-literal {
color: #ef9f76;
}
.frappe code .hljs-number {
color: #ef9f76;
}
.frappe code .hljs-operator {
color: #81c8be;
}
.frappe code .hljs-punctuation {
color: #b5bfe2;
}
.frappe code .hljs-property {
color: #81c8be;
}
.frappe code .hljs-regexp {
color: #f4b8e4;
}
.frappe code .hljs-string {
color: #a6d189;
}
.frappe code .hljs-char.escape_ {
color: #a6d189;
}
.frappe code .hljs-subst {
color: #a5adce;
}
.frappe code .hljs-symbol {
color: #eebebe;
}
.frappe code .hljs-variable {
color: #ca9ee6;
}
.frappe code .hljs-variable.language_ {
color: #ca9ee6;
}
.frappe code .hljs-variable.constant_ {
color: #ef9f76;
}
.frappe code .hljs-title {
color: #8caaee;
}
.frappe code .hljs-title.class_ {
color: #e5c890;
}
.frappe code .hljs-title.function_ {
color: #8caaee;
}
.frappe code .hljs-params {
color: #c6d0f5;
}
.frappe code .hljs-comment {
color: #626880;
}
.frappe code .hljs-doctag {
color: #e78284;
}
.frappe code .hljs-meta {
color: #ef9f76;
}
.frappe code .hljs-section {
color: #8caaee;
}
.frappe code .hljs-tag {
color: #a5adce;
}
.frappe code .hljs-name {
color: #ca9ee6;
}
.frappe code .hljs-attr {
color: #8caaee;
}
.frappe code .hljs-attribute {
color: #a6d189;
}
.frappe code .hljs-bullet {
color: #81c8be;
}
.frappe code .hljs-code {
color: #a6d189;
}
.frappe code .hljs-emphasis {
color: #e78284;
font-style: italic;
}
.frappe code .hljs-strong {
color: #e78284;
font-weight: bold;
}
.frappe code .hljs-formula {
color: #81c8be;
}
.frappe code .hljs-link {
color: #85c1dc;
font-style: italic;
}
.frappe code .hljs-quote {
color: #a6d189;
font-style: italic;
}
.frappe code .hljs-selector-tag {
color: #e5c890;
}
.frappe code .hljs-selector-id {
color: #8caaee;
}
.frappe code .hljs-selector-class {
color: #81c8be;
}
.frappe code .hljs-selector-attr {
color: #ca9ee6;
}
.frappe code .hljs-selector-pseudo {
color: #81c8be;
}
.frappe code .hljs-template-tag {
color: #eebebe;
}
.frappe code .hljs-template-variable {
color: #eebebe;
}
.frappe code .hljs-diff-addition {
color: #a6d189;
background: rgba(166, 209, 137, 0.15);
}
.frappe code .hljs-diff-deletion {
color: #e78284;
background: rgba(231, 130, 132, 0.15);
}
.latte code .hljs-keyword {
color: #8839ef;
}
.latte code .hljs-built_in {
color: #d20f39;
}
.latte code .hljs-type {
color: #df8e1d;
}
.latte code .hljs-literal {
color: #fe640b;
}
.latte code .hljs-number {
color: #fe640b;
}
.latte code .hljs-operator {
color: #179299;
}
.latte code .hljs-punctuation {
color: #5c5f77;
}
.latte code .hljs-property {
color: #179299;
}
.latte code .hljs-regexp {
color: #ea76cb;
}
.latte code .hljs-string {
color: #40a02b;
}
.latte code .hljs-char.escape_ {
color: #40a02b;
}
.latte code .hljs-subst {
color: #6c6f85;
}
.latte code .hljs-symbol {
color: #dd7878;
}
.latte code .hljs-variable {
color: #8839ef;
}
.latte code .hljs-variable.language_ {
color: #8839ef;
}
.latte code .hljs-variable.constant_ {
color: #fe640b;
}
.latte code .hljs-title {
color: #1e66f5;
}
.latte code .hljs-title.class_ {
color: #df8e1d;
}
.latte code .hljs-title.function_ {
color: #1e66f5;
}
.latte code .hljs-params {
color: #4c4f69;
}
.latte code .hljs-comment {
color: #acb0be;
}
.latte code .hljs-doctag {
color: #d20f39;
}
.latte code .hljs-meta {
color: #fe640b;
}
.latte code .hljs-section {
color: #1e66f5;
}
.latte code .hljs-tag {
color: #6c6f85;
}
.latte code .hljs-name {
color: #8839ef;
}
.latte code .hljs-attr {
color: #1e66f5;
}
.latte code .hljs-attribute {
color: #40a02b;
}
.latte code .hljs-bullet {
color: #179299;
}
.latte code .hljs-code {
color: #40a02b;
}
.latte code .hljs-emphasis {
color: #d20f39;
font-style: italic;
}
.latte code .hljs-strong {
color: #d20f39;
font-weight: bold;
}
.latte code .hljs-formula {
color: #179299;
}
.latte code .hljs-link {
color: #209fb5;
font-style: italic;
}
.latte code .hljs-quote {
color: #40a02b;
font-style: italic;
}
.latte code .hljs-selector-tag {
color: #df8e1d;
}
.latte code .hljs-selector-id {
color: #1e66f5;
}
.latte code .hljs-selector-class {
color: #179299;
}
.latte code .hljs-selector-attr {
color: #8839ef;
}
.latte code .hljs-selector-pseudo {
color: #179299;
}
.latte code .hljs-template-tag {
color: #dd7878;
}
.latte code .hljs-template-variable {
color: #dd7878;
}
.latte code .hljs-diff-addition {
color: #40a02b;
background: rgba(64, 160, 43, 0.15);
}
.latte code .hljs-diff-deletion {
color: #d20f39;
background: rgba(210, 15, 57, 0.15);
}
.mocha code {
color: #a6adc8;
background: #181825;
}
.mocha .ace_gutter {
color: #7f849c;
background: #181825;
}
.mocha .ace_gutter-active-line.ace_gutter-cell {
color: #f5c2e7;
background: #181825;
}
.macchiato code {
color: #a5adcb;
background: #1e2030;
}
.macchiato .ace_gutter {
color: #8087a2;
background: #1e2030;
}
.macchiato .ace_gutter-active-line.ace_gutter-cell {
color: #f5bde6;
background: #1e2030;
}
.frappe code {
color: #a5adce;
background: #292c3c;
}
.frappe .ace_gutter {
color: #838ba7;
background: #292c3c;
}
.frappe .ace_gutter-active-line.ace_gutter-cell {
color: #f4b8e4;
background: #292c3c;
}
.latte code {
color: #6c6f85;
background: #e6e9ef;
}
.latte .ace_gutter {
color: #8c8fa1;
background: #e6e9ef;
}
.latte .ace_gutter-active-line.ace_gutter-cell {
color: #ea76cb;
background: #e6e9ef;
}

123
website/docs/theme/catppuccin.css vendored Normal file
View File

@ -0,0 +1,123 @@
.mocha {
--bg: #1e1e2e;
--fg: #cdd6f4;
--sidebar-bg: #181825;
--sidebar-fg: #cdd6f4;
--sidebar-non-existant: #6c7086;
--sidebar-active: #89b4fa;
--sidebar-spacer: #6c7086;
--scrollbar: #6c7086;
--icons: #6c7086;
--icons-hover: #7f849c;
--links: #89b4fa;
--inline-code-color: #fab387;
--theme-popup-bg: #181825;
--theme-popup-border: #6c7086;
--theme-hover: #6c7086;
--quote-bg: #181825;
--quote-border: #11111b;
--table-border-color: #11111b;
--table-header-bg: #181825;
--table-alternate-bg: #11111b;
--searchbar-border-color: #11111b;
--searchbar-bg: #181825;
--searchbar-fg: #cdd6f4;
--searchbar-shadow-color: #11111b;
--searchresults-header-fg: #cdd6f4;
--searchresults-border-color: #11111b;
--searchresults-li-bg: #1e1e2e;
--search-mark-bg: #fab387;
}
.macchiato {
--bg: #24273a;
--fg: #cad3f5;
--sidebar-bg: #1e2030;
--sidebar-fg: #cad3f5;
--sidebar-non-existant: #6e738d;
--sidebar-active: #8aadf4;
--sidebar-spacer: #6e738d;
--scrollbar: #6e738d;
--icons: #6e738d;
--icons-hover: #8087a2;
--links: #8aadf4;
--inline-code-color: #f5a97f;
--theme-popup-bg: #1e2030;
--theme-popup-border: #6e738d;
--theme-hover: #6e738d;
--quote-bg: #1e2030;
--quote-border: #181926;
--table-border-color: #181926;
--table-header-bg: #1e2030;
--table-alternate-bg: #181926;
--searchbar-border-color: #181926;
--searchbar-bg: #1e2030;
--searchbar-fg: #cad3f5;
--searchbar-shadow-color: #181926;
--searchresults-header-fg: #cad3f5;
--searchresults-border-color: #181926;
--searchresults-li-bg: #24273a;
--search-mark-bg: #f5a97f;
}
.frappe {
--bg: #303446;
--fg: #c6d0f5;
--sidebar-bg: #292c3c;
--sidebar-fg: #c6d0f5;
--sidebar-non-existant: #737994;
--sidebar-active: #8caaee;
--sidebar-spacer: #737994;
--scrollbar: #737994;
--icons: #737994;
--icons-hover: #838ba7;
--links: #8caaee;
--inline-code-color: #ef9f76;
--theme-popup-bg: #292c3c;
--theme-popup-border: #737994;
--theme-hover: #737994;
--quote-bg: #292c3c;
--quote-border: #232634;
--table-border-color: #232634;
--table-header-bg: #292c3c;
--table-alternate-bg: #232634;
--searchbar-border-color: #232634;
--searchbar-bg: #292c3c;
--searchbar-fg: #c6d0f5;
--searchbar-shadow-color: #232634;
--searchresults-header-fg: #c6d0f5;
--searchresults-border-color: #232634;
--searchresults-li-bg: #303446;
--search-mark-bg: #ef9f76;
}
.latte {
--bg: #eff1f5;
--fg: #4c4f69;
--sidebar-bg: #e6e9ef;
--sidebar-fg: #4c4f69;
--sidebar-non-existant: #9ca0b0;
--sidebar-active: #1e66f5;
--sidebar-spacer: #9ca0b0;
--scrollbar: #9ca0b0;
--icons: #9ca0b0;
--icons-hover: #8c8fa1;
--links: #1e66f5;
--inline-code-color: #fe640b;
--theme-popup-bg: #e6e9ef;
--theme-popup-border: #9ca0b0;
--theme-hover: #9ca0b0;
--quote-bg: #e6e9ef;
--quote-border: #dce0e8;
--table-border-color: #dce0e8;
--table-header-bg: #e6e9ef;
--table-alternate-bg: #dce0e8;
--searchbar-border-color: #dce0e8;
--searchbar-bg: #e6e9ef;
--searchbar-fg: #4c4f69;
--searchbar-shadow-color: #dce0e8;
--searchresults-header-fg: #4c4f69;
--searchresults-border-color: #dce0e8;
--searchresults-li-bg: #eff1f5;
--search-mark-bg: #fe640b;
}

318
website/docs/theme/index.hbs vendored Normal file
View File

@ -0,0 +1,318 @@
<!DOCTYPE HTML>
<html lang="{{ language }}" class="sidebar-visible no-js {{ default_theme }}">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>{{ title }}</title>
{{#if is_print }}
<meta name="robots" content="noindex" />
{{/if}}
{{#if base_url}}
<base href="{{ base_url }}">
{{/if}}
<!-- Custom HTML head -->
{{> head}}
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="{{ description }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
{{#if favicon_svg}}
<link rel="icon" href="{{ path_to_root }}favicon.svg">
{{/if}}
{{#if favicon_png}}
<link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
{{/if}}
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
{{#if print_enable}}
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
{{/if}}
<!-- Fonts -->
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
{{#if copy_fonts}}
<link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
{{/if}}
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
<!-- Custom theme stylesheets -->
{{#each additional_css}}
<link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
{{/each}}
{{#if mathjax_support}}
<!-- MathJax -->
<script async type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
{{/if}}
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "{{ path_to_root }}";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('{{ default_theme }}')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
{{#toc}}{{/toc}}
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
{{> header}}
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">{{ theme_option "Light" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">{{ theme_option "Rust" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">{{ theme_option "Coal" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">{{ theme_option "Navy" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">{{ theme_option "Ayu" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="latte">{{ theme_option "Latte" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="frappe">{{ theme_option "Frappé" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="macchiato">{{ theme_option "Macchiato" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="mocha">{{ theme_option "Mocha" }}</button></li>
</ul>
{{#if search_enabled}}
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
{{/if}}
</div>
<h1 class="menu-title">{{ book_title }}</h1>
<div class="right-buttons">
{{#if print_enable}}
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
{{/if}}
{{#if git_repository_url}}
<a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
</a>
{{/if}}
{{#if git_repository_edit_url}}
<a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
{{/if}}
</div>
</div>
{{#if search_enabled}}
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
{{/if}}
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
{{{ content }}}
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
{{#previous}}
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
{{/previous}}
{{#next}}
<a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
{{/next}}
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
{{#previous}}
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
{{/previous}}
{{#next}}
<a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
{{/next}}
</nav>
</div>
{{#if live_reload_endpoint}}
<!-- Livereload script (if served using the cli tool) -->
<script type="text/javascript">
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "{{{live_reload_endpoint}}}";
const socket = new WebSocket(wsAddress);
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
{{/if}}
{{#if google_analytics}}
<!-- Google Analytics Tag -->
<script type="text/javascript">
var localAddrs = ["localhost", "127.0.0.1", ""];
// make sure we don't activate google analytics if the developer is
// inspecting the book locally...
if (localAddrs.indexOf(document.location.hostname) === -1) {
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', '{{google_analytics}}', 'auto');
ga('send', 'pageview');
}
</script>
{{/if}}
{{#if playground_line_numbers}}
<script type="text/javascript">
window.playground_line_numbers = true;
</script>
{{/if}}
{{#if playground_copyable}}
<script type="text/javascript">
window.playground_copyable = true;
</script>
{{/if}}
{{#if playground_js}}
<script src="{{ path_to_root }}ace.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}editor.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}mode-rust.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}theme-dawn.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
{{/if}}
{{#if search_js}}
<script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}searcher.js" type="text/javascript" charset="utf-8"></script>
{{/if}}
<script src="{{ path_to_root }}clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
{{#each additional_js}}
<script type="text/javascript" src="{{ ../path_to_root }}{{this}}"></script>
{{/each}}
{{#if is_print}}
{{#if mathjax_support}}
<script type="text/javascript">
window.addEventListener('load', function() {
MathJax.Hub.Register.StartupHook('End', function() {
window.setTimeout(window.print, 100);
});
});
</script>
{{else}}
<script type="text/javascript">
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
</script>
{{/if}}
{{/if}}
</body>
</html>