diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..9236256 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2653 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "async-stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "binascii" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata 0.1.10", +] + +[[package]] +name = "bstr" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +dependencies = [ + "memchr", + "regex-automata 0.3.6", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "chrono-tz" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c39203181991a7dd4343b8005bd804e7a9a37afb8ac070e43771e8c820bbde" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f509c3a87b33437b05e2458750a0700e5bdd6956176773e6c7d6dd15a283a0c" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + +[[package]] +name = "cipher" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" +dependencies = [ + "bitflags 1.3.2", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "cookie" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" +dependencies = [ + "aes-gcm", + "base64 0.13.1", + "hkdf", + "hmac", + "percent-encoding", + "rand", + "sha2", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "cxx" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "deunicode" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" + +[[package]] +name = "devise" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c7580b072f1c8476148f16e0a0d5dedddab787da98d86c5082c5e9ed8ab595" +dependencies = [ + "devise_codegen", + "devise_core", +] + +[[package]] +name = "devise_codegen" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123c73e7a6e51b05c75fe1a1b2f4e241399ea5740ed810b0e3e6cacd9db5e7b2" +dependencies = [ + "devise_core", + "quote", +] + +[[package]] +name = "devise_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841ef46f4787d9097405cac4e70fb8644fc037b526e8c14054247c0263c400d0" +dependencies = [ + "bitflags 1.3.2", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "encoding_rs_io" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83" +dependencies = [ + "encoding_rs", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "figment" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9" +dependencies = [ + "atomic", + "pear", + "serde", + "toml 0.5.9", + "uncased", + "version_check", +] + +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libgit2-sys", + "log", + "url", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "globset" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" +dependencies = [ + "aho-corasick 0.7.20", + "bstr 0.2.17", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] +name = "grep" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cea81f81c4c120466aef365c225a05c707b002a20f2b9fe3287124b809a8d4f" +dependencies = [ + "grep-cli", + "grep-matcher", + "grep-printer", + "grep-regex", + "grep-searcher", +] + +[[package]] +name = "grep-cli" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dd110c34bb4460d0de5062413b773e385cbf8a85a63fc535590110a09e79e8a" +dependencies = [ + "atty", + "bstr 0.2.17", + "globset", + "lazy_static", + "log", + "regex", + "same-file", + "termcolor", + "winapi-util", +] + +[[package]] +name = "grep-matcher" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3902ca28f26945fe35cad349d776f163981d777fee382ccd6ef451126f51b319" +dependencies = [ + "memchr", +] + +[[package]] +name = "grep-printer" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14551578f49da1f774b70da5bd1b8c20bbbead01620c426cb0a217536d95a6a" +dependencies = [ + "base64 0.20.0", + "bstr 1.6.0", + "grep-matcher", + "grep-searcher", + "serde", + "serde_json", + "termcolor", +] + +[[package]] +name = "grep-regex" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "997598b41d53a37a2e3fc5300d5c11d825368c054420a9c65125b8fe1078463f" +dependencies = [ + "aho-corasick 0.7.20", + "bstr 1.6.0", + "grep-matcher", + "log", + "regex", + "regex-syntax 0.6.28", + "thread_local", +] + +[[package]] +name = "grep-searcher" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5601c4b9f480f0c9ebb40b1f6cbf447b8a50c5369223937a6c5214368c58779f" +dependencies = [ + "bstr 1.6.0", + "bytecount", + "encoding_rs", + "encoding_rs_io", + "grep-matcher", + "log", + "memmap2", +] + +[[package]] +name = "h2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "historian" +version = "0.0.1" +dependencies = [ + "chrono", + "clap", + "git2", + "grep", + "pathdiff", + "pulldown-cmark", + "regex", + "rocket", + "serde", + "tera", + "toml 0.4.10", +] + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humansize" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" + +[[package]] +name = "hyper" +version = "0.14.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[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.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libz-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "multer" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed4198ce7a4cbd2a57af78d28c6fbb57d81ac5f1d6ad79ac6c5587419cbdf22" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "log", + "memchr", + "mime", + "spin", + "tokio", + "tokio-util", + "version_check", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi 0.1.19", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "pear" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi", +] + +[[package]] +name = "pear_codegen" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pest" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f400b0f7905bf702f9f3dc3df5a121b16c54e9e8012c082905fdf09a931861a" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "423c2ba011d6e27b02b482a3707c773d19aec65cc024637aec44e19652e66f63" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e64e6c2c85031c02fdbd9e5c72845445ca0a724d419aa0bc068ac620c9935c1" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57959b91f0a133f89a68be874a5c88ed689c19cd729ecdb5d762ebf16c64d662" +dependencies = [ + "once_cell", + "pest", + "sha1", +] + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", + "uncased", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "polyval" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + +[[package]] +name = "pulldown-cmark" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63" +dependencies = [ + "bitflags 1.3.2", + "getopts", + "memchr", + "unicase", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "ref-cast" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b15debb4f9d60d767cd8ca9ef7abb2452922f3214671ff052defc7f3502c44" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfa8511e9e94fd3de6585a3d3cd00e01ed556dc9814829280af0e8dc72a8f36" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick 1.1.3", + "memchr", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.28", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick 1.1.3", + "memchr", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rocket" +version = "0.5.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ead083fce4a405feb349cf09abdf64471c6077f14e0ce59364aa90d4b99317" +dependencies = [ + "async-stream", + "async-trait", + "atomic", + "atty", + "binascii", + "bytes", + "either", + "figment", + "futures", + "indexmap", + "log", + "memchr", + "multer", + "num_cpus", + "parking_lot", + "pin-project-lite", + "rand", + "ref-cast", + "rocket_codegen", + "rocket_http", + "serde", + "serde_json", + "state", + "tempfile", + "time", + "tokio", + "tokio-stream", + "tokio-util", + "ubyte", + "version_check", + "yansi", +] + +[[package]] +name = "rocket_codegen" +version = "0.5.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6aeb6bb9c61e9cd2c00d70ea267bf36f76a4cc615e5908b349c2f9d93999b47" +dependencies = [ + "devise", + "glob", + "indexmap", + "proc-macro2", + "quote", + "rocket_http", + "syn", + "unicode-xid", +] + +[[package]] +name = "rocket_http" +version = "0.5.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ded65d127954de3c12471630bf4b81a2792f065984461e65b91d0fdaafc17a2" +dependencies = [ + "cookie", + "either", + "futures", + "http", + "hyper", + "indexmap", + "log", + "memchr", + "pear", + "percent-encoding", + "pin-project-lite", + "ref-cast", + "serde", + "smallvec", + "stable-pattern", + "state", + "time", + "tokio", + "uncased", +] + +[[package]] +name = "rustix" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "serde" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[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 = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slug" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" +dependencies = [ + "deunicode", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" + +[[package]] +name = "stable-pattern" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" +dependencies = [ + "memchr", +] + +[[package]] +name = "state" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" +dependencies = [ + "loom", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tera" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df578c295f9ec044ff1c829daf31bb7581d5b3c2a7a3d87419afe1f2531438c" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "ubyte" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" +dependencies = [ + "serde", +] + +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + +[[package]] +name = "uncased" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" +dependencies = [ + "serde", + "version_check", +] + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524b68aca1d05e03fdf03fcdce2c6c94b6daf6d16861ddaa7e4f2b6638a9052c" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[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-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", +] + +[[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 = "windows" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec" +dependencies = [ + "windows_aarch64_msvc 0.32.0", + "windows_i686_gnu 0.32.0", + "windows_i686_msvc 0.32.0", + "windows_x86_64_gnu 0.32.0", + "windows_x86_64_msvc 0.32.0", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.0", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm 0.42.0", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..90e1eae --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "historian" +version = "0.0.1" +authors = ["Adrian Kuschelyagi Malacoda "] +edition = "2021" + +[dependencies] +pulldown-cmark = "0.9.2" +tera = "1.17.1" +toml = "0.4.2" +grep = "0.2" +regex = "1.10.5" +pathdiff = "0.2.1" + +[dependencies.chrono] +version = "0.4.38" +features = ["serde"] + +[dependencies.git2] +version = "0.19.0" +default-features = false + +[dependencies.clap] +version = "4.0.29" +features = ["derive"] + +[dependencies.rocket] +version = "0.5.0-rc.2" +features = ["json"] + +[dependencies.serde] +version = "1.0" +features = ["derive"] diff --git a/README.md b/README.md index 81bef71..70ef678 100644 --- a/README.md +++ b/README.md @@ -1 +1,10 @@ # Historian +Historian is a hybrid wiki and static site generator. + +More broadly, Historian aims to present a git repository of Markdown files as a web-editable wiki, which can be exported into a static site. As such, Historian tries not to introduce its own special syntax or conventions. A Historian wiki should be editable and previewable in any Markdown editor, and should be usable as a wiki or documentation site in e.g. a GitHub or Gitea repo. + +That being said Historian does also include some helper tools to make management of such a wiki easier, for example, it includes a tool to resolve MediaWiki style [[wikilinks]] into a markdown links. These tools can be used both on the command line and in the Historian web interface. + +The Historian web interface is a very simple wiki interface that provides an editor and a page history view. It does not currently do authentication; it's intended exclusively as an internal wiki. + +A search functionality is planned but not implemented. Ideally it would be possible to include the search component as part of the statically built website, perhaps by compiling a search index along with the website contents. diff --git a/guix.scm b/guix.scm new file mode 100644 index 0000000..73dddf9 --- /dev/null +++ b/guix.scm @@ -0,0 +1,40 @@ +(define-module (historian) + #:use-module (guix packages) + #:use-module (guix download) + #:use-module (guix git-download) + #:use-module (guix build-system cargo) + #:use-module (guix licenses) + #:use-module (guix gexp) + #:use-module (gnu packages rust) + #:use-module (gnu packages crates-io) + #:use-module (gnu packages crates-web) + #:use-module ((guix licenses) #:prefix license:)) + +(define-public historian + (package + (name "historian") + (version "0.0.1") + (source + (local-file (dirname (current-filename)) + #:recursive? #t)) + (build-system cargo-build-system) + (arguments + `(#:cargo-inputs + (("rust-rocket" ,rust-rocket-0.4) + ("rust-regex" ,rust-regex-1)) + #:cargo-development-inputs + ())) +; (arguments +; `(#:rust (rust-1.57) +; #:cargo-inputs +; (("rust-rocket" ,rust-rocket-0.4)) +; #:cargo-development-inputs +; ())) +; (inputs) +; (native-inputs) + (home-page "https://forge.monarch-pass.net/malacoda/project-mushroom") + (synopsis "") + (description "") + (license license:gpl3+))) + +historian diff --git a/make-dev-environment b/make-dev-environment new file mode 100755 index 0000000..a16136c --- /dev/null +++ b/make-dev-environment @@ -0,0 +1,7 @@ +#!/usr/bin/env -S guix shell -D -f guix.scm rust-analyzer -- sh +##!/usr/bin/env -S guix shell -D -f guix.scm -- sh +#export LIBCLANG_PATH=$GUIX_ENVIRONMENT/lib/libclang.so +export CC=gcc +COMMAND=${1:-$SHELL} +ARGS=${@:2} +$COMMAND $ARGS diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..fae6b5c --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,564 @@ +static DEFAULT_INDEX_FILENAME: &'static str = "README.md"; +static DEFAULT_TEMPLATES_PATH: &'static str = "templates"; +static DEFAULT_TOML_FILENAME: &'static str = "Historian.toml"; + +extern crate pulldown_cmark; +extern crate tera; +extern crate serde; +extern crate git2; +extern crate regex; +extern crate pathdiff; +extern crate chrono; +#[macro_use] extern crate toml; + +use std::fs; +use std::path::{Path, PathBuf}; +use std::io::{Read, Write}; +use std::collections::{HashMap, VecDeque}; +use std::convert::From; +use std::sync::Mutex; +use std::ffi::OsStr; + +use git2::{Repository, Signature, Commit}; + +use tera::Tera; +use toml::value::Table; +use serde::Serialize; + +use regex::Regex; +use pathdiff::diff_paths; + +use chrono::{DateTime, MappedLocalTime, TimeZone, Local}; + +pub struct Historian { + source_root: PathBuf, + index_filename: String, + pub repository: Option>, + pub site_config: Table +} + +impl Historian { + pub fn new(root: String) -> Historian { + let source_root: PathBuf = root.into(); + let toml_path = source_root.join(DEFAULT_TOML_FILENAME); + let site_config = match fs::metadata(&toml_path) { + Err(_) => Table::new(), + Ok(_) => { + let toml_data = fs::read(&toml_path).unwrap(); + toml::de::from_slice(&toml_data).unwrap() + } + }; + + Historian { + source_root: source_root.clone(), + index_filename: DEFAULT_INDEX_FILENAME.to_owned(), + repository: Repository::open(source_root).ok().map(Mutex::new), + site_config + } + } + + pub fn resolve_to_page(&self, name: &str) -> Option { + let mut file_path = self.source_root.clone().join(Path::new(name)); + match fs::metadata(&file_path) { + Err(_) => None, + Ok(metadata) => { + let mut children = vec![]; + if metadata.is_dir() { + for entry in fs::read_dir(&file_path).unwrap() { + let child = entry.unwrap().file_name().into_string().unwrap(); + if !(child.starts_with(".") || child == self.index_filename || child == DEFAULT_TOML_FILENAME) { + children.push(child); + } + } + + file_path.push(&self.index_filename); + } + + let mut split_path = name.rsplitn(2, "/"); + let base_name = split_path.next().unwrap().to_owned(); + let parent_page = if name != "" { + self.resolve_to_page(split_path.next().unwrap_or("")) + .map(Box::new) + } else { + None + }; + + let mut url = name.to_owned(); + if url != "" && metadata.is_dir() { + url.push('/'); + } + Some(Page { + full_name: name.to_owned(), + name: base_name, + url, + parent: parent_page, + path: file_path, + is_directory: metadata.is_dir(), + children + }) + } + } + } + + // Creates a struct for a new page. + // The page is not saved until an edit is submitted. + pub fn start_page(&self, name: &str) -> Page { + let mut file_path = self.source_root.clone().join(Path::new(name)); + let is_directory = file_path.extension().is_none(); + let mut url = name.to_owned(); + + if is_directory { + file_path.push(&self.index_filename); + url.push('/'); + } + + let mut split_path = name.rsplitn(2, "/"); + let base_name = split_path.next().unwrap().to_owned(); + + Page { + full_name: name.to_owned(), + name: base_name, + url, + parent: None, + path: file_path, + is_directory, + children: vec![] + } + } + + pub fn submit_edit(&self, page: &Page, change: &Edit) { + // Create parent directories if necessary + if let Some(directory) = &page.path.parent() { + fs::create_dir_all(directory); + } + + // write contents of file + let mut page_html_file = fs::File::create(&page.path).unwrap(); + page_html_file.write_all(change.content.as_bytes()).unwrap(); + + // commit file to git repository + if let Some(repository_mutex) = &self.repository { + if let Ok(repository) = repository_mutex.lock() { + // add file to index + let mut index = repository.index().unwrap(); + index.add_path(&page.path.strip_prefix(&self.source_root).unwrap()).unwrap(); + index.write().unwrap(); + let tree_oid = index.write_tree().unwrap(); + let tree = repository.find_tree(tree_oid).unwrap(); + + // find parent commit + let parent_commit = if let Ok(commit) = repository.revparse_single("HEAD") { + commit.into_commit().ok() + } else { + None + }; + + let mut parents = Vec::new(); + if parent_commit.is_some() { + parents.push(parent_commit.as_ref().unwrap()); + } + + // create commit + let signature = Signature::now(change.author.as_deref().unwrap_or("Historian"), "historian@local").unwrap(); + repository.commit( + Some("HEAD"), + &signature, + &signature, + &change.summary, + &tree, + &parents[..], + ).unwrap(); + } + } + } + + pub fn get_history_of_page(&self, page: &Page) -> Vec { + let mut changes = Vec::new(); + let page_path_in_repo = &page.path.strip_prefix(&self.source_root).unwrap(); + if let Some(repository_mutex) = &self.repository { + if let Ok(repository) = repository_mutex.lock() { + let mut revwalk = repository.revwalk().unwrap(); + revwalk.push_head().unwrap(); + for result in revwalk { + if let Ok(rev) = result { + let commit = repository.find_commit(rev).unwrap(); + if commit_includes_file(&repository, &commit, page_path_in_repo) { + changes.push(Revision { + id: commit.id().to_string(), + author: commit.author().name().unwrap().to_owned(), + summary: commit.summary().unwrap().to_owned(), + datetime: Local.timestamp_opt(commit.time().seconds(), 0).unwrap() + }); + } + } + } + } + } + changes + } + + pub fn get_revision_by_id(&self, id: &str) -> Option { + if let Some(repository_mutex) = &self.repository { + if let Ok(repository) = repository_mutex.lock() { + let object = repository.revparse_single(id).ok()?; + let commit = object.as_commit()?; + return Some(Revision { + id: commit.id().to_string(), + author: commit.author().name().unwrap().to_owned(), + summary: commit.summary().unwrap().to_owned(), + datetime: Local.timestamp_opt(commit.time().seconds(), 0).unwrap() + }); + } + } + None + } + + // ref: https://github.com/rust-lang/git2-rs/issues/996 + pub fn get_page_text_of_revision(&self, page: &Page, revision: &Revision) -> Option { + let page_path_in_repo = &page.path.strip_prefix(&self.source_root).ok()?; + if let Some(repository_mutex) = &self.repository { + if let Ok(repository) = repository_mutex.lock() { + let object = repository.revparse_single(&revision.id).ok()?; + let tree = object.peel_to_tree().ok()?; + let rev_path = tree.get_path(page_path_in_repo).ok()?; + let path_object = rev_path.to_object(&repository).ok()?; + let blob = path_object.into_blob().ok()?; + return Some(std::str::from_utf8(blob.content()).ok()?.to_owned()); + } + } + None + } +} + +fn commit_includes_file(repository: &Repository, commit: &Commit, path: &Path) -> bool { + if commit.parent_count() != 1 { + return false; + } + + let prev_commit = commit.parent(0).unwrap(); + let tree = commit.tree().unwrap(); + let prev_tree = prev_commit.tree().unwrap(); + let diff = repository.diff_tree_to_tree(Some(&prev_tree), Some(&tree), None).unwrap(); + for delta in diff.deltas() { + let file_path = delta.new_file().path().unwrap(); + if file_path == path { + println!(" -- file path {:?}", file_path); + return true; + } + } + false +} + +#[derive(Serialize)] +pub struct Page { + pub full_name: String, + pub name: String, + pub path: PathBuf, + pub url: String, + pub is_directory: bool, + pub parent: Option>, + pub children: Vec +} + +#[derive(Serialize)] +pub struct Edit { + pub author: Option, + pub content: String, + pub summary: String +} + +#[derive(Serialize)] +pub struct Revision { + pub id: String, + pub author: String, + pub summary: String, + pub datetime: DateTime +} + +pub struct PageRenderer { + template_root: PathBuf, + tera: Tera +} + +fn render_markdown (content: &tera::Value, args: &HashMap) -> tera::Result { + let parser = pulldown_cmark::Parser::new(content.as_str().unwrap()); + let mut html_output = String::new(); + pulldown_cmark::html::push_html(&mut html_output, parser); + Ok(tera::Value::String(html_output)) +} + +impl PageRenderer { + pub fn new() -> PageRenderer { + let mut tera = tera::Tera::new("templates/**/*.html").unwrap(); + tera.register_filter("markdown", render_markdown); + PageRenderer { + template_root: DEFAULT_TEMPLATES_PATH.into(), + tera + } + } + + pub fn render_page(&self, historian: &Historian, page: &Page, options: &Table) -> String { + self.render_page_template("page.html", &historian, &page, &options) + } + + pub fn render_page_template(&self, template: &str, historian: &Historian, page: &Page, options: &Table) -> String { + self.template(template) + .with_page(page) + .with_historian(historian) + .insert("options", options) + .render() + } + + pub fn render_page_template_with_variables(&self, template: &str, historian: &Historian, page: &Page, variables: &Table) -> String { + self.template(template) + .with_page(page) + .with_historian(historian) + .insert_all(variables) + .render() + } + + pub fn render_template(&self, template: &str, historian: &Historian, variables: &Table, options: &Table) -> String { + self.template(template) + .with_url("/") + .with_historian(historian) + .insert_all(variables) + .insert("options", options) + .render() + } + + pub fn resource_names(&self) -> Vec { + let mut children = vec![]; + for entry in fs::read_dir(&self.template_root).unwrap() { + let child = entry.unwrap().file_name().into_string().unwrap(); + if !child.ends_with(".html") { + children.push(child); + } + } + + children + } + + pub fn resolve_to_resource(&self, name: &str) -> Option { + let file_path = self.template_root.clone().join(Path::new(name)); + match fs::metadata(&file_path) { + Err(_) => None, + Ok(metadata) => { + if metadata.is_dir() { + None + } else { + Some(file_path) + } + } + } + } + + pub fn template<'a>(&'a self, template: &'a str) -> Render<'a> { + Render::new(&self.tera, template) + } +} + +pub struct Render<'a> { + tera: &'a Tera, + context: tera::Context, + template: &'a str +} + +fn make_relative_root (url: &str) -> String { + let mut slash_count = 0; + for character in url.chars() { + if character == '/' { + slash_count = slash_count + 1; + } + } + "../".repeat(slash_count) +} + +impl<'a> Render<'a> { + fn new(tera: &'a Tera, template: &'a str) -> Render<'a> { + Render { + tera, + context: tera::Context::new(), + template + } + } + + pub fn insert>(mut self, key: S, value: &'a T) -> Render { + self.context.insert(key, value); + self + } + + pub fn insert_all(mut self, variables: &'a Table) -> Render { + for (key, value) in variables { + self.context.insert(key, value); + } + self + } + + pub fn with_url(mut self, url: &'a str) -> Render { + self.context.insert("relative_root", &make_relative_root(url)); + self + } + + pub fn with_historian(mut self, historian: &'a Historian) -> Render { + self.context.insert("site", &historian.site_config); + self.context.insert("has_git", &historian.repository.is_some()); + self + } + + pub fn with_page(mut self, page: &'a Page) -> Render { + self.context.insert("page", &page); + + let mut content = String::new(); + if let Ok(mut file) = fs::File::open(&page.path) { + file.read_to_string(&mut content).unwrap(); + } + self.context.insert("content", &content); + + let mut ancestors: VecDeque<&Page> = VecDeque::new(); + let mut ancestor = page.parent.as_ref(); + while ancestor.is_some() { + ancestors.push_front(ancestor.unwrap().as_ref()); + ancestor = ancestor.unwrap().parent.as_ref(); + } + self.context.insert("ancestors", &ancestors); + + let mut page_url = page.full_name.clone(); + if page.full_name != "" && page.is_directory { + page_url.push('/'); + } + self.context.insert("relative_root", &make_relative_root(&page.url)); + self + } + + pub fn render(self) -> String { + self.tera.render(&self.template, &self.context).unwrap() + } +} + +impl From> for String { + fn from(render: Render) -> Self { + render.render() + } +} + +pub fn export_wiki(historian: &Historian, renderer: &PageRenderer, output_path: &str) { + fs::create_dir_all(&output_path).unwrap(); + for resource_name in renderer.resource_names() { + let mut resource_output_path: PathBuf = output_path.into(); + resource_output_path.push(&resource_name); + println!("export resource {} to {:?}", resource_name, resource_output_path); + fs::copy(renderer.resolve_to_resource(&resource_name).unwrap(), resource_output_path).unwrap(); + } + + export_wiki_page(historian, renderer, "", output_path); +} + +fn export_wiki_page(historian: &Historian, renderer: &PageRenderer, name: &str, output_path: &str) { + if let Some(page) = historian.resolve_to_page(name) { + let page_path: PathBuf = page.full_name.to_owned().replace(".md", ".html").into(); + let mut page_output_path: PathBuf = output_path.into(); + page_output_path.push(&page_path); + + if page.is_directory { + println!("create directory {:?}", page_output_path); + fs::create_dir_all(&page_output_path); + page_output_path.push("index.html"); + } + + println!("export: {} to {:?}", page.full_name, page_output_path); + let page_html = renderer.render_page_template("page.html", historian, &page, toml! { + dynamic = false + }.as_table().unwrap()).replace(".md", ".html"); + + let mut page_html_file = fs::File::create(page_output_path).unwrap(); + page_html_file.write_all(page_html.as_bytes()); + + for child in page.children { + let child_path = page_path.join(child); + export_wiki_page(historian, renderer, child_path.to_str().unwrap(), output_path); + } + } +} + +pub struct Linker<'a> { + historian: &'a Historian, + link_regex: Regex +} + +impl<'a> Linker<'a> { + pub fn new(historian: &Historian) -> Linker { + Linker { + historian, + link_regex: Regex::new(r"\[\[([\w\s\|]+)\]\]").unwrap() + } + } + + pub fn resolve_link(&self, link: &str) -> Option { + let root = self.historian.resolve_to_page("")?; + let mut page_names = root.children; + + loop { + let mut next_page_names: Vec = vec![]; + + // loop through current list of page names to find match + for page_name in page_names { + let page = self.historian.resolve_to_page(&page_name)?; + if self.link_matches_path(link, &page_name) { + return Some(page.full_name.to_owned()); + } + + // Collect list of (fully qualified) subpages + for child in page.children { + let mut child_path = page.full_name.to_owned(); + child_path.push('/'); + child_path.push_str(&child); + next_page_names.push(child_path); + } + } + + if next_page_names.is_empty() { + break; + } + + // + page_names = next_page_names; + } + + None + } + + pub fn resolve_links(&self, page: &Page) -> String { + let mut content = String::new(); + if let Ok(mut file) = fs::File::open(&page.path) { + file.read_to_string(&mut content).unwrap(); + } + + self.resolve_links_for_edit(&page, &Edit { + author: None, + content, + summary: String::new() + }) + } + + pub fn resolve_links_for_edit(&self, page: &Page, edit: &Edit) -> String { + let mut content = edit.content.to_owned(); + for (link_full, [link]) in self.link_regex.captures_iter(&content.to_owned()).map(|c| c.extract()) { + if let Some(resolved_link) = self.resolve_link(link) { + let mut absolute_link_path = self.historian.source_root.to_owned(); + absolute_link_path.push(&resolved_link); + let relative_link_path = diff_paths(&absolute_link_path, &page.path.parent().unwrap()).unwrap(); + content = content.replace(link_full, &format!("[{}](<{}>)", link, relative_link_path.display())); + } + } + + content + } + + fn link_matches_path(&self, link: &str, path: &str) -> bool { + if let Some(page_name) = path.split('/').last() { + page_name == link || Path::new(page_name).file_stem() == Some(OsStr::new(link)) + } else { + false + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..a55b2ec --- /dev/null +++ b/src/main.rs @@ -0,0 +1,216 @@ +use std::path::PathBuf; + +extern crate historian; +use historian::{Historian, Page, Edit, PageRenderer, export_wiki, Linker}; + +#[macro_use] extern crate rocket; +use rocket::serde::json::Json; +use rocket::Responder; +use rocket::response::{Redirect, content::{RawHtml, RawText}}; +use rocket::form::Form; +use rocket::http::uri::Origin; +use rocket::fs::NamedFile; +use rocket::State; + +extern crate clap; +use clap::Parser; + +extern crate grep; + +#[macro_use] extern crate toml; + +#[derive(Responder)] +enum PageResponder { + Redirect(Redirect), + File(NamedFile), + Page(RawHtml), + Text(RawText) +} + +#[get("/")] +async fn page<'r>( + path: PathBuf, origin: &Origin<'r>, + historian: &State, renderer: &State +) -> Option { + let path_str = path.to_str().unwrap(); + if let Some(resource_path) = renderer.resolve_to_resource(path_str) { + Some(PageResponder::File(NamedFile::open(resource_path).await.unwrap())) + } else { + historian.resolve_to_page(path_str).map(|page| { + if let Some(query) = origin.query() { + for (key, value) in query.segments() { + if key == "action" { + if value == "edit" { + return PageResponder::Page(RawHtml(renderer.render_page_template("edit.html", &historian, &page, toml! { + dynamic = true + }.as_table().unwrap()))) + } else if value == "history" { + return PageResponder::Page(RawHtml(renderer.template("history.html") + .with_historian(&historian) + .with_page(&page) + .insert("revisions", &historian.get_history_of_page(&page)) + .insert("options", toml! { + dynamic = true + }.as_table().unwrap()) + .render())) + } + } + + if key == "revision" { + if let Some(revision) = historian.get_revision_by_id(value) { + return PageResponder::Page(RawHtml(renderer.template("revision.html") + .with_historian(&historian) + .with_page(&page) + .insert("revision", &revision) + .insert("content", &historian.get_page_text_of_revision(&page, &revision).unwrap()) + .insert("options", toml! { + dynamic = true + }.as_table().unwrap()) + .render())) + } + } + } + } + + if page.is_directory && !origin.path().ends_with("/") { + PageResponder::Redirect(Redirect::to(origin.path().as_str().to_owned() + "/")) + } else { + PageResponder::Page(RawHtml(renderer.render_page(&historian, &page, toml! { + dynamic = true + }.as_table().unwrap()))) + } + }).or_else(|| { + if let Some(query) = origin.query() { + for (key, value) in query.segments() { + if key == "action" && value == "edit" { + return Some(PageResponder::Page(RawHtml(renderer.template("edit.html") + .with_historian(&historian) + .with_url(&path_str) + .insert("page", &historian.start_page(path_str)) + .insert("content", "") + .insert("ancestors", &Vec::::with_capacity(0)) + .insert("options", toml! { + dynamic = true + }.as_table().unwrap()) + .render()))) + } + } + None + } else { + Some(PageResponder::Redirect(Redirect::to(origin.path().as_str().to_owned() + "?action=edit"))) + } + }) + } +} + +#[derive(FromForm)] +struct PageAction<'r> { + content: &'r str, + author: &'r str, + summary: &'r str, + subaction: &'r str +} + +#[post("/", data = "")] +fn action( + path: PathBuf, origin: &Origin, + historian: &State, renderer: &State, + action: Form> +) -> PageResponder { + let path_str = path.to_str().unwrap(); + let page = historian.resolve_to_page(path_str).unwrap_or_else(|| historian.start_page(path_str)); + + if let Some(query) = origin.query() { + println!("{:?}", query); + for (key, value) in query.segments() { + if key == "action" { + if value == "edit" { + if action.subaction == "preview" { + return PageResponder::Page(RawHtml(renderer.template("edit.html") + .with_page(&page) + .with_historian(&historian) + .insert("content", action.content) + .insert("subaction", action.subaction) + .insert("summary", action.summary) + .insert("author", action.author) + .insert("options", toml! { + dynamic = true + }.as_table().unwrap()) + .render())) + } else { + historian.submit_edit(&page, &Edit { + author: Some(action.author.to_owned()), + summary: action.summary.to_owned(), + content: action.content.to_owned() + }); + return PageResponder::Redirect(Redirect::to(origin.path().as_str().to_owned())) + } + } else if value == "resolvelinks" { + let linker = Linker::new(&historian); + return PageResponder::Text(RawText(linker.resolve_links_for_edit(&page, &Edit { + author: None, + summary: action.summary.to_owned(), + content: action.content.to_owned() + }))) + } + } + } + } + + PageResponder::Page(RawHtml(renderer.render_template("message.html", &historian, toml! { + header = "Invalid Action" + message = "Action was invalid or misunderstood" + }.as_table().unwrap(), toml! { + dynamic = true + }.as_table().unwrap()))) +} + +#[derive(Parser)] +#[command(version, about, long_about = None)] +struct Args { + /// Path to wiki repository + wiki_path: String, + + /// Render the wiki to a static website + #[arg(long)] + render_to: Option, + + /// Resolve a link to a page on the wiki + #[arg(long)] + resolve_link: Option, + + /// Resolve all wiki links in the given page, output the modified text + #[arg(long)] + resolve_links: Option +} + +#[rocket::main] +async fn main() { + let args = Args::parse(); + let historian = Historian::new(args.wiki_path); + let renderer = PageRenderer::new(); + let linker = Linker::new(&historian); + + if let Some(resolve_link) = args.resolve_link { + println!("{}", linker.resolve_link(&resolve_link).unwrap()); + return; + } + + if let Some(resolve_links) = args.resolve_links { + let page = historian.resolve_to_page(&resolve_links).expect("failed to find page"); + println!("{}", linker.resolve_links(&page)); + return; + } + + if let Some(render_to) = args.render_to { + export_wiki(&historian, &renderer, &render_to); + return; + } + + rocket::build() + .manage(historian) + .manage(renderer) + .mount("/", routes![page, action]) + .launch() + .await; +} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..ddbe842 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,134 @@ + + + + {{ page.name }} + + + + + + + + + + {% block styles %} + + + {% endblock styles %} + + + + + + + + + + + + + + + + + + + + +
+ + + +{% block content %} +{% endblock content %} + +
+
+ + + + + + + + diff --git a/templates/edit.css b/templates/edit.css new file mode 100644 index 0000000..2bc7eb8 --- /dev/null +++ b/templates/edit.css @@ -0,0 +1,18 @@ +#edit-area { + width: 100%; + height: 450px; +} + +#edit-summary-label, #edit-author-label { + margin-top: 5px; + display: block; + margin-bottom: 5px; +} + +#edit-summary, #edit-author { + width: 500px; +} + +button { + padding: 5px 10px 5px 10px; +} diff --git a/templates/edit.html b/templates/edit.html new file mode 100644 index 0000000..ff519f0 --- /dev/null +++ b/templates/edit.html @@ -0,0 +1,64 @@ +{% extends "base.html" %} + +{% block styles %} + {{ super() }} + +{% endblock styles %} + +{% block content %} + +{% if subaction and subaction == "preview" %} +
{{ content | markdown | safe }}
+{% endif %} + +
+ + + + + +
+ + +
+
+ + +{% endblock content %} diff --git a/templates/favicon.ico b/templates/favicon.ico new file mode 100644 index 0000000..1040adb Binary files /dev/null and b/templates/favicon.ico differ diff --git a/templates/history.css b/templates/history.css new file mode 100644 index 0000000..92dba42 --- /dev/null +++ b/templates/history.css @@ -0,0 +1,22 @@ +#revision-details { + text-align: center; + padding: 4px; + color: rgb(112, 182, 255); + background-color: rgb(24, 51, 111); + border: 1px solid rgb(112, 182, 255); + margin-top: 10px; + margin-bottom: 10px; +} + +#revision-summary { + display: block; + font-style: italic; +} + +#revision-author { + font-weight: bold; +} + +#revision-datetime { + font-weight: bold; +} diff --git a/templates/history.html b/templates/history.html new file mode 100644 index 0000000..b4c5310 --- /dev/null +++ b/templates/history.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block styles %} + {{ super() }} + +{% endblock styles %} + +{% block content %} + + + +{% endblock content %} diff --git a/templates/message.html b/templates/message.html new file mode 100644 index 0000000..1edff09 --- /dev/null +++ b/templates/message.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} +{% block content %} +

{{ header }}

+{{ message | safe }} +{% endblock content %} diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..a8c01b0 --- /dev/null +++ b/templates/page.html @@ -0,0 +1,4 @@ +{% extends "base.html" %} +{% block content %} +{{ content | markdown | safe }} +{% endblock content %} diff --git a/templates/revision.html b/templates/revision.html new file mode 100644 index 0000000..a4b81bc --- /dev/null +++ b/templates/revision.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} + +{% block styles %} + {{ super() }} + +{% endblock styles %} + +{% block content %} +
+ Revision {{ revision.datetime }} by {{ revision.author }} + {{ revision.summary }} +
+{{ content | markdown | safe }} +{% endblock content %} diff --git a/templates/sinorcaish-print.css b/templates/sinorcaish-print.css new file mode 100644 index 0000000..42130a8 --- /dev/null +++ b/templates/sinorcaish-print.css @@ -0,0 +1,705 @@ +/************************************************************************ +* * +* Sinorcaish Print-based Style Sheet * +* Copyright (C) 2004-07, John Zaitseff * +* * +************************************************************************/ + +/* Author: John Zaitseff + Version: 1.3 + + $Id: sinorcaish-print.css 192 2007-03-22 02:10:24Z john $ + + This file provides the Sinorcaish style sheet for printing HTML pages + to paper. This file conforms to the Cascading Style Sheets 2.1 + specification. + + The design of Sinorcaish is influenced by Sinorca (available from the + Open Source Web Design site, http://www.oswd.org/), which in turn was + based on the Acronis company web site (http://www.acronis.com/). You + can find more information about this design from its home page on the + ZAP Group web site, http://www.zap.org.au/documents/styles/sinorcaish/. + + This file may be redistributed and/or modified on the condition that + the original copyright notice is retained. +*/ + + +/********** Global Styles **********/ + +@page { + margin: 0.5in; +} + +body { + font-family: "Lucida Bright", "Georgia", "DejaVu Serif", "Bitstream Vera Serif", "Times New Roman", TimesNR, Times, Roman, serif; + font-size: 11pt; + color: black; + background: white; + margin: 0; + padding: 0; + border: none; + orphans: 2; + widows: 2; +} + +.hidden { /* Used for content that should be displayed */ + /* by non-stylesheet-aware browsers */ + display: none !important; +} + +.notprinted { /* Used for content that should not be */ + /* printed to paper */ + display: none !important; +} + + +/* Headings */ + +h1, /* Headings (H1-H6) should only be used in */ +h2, /* the main content area */ +h3, +h4, +h5, +h6, +.title { + font-family: "Lucida Sans", "DejaVu Sans", "Bitstream Vera Sans", Verdana, Arial, Helvetica, sans-serif; +} + +h1, +h2, +h3 { + font-weight: bold; + text-align: left; + margin: 1.5em 0 0 0; + padding: 0; + page-break-after: avoid; + page-break-inside: avoid; +} + +h4, +h5, +h6 { + font-weight: bold; + text-align: left; + margin: 1.25em 0 0 0; + padding: 0; + page-break-after: avoid; + page-break-inside: avoid; +} + +h1 { font-size: 175% } +h2 { font-size: 145% } +h3 { font-size: 120% } +h4 { font-size: 105% } +h5 { font-size: 80% } +h6 { font-size: 65% } + + +/* Anchors */ + +a:link { + text-decoration: none; + color: black; + background: transparent; +} + +a:visited { + text-decoration: none; + color: black; + background: transparent; +} + +a:hover, +a:active { + text-decoration: none; +} + + +/* Inline elements and classes */ + + /* This style sheet assumes B, BIG, EM, I, */ + /* SMALL, STRONG, SUB and SUP are defined */ + /* by the browser as per the HTML4 sample */ + /* style sheet. */ +code, +kbd, +samp, +tt { + font-family: "Courier New", Courier, monospace; + font-size: 100%; +} + +kbd, +code.markup, /* HTML/CSS markup */ +span.markup, /* Alternative form for HTML/CSS markup */ +.title { /* Title in floating boxes / left sidebar */ + font-weight: bolder; +} + +.title { + page-break-after: avoid; + page-break-inside: avoid; +} + +abbr, +acronym { + font: inherit; /* Don't use small-caps, etc. */ +} + +.tooltip { + border: none; +} + +abbr[title], +acronym[title] { + border: none; +} + +cite, +dfn, +var, +.fn, /* Filename */ +.url, /* Uniform Resource Locator */ +.email { /* E-mail address */ + font-style: italic; +} + +.program, /* Command-line name of a computer program */ +.window, /* Window or dialog box name */ +.menu, /* Menu item in a computer program */ +.gui, /* Generic GUI element in a computer program */ +.key { /* Keypress in a computer program */ + font-weight: bolder; +} + +.clearboxes { /* Clear navboxes and floatboxes */ + clear: right; +} + +.unicode { + font-family: "Arial Unicode MS", "Lucida Sans Unicode", Verdana, "DejaVu Sans", "Bitstream Vera Sans", "Lucida Sans", Arial, Helvetica, sans-serif; +} + + +/* Block-inline elements and classes */ + +img { + vertical-align: baseline; + margin: 0; + padding: 0; + border: none; +} + +img.icon16 { /* For 16x16 file-type icons */ + vertical-align: -2px; +} + +del, +del * { /* Required for Mozilla */ + text-decoration: line-through; +} + +ins, +ins * { /* Required for Mozilla */ + text-decoration: underline; +} + +.floatleft { /* Left-floating images and spans */ + margin: 0.5em 1.5em 0.5em 0; + float: left; +} + +.floatright { /* Right-floating images and spans */ + margin: 0.5em 0 0.5em 1.5em; + float: right; +} + +.nowrap { + white-space: nowrap; +} + + +/* Block elements */ + +p { + margin: 1em 0; + padding: 0; +} + +blockquote { /* Should only be used in main content area, */ + /* floating boxes or left sidebar. */ + margin: 1em 2.5em; + padding: 0; +} + +pre { /* Should only be used in main content area */ + /* and floating boxes. */ + font-family: "Courier New", Courier, monospace; + font-size: 100%; + line-height: 1.2; + margin: 1em 2.5em; + padding: 0; +} + +hr { + color: black; + background: transparent; + height: 1pt; /* Required for IE/Win */ + margin: 0; + padding: 0; + border-color: black; + border-width: 1pt; + border-style: none none solid none; +} + +hr.lighter { + display: none; +} + + +/* Lists */ + +ol { + list-style: decimal outside; + margin: 1em 0; + padding: 0 0 0 2.5em; +} + +ol.alpha { + list-style-type: lower-alpha; +} + +ol.number { + list-style-type: decimal; +} + +ul { + list-style: square outside; + margin: 1em 0; + padding: 0 0 0 2.5em; +} + +ol ol, +ol ul, +ul ol, +ul ul { + margin-top: 0; + margin-bottom: 0; +} + +ol ul, /* Override possible browser styles */ +ol ol ul, +ol ul ul, +ul ul, +ul ol ul, +ul ul ul { + list-style: square outside; +} + +li { + margin: 0; + padding: 0; +} + +dl { + margin: 1em 0; + padding: 0; +} + +dt { + font: inherit; /* Don't make the text bold by default */ + margin: 1em 0 0.25em 0; + padding: 0; + page-break-after: avoid; + page-break-inside: avoid; +} + +dd { + margin: 0 0 1em 2.5em; + padding: 0; +} + + +/* Tables */ + /* Tables should never be used for visual */ + /* formatting: that is the role of CSS! */ + +table.simple { + color: inherit; + background: inherit; /* Don't make tables transparent */ + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + margin: 0.5em 2.5em; + padding: 0; + border: 1pt solid black; +} + +table.simple caption { + text-align: center; + caption-side: top; + margin: 0 2.5em 0.75em; + padding: 0; + border: none; +} + +table.simple td, +table.simple th { + text-align: center; + vertical-align: middle; + margin: 0; + padding: 0.25em 0.5em; + border: 1pt solid black; +} + +table.simple th, +table.simple td.highlight, +table.simple th.highlight { + font-weight: bold; + color: inherit; + background: inherit; +} + +table.simple td.lighter, +table.simple th.lighter { + color: inherit; + background: inherit; +} + +table.simple td.left, +table.simple th.left { + text-align: left; +} + +table.simple td.center, +table.simple th.center { + text-align: center; +} + +table.simple td.right, +table.simple th.right { + text-align: right; +} + +thead { + page-break-after: avoid; + page-break-inside: avoid; + +} + +tfoot { + page-break-before: avoid; + page-break-inside: avoid; + +} + + +/* Forms */ + +form { + margin: 1em 0; + padding: 0; + border: none; +} + +input, +button, +select, +fieldset, +legend { + font-size: 95%; + color: black; + background: inherit; + vertical-align: middle; +} + +input, +button, +select { + font-family: Verdana, "DejaVu Sans", "Bitstream Vera Sans", "Lucida Sans", Arial, Helvetica, sans-serif; +} + +fieldset, +legend { + font-family: "Lucida Bright", "Georgia", "DejaVu Serif", "Bitstream Vera Serif", "Times New Roman", TimesNR, Times, Roman, serif; +} + +textarea { + font-family: "Courier New", Courier, monospace; + font-size: 100%; + color: black; + background: inherit; + vertical-align: middle; +} + +fieldset { + font-size: 100%; + margin: 1em 0; + border: 1pt solid black; +} + +legend { + font-size: 100%; + margin: 0 0.5em; + padding: 0 0.25em; + border: none; +} + +table.formtable { + color: inherit; + background: inherit; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + margin: 0; + padding: 0; + border: none; +} + +table.formtable td, +table.formtable th { + text-align: justify; + vertical-align: middle; + margin: 0; + padding: 0.25em 0.5em; + border: none; +} + +table.formtable th { + text-align: center; + font-weight: bold; +} + +table.formtable td.label, +table.formtable th.label { + text-align: right; + vertical-align: top; +} + +table.formtable td.vertspace, +table.formtable th.vertspace { + empty-cells: show; + margin: 0; + padding: 0.5em 0; + height: 1em; /* Required for IE/Win */ +} + +table.formtable fieldset { + margin: 0; +} + +table.formtable fieldset td, +table.formtable fieldset th { + margin: 0.25em 0.5em; +} + +.reqfield { + font-family: Verdana, "DejaVu Sans", "Bitstream Vera Sans", "Lucida Sans", Arial, Helvetica, sans-serif; + color: black; + background: transparent; + font-weight: bolder; +} + +.info { + color: black; + background: transparent; + font-style: italic; + font-size: 90%; +} + + +/* The following HTML elements should NOT be used in documents using this + style sheet: + + address - use the #footer style instead + q - use “ and ” instead +*/ + + +/********** Styles for Main Content **********/ + +#main { + text-align: justify; + line-height: 1.3; + color: black; + background: white; + margin: 0; + padding: 0; +} + +#main h1 { /* Should be used once, following navhead */ + margin: 0 0 0.5em 0; +} + +#main .highlight { /* Highlight box (for warnings, etc) */ + color: inherit; + background: inherit; + margin: 1em 0; + padding: 1em 2.5em; + border: 1pt solid black; + page-break-inside: avoid; +} + +#main .totop { /* For "Top ^" lines in FAQs, etc */ + display: none; +} + +#main table.simple td.highlight, /* Else "#main .highlight" will override */ +#main table.simple th.highlight { + margin: 0; + padding: 0.25em 0.5em; +} + + +/* Other styles related to the main content */ + +#mainlink { /* "Skip to main content" link */ + display: none !important; +} + +#navhead { /* "Path to this page" information */ + display: none !important; +} + +#endmain { + visibility: hidden; + clear: both; /* Doesn't always work under IE/Win */ +} + + +/********** Styles for Floating Boxes **********/ + + /* "navbox" is used to provide intra/inter- */ + /* page links; it is NOT printed out on */ + /* paper. "floatbox" is used to provide */ + /* floating boxes that may appear anywhere */ + /* in the main content; they ARE printed. */ +.floatbox, +.navbox { + overflow: visible; + font-size: 95%; + line-height: 1.25; + margin: 0 0 0.75em 1.5em; + padding: 0.5em 1em; + border: 1pt solid black; + float: right; + clear: right; + page-break-inside: avoid; +} + +.floatbox { + color: black; + background: white; + width: 35%; +} + +.navbox { + display: none !important; +} + +.floatbox hr, /* Used for non-stylesheet-aware browsers */ +.navbox hr { + display: none !important; +} + +.floatbox p, +.navbox p { + margin: 0.75em 0; + padding: 0; +} + +.floatbox ol, +.floatbox ul { + margin: 0.75em 0; + padding: 0 0 0 1.5em; +} + +.navbox ol, +.navbox ul { + margin: 0.5em 0; + padding: 0 0 0 1.5em; +} + +.floatbox blockquote { + margin: 0.75em 1.5em; + padding: 0; +} + +.floatbox pre { + font-size: 95%; + margin: 0.75em 1.5em; + padding: 0; +} + +.floatbox dt { + margin: 0.75em 0; + padding: 0; +} + +.floatbox dt { + margin: 0.75em 0 0.25em 0; + padding: 0; +} + +.floatbox dd { + margin: 0 0 0.75em 1.5em; + padding: 0; +} + +#main .floatbox .highlight { + color: inherit; + background: inherit; + margin: 0.75em 0; + padding: 0.75em 1.5em; +} + +#main .floatbox table.simple { + margin: 0.75em 0; +} + +#main .floatbox table.simple th, +#main .floatbox table.simple td.highlight, +#main .floatbox table.simple th.highlight { + color: inherit; + background: inherit; + margin: 0; + padding: 0.25em 0.5em; +} + + +/********** Styles for Header **********/ + +#header { + display: none !important; +} + + +/********** Styles for Left Sidebar **********/ + +#sidebar { + display: none !important; +} + + +/********** Styles for Footer **********/ + +#footer { + font-size: 90%; + text-align: left; + color: black; + background: white; + margin: 0; + padding: 0.5em 0 0 0; + border-top: 1pt solid black; + clear: both; + page-break-before: avoid; + page-break-inside: avoid; +} + +#footer hr { + display: none !important; +} + +/* End of the Sinorcaish style sheet */ + diff --git a/templates/sinorcaish-screen.css b/templates/sinorcaish-screen.css new file mode 100644 index 0000000..3aa7d4b --- /dev/null +++ b/templates/sinorcaish-screen.css @@ -0,0 +1,850 @@ +/************************************************************************ +* * +* Sinorcaish Screen-based Style Sheet * +* Copyright (C) 2004-07, John Zaitseff * +* * +************************************************************************/ + +/* Author: John Zaitseff + Version: 1.3 + + $Id: sinorcaish-screen.css 189 2007-03-22 01:35:44Z john $ + + This file provides the Sinorcaish style sheet for screen-based user + agents (ie, for ordinary Web browsers). This file conforms to the + Cascading Style Sheets 2.1 specification. + + The design of Sinorcaish is influenced by Sinorca (available from the + Open Source Web Design site, http://www.oswd.org/), which in turn was + based on the Acronis company web site (http://www.acronis.com/). You + can find more information about this design from its home page on the + ZAP Group web site, http://www.zap.org.au/documents/styles/sinorcaish/. + + This file may be redistributed and/or modified on the condition that + the original copyright notice is retained. +*/ + + +/********** Global Styles **********/ + + /* The global font size is set to 90% as */ + /* most browsers' normal font size is too */ + /* large, at least when using Verdana */ + +body { + font-family: Verdana, "DejaVu Sans", "Bitstream Vera Sans", "Lucida Sans", Arial, Helvetica, sans-serif; + font-size: 90%; /* Allow IE/Win to resize the document */ + color: black; + background: #F0F0F0; + margin: 0; + padding: 0; + border: none; +} + +.hidden { /* Used for content that should be displayed */ + /* by non-stylesheet-aware browsers */ + display: none !important; +} + +.notprinted { /* Used for content that should not be */ +} /* printed to paper */ + + +/* Headings */ + +h1, /* Headings (H1-H6) should only be used in */ +h2, /* the main content area */ +h3 { + font-weight: bold; + text-align: left; + margin: 1.5em 0 0 0; + padding: 0; +} + +h4, +h5, +h6 { + font-weight: bold; + text-align: left; + margin: 1.25em 0 0 0; + padding: 0; +} + +h1 { font-size: 175% } +h2 { font-size: 145% } +h3 { font-size: 120% } +h4 { font-size: 105% } +h5 { font-size: 80% } +h6 { font-size: 65% } + + +/* Anchors */ + +a:link { + text-decoration: none; + color: #0066CC; + background: transparent; +} + +a:visited { + text-decoration: none; + color: #003399; + background: transparent; +} + +a:hover, +a:active { + text-decoration: underline; +} + + +/* Inline elements and classes */ + + /* This style sheet assumes B, BIG, EM, I, */ + /* SMALL, STRONG, SUB and SUP are defined */ + /* by the browser as per the HTML4 sample */ + /* style sheet. */ +code, +kbd, +samp, +tt { + font-family: "Courier New", Courier, monospace; + font-size: 115%; /* Courier tends to be a little too small */ + line-height: 1.0; /* Otherwise lines tend to spread out */ +} + +kbd, +code.markup, /* HTML/CSS markup */ +span.markup, /* Alternative form for HTML/CSS markup */ +.title { /* Title in floating boxes / left sidebar */ + font-weight: bolder; +} + +abbr, +acronym { + font: inherit; /* Don't use small-caps, etc. */ +} + +.tooltip { + cursor: help; + border-bottom: 1px dotted #CCCCCC; +} + +abbr[title], +acronym[title] { + cursor: help; + border-bottom: 1px dotted #CCCCCC; +} + +cite, +dfn, +var, +.fn, /* Filename */ +.url, /* Uniform Resource Locator */ +.email { /* E-mail address */ + font-style: italic; +} + +.program, /* Command-line name of a computer program */ +.window, /* Window or dialog box name */ +.menu, /* Menu item in a computer program */ +.gui, /* Generic GUI element in a computer program */ +.key { /* Keypress in a computer program */ + font-weight: bolder; +} + +.clearboxes { /* Clear navboxes and floatboxes */ + clear: right; +} + +.unicode { + font-family: "Arial Unicode MS", "Lucida Sans Unicode", Verdana, "DejaVu Sans", "Bitstream Vera Sans", "Lucida Sans", Arial, Helvetica, sans-serif; +} + + +/* Block-inline elements and classes */ + +img { + vertical-align: baseline; + margin: 0; + padding: 0; + border: none; +} + +img.icon16 { /* For 16x16 file-type icons */ + vertical-align: -2px; +} + +del, +del * { /* Required for Mozilla */ + text-decoration: line-through; +} + +ins, +ins * { /* Required for Mozilla */ + text-decoration: underline; +} + +.floatleft { /* Left-floating images and spans */ + margin: 0.5em 1.5em 0.5em 0; + float: left; +} + +.floatright { /* Right-floating images and spans */ + margin: 0.5em 0 0.5em 1.5em; + float: right; +} + +.nowrap { + white-space: nowrap; +} + + +/* Block elements */ + +p { + margin: 1em 0; + padding: 0; +} + +blockquote { /* Should only be used in main content area, */ + /* floating boxes or left sidebar. */ + margin: 1em 2.5em; + padding: 0; +} + +pre { /* Should only be used in main content area */ + /* and floating boxes. */ + font-family: "Courier New", Courier, monospace; + font-size: 115%; /* Courier tends to be a little too small */ + line-height: 1.2; + margin: 1em 2.5em; + padding: 0; +} + +pre code, +pre kbd, +pre samp, +pre tt { + font-size: 100%; /* PRE is already enlarged above */ + line-height: 1.2; /* Use same value as for PRE above */ +} + +hr { + color: #999999; + background: transparent; + height: 1px; /* Required for IE/Win */ + margin: 0; + padding: 0; + border-color: #999999; + border-width: 1px; + border-style: none none solid none; +} + +hr.lighter { /* Warning: not printed out on paper */ + color: #F0F0F0; + background: transparent; + border-color: #F0F0F0; +} + + +/* Lists */ + +ol { + list-style: decimal outside; + margin: 1em 0; + padding: 0 0 0 2.5em; +} + +ol.alpha { + list-style-type: lower-alpha; +} + +ol.number { + list-style-type: decimal; +} + +ul { + list-style: square outside; + margin: 1em 0; + padding: 0 0 0 2.5em; +} + +ol ol, +ol ul, +ul ol, +ul ul { + margin-top: 0; + margin-bottom: 0; +} + +ol ul, /* Override possible browser styles */ +ol ol ul, +ol ul ul, +ul ul, +ul ol ul, +ul ul ul { + list-style: square outside; +} + +li { + margin: 0; + padding: 0; +} + +dl { + margin: 1em 0; + padding: 0; +} + +dt { + font: inherit; /* Don't make the text bold by default */ + margin: 1em 0 0.25em 0; + padding: 0; +} + +dd { + margin: 0 0 1em 2.5em; + padding: 0; +} + + +/* Tables */ + /* Tables should never be used for visual */ + /* formatting: that is the role of CSS! */ + +table.simple { + color: inherit; + background: inherit; /* Don't make tables transparent */ + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + margin: 0.5em 2.5em; + padding: 0; + border: 1px solid #999999; +} + +table.simple caption { + text-align: center; + caption-side: top; + margin: 0 2.5em 0.75em; + padding: 0; + border: none; +} + +table.simple td, +table.simple th { + text-align: center; + vertical-align: middle; + margin: 0; + padding: 0.25em 0.5em; + border: 1px solid #999999; +} + +table.simple th, +table.simple td.highlight, +table.simple th.highlight { + font-weight: bold; + color: inherit; + background: #F0F0F0; +} + +table.simple td.lighter, +table.simple th.lighter { + color: inherit; + background: #F8F8F8; +} + +table.simple td.left, +table.simple th.left { + text-align: left; +} + +table.simple td.center, +table.simple th.center { + text-align: center; +} + +table.simple td.right, +table.simple th.right { + text-align: right; +} + + +/* Forms */ + +form { + margin: 1em 0; + padding: 0; + border: none; +} + +input, +button, +select, +fieldset, +legend { + font-family: Verdana, "DejaVu Sans", "Bitstream Vera Sans", "Lucida Sans", Arial, Helvetica, sans-serif; + font-size: 95%; + color: black; + background: inherit; + vertical-align: middle; +} + +textarea { + font-family: "Courier New", Courier, monospace; + font-size: 100%; + color: black; + background: inherit; + vertical-align: middle; +} + +fieldset { + font-size: 100%; + margin: 1em 0; + border: 1px solid #999999; +} + +legend { + font-size: 100%; + margin: 0 0.5em; + padding: 0 0.25em; + border: none; +} + +table.formtable { + color: inherit; + background: inherit; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + margin: 0; + padding: 0; + border: none; +} + +table.formtable td, +table.formtable th { + text-align: justify; + vertical-align: middle; + margin: 0; + padding: 0.25em 0.5em; + border: none; +} + +table.formtable th { + text-align: center; + font-weight: bold; +} + +table.formtable td.label, +table.formtable th.label { + text-align: right; + vertical-align: top; +} + +table.formtable td.vertspace, +table.formtable th.vertspace { + empty-cells: show; + margin: 0; + padding: 0.5em 0; + height: 1em; /* Required for IE/Win */ +} + +table.formtable fieldset { + margin: 0; +} + +table.formtable fieldset td, +table.formtable fieldset th { + margin: 0.25em 0.5em; +} + +.reqfield { + color: red; + background: transparent; + font-weight: bolder; +} + +.info { + color: gray; + background: transparent; + font-size: 90%; +} + + +/* The following HTML elements should NOT be used in documents using this + style sheet: + + address - use the #footer style instead + q - use “ and ” instead +*/ + + +/********** Styles for Main Content **********/ + +#main { + text-align: justify; + line-height: 1.5; + color: black; + background: white; + margin: 0 0 0 12.5em; + padding: 0.25em 1.5em 0.5em 1em; + border-left: 1px solid #999999; +} + +#main h1 { /* Should be used once, following navhead */ + color: #999999; + background: transparent; + margin: 0 0 0.5em 0; +} + +#main .highlight { /* Highlight box (for warnings, etc) */ + color: inherit; + background: #F0F0F0; + margin: 1em 0; + padding: 1em 2.5em; + border: 1px solid #999999; +} + +#main .totop { /* For "Top ^" lines in FAQs, etc */ + font-size: 90%; + text-align: right; + margin: -0.75em 0 1em 0; + padding: 0 0 0.25em 0; + border-bottom: 1px solid #F0F0F0; +} + +#main table.simple td.highlight, /* Else "#main .highlight" will override */ +#main table.simple th.highlight { + margin: 0; + padding: 0.25em 0.5em; +} + + +/* Other styles related to the main content */ + +#mainlink { /* "Skip to main content" link */ + display: none !important; +} + +#navhead { /* "Path to this page" information */ + /* Warning: not printed out on paper */ + font-size: 90%; +} + +#navhead hr { + display: none; +} + +#endmain { + visibility: hidden; + clear: both; /* Doesn't always work under IE/Win */ +} + + +/********** Styles for Floating Boxes **********/ + + /* "navbox" is used to provide intra/inter- */ + /* page links; it is NOT printed out on */ + /* paper. "floatbox" is used to provide */ + /* floating boxes that may appear anywhere */ + /* in the main content; they ARE printed. */ +.floatbox, +.navbox { + overflow: visible; + font-size: 95%; + line-height: 1.25; + margin: 0 0 0.75em 1.5em; + padding: 0.5em 1em; + border: 1px solid #999999; + float: right; + clear: right; +} + +.floatbox { + color: black; + background: #F0F0F0; + width: 35%; +} + +.navbox { + text-align: left; + color: black; + background: white; + width: 12.5em; +} + +.floatbox hr, /* Used for non-stylesheet-aware browsers */ +.navbox hr { + display: none !important; +} + +.floatbox p, +.navbox p { + margin: 0.75em 0; + padding: 0; +} + +.floatbox ol, +.floatbox ul { + margin: 0.75em 0; + padding: 0 0 0 1.5em; +} + +.navbox ol, +.navbox ul { + margin: 0.5em 0; + padding: 0 0 0 1.5em; +} + +.floatbox blockquote { + margin: 0.75em 1.5em; + padding: 0; +} + +.floatbox pre { + font-size: 95%; + margin: 0.75em 1.5em; + padding: 0; +} + +.floatbox dt { + margin: 0.75em 0; + padding: 0; +} + +.floatbox dt { + margin: 0.75em 0 0.25em 0; + padding: 0; +} + +.floatbox dd { + margin: 0 0 0.75em 1.5em; + padding: 0; +} + +#main .floatbox .highlight { + color: inherit; + background: white; + margin: 0.75em 0; + padding: 0.75em 1.5em; +} + +#main .floatbox table.simple { + margin: 0.75em 0; +} + +#main .floatbox table.simple th, +#main .floatbox table.simple td.highlight, +#main .floatbox table.simple th.highlight { + color: inherit; + background: white; + margin: 0; + padding: 0.25em 0.5em; +} + + +/********** Styles for Header **********/ + + /* In this style sheet, headers are composed */ + /* of three parts: left, right and subheader */ + /* Left part is ideally an image. */ + +#header { /* Warning: not printed out on paper */ + color: #003399; + background: #8CA8E6; +} + +#header a:link, +#header a:visited { + color: #003399; + background: transparent; +} + +#header .highlight, +#header a.highlight:link, +#header a.highlight:visited { + color: white; + background: transparent; +} + +/* Left part of header (ideally an image but may be a link) */ + +#header div.left { + float: left; + clear: left; + margin: 0; + padding: 0; +} + +#header div.left img { + display: block; /* Otherwise IMG is an inline, causing gaps */ +} + +#header div.left, +#header div.left a:link, +#header div.left a:visited { + font-size: 200%; + font-weight: bold; + text-decoration: none; + color: white; + background: transparent; +} + +#header div.left p { + margin: 0 0 0 0.25em; + padding: 0; +} + +#header div.left .alt { + color: #FF9800; + background: transparent; +} + +/* Right part of header is for external/global links, search, etc */ + +#header div.right { + font-size: 90%; + text-align: right; + margin: 0; + padding: 0.5em 1.17em 0 1em; + float: right; + clear: right; +} + +#header div.right a:link, +#header div.right a:visited { + margin: 0; + padding: 0 0.5em; +} + +#header div.right form { + margin: 0; + padding: 0.25em 0.5em 0 0; +} + +#header div.right form input { + font-size: 95%; + vertical-align: middle; +} + +/* Subheader for global links */ + +#header div.subheader { + color: white; + background: #003399; + margin: 0; + padding: 0; + border: 1px solid #003399; /* Required for IE/Win */ + clear: both; +} + +#header div.subheader p { /* To overcome an IE/Win unwanted padding */ + /* bug, still present in IE7. */ + margin: 0; + padding: 0.5em; +} + +#header div.subheader a:link, +#header div.subheader a:visited { + font-weight: bolder; + color: white; + background: transparent; + margin: 0; + padding: 0 0.5em; +} + +#header div.subheader .highlight, +#header div.subheader a.highlight:link, +#header div.subheader a.highlight:visited { + color: #FDA05E; + background: transparent; +} + + +/********** Styles for Left Sidebar **********/ + +#sidebar { /* Warning: not printed out on paper */ + width: 12.5em; + border-right: 1px solid #999999; + float: left; + clear: both; +} + +#sidebar div { + font-size: 95%; + text-align: left; + margin: 0; + padding: 0.5em 1em; + border-bottom: 1px solid #999999; +} + +#sidebar div.lighter { + color: inherit; + background: white; +} + +#sidebar p { + margin: 0.5em 0; +} + +#sidebar .title a:link, +#sidebar .title a:visited { + color: black; + background: transparent; +} + +#sidebar ul { + list-style: none outside; + margin: 0.5em 0; + padding: 0; +} + +#sidebar ul li { + margin: 0; + padding: 0.125em 0; +} + +#sidebar ul li.highlight { + color: inherit; + background: white; + margin-left: -1em; + margin-right: -1em; + padding-left: 1em; + border-top: 1px solid #999999; + border-bottom: 1px solid #999999; +} + +#sidebar ul li.highlight a:link, +#sidebar ul li.highlight a:visited { + color: black; + background: transparent; +} + + +/********** Styles for Footer **********/ + +#footer { + font-size: 90%; + text-align: left; + color: white; + background: #6381DC; + margin: 0; + padding: 0.5em 1.67em 0.5em 15.25em; + clear: both; +} + +#footer a:link, +#footer a:visited { + text-decoration: underline; + color: white; + background: transparent; +} + +#footer hr { + display: none !important; +} + +/* End of the Sinorcaish style sheet */ +