diff --git a/.gitignore b/.gitignore index 7d848115..a5873392 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ **/target **/log/*.log* -**/local.*.toml -**/local.toml -Cargo.lock +**/*.local.*.toml workdir diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..afe18b82 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2515 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "actix-codec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-sink", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "actix-files" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0773d59061dedb49a8aed04c67291b9d8cf2fe0b60130a381aab53c6dd86e9be" +dependencies = [ + "actix-http", + "actix-service", + "actix-utils", + "actix-web", + "bitflags", + "bytes", + "derive_more 0.99.18", + "futures-core", + "http-range", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "v_htmlescape", +] + +[[package]] +name = "actix-http" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash", + "base64 0.22.1", + "bitflags", + "brotli", + "bytes", + "bytestring", + "derive_more 0.99.18", + "encoding_rs", + "flate2", + "futures-core", + "h2", + "http", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha1", + "smallvec", + "tokio", + "tokio-util", + "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-router" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" +dependencies = [ + "bytestring", + "cfg-if", + "http", + "regex", + "regex-lite", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite", +] + +[[package]] +name = "actix-session" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efe6976a74f34f1b6d07a6c05aadc0ed0359304a7781c367fa5b4029418db08f" +dependencies = [ + "actix-service", + "actix-utils", + "actix-web", + "anyhow", + "derive_more 1.0.0", + "rand", + "serde", + "serde_json", + "tracing", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash", + "bytes", + "bytestring", + "cfg-if", + "cookie", + "derive_more 0.99.18", + "encoding_rs", + "futures-core", + "futures-util", + "impl-more", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "regex-lite", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2", + "time", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "actix-web-static-files" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adf6d1ef6d7a60e084f9e0595e2a5234abda14e76c105ecf8e2d0e8800c41a1f" +dependencies = [ + "actix-web", + "derive_more 0.99.18", + "futures-util", + "static-files", +] + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "bytestring" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" +dependencies = [ + "bytes", +] + +[[package]] +name = "cc" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "change-detection" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "159fa412eae48a1d94d0b9ecdb85c97ce56eb2a347c62394d3fdbf221adabc1a" +dependencies = [ + "path-matchers", + "path-slash", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "concat-string" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7439becb5fafc780b6f4de382b1a7a3e70234afe783854a4702ee8adbb838609" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "aes-gcm", + "base64 0.20.0", + "hkdf", + "hmac", + "percent-encoding", + "rand", + "sha2", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "cpufeatures" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[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 = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "drust" +version = "0.0.3" +dependencies = [ + "pagetop", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "figlet-rs" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4742a071cd9694fc86f9fa1a08fa3e53d40cc899d7ee532295da2d085639fbc5" + +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fluent-bundle" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493" +dependencies = [ + "fluent-langneg", + "fluent-syntax", + "intl-memoizer", + "intl_pluralrules", + "rustc-hash", + "self_cell 0.10.3", + "smallvec", + "unic-langid", +] + +[[package]] +name = "fluent-langneg" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94" +dependencies = [ + "unic-langid", +] + +[[package]] +name = "fluent-syntax" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d" +dependencies = [ + "thiserror", +] + +[[package]] +name = "fluent-template-macros" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d176e568a4f73ad4225df02aa29ccfecffd8eda31ce78da0bc8b4b310f20a" +dependencies = [ + "flume", + "ignore", + "once_cell", + "proc-macro2", + "quote", + "syn", + "unic-langid", +] + +[[package]] +name = "fluent-templates" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f22f61b2c8551163ea13c16a381484e5360b089401c6e47c4bfcf6b62bb7ac" +dependencies = [ + "fluent-bundle", + "fluent-langneg", + "fluent-syntax", + "fluent-template-macros", + "flume", + "ignore", + "intl-memoizer", + "log", + "once_cell", + "thiserror", + "unic-langid", +] + +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "spin", +] + +[[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.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "globset" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +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.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "ignore" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata 0.4.9", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "impl-more" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae21c3177a27788957044151cc2800043d127acaa460a47ebb9b84dfa2c6aa0" + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "intl-memoizer" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda" +dependencies = [ + "type-map", + "unic-langid", +] + +[[package]] +name = "intl_pluralrules" +version = "7.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972" +dependencies = [ + "unic-langid", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + +[[package]] +name = "local-channel" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" +dependencies = [ + "futures-core", + "futures-sink", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[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 = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "log", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "mutually_exclusive_features" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94e1e6445d314f972ff7395df2de295fe51b71821694f0b0e1e79c4f12c8577" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[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-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pagetop" +version = "0.0.56" +dependencies = [ + "actix-files", + "actix-session", + "actix-web", + "actix-web-static-files", + "concat-string", + "figlet-rs", + "fluent-templates", + "nom", + "pagetop-macros", + "paste", + "serde", + "static-files", + "substring", + "terminal_size", + "toml", + "tracing", + "tracing-actix-web", + "tracing-appender", + "tracing-subscriber", + "unic-langid", +] + +[[package]] +name = "pagetop-build" +version = "0.0.11" +dependencies = [ + "static-files", +] + +[[package]] +name = "pagetop-macros" +version = "0.0.13" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "path-matchers" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36cd9b72a47679ec193a5f0229d9ab686b7bd45e1fbc59ccf953c9f3d83f7b2b" +dependencies = [ + "glob", +] + +[[package]] +name = "path-slash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498a099351efa4becc6a19c72aa9270598e8fd274ca47052e37455241c88b696" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[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.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[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.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[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 = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "self_cell" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d" +dependencies = [ + "self_cell 1.0.4", +] + +[[package]] +name = "self_cell" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static-files" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8590e848e1c53be9258210bcd4a8f4118e08988f03a4e2d63b62e4ad9f7ced" +dependencies = [ + "change-detection", + "mime_guess", + "path-slash", +] + +[[package]] +name = "substring" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +dependencies = [ + "autocfg", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "terminal_size" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +dependencies = [ + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-actix-web" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b87073920bcce23e9f5cb0d2671e9f01d6803bb5229c159b2f5ce6806d73ffc" +dependencies = [ + "actix-web", + "mutually_exclusive_features", + "pin-project", + "tracing", + "uuid", +] + +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "type-map" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" +dependencies = [ + "rustc-hash", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unic-langid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44" +dependencies = [ + "unic-langid-impl", + "unic-langid-macros", +] + +[[package]] +name = "unic-langid-impl" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5" +dependencies = [ + "tinystr", +] + +[[package]] +name = "unic-langid-macros" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da1cd2c042d3c7569a1008806b02039e7a4a2bdf8f8e96bd3c792434a0e275e" +dependencies = [ + "proc-macro-hack", + "tinystr", + "unic-langid-impl", + "unic-langid-macros-impl", +] + +[[package]] +name = "unic-langid-macros-impl" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" +dependencies = [ + "proc-macro-hack", + "quote", + "syn", + "unic-langid-impl", +] + +[[package]] +name = "unicase" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "url" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom", +] + +[[package]] +name = "v_htmlescape" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[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-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 81b9a99a..91e175ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,62 +1,85 @@ -[package] -name = "pagetop" -version = "0.0.56" -edition = "2021" - -description = "An opinionated web framework to build modular Server-Side Rendering web solutions." -homepage = "https://pagetop.cillero.es" -repository = "https://github.com/manuelcillero/pagetop" -license = "MIT OR Apache-2.0" - -authors = [ - "Manuel Cillero " -] -categories = [ - "web-programming", "gui", "development-tools", "asynchronous" -] -keywords = [ - "pagetop", "web", "framework", "frontend", "ssr" -] -exclude = [ - "examples/", "helpers/", "tests/" -] -rust-version = "1.80.0" - [workspace] -members = ["helpers/*"] +resolver = "2" +members = [ + # Helpers + "helpers/pagetop-build", + "helpers/pagetop-macros", -[lib] -name = "pagetop" + # Packages + "packages/pagetop", +# "packages/pagetop-bootsier", +# "packages/pagetop-macros", -[dependencies] -chrono = "0.4.38" -concat-string = "1.0.1" -figlet-rs = "0.1.5" -itoa = "1.0.11" -nom = "7.1.3" -paste = "1.0.15" -substring = "1.4.5" -terminal_size = "0.3.0" -toml = "0.8.19" + # App + "packages/drust", -tracing = "0.1.40" -tracing-appender = "0.2.3" -tracing-subscriber = { version = "0.3.18", features = ["json", "env-filter"] } -tracing-actix-web = "0.7.11" + # Examples +# "examples/app-basic", +# "examples/hello-world", +# "examples/hello-name", +] -fluent-templates = "0.9.4" -unic-langid = { version = "0.9.5", features = ["macros"] } +[workspace.package] +homepage = "https://pagetop.cillero.es" +repository = "https://github.com/manuelcillero/pagetop" +license = "MIT OR Apache-2.0" +authors = ["Manuel Cillero "] -actix-web = "4" -actix-session = { version = "0.10.0", features = ["cookie-session"] } - -actix-web-files = { package = "actix-files", version = "0.6.6" } -actix-web-static-files = "4.0.1" +[workspace.dependencies] +serde = { version = "1.0", features = ["derive"] } static-files = "0.2.4" +pagetop-build = { version = "0.0", path = "helpers/pagetop-build" } pagetop-macros = { version = "0.0", path = "helpers/pagetop-macros" } -serde = { version = "1.0", features = ["derive"] } +pagetop = { version = "0.0", path = "packages/pagetop" } -[build-dependencies] -pagetop-build = { version = "0.0", path = "helpers/pagetop-build" } + + + +actix-web = "4" +actix-web-files = { package = "actix-files", version = "0.6" } +actix-web-static-files = "4.0" +actix-session = { version = "0.10", features = ["cookie-session"] } +fluent-templates = "0.11" +nom = "7.1" +substring = "1.4" +tracing = "0.1" +tracing-appender = "0.2" +tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] } +tracing-actix-web = "0.7" +unic-langid = { version = "0.9", features = ["macros"] } + + +#[dependencies] +#chrono = "0.4.38" +#concat-string = "1.0.1" +#figlet-rs = "0.1.5" +#itoa = "1.0.11" +#nom = "7.1.3" +#paste = "1.0.15" +#substring = "1.4.5" +#terminal_size = "0.4.0" +#toml = "0.8.19" + +#tracing = "0.1.40" +#tracing-appender = "0.2.3" +#tracing-subscriber = { version = "0.3.18", features = ["json", "env-filter"] } +#tracing-actix-web = "0.7.14" + +#fluent-templates = "0.11.0" +#unic-langid = { version = "0.9.5", features = ["macros"] } + +#actix-web = "4" +#actix-session = { version = "0.10.1", features = ["cookie-session"] } + +#actix-web-files = { package = "actix-files", version = "0.6.6" } +#actix-web-static-files = "4.0.1" +#static-files = "0.2.4" + +#pagetop-macros = { version = "0.0", path = "helpers/pagetop-macros" } + +#serde = { version = "1.0", features = ["derive"] } + +#[build-dependencies] +#pagetop-build = { version = "0.0", path = "helpers/pagetop-build" } diff --git a/README.md b/README.md index 1dba1342..df5b2429 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ accessible via `http://localhost:8088` under default settings. # 📂 Helpers * [pagetop-macros](https://github.com/manuelcillero/pagetop/tree/latest/helpers/pagetop-macros): - A collection of procedural macros that enhance the development experience within PageTop. + A collection of macros that enhance the development experience within PageTop. * [pagetop-build](https://github.com/manuelcillero/pagetop/tree/latest/helpers/pagetop-build): Simplifies the process of embedding resources directly into binary files for PageTop applications. diff --git a/helpers/pagetop-build/Cargo.toml b/helpers/pagetop-build/Cargo.toml index a07eaab8..cd6d7448 100644 --- a/helpers/pagetop-build/Cargo.toml +++ b/helpers/pagetop-build/Cargo.toml @@ -4,19 +4,14 @@ version = "0.0.11" edition = "2021" description = "Simplifies the process of embedding resources in PageTop app binaries." -homepage = "https://pagetop.cillero.es" -repository = "https://github.com/manuelcillero/pagetop" -license = "MIT OR Apache-2.0" -authors = [ - "Manuel Cillero " -] -categories = [ - "development-tools::build-utils", "web-programming" -] -keywords = [ - "pagetop", "build", "assets", "resources", "static" -] +categories = ["development-tools::build-utils", "web-programming"] +keywords = ["pagetop", "build", "assets", "resources", "static"] + +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } +authors = { workspace = true } [dependencies] -static-files = "0.2.4" +static-files.workspace = true diff --git a/helpers/pagetop-macros/Cargo.toml b/helpers/pagetop-macros/Cargo.toml index 82836ac6..9e9f3a3d 100644 --- a/helpers/pagetop-macros/Cargo.toml +++ b/helpers/pagetop-macros/Cargo.toml @@ -3,28 +3,20 @@ name = "pagetop-macros" version = "0.0.13" edition = "2021" -description = "A collection of procedural macros that boost PageTop development." -homepage = "https://pagetop.cillero.es" -repository = "https://github.com/manuelcillero/pagetop" -license = "MIT OR Apache-2.0" +description = "A collection of macros that boost PageTop development." -authors = [ - "Manuel Cillero " -] -categories = [ - "development-tools::procedural-macro-helpers", "web-programming" -] -keywords = [ - "pagetop", "macros", "proc-macros", "codegen" -] +categories = ["development-tools::procedural-macro-helpers", "web-programming"] +keywords = ["pagetop", "macros", "proc-macros", "codegen"] + +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } +authors = { workspace = true } [lib] proc-macro = true [dependencies] -concat-string = "1.0.1" -proc-macro2 = "1.0" -proc-macro-crate = "3.1.0" -proc-macro-error = "1.0.4" -quote = "1.0" -syn = { version = "2.0", features = ["full"] } +proc-macro2 = "1.0.89" +quote = "1.0.37" +syn = { version = "2.0.87", features = ["full"] } diff --git a/helpers/pagetop-macros/README.md b/helpers/pagetop-macros/README.md index 56fc5516..58af0ca6 100644 --- a/helpers/pagetop-macros/README.md +++ b/helpers/pagetop-macros/README.md @@ -2,7 +2,7 @@

PageTop Macros

-

A collection of procedural macros that boost PageTop development.

+

A collection of macros that boost PageTop development.

[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg?style=for-the-badge)](#-license) [![API Docs](https://img.shields.io/docsrs/pagetop-macros?label=API%20Docs&style=for-the-badge&logo=Docs.rs)](https://docs.rs/pagetop-macros) @@ -25,11 +25,10 @@ frequent changes. Production use is not recommended until version **0.1.0**. # 🔖 Credits -This crate includes an adapted version of [maud-macros](https://crates.io/crates/maud_macros), -version [0.25.0](https://github.com/lambda-fairy/maud/tree/v0.25.0/maud_macros), by -[Chris Wong](https://crates.io/users/lambda-fairy). This adaptation integrates its functionalities -into **PageTop**, eliminating the need for direct references to `maud` in the `Cargo.toml` file of -each project. +This crate includes an adapted version of [SmartDefault](https://crates.io/crates/smart_default) +(version 0.7.1) by [Jane Doe](https://crates.io/users/jane-doe), named `AutoDefault`, to streamline +Default implementations in **PageTop** projects and eliminate the need to explicitly add +`smart_default` to `Cargo.toml` files. # 📜 License diff --git a/helpers/pagetop-macros/src/lib.rs b/helpers/pagetop-macros/src/lib.rs index 8c6ac065..5d673945 100644 --- a/helpers/pagetop-macros/src/lib.rs +++ b/helpers/pagetop-macros/src/lib.rs @@ -1,118 +1,16 @@ -mod maud; mod smart_default; -use concat_string::concat_string; use proc_macro::TokenStream; -use proc_macro_error::proc_macro_error; -use quote::{quote, quote_spanned, ToTokens}; -use syn::{parse_macro_input, parse_str, DeriveInput, ItemFn}; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; -#[proc_macro] -#[proc_macro_error] -pub fn html(input: TokenStream) -> TokenStream { - maud::expand(input.into()).into() -} - -/// Macro attribute to generate builder methods from `set_` methods. -/// -/// This macro takes a method with the `set_` prefix and generates a corresponding method with the -/// `with_` prefix to use in the builder pattern. -/// -/// # Panics -/// -/// This function will panic if a parameter identifier is not found in the argument list. -/// -/// # Examples -/// -/// ``` -/// #[fn_builder] -/// pub fn set_example(&mut self) -> &mut Self { -/// // implementation -/// } -/// ``` -/// -/// Will generate: -/// -/// ``` -/// pub fn with_example(mut self) -> Self { -/// self.set_example(); -/// self -/// } -/// ``` -#[proc_macro_attribute] -pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream { - let fn_set = parse_macro_input!(item as ItemFn); - let fn_set_name = fn_set.sig.ident.to_string(); - - if !fn_set_name.starts_with("set_") { - let expanded = quote_spanned! { - fn_set.sig.ident.span() => - compile_error!("expected a \"pub fn set_...() -> &mut Self\" method"); - }; - return expanded.into(); +#[proc_macro_derive(AutoDefault, attributes(default))] +pub fn derive_auto_default(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + match smart_default::body_impl::impl_my_derive(&input) { + Ok(output) => output.into(), + Err(error) => error.to_compile_error().into(), } - - let fn_with_name = fn_set_name.replace("set_", "with_"); - let fn_with_generics = if fn_set.sig.generics.params.is_empty() { - fn_with_name.clone() - } else { - let g = &fn_set.sig.generics; - concat_string!(fn_with_name, quote! { #g }.to_string()) - }; - - let where_clause = fn_set - .sig - .generics - .where_clause - .as_ref() - .map_or(String::new(), |where_clause| { - concat_string!(quote! { #where_clause }.to_string(), " ") - }); - - let args: Vec = fn_set - .sig - .inputs - .iter() - .skip(1) - .map(|arg| arg.to_token_stream().to_string()) - .collect(); - - let params: Vec = args - .iter() - .map(|arg| { - arg.split_whitespace() - .next() - .unwrap() - .trim_end_matches(':') - .to_string() - }) - .collect(); - - #[rustfmt::skip] - let fn_with = parse_str::(concat_string!(" - pub fn ", fn_with_generics, "(mut self, ", args.join(", "), ") -> Self ", where_clause, "{ - self.", fn_set_name, "(", params.join(", "), "); - self - } - ").as_str()).unwrap(); - - #[rustfmt::skip] - let fn_set_doc = concat_string!( - "

Use ", - "pub fn ", - fn_with_name, - "(self, …) -> Self for the builder pattern.", - "

" - ); - - let expanded = quote! { - #[doc(hidden)] - #fn_with - #[inline] - #[doc = #fn_set_doc] - #fn_set - }; - expanded.into() } /// Marks async main function as the `PageTop` entry-point. @@ -154,43 +52,3 @@ pub fn test(_: TokenStream, item: TokenStream) -> TokenStream { output.extend(item); output } - -#[proc_macro_derive(AutoDefault, attributes(default))] -pub fn derive_auto_default(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - match smart_default::body_impl::impl_my_derive(&input) { - Ok(output) => output.into(), - Err(error) => error.to_compile_error().into(), - } -} - -#[proc_macro_derive(ComponentClasses)] -pub fn derive_component_classes(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - let name = &input.ident; - - let fn_set_doc = concat_string!( - "

", - "Use ", - " with_classes(self, …) -> Self ", - " to apply the builder pattern.", - "

" - ); - - let expanded = quote! { - impl ComponentClasses for #name { - #[inline] - #[doc = #fn_set_doc] - fn set_classes(&mut self, op: ClassesOp, classes: impl Into) -> &mut Self { - self.classes.set_value(op, classes); - self - } - - fn classes(&self) -> &OptionClasses { - &self.classes - } - } - }; - - TokenStream::from(expanded) -} diff --git a/helpers/pagetop-macros/src/maud.rs b/helpers/pagetop-macros/src/maud.rs deleted file mode 100644 index a4e7873f..00000000 --- a/helpers/pagetop-macros/src/maud.rs +++ /dev/null @@ -1,39 +0,0 @@ -// #![doc(html_root_url = "https://docs.rs/maud_macros/0.25.0")] -// TokenStream values are reference counted, and the mental overhead of tracking -// lifetimes outweighs the marginal gains from explicit borrowing -// #![allow(clippy::needless_pass_by_value)] - -mod ast; -mod escape; -mod generate; -mod parse; - -use proc_macro2::{Ident, Span, TokenStream, TokenTree}; -use proc_macro_crate::{crate_name, FoundCrate}; -use quote::quote; - -pub fn expand(input: TokenStream) -> TokenStream { - let output_ident = TokenTree::Ident(Ident::new("__maud_output", Span::mixed_site())); - // Heuristic: the size of the resulting markup tends to correlate with the - // code size of the template itself - let size_hint = input.to_string().len(); - let markups = parse::parse(input); - let stmts = generate::generate(markups, output_ident.clone()); - - let found_crate = crate_name("pagetop").expect("pagetop is present in `Cargo.toml`"); - let pre_escaped = match found_crate { - FoundCrate::Itself => quote!( - crate::html::PreEscaped(#output_ident) - ), - _ => quote!( - pagetop::html::PreEscaped(#output_ident) - ), - }; - - quote!({ - extern crate alloc; - let mut #output_ident = alloc::string::String::with_capacity(#size_hint); - #stmts - #pre_escaped - }) -} diff --git a/helpers/pagetop-macros/src/maud/ast.rs b/helpers/pagetop-macros/src/maud/ast.rs deleted file mode 100644 index cd8a2cef..00000000 --- a/helpers/pagetop-macros/src/maud/ast.rs +++ /dev/null @@ -1,221 +0,0 @@ -use proc_macro2::{TokenStream, TokenTree}; -use proc_macro_error::SpanRange; - -#[derive(Debug)] -pub enum Markup { - /// Used as a placeholder value on parse error. - ParseError { - span: SpanRange, - }, - Block(Block), - Literal { - content: String, - span: SpanRange, - }, - Symbol { - symbol: TokenStream, - }, - Splice { - expr: TokenStream, - outer_span: SpanRange, - }, - Element { - name: TokenStream, - attrs: Vec, - body: ElementBody, - }, - Let { - at_span: SpanRange, - tokens: TokenStream, - }, - Special { - segments: Vec, - }, - Match { - at_span: SpanRange, - head: TokenStream, - arms: Vec, - arms_span: SpanRange, - }, -} - -impl Markup { - pub fn span(&self) -> SpanRange { - match *self { - Markup::ParseError { span } => span, - Markup::Block(ref block) => block.span(), - Markup::Literal { span, .. } => span, - Markup::Symbol { ref symbol } => span_tokens(symbol.clone()), - Markup::Splice { outer_span, .. } => outer_span, - Markup::Element { - ref name, ref body, .. - } => { - let name_span = span_tokens(name.clone()); - name_span.join_range(body.span()) - } - Markup::Let { - at_span, - ref tokens, - } => at_span.join_range(span_tokens(tokens.clone())), - Markup::Special { ref segments } => join_ranges(segments.iter().map(Special::span)), - Markup::Match { - at_span, arms_span, .. - } => at_span.join_range(arms_span), - } - } -} - -#[derive(Debug)] -pub enum Attr { - Class { - dot_span: SpanRange, - name: Markup, - toggler: Option, - }, - Id { - hash_span: SpanRange, - name: Markup, - }, - Named { - named_attr: NamedAttr, - }, -} - -impl Attr { - pub fn span(&self) -> SpanRange { - match *self { - Attr::Class { - dot_span, - ref name, - ref toggler, - } => { - let name_span = name.span(); - let dot_name_span = dot_span.join_range(name_span); - if let Some(toggler) = toggler { - dot_name_span.join_range(toggler.cond_span) - } else { - dot_name_span - } - } - Attr::Id { - hash_span, - ref name, - } => { - let name_span = name.span(); - hash_span.join_range(name_span) - } - Attr::Named { ref named_attr } => named_attr.span(), - } - } -} - -#[derive(Debug)] -pub enum ElementBody { - Void { semi_span: SpanRange }, - Block { block: Block }, -} - -impl ElementBody { - pub fn span(&self) -> SpanRange { - match *self { - ElementBody::Void { semi_span } => semi_span, - ElementBody::Block { ref block } => block.span(), - } - } -} - -#[derive(Debug)] -pub struct Block { - pub markups: Vec, - pub outer_span: SpanRange, -} - -impl Block { - pub fn span(&self) -> SpanRange { - self.outer_span - } -} - -#[derive(Debug)] -pub struct Special { - pub at_span: SpanRange, - pub head: TokenStream, - pub body: Block, -} - -impl Special { - pub fn span(&self) -> SpanRange { - let body_span = self.body.span(); - self.at_span.join_range(body_span) - } -} - -#[derive(Debug)] -pub struct NamedAttr { - pub name: TokenStream, - pub attr_type: AttrType, -} - -impl NamedAttr { - fn span(&self) -> SpanRange { - let name_span = span_tokens(self.name.clone()); - if let Some(attr_type_span) = self.attr_type.span() { - name_span.join_range(attr_type_span) - } else { - name_span - } - } -} - -#[derive(Debug)] -pub enum AttrType { - Normal { value: Markup }, - Optional { toggler: Toggler }, - Empty { toggler: Option }, -} - -impl AttrType { - fn span(&self) -> Option { - match *self { - AttrType::Normal { ref value } => Some(value.span()), - AttrType::Optional { ref toggler } => Some(toggler.span()), - AttrType::Empty { ref toggler } => toggler.as_ref().map(Toggler::span), - } - } -} - -#[derive(Debug)] -pub struct Toggler { - pub cond: TokenStream, - pub cond_span: SpanRange, -} - -impl Toggler { - fn span(&self) -> SpanRange { - self.cond_span - } -} - -#[derive(Debug)] -pub struct MatchArm { - pub head: TokenStream, - pub body: Block, -} - -pub fn span_tokens>(tokens: I) -> SpanRange { - join_ranges(tokens.into_iter().map(|s| SpanRange::single_span(s.span()))) -} - -pub fn join_ranges>(ranges: I) -> SpanRange { - let mut iter = ranges.into_iter(); - let first = match iter.next() { - Some(span) => span, - None => return SpanRange::call_site(), - }; - let last = iter.last().unwrap_or(first); - first.join_range(last) -} - -pub fn name_to_string(name: TokenStream) -> String { - name.into_iter().map(|token| token.to_string()).collect() -} diff --git a/helpers/pagetop-macros/src/maud/escape.rs b/helpers/pagetop-macros/src/maud/escape.rs deleted file mode 100644 index 49ece776..00000000 --- a/helpers/pagetop-macros/src/maud/escape.rs +++ /dev/null @@ -1,34 +0,0 @@ -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// !!!!!!!! PLEASE KEEP THIS IN SYNC WITH `maud/src/escape.rs` !!!!!!!!! -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -extern crate alloc; - -use alloc::string::String; - -pub fn escape_to_string(input: &str, output: &mut String) { - for b in input.bytes() { - match b { - b'&' => output.push_str("&"), - b'<' => output.push_str("<"), - b'>' => output.push_str(">"), - b'"' => output.push_str("""), - _ => unsafe { output.as_mut_vec().push(b) }, - } - } -} - -#[cfg(test)] -mod test { - extern crate alloc; - - use super::escape_to_string; - use alloc::string::String; - - #[test] - fn it_works() { - let mut s = String::new(); - escape_to_string("", &mut s); - assert_eq!(s, "<script>launchMissiles()</script>"); - } -} diff --git a/helpers/pagetop-macros/src/maud/generate.rs b/helpers/pagetop-macros/src/maud/generate.rs deleted file mode 100644 index be7946d0..00000000 --- a/helpers/pagetop-macros/src/maud/generate.rs +++ /dev/null @@ -1,308 +0,0 @@ -use proc_macro2::{Delimiter, Group, Ident, Literal, Span, TokenStream, TokenTree}; -use proc_macro_error::SpanRange; -use quote::quote; - -use crate::maud::{ast::*, escape}; - -use proc_macro_crate::{crate_name, FoundCrate}; - -pub fn generate(markups: Vec, output_ident: TokenTree) -> TokenStream { - let mut build = Builder::new(output_ident.clone()); - Generator::new(output_ident).markups(markups, &mut build); - build.finish() -} - -struct Generator { - output_ident: TokenTree, -} - -impl Generator { - fn new(output_ident: TokenTree) -> Generator { - Generator { output_ident } - } - - fn builder(&self) -> Builder { - Builder::new(self.output_ident.clone()) - } - - fn markups(&self, markups: Vec, build: &mut Builder) { - for markup in markups { - self.markup(markup, build); - } - } - - fn markup(&self, markup: Markup, build: &mut Builder) { - match markup { - Markup::ParseError { .. } => {} - Markup::Block(Block { - markups, - outer_span, - }) => { - if markups - .iter() - .any(|markup| matches!(*markup, Markup::Let { .. })) - { - self.block( - Block { - markups, - outer_span, - }, - build, - ); - } else { - self.markups(markups, build); - } - } - Markup::Literal { content, .. } => build.push_escaped(&content), - Markup::Symbol { symbol } => self.name(symbol, build), - Markup::Splice { expr, .. } => self.splice(expr, build), - Markup::Element { name, attrs, body } => self.element(name, attrs, body, build), - Markup::Let { tokens, .. } => build.push_tokens(tokens), - Markup::Special { segments } => { - for Special { head, body, .. } in segments { - build.push_tokens(head); - self.block(body, build); - } - } - Markup::Match { - head, - arms, - arms_span, - .. - } => { - let body = { - let mut build = self.builder(); - for MatchArm { head, body } in arms { - build.push_tokens(head); - self.block(body, &mut build); - } - build.finish() - }; - let mut body = TokenTree::Group(Group::new(Delimiter::Brace, body)); - body.set_span(arms_span.collapse()); - build.push_tokens(quote!(#head #body)); - } - } - } - - fn block( - &self, - Block { - markups, - outer_span, - }: Block, - build: &mut Builder, - ) { - let block = { - let mut build = self.builder(); - self.markups(markups, &mut build); - build.finish() - }; - let mut block = TokenTree::Group(Group::new(Delimiter::Brace, block)); - block.set_span(outer_span.collapse()); - build.push_tokens(TokenStream::from(block)); - } - - fn splice(&self, expr: TokenStream, build: &mut Builder) { - let output_ident = self.output_ident.clone(); - - let found_crate = crate_name("pagetop").expect("pagetop is present in `Cargo.toml`"); - build.push_tokens(match found_crate { - FoundCrate::Itself => quote!( - crate::html::html_private::render_to!(&#expr, &mut #output_ident); - ), - _ => quote!( - pagetop::html::html_private::render_to!(&#expr, &mut #output_ident); - ), - }); - } - - fn element(&self, name: TokenStream, attrs: Vec, body: ElementBody, build: &mut Builder) { - build.push_str("<"); - self.name(name.clone(), build); - self.attrs(attrs, build); - build.push_str(">"); - if let ElementBody::Block { block } = body { - self.markups(block.markups, build); - build.push_str(""); - } - } - - fn name(&self, name: TokenStream, build: &mut Builder) { - build.push_escaped(&name_to_string(name)); - } - - fn attrs(&self, attrs: Vec, build: &mut Builder) { - for NamedAttr { name, attr_type } in desugar_attrs(attrs) { - match attr_type { - AttrType::Normal { value } => { - build.push_str(" "); - self.name(name, build); - build.push_str("=\""); - self.markup(value, build); - build.push_str("\""); - } - AttrType::Optional { - toggler: Toggler { cond, .. }, - } => { - let inner_value = quote!(inner_value); - let body = { - let mut build = self.builder(); - build.push_str(" "); - self.name(name, &mut build); - build.push_str("=\""); - self.splice(inner_value.clone(), &mut build); - build.push_str("\""); - build.finish() - }; - build.push_tokens(quote!(if let Some(#inner_value) = (#cond) { #body })); - } - AttrType::Empty { toggler: None } => { - build.push_str(" "); - self.name(name, build); - } - AttrType::Empty { - toggler: Some(Toggler { cond, .. }), - } => { - let body = { - let mut build = self.builder(); - build.push_str(" "); - self.name(name, &mut build); - build.finish() - }; - build.push_tokens(quote!(if (#cond) { #body })); - } - } - } - } -} - -//////////////////////////////////////////////////////// - -fn desugar_attrs(attrs: Vec) -> Vec { - let mut classes_static = vec![]; - let mut classes_toggled = vec![]; - let mut ids = vec![]; - let mut named_attrs = vec![]; - for attr in attrs { - match attr { - Attr::Class { - name, - toggler: Some(toggler), - .. - } => classes_toggled.push((name, toggler)), - Attr::Class { - name, - toggler: None, - .. - } => classes_static.push(name), - Attr::Id { name, .. } => ids.push(name), - Attr::Named { named_attr } => named_attrs.push(named_attr), - } - } - let classes = desugar_classes_or_ids("class", classes_static, classes_toggled); - let ids = desugar_classes_or_ids("id", ids, vec![]); - classes.into_iter().chain(ids).chain(named_attrs).collect() -} - -fn desugar_classes_or_ids( - attr_name: &'static str, - values_static: Vec, - values_toggled: Vec<(Markup, Toggler)>, -) -> Option { - if values_static.is_empty() && values_toggled.is_empty() { - return None; - } - let mut markups = Vec::new(); - let mut leading_space = false; - for name in values_static { - markups.extend(prepend_leading_space(name, &mut leading_space)); - } - for (name, Toggler { cond, cond_span }) in values_toggled { - let body = Block { - markups: prepend_leading_space(name, &mut leading_space), - // TODO: is this correct? - outer_span: cond_span, - }; - markups.push(Markup::Special { - segments: vec![Special { - at_span: SpanRange::call_site(), - head: quote!(if (#cond)), - body, - }], - }); - } - Some(NamedAttr { - name: TokenStream::from(TokenTree::Ident(Ident::new(attr_name, Span::call_site()))), - attr_type: AttrType::Normal { - value: Markup::Block(Block { - markups, - outer_span: SpanRange::call_site(), - }), - }, - }) -} - -fn prepend_leading_space(name: Markup, leading_space: &mut bool) -> Vec { - let mut markups = Vec::new(); - if *leading_space { - markups.push(Markup::Literal { - content: " ".to_owned(), - span: name.span(), - }); - } - *leading_space = true; - markups.push(name); - markups -} - -//////////////////////////////////////////////////////// - -struct Builder { - output_ident: TokenTree, - tokens: Vec, - tail: String, -} - -impl Builder { - fn new(output_ident: TokenTree) -> Builder { - Builder { - output_ident, - tokens: Vec::new(), - tail: String::new(), - } - } - - fn push_str(&mut self, string: &str) { - self.tail.push_str(string); - } - - fn push_escaped(&mut self, string: &str) { - escape::escape_to_string(string, &mut self.tail); - } - - fn push_tokens(&mut self, tokens: TokenStream) { - self.cut(); - self.tokens.extend(tokens); - } - - fn cut(&mut self) { - if self.tail.is_empty() { - return; - } - let push_str_expr = { - let output_ident = self.output_ident.clone(); - let string = TokenTree::Literal(Literal::string(&self.tail)); - quote!(#output_ident.push_str(#string);) - }; - self.tail.clear(); - self.tokens.extend(push_str_expr); - } - - fn finish(mut self) -> TokenStream { - self.cut(); - self.tokens.into_iter().collect() - } -} diff --git a/helpers/pagetop-macros/src/maud/parse.rs b/helpers/pagetop-macros/src/maud/parse.rs deleted file mode 100644 index d24cea6e..00000000 --- a/helpers/pagetop-macros/src/maud/parse.rs +++ /dev/null @@ -1,752 +0,0 @@ -use proc_macro2::{Delimiter, Ident, Literal, Spacing, Span, TokenStream, TokenTree}; -use proc_macro_error::{abort, abort_call_site, emit_error, SpanRange}; -use std::collections::HashMap; - -use syn::Lit; - -use crate::maud::ast; - -pub fn parse(input: TokenStream) -> Vec { - Parser::new(input).markups() -} - -#[derive(Clone)] -struct Parser { - /// If we're inside an attribute, then this contains the attribute name. - current_attr: Option, - input: ::IntoIter, -} - -impl Iterator for Parser { - type Item = TokenTree; - - fn next(&mut self) -> Option { - self.input.next() - } -} - -impl Parser { - fn new(input: TokenStream) -> Parser { - Parser { - current_attr: None, - input: input.into_iter(), - } - } - - fn with_input(&self, input: TokenStream) -> Parser { - Parser { - current_attr: self.current_attr.clone(), - input: input.into_iter(), - } - } - - /// Returns the next token in the stream without consuming it. - fn peek(&mut self) -> Option { - self.clone().next() - } - - /// Returns the next two tokens in the stream without consuming them. - fn peek2(&mut self) -> Option<(TokenTree, Option)> { - let mut clone = self.clone(); - clone.next().map(|first| (first, clone.next())) - } - - /// Advances the cursor by one step. - fn advance(&mut self) { - self.next(); - } - - /// Advances the cursor by two steps. - fn advance2(&mut self) { - self.next(); - self.next(); - } - - /// Parses multiple blocks of markup. - fn markups(&mut self) -> Vec { - let mut result = Vec::new(); - loop { - match self.peek2() { - None => break, - Some((TokenTree::Punct(ref punct), _)) if punct.as_char() == ';' => self.advance(), - Some((TokenTree::Punct(ref punct), Some(TokenTree::Ident(ref ident)))) - if punct.as_char() == '@' && *ident == "let" => - { - self.advance2(); - let keyword = TokenTree::Ident(ident.clone()); - result.push(self.let_expr(punct.span(), keyword)); - } - _ => result.push(self.markup()), - } - } - result - } - - /// Parses a single block of markup. - fn markup(&mut self) -> ast::Markup { - let token = match self.peek() { - Some(token) => token, - None => { - abort_call_site!("unexpected end of input"); - } - }; - let markup = match token { - // Literal - TokenTree::Literal(literal) => { - self.advance(); - self.literal(literal) - } - // Special form - TokenTree::Punct(ref punct) if punct.as_char() == '@' => { - self.advance(); - let at_span = punct.span(); - match self.next() { - Some(TokenTree::Ident(ident)) => { - let keyword = TokenTree::Ident(ident.clone()); - match ident.to_string().as_str() { - "if" => { - let mut segments = Vec::new(); - self.if_expr(at_span, vec![keyword], &mut segments); - ast::Markup::Special { segments } - } - "while" => self.while_expr(at_span, keyword), - "for" => self.for_expr(at_span, keyword), - "match" => self.match_expr(at_span, keyword), - "let" => { - let span = SpanRange { - first: at_span, - last: ident.span(), - }; - abort!(span, "`@let` only works inside a block"); - } - other => { - let span = SpanRange { - first: at_span, - last: ident.span(), - }; - abort!(span, "unknown keyword `@{}`", other); - } - } - } - _ => { - abort!(at_span, "expected keyword after `@`"); - } - } - } - // Element - TokenTree::Ident(ident) => { - let ident_string = ident.to_string(); - match ident_string.as_str() { - "if" | "while" | "for" | "match" | "let" => { - abort!( - ident, - "found keyword `{}`", ident_string; - help = "should this be a `@{}`?", ident_string - ); - } - "true" | "false" => { - if let Some(attr_name) = &self.current_attr { - emit_error!( - ident, - r#"attribute value must be a string"#; - help = "to declare an empty attribute, omit the equals sign: `{}`", - attr_name; - help = "to toggle the attribute, use square brackets: `{}[some_boolean_flag]`", - attr_name; - ); - return ast::Markup::ParseError { - span: SpanRange::single_span(ident.span()), - }; - } - } - _ => {} - } - - // `.try_namespaced_name()` should never fail as we've - // already seen an `Ident` - let name = self.try_namespaced_name().expect("identifier"); - self.element(name) - } - // Div element shorthand - TokenTree::Punct(ref punct) if punct.as_char() == '.' || punct.as_char() == '#' => { - let name = TokenTree::Ident(Ident::new("div", punct.span())); - self.element(name.into()) - } - // Splice - TokenTree::Group(ref group) if group.delimiter() == Delimiter::Parenthesis => { - self.advance(); - ast::Markup::Splice { - expr: group.stream(), - outer_span: SpanRange::single_span(group.span()), - } - } - // Block - TokenTree::Group(ref group) if group.delimiter() == Delimiter::Brace => { - self.advance(); - ast::Markup::Block(self.block(group.stream(), SpanRange::single_span(group.span()))) - } - // ??? - token => { - abort!(token, "invalid syntax"); - } - }; - markup - } - - /// Parses a literal string. - fn literal(&mut self, literal: Literal) -> ast::Markup { - match Lit::new(literal.clone()) { - Lit::Str(lit_str) => { - return ast::Markup::Literal { - content: lit_str.value(), - span: SpanRange::single_span(literal.span()), - } - } - // Boolean literals are idents, so `Lit::Bool` is handled in - // `markup`, not here. - Lit::Int(..) | Lit::Float(..) => { - emit_error!(literal, r#"literal must be double-quoted: `"{}"`"#, literal); - } - Lit::Char(lit_char) => { - emit_error!( - literal, - r#"literal must be double-quoted: `"{}"`"#, - lit_char.value(), - ); - } - _ => { - emit_error!(literal, "expected string"); - } - } - ast::Markup::ParseError { - span: SpanRange::single_span(literal.span()), - } - } - - /// Parses an `@if` expression. - /// - /// The leading `@if` should already be consumed. - fn if_expr(&mut self, at_span: Span, prefix: Vec, segments: &mut Vec) { - let mut head = prefix; - let body = loop { - match self.next() { - Some(TokenTree::Group(ref block)) if block.delimiter() == Delimiter::Brace => { - break self.block(block.stream(), SpanRange::single_span(block.span())); - } - Some(token) => head.push(token), - None => { - let mut span = ast::span_tokens(head); - span.first = at_span; - abort!(span, "expected body for this `@if`"); - } - } - }; - segments.push(ast::Special { - at_span: SpanRange::single_span(at_span), - head: head.into_iter().collect(), - body, - }); - self.else_if_expr(segments) - } - - /// Parses an optional `@else if` or `@else`. - /// - /// The leading `@else if` or `@else` should *not* already be consumed. - fn else_if_expr(&mut self, segments: &mut Vec) { - match self.peek2() { - Some((TokenTree::Punct(ref punct), Some(TokenTree::Ident(ref else_keyword)))) - if punct.as_char() == '@' && *else_keyword == "else" => - { - self.advance2(); - let at_span = punct.span(); - let else_keyword = TokenTree::Ident(else_keyword.clone()); - match self.peek() { - // `@else if` - Some(TokenTree::Ident(ref if_keyword)) if *if_keyword == "if" => { - self.advance(); - let if_keyword = TokenTree::Ident(if_keyword.clone()); - self.if_expr(at_span, vec![else_keyword, if_keyword], segments) - } - // Just an `@else` - _ => match self.next() { - Some(TokenTree::Group(ref group)) - if group.delimiter() == Delimiter::Brace => - { - let body = - self.block(group.stream(), SpanRange::single_span(group.span())); - segments.push(ast::Special { - at_span: SpanRange::single_span(at_span), - head: vec![else_keyword].into_iter().collect(), - body, - }); - } - _ => { - let span = SpanRange { - first: at_span, - last: else_keyword.span(), - }; - abort!(span, "expected body for this `@else`"); - } - }, - } - } - // We didn't find an `@else`; stop - _ => {} - } - } - - /// Parses an `@while` expression. - /// - /// The leading `@while` should already be consumed. - fn while_expr(&mut self, at_span: Span, keyword: TokenTree) -> ast::Markup { - let keyword_span = keyword.span(); - let mut head = vec![keyword]; - let body = loop { - match self.next() { - Some(TokenTree::Group(ref block)) if block.delimiter() == Delimiter::Brace => { - break self.block(block.stream(), SpanRange::single_span(block.span())); - } - Some(token) => head.push(token), - None => { - let span = SpanRange { - first: at_span, - last: keyword_span, - }; - abort!(span, "expected body for this `@while`"); - } - } - }; - ast::Markup::Special { - segments: vec![ast::Special { - at_span: SpanRange::single_span(at_span), - head: head.into_iter().collect(), - body, - }], - } - } - - /// Parses a `@for` expression. - /// - /// The leading `@for` should already be consumed. - fn for_expr(&mut self, at_span: Span, keyword: TokenTree) -> ast::Markup { - let keyword_span = keyword.span(); - let mut head = vec![keyword]; - loop { - match self.next() { - Some(TokenTree::Ident(ref in_keyword)) if *in_keyword == "in" => { - head.push(TokenTree::Ident(in_keyword.clone())); - break; - } - Some(token) => head.push(token), - None => { - let span = SpanRange { - first: at_span, - last: keyword_span, - }; - abort!(span, "missing `in` in `@for` loop"); - } - } - } - let body = loop { - match self.next() { - Some(TokenTree::Group(ref block)) if block.delimiter() == Delimiter::Brace => { - break self.block(block.stream(), SpanRange::single_span(block.span())); - } - Some(token) => head.push(token), - None => { - let span = SpanRange { - first: at_span, - last: keyword_span, - }; - abort!(span, "expected body for this `@for`"); - } - } - }; - ast::Markup::Special { - segments: vec![ast::Special { - at_span: SpanRange::single_span(at_span), - head: head.into_iter().collect(), - body, - }], - } - } - - /// Parses a `@match` expression. - /// - /// The leading `@match` should already be consumed. - fn match_expr(&mut self, at_span: Span, keyword: TokenTree) -> ast::Markup { - let keyword_span = keyword.span(); - let mut head = vec![keyword]; - let (arms, arms_span) = loop { - match self.next() { - Some(TokenTree::Group(ref body)) if body.delimiter() == Delimiter::Brace => { - let span = SpanRange::single_span(body.span()); - break (self.with_input(body.stream()).match_arms(), span); - } - Some(token) => head.push(token), - None => { - let span = SpanRange { - first: at_span, - last: keyword_span, - }; - abort!(span, "expected body for this `@match`"); - } - } - }; - ast::Markup::Match { - at_span: SpanRange::single_span(at_span), - head: head.into_iter().collect(), - arms, - arms_span, - } - } - - fn match_arms(&mut self) -> Vec { - let mut arms = Vec::new(); - while let Some(arm) = self.match_arm() { - arms.push(arm); - } - arms - } - - fn match_arm(&mut self) -> Option { - let mut head = Vec::new(); - loop { - match self.peek2() { - Some((TokenTree::Punct(ref eq), Some(TokenTree::Punct(ref gt)))) - if eq.as_char() == '=' - && gt.as_char() == '>' - && eq.spacing() == Spacing::Joint => - { - self.advance2(); - head.push(TokenTree::Punct(eq.clone())); - head.push(TokenTree::Punct(gt.clone())); - break; - } - Some((token, _)) => { - self.advance(); - head.push(token); - } - None => { - if head.is_empty() { - return None; - } else { - let head_span = ast::span_tokens(head); - abort!(head_span, "unexpected end of @match pattern"); - } - } - } - } - let body = match self.next() { - // $pat => { $stmts } - Some(TokenTree::Group(ref body)) if body.delimiter() == Delimiter::Brace => { - let body = self.block(body.stream(), SpanRange::single_span(body.span())); - // Trailing commas are optional if the match arm is a braced block - if let Some(TokenTree::Punct(ref punct)) = self.peek() { - if punct.as_char() == ',' { - self.advance(); - } - } - body - } - // $pat => $expr - Some(first_token) => { - let mut span = SpanRange::single_span(first_token.span()); - let mut body = vec![first_token]; - loop { - match self.next() { - Some(TokenTree::Punct(ref punct)) if punct.as_char() == ',' => break, - Some(token) => { - span.last = token.span(); - body.push(token); - } - None => break, - } - } - self.block(body.into_iter().collect(), span) - } - None => { - let span = ast::span_tokens(head); - abort!(span, "unexpected end of @match arm"); - } - }; - Some(ast::MatchArm { - head: head.into_iter().collect(), - body, - }) - } - - /// Parses a `@let` expression. - /// - /// The leading `@let` should already be consumed. - fn let_expr(&mut self, at_span: Span, keyword: TokenTree) -> ast::Markup { - let mut tokens = vec![keyword]; - loop { - match self.next() { - Some(token) => match token { - TokenTree::Punct(ref punct) if punct.as_char() == '=' => { - tokens.push(token.clone()); - break; - } - _ => tokens.push(token), - }, - None => { - let mut span = ast::span_tokens(tokens); - span.first = at_span; - abort!(span, "unexpected end of `@let` expression"); - } - } - } - loop { - match self.next() { - Some(token) => match token { - TokenTree::Punct(ref punct) if punct.as_char() == ';' => { - tokens.push(token.clone()); - break; - } - _ => tokens.push(token), - }, - None => { - let mut span = ast::span_tokens(tokens); - span.first = at_span; - abort!( - span, - "unexpected end of `@let` expression"; - help = "are you missing a semicolon?" - ); - } - } - } - ast::Markup::Let { - at_span: SpanRange::single_span(at_span), - tokens: tokens.into_iter().collect(), - } - } - - /// Parses an element node. - /// - /// The element name should already be consumed. - fn element(&mut self, name: TokenStream) -> ast::Markup { - if self.current_attr.is_some() { - let span = ast::span_tokens(name); - abort!(span, "unexpected element"); - } - let attrs = self.attrs(); - let body = match self.peek() { - Some(TokenTree::Punct(ref punct)) - if punct.as_char() == ';' || punct.as_char() == '/' => - { - // Void element - self.advance(); - if punct.as_char() == '/' { - emit_error!( - punct, - "void elements must use `;`, not `/`"; - help = "change this to `;`"; - help = "see https://github.com/lambda-fairy/maud/pull/315 for details"; - ); - } - ast::ElementBody::Void { - semi_span: SpanRange::single_span(punct.span()), - } - } - Some(_) => match self.markup() { - ast::Markup::Block(block) => ast::ElementBody::Block { block }, - markup => { - let markup_span = markup.span(); - abort!( - markup_span, - "element body must be wrapped in braces"; - help = "see https://github.com/lambda-fairy/maud/pull/137 for details" - ); - } - }, - None => abort_call_site!("expected `;`, found end of macro"), - }; - ast::Markup::Element { name, attrs, body } - } - - /// Parses the attributes of an element. - fn attrs(&mut self) -> Vec { - let mut attrs = Vec::new(); - loop { - if let Some(name) = self.try_namespaced_name() { - // Attribute - match self.peek() { - // Non-empty attribute - Some(TokenTree::Punct(ref punct)) if punct.as_char() == '=' => { - self.advance(); - // Parse a value under an attribute context - assert!(self.current_attr.is_none()); - self.current_attr = Some(ast::name_to_string(name.clone())); - let attr_type = match self.attr_toggler() { - Some(toggler) => ast::AttrType::Optional { toggler }, - None => { - let value = self.markup(); - ast::AttrType::Normal { value } - } - }; - self.current_attr = None; - attrs.push(ast::Attr::Named { - named_attr: ast::NamedAttr { name, attr_type }, - }); - } - // Empty attribute (legacy syntax) - Some(TokenTree::Punct(ref punct)) if punct.as_char() == '?' => { - self.advance(); - let toggler = self.attr_toggler(); - attrs.push(ast::Attr::Named { - named_attr: ast::NamedAttr { - name: name.clone(), - attr_type: ast::AttrType::Empty { toggler }, - }, - }); - } - // Empty attribute (new syntax) - _ => { - let toggler = self.attr_toggler(); - attrs.push(ast::Attr::Named { - named_attr: ast::NamedAttr { - name: name.clone(), - attr_type: ast::AttrType::Empty { toggler }, - }, - }); - } - } - } else { - match self.peek() { - // Class shorthand - Some(TokenTree::Punct(ref punct)) if punct.as_char() == '.' => { - self.advance(); - let name = self.class_or_id_name(); - let toggler = self.attr_toggler(); - attrs.push(ast::Attr::Class { - dot_span: SpanRange::single_span(punct.span()), - name, - toggler, - }); - } - // ID shorthand - Some(TokenTree::Punct(ref punct)) if punct.as_char() == '#' => { - self.advance(); - let name = self.class_or_id_name(); - attrs.push(ast::Attr::Id { - hash_span: SpanRange::single_span(punct.span()), - name, - }); - } - // If it's not a valid attribute, backtrack and bail out - _ => break, - } - } - } - - let mut attr_map: HashMap> = HashMap::new(); - let mut has_class = false; - for attr in &attrs { - let name = match attr { - ast::Attr::Class { .. } => { - if has_class { - // Only check the first class to avoid spurious duplicates - continue; - } - has_class = true; - "class".to_string() - } - ast::Attr::Id { .. } => "id".to_string(), - ast::Attr::Named { named_attr } => named_attr - .name - .clone() - .into_iter() - .map(|token| token.to_string()) - .collect(), - }; - let entry = attr_map.entry(name).or_default(); - entry.push(attr.span()); - } - - for (name, spans) in attr_map { - if spans.len() > 1 { - let mut spans = spans.into_iter(); - let first_span = spans.next().expect("spans should be non-empty"); - abort!(first_span, "duplicate attribute `{}`", name); - } - } - - attrs - } - - /// Parses the name of a class or ID. - fn class_or_id_name(&mut self) -> ast::Markup { - if let Some(symbol) = self.try_name() { - ast::Markup::Symbol { symbol } - } else { - self.markup() - } - } - - /// Parses the `[cond]` syntax after an empty attribute or class shorthand. - fn attr_toggler(&mut self) -> Option { - match self.peek() { - Some(TokenTree::Group(ref group)) if group.delimiter() == Delimiter::Bracket => { - self.advance(); - Some(ast::Toggler { - cond: group.stream(), - cond_span: SpanRange::single_span(group.span()), - }) - } - _ => None, - } - } - - /// Parses an identifier, without dealing with namespaces. - fn try_name(&mut self) -> Option { - let mut result = Vec::new(); - if let Some(token @ TokenTree::Ident(_)) = self.peek() { - self.advance(); - result.push(token); - } else { - return None; - } - let mut expect_ident = false; - loop { - expect_ident = match self.peek() { - Some(TokenTree::Punct(ref punct)) if punct.as_char() == '-' => { - self.advance(); - result.push(TokenTree::Punct(punct.clone())); - true - } - Some(TokenTree::Ident(ref ident)) if expect_ident => { - self.advance(); - result.push(TokenTree::Ident(ident.clone())); - false - } - _ => break, - }; - } - Some(result.into_iter().collect()) - } - - /// Parses a HTML element or attribute name, along with a namespace - /// if necessary. - fn try_namespaced_name(&mut self) -> Option { - let mut result = vec![self.try_name()?]; - if let Some(TokenTree::Punct(ref punct)) = self.peek() { - if punct.as_char() == ':' { - self.advance(); - result.push(TokenStream::from(TokenTree::Punct(punct.clone()))); - result.push(self.try_name()?); - } - } - Some(result.into_iter().collect()) - } - - /// Parses the given token stream as a Maud expression. - fn block(&mut self, body: TokenStream, outer_span: SpanRange) -> ast::Block { - let markups = self.with_input(body).markups(); - ast::Block { - markups, - outer_span, - } - } -} diff --git a/packages/drust/Cargo.toml b/packages/drust/Cargo.toml new file mode 100644 index 00000000..75b4dafd --- /dev/null +++ b/packages/drust/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "drust" +version = "0.0.3" +edition = "2021" + +description = "A modern web Content Management System to share your world." + +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } +authors = { workspace = true } + +[dependencies] +pagetop.workspace = true + + + +# Packages. +#pagetop-admin = { version = "0.0", path = "../pagetop-admin" } +#pagetop-user = { version = "0.0", path = "../pagetop-user" } +#pagetop-node = { version = "0.0", path = "../pagetop-node" } +# Themes. +#pagetop-bootsier = { version = "0.0", path = "../pagetop-bootsier" } +#pagetop-bulmix = { version = "0.0", path = "../pagetop-bulmix" } + +#[features] +#default = [ "mysql" ] +#mysql = [ +# "pagetop-user/mysql", +# "pagetop-node/mysql", +#] +#postgres = [ +# "pagetop-user/postgres", +# "pagetop-node/postgres", +#] +#sqlite = [ +# "pagetop-user/sqlite", +# "pagetop-node/sqlite", +#] diff --git a/packages/drust/config/common.toml b/packages/drust/config/common.toml new file mode 100644 index 00000000..2b018a16 --- /dev/null +++ b/packages/drust/config/common.toml @@ -0,0 +1,6 @@ +[app] +name = "Drust" +description = "A modern web Content Management System to share your world." + +[database] +db_type = "mysql" diff --git a/packages/drust/config/default.toml b/packages/drust/config/default.toml new file mode 100644 index 00000000..6f119629 --- /dev/null +++ b/packages/drust/config/default.toml @@ -0,0 +1,10 @@ +[app] +#theme = "Basic" +#theme = "Chassis" +theme = "Inception" +#theme = "Bootsier" +#theme = "Bulmix" +language = "es-ES" + +[log] +tracing = "Info,pagetop=Debug,sqlx::query=Warn" diff --git a/packages/drust/config/local.default.toml b/packages/drust/config/local.default.toml new file mode 100644 index 00000000..852059ed --- /dev/null +++ b/packages/drust/config/local.default.toml @@ -0,0 +1,7 @@ +[database] +db_name = "drust" +db_user = "drust" +db_pass = "demo" + +[dev] +pagetop_project_dir = "/home/manuelcillero/Proyectos/pagetop" diff --git a/packages/drust/src/main.rs b/packages/drust/src/main.rs new file mode 100644 index 00000000..02856abc --- /dev/null +++ b/packages/drust/src/main.rs @@ -0,0 +1,22 @@ +use pagetop::prelude::*; + +struct Drust; + +impl PackageTrait for Drust { + fn dependencies(&self) -> Vec { + vec![ + // Packages. + //&pagetop_admin::Admin, + //&pagetop_user::User, + //&pagetop_node::Node, + // Themes. + //&pagetop_bootsier::Bootsier, + //&pagetop_bulmix::Bulmix, + ] + } +} + +#[pagetop::main] +async fn main() -> std::io::Result<()> { + Application::prepare(&Drust).run()?.await +} diff --git a/packages/pagetop/Cargo.toml b/packages/pagetop/Cargo.toml new file mode 100644 index 00000000..4f2900b7 --- /dev/null +++ b/packages/pagetop/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "pagetop" +version = "0.0.56" +edition = "2021" + +description = "An opinionated web framework to build modular Server-Side Rendering web solutions." + +categories = ["web-programming", "gui", "development-tools", "asynchronous"] +keywords = ["pagetop", "web", "framework", "frontend", "ssr"] +readme = "../../README.md" + +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } +authors = { workspace = true } + +[lib] +name = "pagetop" + +[dependencies] +concat-string = "1.0.1" +figlet-rs = "0.1.5" +paste = "1.0.15" +terminal_size = "0.4.0" +toml = "0.8.19" + +serde.workspace = true +static-files.workspace = true + +pagetop-macros.workspace = true + + + + + +actix-web.workspace = true +actix-web-files.workspace = true +actix-web-static-files.workspace = true +actix-session.workspace = true +fluent-templates.workspace = true +nom.workspace = true +tracing.workspace = true +tracing-appender.workspace = true +tracing-subscriber.workspace = true +tracing-actix-web.workspace = true +substring.workspace = true +unic-langid.workspace = true diff --git a/src/app.rs b/packages/pagetop/src/app.rs similarity index 94% rename from src/app.rs rename to packages/pagetop/src/app.rs index 62a3a0f7..a7237d2a 100644 --- a/src/app.rs +++ b/packages/pagetop/src/app.rs @@ -3,9 +3,6 @@ mod figfont; use crate::core::{package, package::PackageRef}; -use crate::html::Markup; -use crate::response::page::{ErrorPage, ResultPage}; -use crate::service::HttpRequest; use crate::{global, locale, service, trace}; use actix_session::config::{BrowserSession, PersistentSession, SessionLifecycle}; @@ -147,12 +144,12 @@ impl Application { InitError = (), >, > { - service::App::new() - .configure(package::all::configure_services) - .default_service(service::web::route().to(service_not_found)) + service::App::new().configure(package::all::configure_services) + // .default_service(service::web::route().to(service_not_found)) } } - +/* async fn service_not_found(request: HttpRequest) -> ResultPage { Err(ErrorPage::NotFound(request)) } +*/ diff --git a/src/app/figfont.rs b/packages/pagetop/src/app/figfont.rs similarity index 100% rename from src/app/figfont.rs rename to packages/pagetop/src/app/figfont.rs diff --git a/src/app/slant.flf b/packages/pagetop/src/app/slant.flf similarity index 100% rename from src/app/slant.flf rename to packages/pagetop/src/app/slant.flf diff --git a/src/app/small.flf b/packages/pagetop/src/app/small.flf similarity index 100% rename from src/app/small.flf rename to packages/pagetop/src/app/small.flf diff --git a/src/app/speed.flf b/packages/pagetop/src/app/speed.flf similarity index 100% rename from src/app/speed.flf rename to packages/pagetop/src/app/speed.flf diff --git a/src/app/starwars.flf b/packages/pagetop/src/app/starwars.flf similarity index 100% rename from src/app/starwars.flf rename to packages/pagetop/src/app/starwars.flf diff --git a/src/config.rs b/packages/pagetop/src/config.rs similarity index 76% rename from src/config.rs rename to packages/pagetop/src/config.rs index a5baab60..372b6e91 100644 --- a/src/config.rs +++ b/packages/pagetop/src/config.rs @@ -120,53 +120,52 @@ mod path; mod source; mod value; -use crate::concat_string; use crate::config::data::ConfigData; use crate::config::file::File; +use crate::join; use std::sync::LazyLock; use std::env; +use std::path::Path; -/// Directorio donde se encuentran los archivos de configuración. -const CONFIG_DIR: &str = "config"; - -/// Valores originales de la configuración en forma de pares `clave = valor` recogidos de los -/// archivos de configuración. - -#[rustfmt::skip] +/// Original configuration values in `key = value` pairs gathered from configuration files. pub static CONFIG_DATA: LazyLock = LazyLock::new(|| { - // Modo de ejecución según la variable de entorno PAGETOP_RUN_MODE. Por defecto 'default'. + // Identify the configuration directory. + let config_dir = env::var("CARGO_MANIFEST_DIR") + .map(|manifest_dir| { + let manifest_config = Path::new(&manifest_dir).join("config"); + if manifest_config.exists() { + manifest_config.to_string_lossy().to_string() + } else { + "config".to_string() + } + }) + .unwrap_or_else(|_| "config".to_string()); + + // Execution mode based on the environment variable PAGETOP_RUN_MODE, defaults to 'default'. let run_mode = env::var("PAGETOP_RUN_MODE").unwrap_or_else(|_| "default".into()); - // Inicializa los ajustes. + // Initialize settings. let mut settings = ConfigData::default(); - // Combina los archivos (opcionales) de configuración y asigna el modo de ejecución. + // Merge (optional) configuration files and set the execution mode. settings - // Primero añade la configuración común a todos los entornos. Por defecto 'common.toml'. - .merge( - File::with_name(&concat_string!(CONFIG_DIR, "/common.toml")) - .required(false) - ).unwrap() - // Añade la configuración específica del entorno. Por defecto 'default.toml'. - .merge( - File::with_name(&concat_string!(CONFIG_DIR, "/", run_mode, ".toml")) - .required(false) - ).unwrap() - // Añade la configuración local reservada del entorno. Por defecto 'local.default.toml'. - .merge( - File::with_name(&concat_string!(CONFIG_DIR, "/local.", run_mode, ".toml")) - .required(false), - ).unwrap() - // Añade la configuración local reservada general. Por defecto 'local.toml'. - .merge( - File::with_name(&concat_string!(CONFIG_DIR, "/local.toml")) - .required(false) - ).unwrap() - // Salvaguarda el modo de ejecución. + // First, add the common configuration for all environments. Defaults to 'common.toml'. + .merge(File::with_name(&join!(config_dir, "/common.toml")).required(false)) + .expect("Failed to merge common configuration (common.toml)") + // Add the environment-specific configuration. Defaults to 'default.toml'. + .merge(File::with_name(&join!(config_dir, "/", run_mode, ".toml")).required(false)) + .expect(&format!("Failed to merge {run_mode}.toml configuration")) + // Add reserved local configuration for the environment. Defaults to 'local.default.toml'. + .merge(File::with_name(&join!(config_dir, "/local.", run_mode, ".toml")).required(false)) + .expect("Failed to merge reserved local environment configuration") + // Add the general reserved local configuration. Defaults to 'local.toml'. + .merge(File::with_name(&join!(config_dir, "/local.toml")).required(false)) + .expect("Failed to merge general reserved local configuration") + // Save the execution mode. .set("app.run_mode", run_mode) - .unwrap(); + .expect("Failed to set application run mode"); settings }); diff --git a/src/config/data.rs b/packages/pagetop/src/config/data.rs similarity index 100% rename from src/config/data.rs rename to packages/pagetop/src/config/data.rs diff --git a/src/config/de.rs b/packages/pagetop/src/config/de.rs similarity index 100% rename from src/config/de.rs rename to packages/pagetop/src/config/de.rs diff --git a/src/config/error.rs b/packages/pagetop/src/config/error.rs similarity index 100% rename from src/config/error.rs rename to packages/pagetop/src/config/error.rs diff --git a/src/config/file.rs b/packages/pagetop/src/config/file.rs similarity index 100% rename from src/config/file.rs rename to packages/pagetop/src/config/file.rs diff --git a/src/config/file/source.rs b/packages/pagetop/src/config/file/source.rs similarity index 100% rename from src/config/file/source.rs rename to packages/pagetop/src/config/file/source.rs diff --git a/src/config/file/toml.rs b/packages/pagetop/src/config/file/toml.rs similarity index 100% rename from src/config/file/toml.rs rename to packages/pagetop/src/config/file/toml.rs diff --git a/src/config/path.rs b/packages/pagetop/src/config/path.rs similarity index 100% rename from src/config/path.rs rename to packages/pagetop/src/config/path.rs diff --git a/src/config/path/parser.rs b/packages/pagetop/src/config/path/parser.rs similarity index 100% rename from src/config/path/parser.rs rename to packages/pagetop/src/config/path/parser.rs diff --git a/src/config/source.rs b/packages/pagetop/src/config/source.rs similarity index 100% rename from src/config/source.rs rename to packages/pagetop/src/config/source.rs diff --git a/src/config/value.rs b/packages/pagetop/src/config/value.rs similarity index 100% rename from src/config/value.rs rename to packages/pagetop/src/config/value.rs diff --git a/src/core.rs b/packages/pagetop/src/core.rs similarity index 93% rename from src/core.rs rename to packages/pagetop/src/core.rs index 1fe95a5d..dc24270e 100644 --- a/src/core.rs +++ b/packages/pagetop/src/core.rs @@ -69,11 +69,5 @@ impl AnyTo for T {} // API to define functions that alter the behavior of PageTop core. pub mod action; -// API to build new components. -pub mod component; - // API to add new features with packages. pub mod package; - -// API to add new layouts with themes. -pub mod theme; diff --git a/src/core/action.rs b/packages/pagetop/src/core/action.rs similarity index 100% rename from src/core/action.rs rename to packages/pagetop/src/core/action.rs diff --git a/src/core/action/all.rs b/packages/pagetop/src/core/action/all.rs similarity index 100% rename from src/core/action/all.rs rename to packages/pagetop/src/core/action/all.rs diff --git a/src/core/action/definition.rs b/packages/pagetop/src/core/action/definition.rs similarity index 100% rename from src/core/action/definition.rs rename to packages/pagetop/src/core/action/definition.rs diff --git a/src/core/action/list.rs b/packages/pagetop/src/core/action/list.rs similarity index 100% rename from src/core/action/list.rs rename to packages/pagetop/src/core/action/list.rs diff --git a/src/core/package.rs b/packages/pagetop/src/core/package.rs similarity index 100% rename from src/core/package.rs rename to packages/pagetop/src/core/package.rs diff --git a/src/core/package/all.rs b/packages/pagetop/src/core/package/all.rs similarity index 91% rename from src/core/package/all.rs rename to packages/pagetop/src/core/package/all.rs index 33a823f0..4be416a6 100644 --- a/src/core/package/all.rs +++ b/packages/pagetop/src/core/package/all.rs @@ -1,11 +1,10 @@ use crate::core::action::add_action; use crate::core::package::PackageRef; -use crate::core::theme::all::THEMES; -use crate::{global, service, static_files, static_files_service, trace}; +use crate::{service, trace}; use std::sync::{LazyLock, RwLock}; -static_files!(base); +//static_files!(base); // PACKAGES **************************************************************************************** @@ -22,12 +21,12 @@ pub fn register_packages(root_package: Option) { let mut enabled_list: Vec = Vec::new(); // Add default welcome page package to the enabled list. - add_to_enabled(&mut enabled_list, &crate::base::package::Welcome); + // add_to_enabled(&mut enabled_list, &crate::base::package::Welcome); // Add default theme packages to the enabled list. - add_to_enabled(&mut enabled_list, &crate::base::theme::Basic); - add_to_enabled(&mut enabled_list, &crate::base::theme::Chassis); - add_to_enabled(&mut enabled_list, &crate::base::theme::Inception); + // add_to_enabled(&mut enabled_list, &crate::base::theme::Basic); + // add_to_enabled(&mut enabled_list, &crate::base::theme::Chassis); + // add_to_enabled(&mut enabled_list, &crate::base::theme::Inception); // If a root package is provided, add it to the enabled list. if let Some(package) = root_package { @@ -61,7 +60,7 @@ fn add_to_enabled(list: &mut Vec, package: PackageRef) { add_to_enabled(list, *d); } - // Check if the package has an associated theme to register. + /* Check if the package has an associated theme to register. if let Some(theme) = package.theme() { let mut registered_themes = THEMES.write().unwrap(); // Ensure the theme is not already registered to avoid duplicates. @@ -74,7 +73,7 @@ fn add_to_enabled(list: &mut Vec, package: PackageRef) { } } else { trace::debug!("Enabling \"{}\" package", package.short_name()); - } + } */ } } @@ -130,11 +129,13 @@ pub fn init_packages() { // CONFIGURE SERVICES ****************************************************************************** pub fn configure_services(scfg: &mut service::web::ServiceConfig) { + /* static_files_service!( scfg, base => "/base", [&global::SETTINGS.dev.pagetop_project_dir, "static/base"] ); + */ for m in ENABLED_PACKAGES.read().unwrap().iter() { m.configure_service(scfg); } diff --git a/src/core/package/definition.rs b/packages/pagetop/src/core/package/definition.rs similarity index 88% rename from src/core/package/definition.rs rename to packages/pagetop/src/core/package/definition.rs index 3506a929..18880a1f 100644 --- a/src/core/package/definition.rs +++ b/packages/pagetop/src/core/package/definition.rs @@ -1,5 +1,4 @@ use crate::core::action::ActionBox; -use crate::core::theme::ThemeRef; use crate::core::AnyBase; use crate::locale::L10n; use crate::{actions, service}; @@ -16,10 +15,6 @@ pub trait PackageTrait: AnyBase + Send + Sync { L10n::none() } - fn theme(&self) -> Option { - None - } - fn dependencies(&self) -> Vec { vec![] } diff --git a/src/global.rs b/packages/pagetop/src/global.rs similarity index 100% rename from src/global.rs rename to packages/pagetop/src/global.rs diff --git a/src/lib.rs b/packages/pagetop/src/lib.rs similarity index 95% rename from src/lib.rs rename to packages/pagetop/src/lib.rs index b83f82dc..0f3b42bd 100644 --- a/src/lib.rs +++ b/packages/pagetop/src/lib.rs @@ -76,12 +76,12 @@ // RE-EXPORTED MACROS AND DERIVES. // ************************************************************************************************* -pub use concat_string::concat_string; +pub use concat_string::concat_string as join; /// Enables flexible identifier concatenation in macros, allowing new items with pasted identifiers. pub use paste::paste; -pub use pagetop_macros::{fn_builder, main, test, AutoDefault, ComponentClasses}; +pub use pagetop_macros::{main, test, AutoDefault}; // ************************************************************************************************* // GLOBAL. @@ -108,12 +108,8 @@ static_locales!(LOCALES_PAGETOP); pub mod config; // Application tracing and event logging. pub mod trace; -// HTML in code. -pub mod html; // Localization. pub mod locale; -// Date and time handling. -pub mod datetime; // Essential web framework. pub mod service; @@ -124,9 +120,6 @@ pub mod core; // Web request response variants. pub mod response; -// Base actions, components, packages, and themes. -pub mod base; - // Prepare and run the application. pub mod app; diff --git a/src/locale.rs b/packages/pagetop/src/locale.rs similarity index 98% rename from src/locale.rs rename to packages/pagetop/src/locale.rs index 56979f05..466914a0 100644 --- a/src/locale.rs +++ b/packages/pagetop/src/locale.rs @@ -86,7 +86,6 @@ //! static_locales!(LOCALES_SAMPLE in "path/to/locale"); //! ``` -use crate::html::{Markup, PreEscaped}; use crate::{global, kv, AutoDefault, LOCALES_PAGETOP}; pub use fluent_templates; @@ -240,10 +239,6 @@ impl L10n { }, } } - - pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup { - PreEscaped(self.using(langid).unwrap_or_default()) - } } impl fmt::Display for L10n { diff --git a/src/locale/en-US/base.ftl b/packages/pagetop/src/locale/en-US/base.ftl similarity index 100% rename from src/locale/en-US/base.ftl rename to packages/pagetop/src/locale/en-US/base.ftl diff --git a/src/locale/en-US/theme.ftl b/packages/pagetop/src/locale/en-US/theme.ftl similarity index 100% rename from src/locale/en-US/theme.ftl rename to packages/pagetop/src/locale/en-US/theme.ftl diff --git a/src/locale/en-US/welcome.ftl b/packages/pagetop/src/locale/en-US/welcome.ftl similarity index 100% rename from src/locale/en-US/welcome.ftl rename to packages/pagetop/src/locale/en-US/welcome.ftl diff --git a/src/locale/es-ES/base.ftl b/packages/pagetop/src/locale/es-ES/base.ftl similarity index 100% rename from src/locale/es-ES/base.ftl rename to packages/pagetop/src/locale/es-ES/base.ftl diff --git a/src/locale/es-ES/theme.ftl b/packages/pagetop/src/locale/es-ES/theme.ftl similarity index 100% rename from src/locale/es-ES/theme.ftl rename to packages/pagetop/src/locale/es-ES/theme.ftl diff --git a/src/locale/es-ES/welcome.ftl b/packages/pagetop/src/locale/es-ES/welcome.ftl similarity index 100% rename from src/locale/es-ES/welcome.ftl rename to packages/pagetop/src/locale/es-ES/welcome.ftl diff --git a/src/prelude.rs b/packages/pagetop/src/prelude.rs similarity index 57% rename from src/prelude.rs rename to packages/pagetop/src/prelude.rs index 450974df..53d80a34 100644 --- a/src/prelude.rs +++ b/packages/pagetop/src/prelude.rs @@ -1,8 +1,7 @@ //! The `PageTop` Prelude. -// RE-EXPORTED MACROS AND DERIVES. -pub use crate::{concat_string, fn_builder, main, paste, test}; -pub use crate::{AutoDefault, ComponentClasses}; +// RE-EXPORTED. +pub use crate::{join, main, paste, test, AutoDefault}; // GLOBAL. pub use crate::{global, HashMapResources, TypeId, Weight}; @@ -13,8 +12,6 @@ pub use crate::{global, HashMapResources, TypeId, Weight}; pub use crate::kv; // crate::config pub use crate::config_defaults; -// crate::html -pub use crate::html; // crate::locale pub use crate::static_locales; // crate::service @@ -26,26 +23,16 @@ pub use crate::actions; pub use crate::trace; -pub use crate::html::*; - pub use crate::locale::*; -pub use crate::datetime::*; - pub use crate::service; pub use crate::service::{HttpMessage, HttpRequest}; pub use crate::core::{AnyBase, AnyTo}; pub use crate::core::action::*; -pub use crate::core::component::*; pub use crate::core::package::*; -pub use crate::core::theme::*; -pub use crate::response::{json::*, page::*, redirect::*, ResponseError}; - -pub use crate::base::action; -pub use crate::base::component::*; -pub use crate::base::theme; +pub use crate::response::{json::*, redirect::*, ResponseError}; pub use crate::app::Application; diff --git a/src/response.rs b/packages/pagetop/src/response.rs similarity index 87% rename from src/response.rs rename to packages/pagetop/src/response.rs index e51974b1..ecbcd954 100644 --- a/src/response.rs +++ b/packages/pagetop/src/response.rs @@ -2,8 +2,6 @@ pub use actix_web::ResponseError; -pub mod page; - pub mod json; pub mod redirect; diff --git a/src/response/json.rs b/packages/pagetop/src/response/json.rs similarity index 100% rename from src/response/json.rs rename to packages/pagetop/src/response/json.rs diff --git a/src/response/redirect.rs b/packages/pagetop/src/response/redirect.rs similarity index 100% rename from src/response/redirect.rs rename to packages/pagetop/src/response/redirect.rs diff --git a/src/service.rs b/packages/pagetop/src/service.rs similarity index 100% rename from src/service.rs rename to packages/pagetop/src/service.rs diff --git a/src/trace.rs b/packages/pagetop/src/trace.rs similarity index 100% rename from src/trace.rs rename to packages/pagetop/src/trace.rs diff --git a/src/base.rs b/src/base.rs deleted file mode 100644 index 196f119c..00000000 --- a/src/base.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Base actions, components, packages, and themes. - -pub mod action; - -pub mod component; - -pub mod package; - -pub mod theme; diff --git a/src/base/action.rs b/src/base/action.rs deleted file mode 100644 index fe6741c5..00000000 --- a/src/base/action.rs +++ /dev/null @@ -1,9 +0,0 @@ -use crate::prelude::*; - -pub type FnActionWithComponent = fn(component: &mut C, cx: &mut Context); - -pub mod page; - -pub mod theme; - -pub mod component; diff --git a/src/base/action/component.rs b/src/base/action/component.rs deleted file mode 100644 index 03eedf26..00000000 --- a/src/base/action/component.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod is_renderable; -pub use is_renderable::*; - -mod before_prepare_component; -pub use before_prepare_component::*; - -mod after_prepare_component; -pub use after_prepare_component::*; diff --git a/src/base/action/component/after_prepare_component.rs b/src/base/action/component/after_prepare_component.rs deleted file mode 100644 index 233c1a7b..00000000 --- a/src/base/action/component/after_prepare_component.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::prelude::*; - -use crate::base::action::FnActionWithComponent; - -pub struct AfterPrepare { - f: FnActionWithComponent, - referer_type_id: Option, - referer_id: OptionId, - weight: Weight, -} - -impl ActionTrait for AfterPrepare { - fn referer_type_id(&self) -> Option { - self.referer_type_id - } - - fn referer_id(&self) -> Option { - self.referer_id.get() - } - - fn weight(&self) -> Weight { - self.weight - } -} - -impl AfterPrepare { - pub fn new(f: FnActionWithComponent) -> Self { - AfterPrepare { - f, - referer_type_id: Some(TypeId::of::()), - referer_id: OptionId::default(), - weight: 0, - } - } - - pub fn filter_by_referer_id(mut self, id: impl Into) -> Self { - self.referer_id.set_value(id); - self - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } - - #[inline(always)] - #[allow(clippy::inline_always)] - pub(crate) fn dispatch(component: &mut C, cx: &mut Context) { - dispatch_actions( - &ActionKey::new(TypeId::of::(), None, Some(TypeId::of::()), None), - |action: &Self| (action.f)(component, cx), - ); - if let Some(id) = component.id() { - dispatch_actions( - &ActionKey::new( - TypeId::of::(), - None, - Some(TypeId::of::()), - Some(id), - ), - |action: &Self| (action.f)(component, cx), - ); - } - } -} diff --git a/src/base/action/component/before_prepare_component.rs b/src/base/action/component/before_prepare_component.rs deleted file mode 100644 index cedc45db..00000000 --- a/src/base/action/component/before_prepare_component.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::prelude::*; - -use crate::base::action::FnActionWithComponent; - -pub struct BeforePrepare { - f: FnActionWithComponent, - referer_type_id: Option, - referer_id: OptionId, - weight: Weight, -} - -impl ActionTrait for BeforePrepare { - fn referer_type_id(&self) -> Option { - self.referer_type_id - } - - fn referer_id(&self) -> Option { - self.referer_id.get() - } - - fn weight(&self) -> Weight { - self.weight - } -} - -impl BeforePrepare { - pub fn new(f: FnActionWithComponent) -> Self { - BeforePrepare { - f, - referer_type_id: Some(TypeId::of::()), - referer_id: OptionId::default(), - weight: 0, - } - } - - pub fn filter_by_referer_id(mut self, id: impl Into) -> Self { - self.referer_id.set_value(id); - self - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } - - #[inline(always)] - #[allow(clippy::inline_always)] - pub(crate) fn dispatch(component: &mut C, cx: &mut Context) { - dispatch_actions( - &ActionKey::new(TypeId::of::(), None, Some(TypeId::of::()), None), - |action: &Self| (action.f)(component, cx), - ); - if let Some(id) = component.id() { - dispatch_actions( - &ActionKey::new( - TypeId::of::(), - None, - Some(TypeId::of::()), - Some(id), - ), - |action: &Self| (action.f)(component, cx), - ); - } - } -} diff --git a/src/base/action/component/is_renderable.rs b/src/base/action/component/is_renderable.rs deleted file mode 100644 index 93159237..00000000 --- a/src/base/action/component/is_renderable.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::prelude::*; - -pub type FnIsRenderable = fn(component: &C, cx: &mut Context) -> bool; - -pub struct IsRenderable { - f: FnIsRenderable, - referer_type_id: Option, - referer_id: OptionId, - weight: Weight, -} - -impl ActionTrait for IsRenderable { - fn referer_type_id(&self) -> Option { - self.referer_type_id - } - - fn referer_id(&self) -> Option { - self.referer_id.get() - } - - fn weight(&self) -> Weight { - self.weight - } -} - -impl IsRenderable { - pub fn new(f: FnIsRenderable) -> Self { - IsRenderable { - f, - referer_type_id: Some(TypeId::of::()), - referer_id: OptionId::default(), - weight: 0, - } - } - - pub fn filter_by_referer_id(mut self, id: impl Into) -> Self { - self.referer_id.set_value(id); - self - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } - - #[inline(always)] - #[allow(clippy::inline_always)] - pub(crate) fn dispatch(component: &C, cx: &mut Context) -> bool { - let mut renderable = true; - dispatch_actions( - &ActionKey::new(TypeId::of::(), None, Some(TypeId::of::()), None), - |action: &Self| { - if renderable && !(action.f)(component, cx) { - renderable = false; - } - }, - ); - if renderable { - if let Some(id) = component.id() { - dispatch_actions( - &ActionKey::new( - TypeId::of::(), - None, - Some(TypeId::of::()), - Some(id), - ), - |action: &Self| { - if renderable && !(action.f)(component, cx) { - renderable = false; - } - }, - ); - } - } - renderable - } -} diff --git a/src/base/action/page.rs b/src/base/action/page.rs deleted file mode 100644 index fdbff4ac..00000000 --- a/src/base/action/page.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod before_prepare_body; -pub use before_prepare_body::*; - -mod after_prepare_body; -pub use after_prepare_body::*; diff --git a/src/base/action/page/after_prepare_body.rs b/src/base/action/page/after_prepare_body.rs deleted file mode 100644 index 9eb2f397..00000000 --- a/src/base/action/page/after_prepare_body.rs +++ /dev/null @@ -1,34 +0,0 @@ -use crate::prelude::*; - -pub type FnAfterPrepareBody = fn(page: &mut Page); - -pub struct AfterPrepareBody { - f: FnAfterPrepareBody, - weight: Weight, -} - -impl ActionTrait for AfterPrepareBody { - fn weight(&self) -> Weight { - self.weight - } -} - -impl AfterPrepareBody { - pub fn new(f: FnAfterPrepareBody) -> Self { - AfterPrepareBody { f, weight: 0 } - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } - - #[inline(always)] - #[allow(clippy::inline_always)] - pub(crate) fn dispatch(page: &mut Page) { - dispatch_actions( - &ActionKey::new(TypeId::of::(), None, None, None), - |action: &Self| (action.f)(page), - ); - } -} diff --git a/src/base/action/page/before_prepare_body.rs b/src/base/action/page/before_prepare_body.rs deleted file mode 100644 index c1ea5beb..00000000 --- a/src/base/action/page/before_prepare_body.rs +++ /dev/null @@ -1,34 +0,0 @@ -use crate::prelude::*; - -pub type FnBeforePrepareBody = fn(page: &mut Page); - -pub struct BeforePrepareBody { - f: FnBeforePrepareBody, - weight: Weight, -} - -impl ActionTrait for BeforePrepareBody { - fn weight(&self) -> Weight { - self.weight - } -} - -impl BeforePrepareBody { - pub fn new(f: FnBeforePrepareBody) -> Self { - BeforePrepareBody { f, weight: 0 } - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } - - #[inline(always)] - #[allow(clippy::inline_always)] - pub(crate) fn dispatch(page: &mut Page) { - dispatch_actions( - &ActionKey::new(TypeId::of::(), None, None, None), - |action: &Self| (action.f)(page), - ); - } -} diff --git a/src/base/action/theme.rs b/src/base/action/theme.rs deleted file mode 100644 index 8f307d98..00000000 --- a/src/base/action/theme.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod before_prepare_component; -pub use before_prepare_component::*; - -mod after_prepare_component; -pub use after_prepare_component::*; - -mod render_component; -pub use render_component::*; diff --git a/src/base/action/theme/after_prepare_component.rs b/src/base/action/theme/after_prepare_component.rs deleted file mode 100644 index 7285aec1..00000000 --- a/src/base/action/theme/after_prepare_component.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::prelude::*; - -use crate::base::action::FnActionWithComponent; - -pub struct AfterPrepare { - f: FnActionWithComponent, - theme_type_id: Option, - referer_type_id: Option, -} - -impl ActionTrait for AfterPrepare { - fn theme_type_id(&self) -> Option { - self.theme_type_id - } - - fn referer_type_id(&self) -> Option { - self.referer_type_id - } -} - -impl AfterPrepare { - pub fn new(theme: ThemeRef, f: FnActionWithComponent) -> Self { - AfterPrepare { - f, - theme_type_id: Some(theme.type_id()), - referer_type_id: Some(TypeId::of::()), - } - } - - #[inline(always)] - #[allow(clippy::inline_always)] - pub(crate) fn dispatch(component: &mut C, cx: &mut Context) { - dispatch_actions( - &ActionKey::new( - TypeId::of::(), - Some(cx.theme().type_id()), - Some(TypeId::of::()), - None, - ), - |action: &Self| (action.f)(component, cx), - ); - } -} diff --git a/src/base/action/theme/before_prepare_component.rs b/src/base/action/theme/before_prepare_component.rs deleted file mode 100644 index 7c80a655..00000000 --- a/src/base/action/theme/before_prepare_component.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::prelude::*; - -use crate::base::action::FnActionWithComponent; - -pub struct BeforePrepare { - f: FnActionWithComponent, - theme_type_id: Option, - referer_type_id: Option, -} - -impl ActionTrait for BeforePrepare { - fn theme_type_id(&self) -> Option { - self.theme_type_id - } - - fn referer_type_id(&self) -> Option { - self.referer_type_id - } -} - -impl BeforePrepare { - pub fn new(theme: ThemeRef, f: FnActionWithComponent) -> Self { - BeforePrepare { - f, - theme_type_id: Some(theme.type_id()), - referer_type_id: Some(TypeId::of::()), - } - } - - #[inline(always)] - #[allow(clippy::inline_always)] - pub(crate) fn dispatch(component: &mut C, cx: &mut Context) { - dispatch_actions( - &ActionKey::new( - TypeId::of::(), - Some(cx.theme().type_id()), - Some(TypeId::of::()), - None, - ), - |action: &Self| (action.f)(component, cx), - ); - } -} diff --git a/src/base/action/theme/render_component.rs b/src/base/action/theme/render_component.rs deleted file mode 100644 index e79c5c92..00000000 --- a/src/base/action/theme/render_component.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::prelude::*; - -pub type FnRenderComponent = fn(component: &C, cx: &mut Context) -> Option; - -pub struct RenderComponent { - f: FnRenderComponent, - theme_type_id: Option, - referer_type_id: Option, -} - -impl ActionTrait for RenderComponent { - fn theme_type_id(&self) -> Option { - self.theme_type_id - } - - fn referer_type_id(&self) -> Option { - self.referer_type_id - } -} - -impl RenderComponent { - pub fn new(theme: ThemeRef, f: FnRenderComponent) -> Self { - RenderComponent { - f, - theme_type_id: Some(theme.type_id()), - referer_type_id: Some(TypeId::of::()), - } - } - - #[inline(always)] - #[allow(clippy::inline_always)] - pub(crate) fn dispatch(component: &C, cx: &mut Context) -> Option { - let mut render_component: Option = None; - dispatch_actions( - &ActionKey::new( - TypeId::of::(), - Some(cx.theme().type_id()), - Some(TypeId::of::()), - None, - ), - |action: &Self| { - if render_component.is_none() { - render_component = (action.f)(component, cx); - } - }, - ); - render_component - } -} diff --git a/src/base/component.rs b/src/base/component.rs deleted file mode 100644 index 14bfd84d..00000000 --- a/src/base/component.rs +++ /dev/null @@ -1,201 +0,0 @@ -use crate::core::component::{AssetsOp, Context}; -use crate::html::{JavaScript, StyleSheet}; -use crate::{AutoDefault, Weight}; - -use std::fmt; - -// Context parameters. -pub const PARAM_BASE_WEIGHT: &str = "base.weight"; -pub const PARAM_BASE_INCLUDE_ICONS: &str = "base.include.icon"; -pub const PARAM_BASE_INCLUDE_FLEX_ASSETS: &str = "base.include.flex"; -pub const PARAM_BASE_INCLUDE_MENU_ASSETS: &str = "base.include.menu"; - -pub(crate) fn add_base_assets(cx: &mut Context) { - let weight = cx.get_param::(PARAM_BASE_WEIGHT).unwrap_or(-90); - - cx.set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/root.css") - .with_version("0.0.1") - .with_weight(weight), - )) - .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/looks.css") - .with_version("0.0.2") - .with_weight(weight), - )) - .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/buttons.css") - .with_version("0.0.2") - .with_weight(weight), - )); - - if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_ICONS) { - cx.set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/icons.min.css") - .with_version("1.11.1") - .with_weight(weight), - )); - } - - if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_FLEX_ASSETS) { - cx.set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/flex.css") - .with_version("0.0.1") - .with_weight(weight), - )); - } - - if let Ok(true) = cx.get_param::(PARAM_BASE_INCLUDE_MENU_ASSETS) { - cx.set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/menu.css") - .with_version("0.0.1") - .with_weight(weight), - )) - .set_assets(AssetsOp::AddJavaScript( - JavaScript::defer("/base/js/menu.js") - .with_version("0.0.1") - .with_weight(weight), - )); - } -} - -// ************************************************************************************************* - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub enum BreakPoint { - #[default] - None, // Does not apply. Rest initially assume 1 pixel = 0.0625rem - SM, // @media screen and [ (max-width: 35.5rem) <= 568px < (min-width: 35.5625rem) ] - MD, // @media screen and [ (max-width: 48rem) <= 768px < (min-width: 48.0625rem) ] - LG, // @media screen and [ (max-width: 62rem) <= 992px < (min-width: 62.0625rem) ] - XL, // @media screen and [ (max-width: 80rem) <= 1280px < (min-width: 80.0625rem) ] - X2L, // @media screen and [ (max-width: 90rem) <= 1440px < (min-width: 90.0625rem) ] - X3L, // @media screen and [ (max-width: 120rem) <= 1920px < (min-width: 120.0625rem) ] - X2K, // @media screen and [ (max-width: 160rem) <= 2560px < (min-width: 160.0625rem) ] -} - -#[rustfmt::skip] -impl fmt::Display for BreakPoint { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - BreakPoint::None => write!(f, "bp__none"), - BreakPoint::SM => write!(f, "bp__sm"), - BreakPoint::MD => write!(f, "bp__md"), - BreakPoint::LG => write!(f, "bp__lg"), - BreakPoint::XL => write!(f, "bp__xl"), - BreakPoint::X2L => write!(f, "bp__x2l"), - BreakPoint::X3L => write!(f, "bp__x3l"), - BreakPoint::X2K => write!(f, "bp__x2k"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum StyleBase { - #[default] - Default, - Info, - Success, - Warning, - Danger, - Light, - Dark, - Link, -} - -#[rustfmt::skip] -impl fmt::Display for StyleBase { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - StyleBase::Default => write!(f, "style__default"), - StyleBase::Info => write!(f, "style__info"), - StyleBase::Success => write!(f, "style__success"), - StyleBase::Warning => write!(f, "style__warning"), - StyleBase::Danger => write!(f, "style__danger"), - StyleBase::Light => write!(f, "style__light"), - StyleBase::Dark => write!(f, "style__dark"), - StyleBase::Link => write!(f, "style__link"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum FontSize { - ExtraLarge, - XxLarge, - XLarge, - Large, - Medium, - #[default] - Normal, - Small, - XSmall, - XxSmall, - ExtraSmall, -} - -#[rustfmt::skip] -impl fmt::Display for FontSize { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - FontSize::ExtraLarge => write!(f, "fs__x3l"), - FontSize::XxLarge => write!(f, "fs__x2l"), - FontSize::XLarge => write!(f, "fs__xl"), - FontSize::Large => write!(f, "fs__l"), - FontSize::Medium => write!(f, "fs__m"), - FontSize::Normal => write!(f, ""), - FontSize::Small => write!(f, "fs__s"), - FontSize::XSmall => write!(f, "fs__xs"), - FontSize::XxSmall => write!(f, "fs__x2s"), - FontSize::ExtraSmall => write!(f, "fs__x3s"), - } - } -} - -// ************************************************************************************************* - -pub mod flex; - -mod basic; -pub use basic::*; - -mod error403; -pub use error403::Error403; - -mod error404; -pub use error404::Error404; - -mod heading; -pub use heading::{Heading, HeadingSize, HeadingType}; - -mod paragraph; -pub use paragraph::Paragraph; - -mod icon; -pub use icon::Icon; - -mod button; -pub use button::{Button, ButtonTarget}; - -mod image; -pub use image::{Image, ImageSize}; - -mod block; -pub use block::Block; - -mod branding; -pub use branding::Branding; - -mod powered_by; -pub use powered_by::{PoweredBy, PoweredByLogo}; - -pub mod menu; -pub use menu::Menu; - -pub mod form; -pub use form::{Form, FormMethod}; diff --git a/src/base/component/basic.rs b/src/base/component/basic.rs deleted file mode 100644 index 51ce6c9d..00000000 --- a/src/base/component/basic.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod html; -pub use html::Html; - -mod fluent; -pub use fluent::Fluent; diff --git a/src/base/component/basic/fluent.rs b/src/base/component/basic/fluent.rs deleted file mode 100644 index 9e7220fa..00000000 --- a/src/base/component/basic/fluent.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::prelude::*; - -#[derive(AutoDefault)] -pub struct Fluent(L10n); - -impl ComponentTrait for Fluent { - fn new() -> Self { - Fluent::default() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::With(self.0.escaped(cx.langid())) - } -} - -impl Fluent { - pub fn with(l10n: L10n) -> Self { - Fluent(l10n) - } - - pub fn set_l10n(&mut self, l10n: L10n) -> &mut Self { - self.0 = l10n; - self - } -} diff --git a/src/base/component/basic/html.rs b/src/base/component/basic/html.rs deleted file mode 100644 index 6d308438..00000000 --- a/src/base/component/basic/html.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::prelude::*; - -#[derive(AutoDefault)] -pub struct Html(Markup); - -impl ComponentTrait for Html { - fn new() -> Self { - Html::default() - } - - fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::With(html! { (self.0) }) - } -} - -impl Html { - pub fn with(html: Markup) -> Self { - Html(html) - } - - pub fn set_html(&mut self, html: Markup) -> &mut Self { - self.0 = html; - self - } -} diff --git a/src/base/component/block.rs b/src/base/component/block.rs deleted file mode 100644 index 59d22ed8..00000000 --- a/src/base/component/block.rs +++ /dev/null @@ -1,95 +0,0 @@ -use crate::prelude::*; - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Block { - id : OptionId, - classes: OptionClasses, - style : StyleBase, - title : OptionTranslated, - mixed : MixedComponents, -} - -impl ComponentTrait for Block { - fn new() -> Self { - Block::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn setup_before_prepare(&mut self, _cx: &mut Context) { - self.set_classes( - ClassesOp::Prepend, - ["block__container".to_string(), self.style().to_string()].join(" "), - ); - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let block_body = self.components().render(cx); - - if block_body.is_empty() { - return PrepareMarkup::None; - } - - let id = cx.required_id::(self.id()); - - PrepareMarkup::With(html! { - div id=(id) class=[self.classes().get()] { - @if let Some(title) = self.title().using(cx.langid()) { - h2 class="block__title" { (title) } - } - div class="block__content" { (block_body) } - } - }) - } -} - -impl Block { - // Block BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_style(&mut self, style: StyleBase) -> &mut Self { - self.style = style; - self - } - - #[fn_builder] - pub fn set_title(&mut self, title: L10n) -> &mut Self { - self.title.set_value(title); - self - } - - #[fn_builder] - pub fn set_components(&mut self, op: AnyOp) -> &mut Self { - self.mixed.set_value(op); - self - } - - #[rustfmt::skip] - pub fn add_component(mut self, component: impl ComponentTrait) -> Self { - self.mixed.set_value(AnyOp::Add(AnyComponent::with(component))); - self - } - - // Block GETTERS. - - pub fn style(&self) -> &StyleBase { - &self.style - } - - pub fn title(&self) -> &OptionTranslated { - &self.title - } - - pub fn components(&self) -> &MixedComponents { - &self.mixed - } -} diff --git a/src/base/component/branding.rs b/src/base/component/branding.rs deleted file mode 100644 index 08ba8b01..00000000 --- a/src/base/component/branding.rs +++ /dev/null @@ -1,102 +0,0 @@ -use crate::prelude::*; - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Branding { - id : OptionId, - #[default(_code = "global::SETTINGS.app.name.to_owned()")] - app_name : String, - slogan : OptionTranslated, - logo : OptionComponent, - #[default(_code = "|_| \"/\"")] - frontpage: FnContextualPath, -} - -impl ComponentTrait for Branding { - fn new() -> Self { - Branding::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let logo = self.logo().render(cx); - let home = self.frontpage()(cx); - let title = &L10n::l("site_home").using(cx.langid()); - PrepareMarkup::With(html! { - div id=[self.id()] class="branding__container" { - div class="branding__content" { - @if !logo.is_empty() { - a class="branding__logo" href=(home) title=[title] rel="home" { - (logo) - } - } - div class="branding__text" { - a class="branding__name" href=(home) title=[title] rel="home" { - (self.app_name()) - } - @if let Some(slogan) = self.slogan().using(cx.langid()) { - div class="branding__slogan" { - (slogan) - } - } - } - } - } - }) - } -} - -impl Branding { - // Branding BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_app_name(&mut self, app_name: impl Into) -> &mut Self { - self.app_name = app_name.into(); - self - } - - #[fn_builder] - pub fn set_slogan(&mut self, slogan: L10n) -> &mut Self { - self.slogan.set_value(slogan); - self - } - - #[fn_builder] - pub fn set_logo(&mut self, logo: Option) -> &mut Self { - self.logo.set_value(logo); - self - } - - #[fn_builder] - pub fn set_frontpage(&mut self, frontpage: FnContextualPath) -> &mut Self { - self.frontpage = frontpage; - self - } - - // Branding GETTERS. - - pub fn app_name(&self) -> &String { - &self.app_name - } - - pub fn slogan(&self) -> &OptionTranslated { - &self.slogan - } - - pub fn logo(&self) -> &OptionComponent { - &self.logo - } - - pub fn frontpage(&self) -> &FnContextualPath { - &self.frontpage - } -} diff --git a/src/base/component/button.rs b/src/base/component/button.rs deleted file mode 100644 index 2215a4bb..00000000 --- a/src/base/component/button.rs +++ /dev/null @@ -1,156 +0,0 @@ -use crate::prelude::*; - -#[derive(AutoDefault)] -pub enum ButtonTarget { - #[default] - Default, - Blank, - Parent, - Top, - Context(String), -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Button { - id : OptionId, - classes : OptionClasses, - style : StyleBase, - font_size : FontSize, - left_icon : OptionComponent, - right_icon: OptionComponent, - href : OptionString, - html : OptionTranslated, - target : ButtonTarget, -} - -impl ComponentTrait for Button { - fn new() -> Self { - Button::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn setup_before_prepare(&mut self, _cx: &mut Context) { - self.set_classes( - ClassesOp::Prepend, - [ - "button__tap".to_string(), - self.style().to_string(), - self.font_size().to_string(), - ] - .join(" "), - ); - } - - #[rustfmt::skip] - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let target = match &self.target() { - ButtonTarget::Default => None, - ButtonTarget::Blank => Some("_blank"), - ButtonTarget::Parent => Some("_parent"), - ButtonTarget::Top => Some("_top"), - ButtonTarget::Context(name) => Some(name.as_str()), - }; - PrepareMarkup::With(html! { - a - id=[self.id()] - class=[self.classes().get()] - href=[self.href().get()] - target=[target] - { - (self.left_icon().render(cx)) - span { (self.html().escaped(cx.langid())) } - (self.right_icon().render(cx)) - } - }) - } -} - -impl Button { - pub fn anchor(href: impl Into, html: L10n) -> Self { - Button::default().with_href(href).with_html(html) - } - - // Button BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_style(&mut self, style: StyleBase) -> &mut Self { - self.style = style; - self - } - - #[fn_builder] - pub fn set_font_size(&mut self, font_size: FontSize) -> &mut Self { - self.font_size = font_size; - self - } - - #[fn_builder] - pub fn set_left_icon(&mut self, icon: Option) -> &mut Self { - self.left_icon.set_value(icon); - self - } - - #[fn_builder] - pub fn set_right_icon(&mut self, icon: Option) -> &mut Self { - self.right_icon.set_value(icon); - self - } - - #[fn_builder] - pub fn set_href(&mut self, href: impl Into) -> &mut Self { - self.href.set_value(href); - self - } - - #[fn_builder] - pub fn set_html(&mut self, html: L10n) -> &mut Self { - self.html.set_value(html); - self - } - - #[fn_builder] - pub fn set_target(&mut self, target: ButtonTarget) -> &mut Self { - self.target = target; - self - } - - // Button GETTERS. - - pub fn style(&self) -> &StyleBase { - &self.style - } - - pub fn font_size(&self) -> &FontSize { - &self.font_size - } - - pub fn left_icon(&self) -> &OptionComponent { - &self.left_icon - } - - pub fn right_icon(&self) -> &OptionComponent { - &self.right_icon - } - - pub fn href(&self) -> &OptionString { - &self.href - } - - pub fn html(&self) -> &OptionTranslated { - &self.html - } - - pub fn target(&self) -> &ButtonTarget { - &self.target - } -} diff --git a/src/base/component/error403.rs b/src/base/component/error403.rs deleted file mode 100644 index 172487d7..00000000 --- a/src/base/component/error403.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::prelude::*; - -pub struct Error403; - -impl ComponentTrait for Error403 { - fn new() -> Self { - Error403 - } - - fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::With(html! { - div { - h1 { ("FORBIDDEN ACCESS") } - } - }) - } -} diff --git a/src/base/component/error404.rs b/src/base/component/error404.rs deleted file mode 100644 index 0292df8f..00000000 --- a/src/base/component/error404.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::prelude::*; - -pub struct Error404; - -impl ComponentTrait for Error404 { - fn new() -> Self { - Error404 - } - - fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::With(html! { - div { - h1 { ("RESOURCE NOT FOUND") } - } - }) - } -} diff --git a/src/base/component/flex.rs b/src/base/component/flex.rs deleted file mode 100644 index 0b732dcd..00000000 --- a/src/base/component/flex.rs +++ /dev/null @@ -1,311 +0,0 @@ -mod container; -pub use container::Container; - -mod item; -pub use item::Item; - -use crate::prelude::*; - -use std::fmt; - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Direction { - #[default] - Default, - Row(BreakPoint), - RowReverse(BreakPoint), - Column(BreakPoint), - ColumnReverse(BreakPoint), -} - -#[rustfmt::skip] -impl fmt::Display for Direction { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Direction::Default => write!(f, "flex__row {}", BreakPoint::default()), - Direction::Row(bp) => write!(f, "flex__row {bp}"), - Direction::RowReverse(bp) => write!(f, "flex__row flex__reverse {bp}"), - Direction::Column(bp) => write!(f, "flex__col {bp}"), - Direction::ColumnReverse(bp) => write!(f, "flex__col flex__reverse {bp}"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Wrap { - #[default] - Default, - NoWrap, - Wrap(ContentAlign), - WrapReverse(ContentAlign), -} - -#[rustfmt::skip] -impl fmt::Display for Wrap { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Wrap::Default => write!(f, ""), - Wrap::NoWrap => write!(f, "flex__nowrap"), - Wrap::Wrap(a) => write!(f, "flex__wrap {a}"), - Wrap::WrapReverse(a) => write!(f, "flex__wrap-reverse {a}"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum ContentAlign { - #[default] - Default, - Start, - End, - Center, - Stretch, - SpaceBetween, - SpaceAround, -} - -#[rustfmt::skip] -impl fmt::Display for ContentAlign { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ContentAlign::Default => write!(f, ""), - ContentAlign::Start => write!(f, "flex__align-start"), - ContentAlign::End => write!(f, "flex__align-end"), - ContentAlign::Center => write!(f, "flex__align-center"), - ContentAlign::Stretch => write!(f, "flex__align-stretch"), - ContentAlign::SpaceBetween => write!(f, "flex__align-space-between"), - ContentAlign::SpaceAround => write!(f, "flex__align-space-around"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Justify { - #[default] - Default, - Start, - End, - Center, - SpaceBetween, - SpaceAround, - SpaceEvenly, -} - -#[rustfmt::skip] -impl fmt::Display for Justify { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Justify::Default => write!(f, ""), - Justify::Start => write!(f, "flex__justify-start"), - Justify::End => write!(f, "flex__justify-end"), - Justify::Center => write!(f, "flex__justify-center"), - Justify::SpaceBetween => write!(f, "flex__justify-space-between"), - Justify::SpaceAround => write!(f, "flex__justify-space-around"), - Justify::SpaceEvenly => write!(f, "flex__justify-space-evenly"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Align { - #[default] - Default, - Start, - End, - Center, - Stretch, - Baseline, -} - -#[rustfmt::skip] -impl fmt::Display for Align { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Align::Default => write!(f, ""), - Align::Start => write!(f, "flex__start"), - Align::End => write!(f, "flex__end"), - Align::Center => write!(f, "flex__center"), - Align::Stretch => write!(f, "flex__stretch"), - Align::Baseline => write!(f, "flex__baseline"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Gap { - #[default] - Default, - Row(unit::Value), - Column(unit::Value), - Distinct(unit::Value, unit::Value), - Both(unit::Value), -} - -#[rustfmt::skip] -impl fmt::Display for Gap { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Gap::Default => write!(f, ""), - Gap::Row(r) => write!(f, "row-gap: {r};"), - Gap::Column(c) => write!(f, "column-gap: {c};"), - Gap::Distinct(r, c) => write!(f, "gap: {r} {c};"), - Gap::Both(v) => write!(f, "gap: {v};"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Grow { - #[default] - Default, - Is1, - Is2, - Is3, - Is4, - Is5, - Is6, - Is7, - Is8, - Is9, -} - -impl fmt::Display for Grow { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Grow::Default => write!(f, ""), - Grow::Is1 => write!(f, "flex__grow-1"), - Grow::Is2 => write!(f, "flex__grow-2"), - Grow::Is3 => write!(f, "flex__grow-3"), - Grow::Is4 => write!(f, "flex__grow-4"), - Grow::Is5 => write!(f, "flex__grow-5"), - Grow::Is6 => write!(f, "flex__grow-6"), - Grow::Is7 => write!(f, "flex__grow-7"), - Grow::Is8 => write!(f, "flex__grow-8"), - Grow::Is9 => write!(f, "flex__grow-9"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Shrink { - #[default] - Default, - Is1, - Is2, - Is3, - Is4, - Is5, - Is6, - Is7, - Is8, - Is9, -} - -impl fmt::Display for Shrink { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Shrink::Default => write!(f, ""), - Shrink::Is1 => write!(f, "flex__shrink-1"), - Shrink::Is2 => write!(f, "flex__shrink-2"), - Shrink::Is3 => write!(f, "flex__shrink-3"), - Shrink::Is4 => write!(f, "flex__shrink-4"), - Shrink::Is5 => write!(f, "flex__shrink-5"), - Shrink::Is6 => write!(f, "flex__shrink-6"), - Shrink::Is7 => write!(f, "flex__shrink-7"), - Shrink::Is8 => write!(f, "flex__shrink-8"), - Shrink::Is9 => write!(f, "flex__shrink-9"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Size { - #[default] - Default, - Percent10, - Percent20, - Percent25, - Percent33, - Percent40, - Percent50, - Percent60, - Percent66, - Percent75, - Percent80, - Percent90, -} - -impl fmt::Display for Size { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Size::Default => write!(f, ""), - Size::Percent10 => write!(f, "flex__size-10"), - Size::Percent20 => write!(f, "flex__size-20"), - Size::Percent25 => write!(f, "flex__size-25"), - Size::Percent33 => write!(f, "flex__size-33"), - Size::Percent40 => write!(f, "flex__size-40"), - Size::Percent50 => write!(f, "flex__size-50"), - Size::Percent60 => write!(f, "flex__size-60"), - Size::Percent66 => write!(f, "flex__size-66"), - Size::Percent75 => write!(f, "flex__size-75"), - Size::Percent80 => write!(f, "flex__size-80"), - Size::Percent90 => write!(f, "flex__size-90"), - } - } -} - -// ************************************************************************************************* - -#[derive(AutoDefault)] -pub enum Offset { - #[default] - Default, - Offset10, - Offset20, - Offset25, - Offset33, - Offset40, - Offset50, - Offset60, - Offset66, - Offset75, - Offset80, - Offset90, -} - -impl fmt::Display for Offset { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Offset::Default => write!(f, ""), - Offset::Offset10 => write!(f, "flex__offset-10"), - Offset::Offset20 => write!(f, "flex__offset-20"), - Offset::Offset25 => write!(f, "flex__offset-25"), - Offset::Offset33 => write!(f, "flex__offset-33"), - Offset::Offset40 => write!(f, "flex__offset-40"), - Offset::Offset50 => write!(f, "flex__offset-50"), - Offset::Offset60 => write!(f, "flex__offset-60"), - Offset::Offset66 => write!(f, "flex__offset-66"), - Offset::Offset75 => write!(f, "flex__offset-75"), - Offset::Offset80 => write!(f, "flex__offset-80"), - Offset::Offset90 => write!(f, "flex__offset-90"), - } - } -} diff --git a/src/base/component/flex/container.rs b/src/base/component/flex/container.rs deleted file mode 100644 index 0b095c30..00000000 --- a/src/base/component/flex/container.rs +++ /dev/null @@ -1,212 +0,0 @@ -use crate::prelude::*; - -#[derive(AutoDefault)] -pub enum ContainerType { - #[default] - Default, - Header, - Main, - Section, - Article, - Footer, -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Container { - id : OptionId, - classes : OptionClasses, - container_type: ContainerType, - direction : flex::Direction, - flex_wrap : flex::Wrap, - flex_justify : flex::Justify, - flex_align : flex::Align, - flex_gap : flex::Gap, - items : MixedComponents, -} - -impl ComponentTrait for Container { - fn new() -> Self { - Container::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn setup_before_prepare(&mut self, cx: &mut Context) { - self.set_classes( - ClassesOp::Prepend, - [ - "flex__container".to_string(), - self.direction().to_string(), - self.wrap().to_string(), - self.justify().to_string(), - self.align().to_string(), - ] - .join(" "), - ); - - cx.set_param::(PARAM_BASE_INCLUDE_FLEX_ASSETS, &true); - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let output = self.items().render(cx); - if output.is_empty() { - return PrepareMarkup::None; - } - - let gap = match self.gap() { - flex::Gap::Default => None, - _ => Some(self.gap().to_string()), - }; - match self.container_type() { - ContainerType::Default => PrepareMarkup::With(html! { - div id=[self.id()] class=[self.classes().get()] style=[gap] { - (output) - } - }), - ContainerType::Header => PrepareMarkup::With(html! { - header id=[self.id()] class=[self.classes().get()] style=[gap] { - (output) - } - }), - ContainerType::Main => PrepareMarkup::With(html! { - main id=[self.id()] class=[self.classes().get()] style=[gap] { - (output) - } - }), - ContainerType::Section => PrepareMarkup::With(html! { - section id=[self.id()] class=[self.classes().get()] style=[gap] { - (output) - } - }), - ContainerType::Article => PrepareMarkup::With(html! { - article id=[self.id()] class=[self.classes().get()] style=[gap] { - (output) - } - }), - ContainerType::Footer => PrepareMarkup::With(html! { - footer id=[self.id()] class=[self.classes().get()] style=[gap] { - (output) - } - }), - } - } -} - -impl Container { - pub fn header() -> Self { - Container { - container_type: ContainerType::Header, - ..Default::default() - } - } - - pub fn main() -> Self { - Container { - container_type: ContainerType::Main, - ..Default::default() - } - } - - pub fn section() -> Self { - Container { - container_type: ContainerType::Section, - ..Default::default() - } - } - - pub fn article() -> Self { - Container { - container_type: ContainerType::Article, - ..Default::default() - } - } - - pub fn footer() -> Self { - Container { - container_type: ContainerType::Footer, - ..Default::default() - } - } - - // Container BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_direction(&mut self, direction: flex::Direction) -> &mut Self { - self.direction = direction; - self - } - - #[fn_builder] - pub fn set_wrap(&mut self, wrap: flex::Wrap) -> &mut Self { - self.flex_wrap = wrap; - self - } - - #[fn_builder] - pub fn set_justify(&mut self, justify: flex::Justify) -> &mut Self { - self.flex_justify = justify; - self - } - - #[fn_builder] - pub fn set_align(&mut self, align: flex::Align) -> &mut Self { - self.flex_align = align; - self - } - - #[fn_builder] - pub fn set_gap(&mut self, gap: flex::Gap) -> &mut Self { - self.flex_gap = gap; - self - } - - #[fn_builder] - pub fn set_items(&mut self, op: TypedOp) -> &mut Self { - self.items.set_typed(op); - self - } - - pub fn add_item(mut self, item: flex::Item) -> Self { - self.items.set_value(AnyOp::Add(AnyComponent::with(item))); - self - } - - // Container GETTERS. - - pub fn container_type(&self) -> &ContainerType { - &self.container_type - } - - pub fn direction(&self) -> &flex::Direction { - &self.direction - } - - pub fn wrap(&self) -> &flex::Wrap { - &self.flex_wrap - } - - pub fn justify(&self) -> &flex::Justify { - &self.flex_justify - } - - pub fn align(&self) -> &flex::Align { - &self.flex_align - } - - pub fn gap(&self) -> &flex::Gap { - &self.flex_gap - } - - pub fn items(&self) -> &MixedComponents { - &self.items - } -} diff --git a/src/base/component/flex/item.rs b/src/base/component/flex/item.rs deleted file mode 100644 index b1ec3073..00000000 --- a/src/base/component/flex/item.rs +++ /dev/null @@ -1,200 +0,0 @@ -use crate::prelude::*; - -#[derive(AutoDefault)] -pub enum ItemType { - #[default] - Default, - Region, - Wrapper, - Bundle, -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Item { - id : OptionId, - classes : OptionClasses, - item_type : ItemType, - flex_grow : flex::Grow, - flex_shrink: flex::Shrink, - flex_size : flex::Size, - flex_offset: flex::Offset, - flex_align : flex::Align, - mixed : MixedComponents, -} - -impl ComponentTrait for Item { - fn new() -> Self { - Item::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn setup_before_prepare(&mut self, _cx: &mut Context) { - self.set_classes( - ClassesOp::Prepend, - [ - "flex__item".to_string(), - self.grow().to_string(), - self.shrink().to_string(), - self.size().to_string(), - self.offset().to_string(), - self.align().to_string(), - ] - .join(" "), - ); - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let (output, region) = match self.item_type() { - ItemType::Region => ( - self.components().render(cx), - if let Some(id) = self.id() { - cx.prepare_region(id) - } else { - Markup::default() - }, - ), - _ => (self.components().render(cx), Markup::default()), - }; - if output.is_empty() && region.is_empty() { - return PrepareMarkup::None; - } - match self.item_type() { - ItemType::Default => PrepareMarkup::With(html! { - div id=[self.id()] class=[self.classes().get()] { - div class="flex__content" { - (output) - } - } - }), - ItemType::Region => PrepareMarkup::With(html! { - div id=[self.id()] class=[self.classes().get()] { - div class="flex__content flex__region" { - (region) - (output) - } - } - }), - ItemType::Wrapper => PrepareMarkup::With(html! { - div id=[self.id()] class=[self.classes().get()] { - (output) - } - }), - ItemType::Bundle => PrepareMarkup::With(html! { - (output) - }), - } - } -} - -impl Item { - pub fn region() -> Self { - Item { - item_type: ItemType::Region, - ..Default::default() - } - } - - pub fn wrapper() -> Self { - Item { - item_type: ItemType::Wrapper, - ..Default::default() - } - } - - pub fn bundle() -> Self { - Item { - item_type: ItemType::Bundle, - ..Default::default() - } - } - - pub fn with(component: impl ComponentTrait) -> Self { - Item::default().add_component(component) - } - - // Item BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_grow(&mut self, grow: flex::Grow) -> &mut Self { - self.flex_grow = grow; - self - } - - #[fn_builder] - pub fn set_shrink(&mut self, shrink: flex::Shrink) -> &mut Self { - self.flex_shrink = shrink; - self - } - - #[fn_builder] - // Ensures the item occupies the exact specified width, neither growing nor shrinking, - // regardless of the available space in the container or the size of other items. - pub fn set_size(&mut self, size: flex::Size) -> &mut Self { - self.flex_size = size; - self - } - - #[fn_builder] - pub fn set_offset(&mut self, offset: flex::Offset) -> &mut Self { - self.flex_offset = offset; - self - } - - #[fn_builder] - pub fn set_align(&mut self, align: flex::Align) -> &mut Self { - self.flex_align = align; - self - } - - #[fn_builder] - pub fn set_components(&mut self, op: AnyOp) -> &mut Self { - self.mixed.set_value(op); - self - } - - #[rustfmt::skip] - pub fn add_component(mut self, component: impl ComponentTrait) -> Self { - self.mixed.set_value(AnyOp::Add(AnyComponent::with(component))); - self - } - - // Item GETTERS. - - pub fn item_type(&self) -> &ItemType { - &self.item_type - } - - pub fn grow(&self) -> &flex::Grow { - &self.flex_grow - } - - pub fn shrink(&self) -> &flex::Shrink { - &self.flex_shrink - } - - pub fn size(&self) -> &flex::Size { - &self.flex_size - } - - pub fn offset(&self) -> &flex::Offset { - &self.flex_offset - } - - pub fn align(&self) -> &flex::Align { - &self.flex_align - } - - pub fn components(&self) -> &MixedComponents { - &self.mixed - } -} diff --git a/src/base/component/form.rs b/src/base/component/form.rs deleted file mode 100644 index bb5dd943..00000000 --- a/src/base/component/form.rs +++ /dev/null @@ -1,14 +0,0 @@ -mod form_main; -pub use form_main::{Form, FormMethod}; - -mod input; -pub use input::{Input, InputType}; - -mod hidden; -pub use hidden::Hidden; - -mod date; -pub use date::Date; - -mod action_button; -pub use action_button::{ActionButton, ActionButtonType}; diff --git a/src/base/component/form/action_button.rs b/src/base/component/form/action_button.rs deleted file mode 100644 index cadbe391..00000000 --- a/src/base/component/form/action_button.rs +++ /dev/null @@ -1,182 +0,0 @@ -use crate::prelude::*; - -use std::fmt; - -#[derive(AutoDefault)] -pub enum ActionButtonType { - #[default] - Submit, - Reset, -} - -#[rustfmt::skip] -impl fmt::Display for ActionButtonType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ActionButtonType::Submit => write!(f, "submit"), - ActionButtonType::Reset => write!(f, "reset"), - } - } -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct ActionButton { - classes : OptionClasses, - button_type: ActionButtonType, - style : StyleBase, - font_size : FontSize, - left_icon : OptionComponent, - right_icon : OptionComponent, - name : OptionString, - value : OptionTranslated, - autofocus : OptionString, - disabled : OptionString, -} - -impl ComponentTrait for ActionButton { - fn new() -> Self { - ActionButton::submit() - } - - fn setup_before_prepare(&mut self, _cx: &mut Context) { - self.set_classes( - ClassesOp::Prepend, - [ - "button__tap".to_string(), - self.style().to_string(), - self.font_size().to_string(), - ] - .join(" "), - ); - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let id = self.name().get().map(|name| concat_string!("edit-", name)); - PrepareMarkup::With(html! { - button - type=(self.button_type().to_string()) - id=[id] - class=[self.classes().get()] - name=[self.name().get()] - value=[self.value().using(cx.langid())] - autofocus=[self.autofocus().get()] - disabled=[self.disabled().get()] - { - (self.left_icon().render(cx)) - span { (self.value().escaped(cx.langid())) } - (self.right_icon().render(cx)) - } - }) - } -} - -impl ActionButton { - pub fn submit() -> Self { - ActionButton { - button_type: ActionButtonType::Submit, - style: StyleBase::Default, - value: OptionTranslated::new(L10n::l("button_submit")), - ..Default::default() - } - } - - pub fn reset() -> Self { - ActionButton { - button_type: ActionButtonType::Reset, - style: StyleBase::Info, - value: OptionTranslated::new(L10n::l("button_reset")), - ..Default::default() - } - } - - // Button BUILDER. - - #[fn_builder] - pub fn set_style(&mut self, style: StyleBase) -> &mut Self { - self.style = style; - self - } - - #[fn_builder] - pub fn set_font_size(&mut self, font_size: FontSize) -> &mut Self { - self.font_size = font_size; - self - } - - #[fn_builder] - pub fn set_left_icon(&mut self, icon: Option) -> &mut Self { - self.left_icon.set_value(icon); - self - } - - #[fn_builder] - pub fn set_right_icon(&mut self, icon: Option) -> &mut Self { - self.right_icon.set_value(icon); - self - } - - #[fn_builder] - pub fn set_name(&mut self, name: &str) -> &mut Self { - self.name.set_value(name); - self - } - - #[fn_builder] - pub fn set_value(&mut self, value: L10n) -> &mut Self { - self.value.set_value(value); - self - } - - #[fn_builder] - pub fn set_autofocus(&mut self, toggle: bool) -> &mut Self { - self.autofocus - .set_value(if toggle { "autofocus" } else { "" }); - self - } - - #[fn_builder] - pub fn set_disabled(&mut self, toggle: bool) -> &mut Self { - self.disabled - .set_value(if toggle { "disabled" } else { "" }); - self - } - - // Button GETTERS. - - pub fn button_type(&self) -> &ActionButtonType { - &self.button_type - } - - pub fn style(&self) -> &StyleBase { - &self.style - } - - pub fn font_size(&self) -> &FontSize { - &self.font_size - } - - pub fn left_icon(&self) -> &OptionComponent { - &self.left_icon - } - - pub fn right_icon(&self) -> &OptionComponent { - &self.right_icon - } - - pub fn name(&self) -> &OptionString { - &self.name - } - - pub fn value(&self) -> &OptionTranslated { - &self.value - } - - pub fn autofocus(&self) -> &OptionString { - &self.autofocus - } - - pub fn disabled(&self) -> &OptionString { - &self.disabled - } -} diff --git a/src/base/component/form/date.rs b/src/base/component/form/date.rs deleted file mode 100644 index 859a2e86..00000000 --- a/src/base/component/form/date.rs +++ /dev/null @@ -1,166 +0,0 @@ -use crate::prelude::*; - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Date { - classes : OptionClasses, - name : OptionString, - value : OptionString, - label : OptionString, - placeholder : OptionString, - autofocus : OptionString, - autocomplete: OptionString, - disabled : OptionString, - readonly : OptionString, - required : OptionString, - help_text : OptionString, -} - -impl ComponentTrait for Date { - fn new() -> Self { - Date::default().with_classes(ClassesOp::Add, "form-item form-type-date") - } - - fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup { - let id = self.name().get().map(|name| concat_string!("edit-", name)); - PrepareMarkup::With(html! { - div class=[self.classes().get()] { - @if let Some(label) = self.label().get() { - label class="form-label" for=[&id] { - (label) " " - @if self.required().get().is_some() { - span - class="form-required" - title="Este campo es obligatorio." { "*" } " " - } - } - } - input - type="date" - id=[id] - class="form-control" - name=[self.name().get()] - value=[self.value().get()] - placeholder=[self.placeholder().get()] - autofocus=[self.autofocus().get()] - autocomplete=[self.autocomplete().get()] - readonly=[self.readonly().get()] - required=[self.required().get()] - disabled=[self.disabled().get()] {} - @if let Some(help_text) = self.help_text().get() { - div class="form-text" { (help_text) } - } - } - }) - } -} - -impl Date { - // Date BUILDER. - - #[fn_builder] - pub fn set_name(&mut self, name: &str) -> &mut Self { - self.name.set_value(name); - self - } - - #[fn_builder] - pub fn set_value(&mut self, value: &str) -> &mut Self { - self.value.set_value(value); - self - } - - #[fn_builder] - pub fn set_label(&mut self, label: &str) -> &mut Self { - self.label.set_value(label); - self - } - - #[fn_builder] - pub fn set_placeholder(&mut self, placeholder: &str) -> &mut Self { - self.placeholder.set_value(placeholder); - self - } - - #[fn_builder] - pub fn set_autofocus(&mut self, toggle: bool) -> &mut Self { - self.autofocus - .set_value(if toggle { "autofocus" } else { "" }); - self - } - - #[fn_builder] - pub fn set_autocomplete(&mut self, toggle: bool) -> &mut Self { - self.autocomplete.set_value(if toggle { "" } else { "off" }); - self - } - - #[fn_builder] - pub fn set_disabled(&mut self, toggle: bool) -> &mut Self { - self.disabled - .set_value(if toggle { "disabled" } else { "" }); - self - } - - #[fn_builder] - pub fn set_readonly(&mut self, toggle: bool) -> &mut Self { - self.readonly - .set_value(if toggle { "readonly" } else { "" }); - self - } - - #[fn_builder] - pub fn set_required(&mut self, toggle: bool) -> &mut Self { - self.required - .set_value(if toggle { "required" } else { "" }); - self - } - - #[fn_builder] - pub fn set_help_text(&mut self, help_text: &str) -> &mut Self { - self.help_text.set_value(help_text); - self - } - - // Date GETTERS. - - pub fn name(&self) -> &OptionString { - &self.name - } - - pub fn value(&self) -> &OptionString { - &self.value - } - - pub fn label(&self) -> &OptionString { - &self.label - } - - pub fn placeholder(&self) -> &OptionString { - &self.placeholder - } - - pub fn autofocus(&self) -> &OptionString { - &self.autofocus - } - - pub fn autocomplete(&self) -> &OptionString { - &self.autocomplete - } - - pub fn disabled(&self) -> &OptionString { - &self.disabled - } - - pub fn readonly(&self) -> &OptionString { - &self.readonly - } - - pub fn required(&self) -> &OptionString { - &self.required - } - - pub fn help_text(&self) -> &OptionString { - &self.help_text - } -} diff --git a/src/base/component/form/form_main.rs b/src/base/component/form/form_main.rs deleted file mode 100644 index b630571c..00000000 --- a/src/base/component/form/form_main.rs +++ /dev/null @@ -1,107 +0,0 @@ -use crate::prelude::*; - -#[derive(AutoDefault)] -pub enum FormMethod { - #[default] - Post, - Get, -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Form { - id : OptionId, - classes: OptionClasses, - action : OptionString, - charset: OptionString, - method : FormMethod, - mixed : MixedComponents, -} - -impl ComponentTrait for Form { - fn new() -> Self { - Form::default() - .with_classes(ClassesOp::Add, "form") - .with_charset("UTF-8") - } - - fn id(&self) -> Option { - self.id.get() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let method = match self.method() { - FormMethod::Post => Some("post".to_owned()), - FormMethod::Get => None, - }; - PrepareMarkup::With(html! { - form - id=[self.id()] - class=[self.classes().get()] - action=[self.action().get()] - method=[method] - accept-charset=[self.charset().get()] - { - div { (self.elements().render(cx)) } - } - }) - } -} - -impl Form { - // Form BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_action(&mut self, action: &str) -> &mut Self { - self.action.set_value(action); - self - } - - #[fn_builder] - pub fn set_charset(&mut self, charset: &str) -> &mut Self { - self.charset.set_value(charset); - self - } - - #[fn_builder] - pub fn set_method(&mut self, method: FormMethod) -> &mut Self { - self.method = method; - self - } - - #[fn_builder] - pub fn set_elements(&mut self, op: AnyOp) -> &mut Self { - self.mixed.set_value(op); - self - } - - #[rustfmt::skip] - pub fn add_element(mut self, element: impl ComponentTrait) -> Self { - self.mixed.set_value(AnyOp::Add(AnyComponent::with(element))); - self - } - - // Form GETTERS. - - pub fn action(&self) -> &OptionString { - &self.action - } - - pub fn charset(&self) -> &OptionString { - &self.charset - } - - pub fn method(&self) -> &FormMethod { - &self.method - } - - pub fn elements(&self) -> &MixedComponents { - &self.mixed - } -} diff --git a/src/base/component/form/hidden.rs b/src/base/component/form/hidden.rs deleted file mode 100644 index 66bfccb9..00000000 --- a/src/base/component/form/hidden.rs +++ /dev/null @@ -1,51 +0,0 @@ -use crate::prelude::*; - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Hidden { - name : OptionName, - value : OptionString, -} - -impl ComponentTrait for Hidden { - fn new() -> Self { - Hidden::default() - } - - fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup { - let id = self.name().get().map(|name| concat_string!("value-", name)); - PrepareMarkup::With(html! { - input type="hidden" id=[id] name=[self.name().get()] value=[self.value().get()] {} - }) - } -} - -impl Hidden { - pub fn set(name: &str, value: &str) -> Self { - Hidden::default().with_name(name).with_value(value) - } - - // Hidden BUILDER. - - #[fn_builder] - pub fn set_name(&mut self, name: &str) -> &mut Self { - self.name.set_value(name); - self - } - - #[fn_builder] - pub fn set_value(&mut self, value: &str) -> &mut Self { - self.value.set_value(value); - self - } - - // Hidden GETTERS. - - pub fn name(&self) -> &OptionName { - &self.name - } - - pub fn value(&self) -> &OptionString { - &self.value - } -} diff --git a/src/base/component/form/input.rs b/src/base/component/form/input.rs deleted file mode 100644 index a59d77c8..00000000 --- a/src/base/component/form/input.rs +++ /dev/null @@ -1,283 +0,0 @@ -use crate::prelude::*; - -#[derive(AutoDefault)] -pub enum InputType { - #[default] - Textfield, - Password, - Search, - Email, - Telephone, - Url, -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Input { - classes : OptionClasses, - input_type : InputType, - name : OptionName, - value : OptionString, - label : OptionTranslated, - size : Option, - minlength : Option, - maxlength : Option, - placeholder : OptionString, - autofocus : OptionString, - autocomplete: OptionString, - disabled : OptionString, - readonly : OptionString, - required : OptionString, - help_text : OptionTranslated, -} - -impl ComponentTrait for Input { - fn new() -> Self { - Input::default() - .with_classes(ClassesOp::Add, "form-item form-type-textfield") - .with_size(Some(60)) - .with_maxlength(Some(128)) - } - - #[rustfmt::skip] - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let type_input = match self.input_type() { - InputType::Textfield => "text", - InputType::Password => "password", - InputType::Search => "search", - InputType::Email => "email", - InputType::Telephone => "tel", - InputType::Url => "url", - }; - let id = self.name().get().map(|name| concat_string!("edit-", name)); - PrepareMarkup::With(html! { - div class=[self.classes().get()] { - @if let Some(label) = self.label().using(cx.langid()) { - label class="form-label" for=[&id] { - (label) " " - @if self.required().get().is_some() { - span - class="form-required" - title="Este campo es obligatorio." { "*" } " " - } - } - } - input - type=(type_input) - id=[id] - class="form-control" - name=[self.name().get()] - value=[self.value().get()] - size=[self.size()] - minlength=[self.minlength()] - maxlength=[self.maxlength()] - placeholder=[self.placeholder().get()] - autofocus=[self.autofocus().get()] - autocomplete=[self.autocomplete().get()] - readonly=[self.readonly().get()] - required=[self.required().get()] - disabled=[self.disabled().get()] {} - @if let Some(description) = self.help_text().using(cx.langid()) { - div class="form-text" { (description) } - } - } - }) - } -} - -impl Input { - pub fn textfield() -> Self { - Input::default() - } - - pub fn password() -> Self { - let mut input = Input::default().with_classes( - ClassesOp::Replace("form-type-textfield".to_owned()), - "form-type-password", - ); - input.input_type = InputType::Password; - input - } - - pub fn search() -> Self { - let mut input = Input::default().with_classes( - ClassesOp::Replace("form-type-textfield".to_owned()), - "form-type-search", - ); - input.input_type = InputType::Search; - input - } - - pub fn email() -> Self { - let mut input = Input::default().with_classes( - ClassesOp::Replace("form-type-textfield".to_owned()), - "form-type-email", - ); - input.input_type = InputType::Email; - input - } - - pub fn telephone() -> Self { - let mut input = Input::default().with_classes( - ClassesOp::Replace("form-type-textfield".to_owned()), - "form-type-telephone", - ); - input.input_type = InputType::Telephone; - input - } - - pub fn url() -> Self { - let mut input = Input::default().with_classes( - ClassesOp::Replace("form-type-textfield".to_owned()), - "form-type-url", - ); - input.input_type = InputType::Url; - input - } - - // Input BUILDER. - - #[fn_builder] - pub fn set_name(&mut self, name: &str) -> &mut Self { - if let Some(previous) = self.name.get() { - self.set_classes(ClassesOp::Remove, concat_string!("form-item-", previous)); - } - self.set_classes(ClassesOp::Add, concat_string!("form-item-", name)); - self.name.set_value(name); - self - } - - #[fn_builder] - pub fn set_value(&mut self, value: &str) -> &mut Self { - self.value.set_value(value); - self - } - - #[fn_builder] - pub fn set_label(&mut self, label: L10n) -> &mut Self { - self.label.set_value(label); - self - } - - #[fn_builder] - pub fn set_size(&mut self, size: Option) -> &mut Self { - self.size = size; - self - } - - #[fn_builder] - pub fn set_minlength(&mut self, minlength: Option) -> &mut Self { - self.minlength = minlength; - self - } - - #[fn_builder] - pub fn set_maxlength(&mut self, maxlength: Option) -> &mut Self { - self.maxlength = maxlength; - self - } - - #[fn_builder] - pub fn set_placeholder(&mut self, placeholder: &str) -> &mut Self { - self.placeholder.set_value(placeholder); - self - } - - #[fn_builder] - pub fn set_autofocus(&mut self, toggle: bool) -> &mut Self { - self.autofocus - .set_value(if toggle { "autofocus" } else { "" }); - self - } - - #[fn_builder] - pub fn set_autocomplete(&mut self, toggle: bool) -> &mut Self { - self.autocomplete.set_value(if toggle { "" } else { "off" }); - self - } - - #[fn_builder] - pub fn set_disabled(&mut self, toggle: bool) -> &mut Self { - self.disabled - .set_value(if toggle { "disabled" } else { "" }); - self - } - - #[fn_builder] - pub fn set_readonly(&mut self, toggle: bool) -> &mut Self { - self.readonly - .set_value(if toggle { "readonly" } else { "" }); - self - } - - #[fn_builder] - pub fn set_required(&mut self, toggle: bool) -> &mut Self { - self.required - .set_value(if toggle { "required" } else { "" }); - self - } - - #[fn_builder] - pub fn set_help_text(&mut self, help_text: L10n) -> &mut Self { - self.help_text.set_value(help_text); - self - } - - // Input GETTERS. - - pub fn input_type(&self) -> &InputType { - &self.input_type - } - - pub fn name(&self) -> &OptionName { - &self.name - } - - pub fn value(&self) -> &OptionString { - &self.value - } - - pub fn label(&self) -> &OptionTranslated { - &self.label - } - - pub fn size(&self) -> Option { - self.size - } - - pub fn minlength(&self) -> Option { - self.minlength - } - - pub fn maxlength(&self) -> Option { - self.maxlength - } - - pub fn placeholder(&self) -> &OptionString { - &self.placeholder - } - - pub fn autofocus(&self) -> &OptionString { - &self.autofocus - } - - pub fn autocomplete(&self) -> &OptionString { - &self.autocomplete - } - - pub fn disabled(&self) -> &OptionString { - &self.disabled - } - - pub fn readonly(&self) -> &OptionString { - &self.readonly - } - - pub fn required(&self) -> &OptionString { - &self.required - } - - pub fn help_text(&self) -> &OptionTranslated { - &self.help_text - } -} diff --git a/src/base/component/heading.rs b/src/base/component/heading.rs deleted file mode 100644 index 7cb3b594..00000000 --- a/src/base/component/heading.rs +++ /dev/null @@ -1,157 +0,0 @@ -use crate::prelude::*; - -use std::fmt; - -#[derive(AutoDefault)] -pub enum HeadingType { - #[default] - H1, - H2, - H3, - H4, - H5, - H6, -} - -#[derive(AutoDefault)] -pub enum HeadingSize { - ExtraLarge, - XxLarge, - XLarge, - Large, - Medium, - #[default] - Normal, - Subtitle, -} - -#[rustfmt::skip] -impl fmt::Display for HeadingSize { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - HeadingSize::ExtraLarge => write!(f, "heading__title-x3l"), - HeadingSize::XxLarge => write!(f, "heading__title-x2l"), - HeadingSize::XLarge => write!(f, "heading__title-xl"), - HeadingSize::Large => write!(f, "heading__title-l"), - HeadingSize::Medium => write!(f, "heading__title-m"), - HeadingSize::Normal => write!(f, ""), - HeadingSize::Subtitle => write!(f, "heading__subtitle"), - } - } -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Heading { - id : OptionId, - classes : OptionClasses, - heading_type: HeadingType, - size : HeadingSize, - text : OptionTranslated, -} - -impl ComponentTrait for Heading { - fn new() -> Self { - Heading::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn setup_before_prepare(&mut self, _cx: &mut Context) { - self.set_classes(ClassesOp::Add, self.size().to_string()); - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let id = self.id(); - let classes = self.classes().get(); - let text = self.text().escaped(cx.langid()); - PrepareMarkup::With(html! { @match &self.heading_type() { - HeadingType::H1 => h1 id=[id] class=[classes] { (text) }, - HeadingType::H2 => h2 id=[id] class=[classes] { (text) }, - HeadingType::H3 => h3 id=[id] class=[classes] { (text) }, - HeadingType::H4 => h4 id=[id] class=[classes] { (text) }, - HeadingType::H5 => h5 id=[id] class=[classes] { (text) }, - HeadingType::H6 => h6 id=[id] class=[classes] { (text) }, - }}) - } -} - -impl Heading { - pub fn h1(text: L10n) -> Self { - Heading::default() - .with_heading_type(HeadingType::H1) - .with_text(text) - } - - pub fn h2(text: L10n) -> Self { - Heading::default() - .with_heading_type(HeadingType::H2) - .with_text(text) - } - - pub fn h3(text: L10n) -> Self { - Heading::default() - .with_heading_type(HeadingType::H3) - .with_text(text) - } - - pub fn h4(text: L10n) -> Self { - Heading::default() - .with_heading_type(HeadingType::H4) - .with_text(text) - } - - pub fn h5(text: L10n) -> Self { - Heading::default() - .with_heading_type(HeadingType::H5) - .with_text(text) - } - - pub fn h6(text: L10n) -> Self { - Heading::default() - .with_heading_type(HeadingType::H6) - .with_text(text) - } - - // Heading BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_heading_type(&mut self, heading_type: HeadingType) -> &mut Self { - self.heading_type = heading_type; - self - } - - #[fn_builder] - pub fn set_size(&mut self, size: HeadingSize) -> &mut Self { - self.size = size; - self - } - - #[fn_builder] - pub fn set_text(&mut self, text: L10n) -> &mut Self { - self.text.set_value(text); - self - } - - // Paragraph GETTERS. - - pub fn heading_type(&self) -> &HeadingType { - &self.heading_type - } - - pub fn size(&self) -> &HeadingSize { - &self.size - } - - pub fn text(&self) -> &OptionTranslated { - &self.text - } -} diff --git a/src/base/component/icon.rs b/src/base/component/icon.rs deleted file mode 100644 index 7e0a6a1e..00000000 --- a/src/base/component/icon.rs +++ /dev/null @@ -1,62 +0,0 @@ -use crate::prelude::*; - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Icon { - classes : OptionClasses, - icon_name: OptionString, - font_size: FontSize, -} - -impl ComponentTrait for Icon { - fn new() -> Self { - Icon::default() - } - - #[rustfmt::skip] - fn setup_before_prepare(&mut self, cx: &mut Context) { - if let Some(icon_name) = self.icon_name().get() { - self.set_classes(ClassesOp::Prepend, - concat_string!("bi-", icon_name, " ", self.font_size().to_string()), - ); - cx.set_param::(PARAM_BASE_INCLUDE_ICONS, &true); - } - } - - fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup { - match self.icon_name().get() { - None => PrepareMarkup::None, - _ => PrepareMarkup::With(html! { i class=[self.classes().get()] {} }), - } - } -} - -impl Icon { - pub fn with(icon_name: impl Into) -> Self { - Icon::default().with_icon_name(icon_name) - } - - // Icon BUILDER. - - #[fn_builder] - pub fn set_icon_name(&mut self, name: impl Into) -> &mut Self { - self.icon_name.set_value(name); - self - } - - #[fn_builder] - pub fn set_font_size(&mut self, font_size: FontSize) -> &mut Self { - self.font_size = font_size; - self - } - - // Icon GETTERS. - - pub fn icon_name(&self) -> &OptionString { - &self.icon_name - } - - pub fn font_size(&self) -> &FontSize { - &self.font_size - } -} diff --git a/src/base/component/image.rs b/src/base/component/image.rs deleted file mode 100644 index dcf2c625..00000000 --- a/src/base/component/image.rs +++ /dev/null @@ -1,102 +0,0 @@ -use crate::prelude::*; - -const IMG_FLUID: &str = "img__fluid"; -const IMG_FIXED: &str = "img__fixed"; - -#[derive(AutoDefault)] -pub enum ImageSize { - #[default] - Auto, - Size(u16, u16), - Width(u16), - Height(u16), - Both(u16), -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Image { - id : OptionId, - classes: OptionClasses, - source : OptionString, - size : ImageSize, -} - -impl ComponentTrait for Image { - fn new() -> Self { - Image::default().with_classes(ClassesOp::Add, IMG_FLUID) - } - - fn id(&self) -> Option { - self.id.get() - } - - fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup { - let (width, height) = match self.size() { - ImageSize::Auto => (None, None), - ImageSize::Size(width, height) => (Some(width), Some(height)), - ImageSize::Width(width) => (Some(width), None), - ImageSize::Height(height) => (None, Some(height)), - ImageSize::Both(value) => (Some(value), Some(value)), - }; - PrepareMarkup::With(html! { - img - src=[self.source().get()] - id=[self.id()] - class=[self.classes().get()] - width=[width] - height=[height] {} - }) - } -} - -impl Image { - pub fn with(source: &str) -> Self { - Image::default() - .with_source(source) - .with_classes(ClassesOp::Add, IMG_FLUID) - } - - pub fn fixed(source: &str) -> Self { - Image::default() - .with_source(source) - .with_classes(ClassesOp::Add, IMG_FIXED) - } - - pub fn pagetop() -> Self { - Image::default() - .with_source("/base/pagetop-logo.svg") - .with_classes(ClassesOp::Add, IMG_FIXED) - .with_size(ImageSize::Size(64, 64)) - } - - // Image BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_source(&mut self, source: &str) -> &mut Self { - self.source.set_value(source); - self - } - - #[fn_builder] - pub fn set_size(&mut self, size: ImageSize) -> &mut Self { - self.size = size; - self - } - - // Image GETTERS. - - pub fn source(&self) -> &OptionString { - &self.source - } - - pub fn size(&self) -> &ImageSize { - &self.size - } -} diff --git a/src/base/component/menu.rs b/src/base/component/menu.rs deleted file mode 100644 index 34ab59fe..00000000 --- a/src/base/component/menu.rs +++ /dev/null @@ -1,17 +0,0 @@ -mod menu_main; -pub use menu_main::Menu; - -mod item; -pub use item::{Item, ItemType}; - -mod submenu; -pub use submenu::Submenu; - -mod megamenu; -pub use megamenu::Megamenu; - -mod group; -pub use group::Group; - -mod element; -pub use element::{Element, ElementType}; diff --git a/src/base/component/menu/element.rs b/src/base/component/menu/element.rs deleted file mode 100644 index 5c39f7ea..00000000 --- a/src/base/component/menu/element.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::prelude::*; - -use super::Submenu; - -type Content = TypedComponent; -type SubmenuItems = TypedComponent; - -#[derive(AutoDefault)] -pub enum ElementType { - #[default] - Void, - Html(Content), - Submenu(SubmenuItems), -} - -// Element. - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Element { - element_type: ElementType, -} - -impl ComponentTrait for Element { - fn new() -> Self { - Element::default() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - match self.element_type() { - ElementType::Void => PrepareMarkup::None, - ElementType::Html(content) => PrepareMarkup::With(html! { - (content.render(cx)) - }), - ElementType::Submenu(submenu) => PrepareMarkup::With(html! { - (submenu.render(cx)) - }), - } - } -} - -impl Element { - pub fn html(content: Html) -> Self { - Element { - element_type: ElementType::Html(Content::with(content)), - } - } - - pub fn submenu(submenu: Submenu) -> Self { - Element { - element_type: ElementType::Submenu(SubmenuItems::with(submenu)), - } - } - - // Element GETTERS. - - pub fn element_type(&self) -> &ElementType { - &self.element_type - } -} diff --git a/src/base/component/menu/group.rs b/src/base/component/menu/group.rs deleted file mode 100644 index d3b8a33d..00000000 --- a/src/base/component/menu/group.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::prelude::*; - -use super::Element; - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Group { - id : OptionId, - elements: MixedComponents, -} - -impl ComponentTrait for Group { - fn new() -> Self { - Group::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::With(html! { - div id=[self.id()] class="menu-group" { - (self.elements().render(cx)) - } - }) - } -} - -impl Group { - // Group BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_elements(&mut self, op: TypedOp) -> &mut Self { - self.elements.set_typed(op); - self - } - - #[rustfmt::skip] - pub fn add_element(mut self, element: Element) -> Self { - self.elements.set_value(AnyOp::Add(AnyComponent::with(element))); - self - } - - // Group GETTERS. - - pub fn elements(&self) -> &MixedComponents { - &self.elements - } -} diff --git a/src/base/component/menu/item.rs b/src/base/component/menu/item.rs deleted file mode 100644 index e59899b0..00000000 --- a/src/base/component/menu/item.rs +++ /dev/null @@ -1,184 +0,0 @@ -use crate::prelude::*; - -use super::{Megamenu, Submenu}; - -type Label = L10n; -type Content = TypedComponent; -type SubmenuItems = TypedComponent; -type MegamenuGroups = TypedComponent; - -#[derive(AutoDefault)] -pub enum ItemType { - #[default] - Void, - Label(Label), - Link(Label, FnContextualPath), - LinkBlank(Label, FnContextualPath), - Html(Content), - Submenu(Label, SubmenuItems), - Megamenu(Label, MegamenuGroups), -} - -// Item. - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Item { - item_type : ItemType, - description: OptionTranslated, - left_icon : OptionComponent, - right_icon : OptionComponent, -} - -impl ComponentTrait for Item { - fn new() -> Self { - Item::default() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let description = self.description.using(cx.langid()); - - let left_icon = self.left_icon().render(cx); - let right_icon = self.right_icon().render(cx); - - match self.item_type() { - ItemType::Void => PrepareMarkup::None, - ItemType::Label(label) => PrepareMarkup::With(html! { - li class="menu__label" { - span title=[description] { - (left_icon) - (label.escaped(cx.langid())) - (right_icon) - } - } - }), - ItemType::Link(label, path) => PrepareMarkup::With(html! { - li class="menu__link" { - a href=(path(cx)) title=[description] { - (left_icon) - (label.escaped(cx.langid())) - (right_icon) - } - } - }), - ItemType::LinkBlank(label, path) => PrepareMarkup::With(html! { - li class="menu__link" { - a href=(path(cx)) title=[description] target="_blank" { - (left_icon) - (label.escaped(cx.langid())) - (right_icon) - } - } - }), - ItemType::Html(content) => PrepareMarkup::With(html! { - li class="menu__html" { - (content.render(cx)) - } - }), - ItemType::Submenu(label, submenu) => PrepareMarkup::With(html! { - li class="menu__children" { - a href="#" title=[description] { - (left_icon) - (label.escaped(cx.langid())) i class="menu__icon bi-chevron-down" {} - } - div class="menu__subs" { - (submenu.render(cx)) - } - } - }), - ItemType::Megamenu(label, megamenu) => PrepareMarkup::With(html! { - li class="menu__children" { - a href="#" title=[description] { - (left_icon) - (label.escaped(cx.langid())) i class="menu__icon bi-chevron-down" {} - } - div class="menu__subs menu__mega" { - (megamenu.render(cx)) - } - } - }), - } - } -} - -impl Item { - pub fn label(label: L10n) -> Self { - Item { - item_type: ItemType::Label(label), - ..Default::default() - } - } - - pub fn link(label: L10n, path: FnContextualPath) -> Self { - Item { - item_type: ItemType::Link(label, path), - ..Default::default() - } - } - - pub fn link_blank(label: L10n, path: FnContextualPath) -> Self { - Item { - item_type: ItemType::LinkBlank(label, path), - ..Default::default() - } - } - - pub fn html(content: Html) -> Self { - Item { - item_type: ItemType::Html(Content::with(content)), - ..Default::default() - } - } - - pub fn submenu(label: L10n, submenu: Submenu) -> Self { - Item { - item_type: ItemType::Submenu(label, SubmenuItems::with(submenu)), - ..Default::default() - } - } - - pub fn megamenu(label: L10n, megamenu: Megamenu) -> Self { - Item { - item_type: ItemType::Megamenu(label, MegamenuGroups::with(megamenu)), - ..Default::default() - } - } - - // Item BUILDER. - - #[fn_builder] - pub fn set_description(&mut self, text: L10n) -> &mut Self { - self.description.set_value(text); - self - } - - #[fn_builder] - pub fn set_left_icon(&mut self, icon: Option) -> &mut Self { - self.left_icon.set_value(icon); - self - } - - #[fn_builder] - pub fn set_right_icon(&mut self, icon: Option) -> &mut Self { - self.right_icon.set_value(icon); - self - } - - // Item GETTERS. - - pub fn item_type(&self) -> &ItemType { - &self.item_type - } - - pub fn description(&self) -> &OptionTranslated { - &self.description - } - - pub fn left_icon(&self) -> &OptionComponent { - &self.left_icon - } - - pub fn right_icon(&self) -> &OptionComponent { - &self.right_icon - } -} diff --git a/src/base/component/menu/megamenu.rs b/src/base/component/menu/megamenu.rs deleted file mode 100644 index 5a21ddd5..00000000 --- a/src/base/component/menu/megamenu.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::prelude::*; - -use super::Group; - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Megamenu { - id : OptionId, - groups: MixedComponents, -} - -impl ComponentTrait for Megamenu { - fn new() -> Self { - Megamenu::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::With(html! { - div id=[self.id()] class="menu__groups" { - (self.groups().render(cx)) - } - }) - } -} - -impl Megamenu { - // Megamenu BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_groups(&mut self, op: TypedOp) -> &mut Self { - self.groups.set_typed(op); - self - } - - #[rustfmt::skip] - pub fn add_group(mut self, group: Group) -> Self { - self.groups.set_value(AnyOp::Add(AnyComponent::with(group))); - self - } - - // Megamenu GETTERS. - - pub fn groups(&self) -> &MixedComponents { - &self.groups - } -} diff --git a/src/base/component/menu/menu_main.rs b/src/base/component/menu/menu_main.rs deleted file mode 100644 index 94d51d8d..00000000 --- a/src/base/component/menu/menu_main.rs +++ /dev/null @@ -1,84 +0,0 @@ -use crate::prelude::*; - -use super::Item; - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Menu { - id : OptionId, - items: MixedComponents, -} - -impl ComponentTrait for Menu { - fn new() -> Self { - Menu::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - cx.set_param::(PARAM_BASE_INCLUDE_MENU_ASSETS, &true); - cx.set_param::(PARAM_BASE_INCLUDE_ICONS, &true); - - PrepareMarkup::With(html! { - div id=[self.id()] class="menu__container" { - div class="menu__content" { - div class="menu__main" { - div class="menu__overlay" {} - nav class="menu__nav" { - div class="menu__header" { - button type="button" class="menu__arrow" { - i class="bi-chevron-left" {} - } - div class="menu__title" {} - button type="button" class="menu__close" { - i class="bi-x" {} - } - } - ul class="menu__section" { - (self.items().render(cx)) - } - } - } - button - type="button" - class="menu__trigger" - title=[L10n::l("menu_toggle").using(cx.langid())] - { - span {} span {} span {} - } - } - } - }) - } -} - -impl Menu { - // Menu BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_items(&mut self, op: TypedOp) -> &mut Self { - self.items.set_typed(op); - self - } - - #[rustfmt::skip] - pub fn add_item(mut self, item: Item) -> Self { - self.items.set_value(AnyOp::Add(AnyComponent::with(item))); - self - } - - // Menu GETTERS. - - pub fn items(&self) -> &MixedComponents { - &self.items - } -} diff --git a/src/base/component/menu/submenu.rs b/src/base/component/menu/submenu.rs deleted file mode 100644 index 4e5e91df..00000000 --- a/src/base/component/menu/submenu.rs +++ /dev/null @@ -1,72 +0,0 @@ -use crate::prelude::*; - -use super::Item; - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Submenu { - id : OptionId, - title: OptionTranslated, - items: MixedComponents, -} - -impl ComponentTrait for Submenu { - fn new() -> Self { - Submenu::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::With(html! { - div id=[self.id()] class="menu__items" { - @if let Some(title) = self.title().using(cx.langid()) { - h4 class="menu__title" { (title) } - } - ul { - (self.items().render(cx)) - } - } - }) - } -} - -impl Submenu { - // Submenu BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_title(&mut self, title: L10n) -> &mut Self { - self.title.set_value(title); - self - } - - #[fn_builder] - pub fn set_items(&mut self, op: TypedOp) -> &mut Self { - self.items.set_typed(op); - self - } - - #[rustfmt::skip] - pub fn add_item(mut self, item: Item) -> Self { - self.items.set_value(AnyOp::Add(AnyComponent::with(item))); - self - } - - // Submenu GETTERS. - - pub fn title(&self) -> &OptionTranslated { - &self.title - } - - pub fn items(&self) -> &MixedComponents { - &self.items - } -} diff --git a/src/base/component/paragraph.rs b/src/base/component/paragraph.rs deleted file mode 100644 index 9beeefa8..00000000 --- a/src/base/component/paragraph.rs +++ /dev/null @@ -1,81 +0,0 @@ -use crate::prelude::*; - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Paragraph { - id : OptionId, - classes : OptionClasses, - font_size: FontSize, - mixed : MixedComponents, -} - -impl ComponentTrait for Paragraph { - fn new() -> Self { - Paragraph::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn setup_before_prepare(&mut self, _cx: &mut Context) { - self.set_classes(ClassesOp::Prepend, self.font_size().to_string()); - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::With(html! { - p - id=[self.id()] - class=[self.classes().get()] - { - (self.components().render(cx)) - } - }) - } -} - -impl Paragraph { - pub fn with(component: impl ComponentTrait) -> Self { - Paragraph::default().add_component(component) - } - - pub fn fluent(l10n: L10n) -> Self { - Paragraph::default().add_component(Fluent::with(l10n)) - } - - // Paragraph BUILDER. - - #[fn_builder] - pub fn set_id(&mut self, id: impl Into) -> &mut Self { - self.id.set_value(id); - self - } - - #[fn_builder] - pub fn set_font_size(&mut self, font_size: FontSize) -> &mut Self { - self.font_size = font_size; - self - } - - #[fn_builder] - pub fn set_components(&mut self, op: AnyOp) -> &mut Self { - self.mixed.set_value(op); - self - } - - #[rustfmt::skip] - pub fn add_component(mut self, component: impl ComponentTrait) -> Self { - self.mixed.set_value(AnyOp::Add(AnyComponent::with(component))); - self - } - - // Paragraph GETTERS. - - pub fn font_size(&self) -> &FontSize { - &self.font_size - } - - pub fn components(&self) -> &MixedComponents { - &self.mixed - } -} diff --git a/src/base/component/powered_by.rs b/src/base/component/powered_by.rs deleted file mode 100644 index 62c7b76b..00000000 --- a/src/base/component/powered_by.rs +++ /dev/null @@ -1,108 +0,0 @@ -use crate::prelude::*; - -use std::convert::Into; - -#[derive(Default, Eq, PartialEq)] -pub enum PoweredByLogo { - #[default] - None, - Color, - LineDark, - LineLight, - LineRGB(u8, u8, u8), -} - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct PoweredBy { - copyright: Option, - logo : PoweredByLogo, -} - -impl ComponentTrait for PoweredBy { - fn new() -> Self { - let year = Utc::now().format("%Y").to_string(); - let c = concat_string!(year, " © ", global::SETTINGS.app.name); - PoweredBy { - copyright: Some(c), - ..Default::default() - } - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let poweredby_pagetop = L10n::l("poweredby_pagetop") - .with_arg( - "pagetop_link", - "PageTop", - ) - .escaped(cx.langid()); - - let pagetop_logo = match self.logo() { - PoweredByLogo::None => html! {}, - PoweredByLogo::Color => self.logo_color(cx), - PoweredByLogo::LineDark => self.logo_line(10, 11, 9, cx), - PoweredByLogo::LineLight => self.logo_line(255, 255, 255, cx), - PoweredByLogo::LineRGB(r, g, b) => self.logo_line(*r, *g, *b, cx), - }; - - PrepareMarkup::With(html! { - div id=[self.id()] class="poweredby__container" { - @if let Some(c) = self.copyright() { - span class="poweredby__copyright" { (c) "." } " " - } - span class="poweredby__pagetop" { (poweredby_pagetop) " " (pagetop_logo) } - } - }) - } -} - -impl PoweredBy { - // PoweredBy BUILDER. - - #[fn_builder] - pub fn set_copyright(&mut self, copyright: Option>) -> &mut Self { - self.copyright = copyright.map(Into::into); - self - } - - #[fn_builder] - pub fn set_logo(&mut self, logo: PoweredByLogo) -> &mut Self { - self.logo = logo; - self - } - - // PoweredBy GETTERS. - - pub fn copyright(&self) -> &Option { - &self.copyright - } - - pub fn logo(&self) -> &PoweredByLogo { - &self.logo - } - - // PoweredBy PRIVATE. - - fn logo_color(&self, cx: &mut Context) -> Markup { - let logo_txt = &L10n::l("pagetop_logo").using(cx.langid()); - html! { - span class="poweredby__logo" aria-label=[logo_txt] { - img src="/base/pagetop-logo.svg" alt=[logo_txt] {} - } - } - } - - fn logo_line(&self, r: u8, g: u8, b: u8, cx: &mut Context) -> Markup { - let logo_txt = L10n::l("pagetop_logo").using(cx.langid()); - let logo_rgb = format!("rgb({r},{g},{b})"); - html! { - span class="poweredby__logo" aria-label=[logo_txt] { - svg viewBox="0 0 1614 1614" xmlns="http://www.w3.org/2000/svg" role="img" { - path fill=(logo_rgb) d="M 1573,357 L 1415,357 C 1400,357 1388,369 1388,383 L 1388,410 1335,410 1335,357 C 1335,167 1181,13 992,13 L 621,13 C 432,13 278,167 278,357 L 278,410 225,410 225,383 C 225,369 213,357 198,357 L 40,357 C 25,357 13,369 13,383 L 13,648 C 13,662 25,674 40,674 L 198,674 C 213,674 225,662 225,648 L 225,621 278,621 278,1256 C 278,1446 432,1600 621,1600 L 992,1600 C 1181,1600 1335,1446 1335,1256 L 1335,621 1388,621 1388,648 C 1388,662 1400,674 1415,674 L 1573,674 C 1588,674 1600,662 1600,648 L 1600,383 C 1600,369 1588,357 1573,357 L 1573,357 1573,357 Z M 66,410 L 172,410 172,621 66,621 66,410 66,410 Z M 1282,357 L 1282,488 C 1247,485 1213,477 1181,464 L 1196,437 C 1203,425 1199,409 1186,401 1174,394 1158,398 1150,411 L 1133,440 C 1105,423 1079,401 1056,376 L 1075,361 C 1087,352 1089,335 1079,324 1070,313 1054,311 1042,320 L 1023,335 C 1000,301 981,263 967,221 L 1011,196 C 1023,189 1028,172 1021,160 1013,147 997,143 984,150 L 953,168 C 945,136 941,102 940,66 L 992,66 C 1152,66 1282,197 1282,357 L 1282,357 1282,357 Z M 621,66 L 674,66 674,225 648,225 C 633,225 621,237 621,251 621,266 633,278 648,278 L 674,278 674,357 648,357 C 633,357 621,369 621,383 621,398 633,410 648,410 L 674,410 674,489 648,489 C 633,489 621,501 621,516 621,530 633,542 648,542 L 664,542 C 651,582 626,623 600,662 583,653 563,648 542,648 469,648 410,707 410,780 410,787 411,794 412,801 388,805 361,806 331,806 L 331,357 C 331,197 461,66 621,66 L 621,66 621,66 Z M 621,780 C 621,824 586,859 542,859 498,859 463,824 463,780 463,736 498,701 542,701 586,701 621,736 621,780 L 621,780 621,780 Z M 225,463 L 278,463 278,569 225,569 225,463 225,463 Z M 992,1547 L 621,1547 C 461,1547 331,1416 331,1256 L 331,859 C 367,859 400,858 431,851 454,888 495,912 542,912 615,912 674,853 674,780 674,747 662,718 642,695 675,645 706,594 720,542 L 780,542 C 795,542 807,530 807,516 807,501 795,489 780,489 L 727,489 727,410 780,410 C 795,410 807,398 807,383 807,369 795,357 780,357 L 727,357 727,278 780,278 C 795,278 807,266 807,251 807,237 795,225 780,225 L 727,225 727,66 887,66 C 889,111 895,155 905,196 L 869,217 C 856,224 852,240 859,253 864,261 873,266 882,266 887,266 891,265 895,263 L 921,248 C 937,291 958,331 983,367 L 938,403 C 926,412 925,429 934,440 939,447 947,450 954,450 960,450 966,448 971,444 L 1016,408 C 1043,438 1074,465 1108,485 L 1084,527 C 1076,539 1081,555 1093,563 1098,565 1102,566 1107,566 1116,566 1125,561 1129,553 L 1155,509 C 1194,527 1237,538 1282,541 L 1282,1256 C 1282,1416 1152,1547 992,1547 L 992,1547 992,1547 Z M 1335,463 L 1388,463 1388,569 1335,569 1335,463 1335,463 Z M 1441,410 L 1547,410 1547,621 1441,621 1441,410 1441,410 Z" {} - path fill=(logo_rgb) d="M 1150,1018 L 463,1018 C 448,1018 436,1030 436,1044 L 436,1177 C 436,1348 545,1468 701,1468 L 912,1468 C 1068,1468 1177,1348 1177,1177 L 1177,1044 C 1177,1030 1165,1018 1150,1018 L 1150,1018 1150,1018 Z M 912,1071 L 1018,1071 1018,1124 912,1124 912,1071 912,1071 Z M 489,1071 L 542,1071 542,1124 489,1124 489,1071 489,1071 Z M 701,1415 L 700,1415 C 701,1385 704,1352 718,1343 731,1335 759,1341 795,1359 802,1363 811,1363 818,1359 854,1341 882,1335 895,1343 909,1352 912,1385 913,1415 L 912,1415 701,1415 701,1415 701,1415 Z M 1124,1177 C 1124,1296 1061,1384 966,1408 964,1365 958,1320 922,1298 894,1281 856,1283 807,1306 757,1283 719,1281 691,1298 655,1320 649,1365 647,1408 552,1384 489,1296 489,1177 L 569,1177 C 583,1177 595,1165 595,1150 L 595,1071 859,1071 859,1150 C 859,1165 871,1177 886,1177 L 1044,1177 C 1059,1177 1071,1165 1071,1150 L 1071,1071 1124,1071 1124,1177 1124,1177 1124,1177 Z" {} - path fill=(logo_rgb) d="M 1071,648 C 998,648 939,707 939,780 939,853 998,912 1071,912 1144,912 1203,853 1203,780 1203,707 1144,648 1071,648 L 1071,648 1071,648 Z M 1071,859 C 1027,859 992,824 992,780 992,736 1027,701 1071,701 1115,701 1150,736 1150,780 1150,824 1115,859 1071,859 L 1071,859 1071,859 Z" {} - } - } - } - } -} diff --git a/src/base/package.rs b/src/base/package.rs deleted file mode 100644 index 1b0fa82b..00000000 --- a/src/base/package.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod welcome; -pub use welcome::Welcome; diff --git a/src/base/package/welcome.rs b/src/base/package/welcome.rs deleted file mode 100644 index 99a15e90..00000000 --- a/src/base/package/welcome.rs +++ /dev/null @@ -1,240 +0,0 @@ -use crate::prelude::*; - -pub struct Welcome; - -impl PackageTrait for Welcome { - fn name(&self) -> L10n { - L10n::l("welcome_package_name") - } - - fn description(&self) -> L10n { - L10n::l("welcome_package_description") - } - - fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { - scfg.route("/", service::web::get().to(home_page)) - .route("/{lang}", service::web::get().to(home_lang)); - } -} - -async fn home_page(request: HttpRequest) -> ResultPage { - home(request, &LANGID_DEFAULT) -} - -async fn home_lang( - request: HttpRequest, - path: service::web::Path, -) -> ResultPage { - match langid_for(path.into_inner()) { - Ok(lang) => home(request, lang), - _ => Err(ErrorPage::NotFound(request)), - } -} - -fn home(request: HttpRequest, lang: &'static LanguageIdentifier) -> ResultPage { - Page::new(request) - .with_title(L10n::l("welcome_title")) - .with_assets(AssetsOp::LangId(lang)) - .with_assets(AssetsOp::AddStyleSheet(StyleSheet::from( - "/base/css/welcome.css", - ))) - .with_body_id("welcome") - .with_component(hello_world()) - .with_component(welcome()) - .with_component(about_pagetop()) - .with_component(promo_pagetop()) - .with_component(reporting_issues()) - .render() -} - -fn hello_world() -> flex::Container { - flex::Container::header() - .with_classes(ClassesOp::Add, "hello-world") - .with_justify(flex::Justify::Center) - .add_item( - flex::Item::new() - .with_size(flex::Size::Percent90) - .add_component( - flex::Container::new() - .with_direction(flex::Direction::Column(BreakPoint::MD)) - .add_item( - flex::Item::new() - .with_classes(ClassesOp::Add, "hello-col-text") - .with_size(flex::Size::Percent40) - .add_component( - Heading::h1(L10n::l("welcome_title")) - .with_size(HeadingSize::Medium), - ) - .add_component( - Paragraph::fluent(L10n::l("welcome_intro").with_arg( - "app", - format!( - "{}", - &global::SETTINGS.app.name, - ), - )) - .with_font_size(FontSize::Medium), - ) - .add_component(Paragraph::fluent( - L10n::l("welcome_powered").with_arg( - "pagetop", - format!( - "{}", - "https://pagetop.cillero.es", "PageTop", - ), - ), - )) - .add_component( - Button::anchor( - "https://github.com/manuelcillero/pagetop", - L10n::l("welcome_code"), - ) - .with_target(ButtonTarget::Blank) - .with_left_icon(Some(Icon::with("git"))) - .with_classes(ClassesOp::Add, "code-link") - .with_font_size(FontSize::Medium), - ) - .add_component( - Button::anchor("#welcome-page", L10n::l("welcome")) - .with_style(StyleBase::Link) - .with_left_icon(Some(Icon::with("arrow-down-circle-fill"))) - .with_classes(ClassesOp::Add, "welcome-link") - .with_font_size(FontSize::Medium), - ), - ) - .add_item( - flex::Item::with(Image::with("/base/images/header.svg")) - .with_classes(ClassesOp::Add, "hello-col-image") - .with_size(flex::Size::Percent60), - ), - ), - ) -} - -fn welcome() -> flex::Container { - flex::Container::section() - .with_id("welcome-page") - .with_classes(ClassesOp::Add, "welcome") - .with_justify(flex::Justify::Center) - .add_item( - flex::Item::new() - .with_size(flex::Size::Percent80) - .add_component(Heading::h2(L10n::l("welcome_page"))) - .add_component( - Heading::h3(L10n::l("welcome_subtitle").with_arg( - "app", - format!( - "{}", - &global::SETTINGS.app.name - ), - )) - .with_size(HeadingSize::Subtitle), - ) - .add_component( - Paragraph::fluent(L10n::l("welcome_text1")).with_font_size(FontSize::Medium), - ) - .add_component(Paragraph::fluent(L10n::l("welcome_text2"))), - ) -} - -fn about_pagetop() -> flex::Container { - flex::Container::new() - .with_classes(ClassesOp::Add, "pagetop") - .with_justify(flex::Justify::Center) - .add_item( - flex::Item::new() - .with_size(flex::Size::Percent90) - .add_component( - flex::Container::new() - .with_direction(flex::Direction::Column(BreakPoint::SM)) - .add_item( - flex::Item::with(Image::with("/base/images/about.svg")) - .with_classes(ClassesOp::Add, "pagetop-col-image") - .with_size(flex::Size::Percent40), - ) - .add_item( - flex::Item::new() - .with_classes(ClassesOp::Add, "pagetop-col-text") - .add_component(Heading::h2(L10n::l("welcome_pagetop_title"))) - .add_component( - Paragraph::fluent(L10n::l("welcome_pagetop_text1")) - .with_font_size(FontSize::Medium), - ) - .add_component(Paragraph::fluent(L10n::l("welcome_pagetop_text2"))) - .add_component(Paragraph::fluent(L10n::l("welcome_pagetop_text3"))), - ), - ), - ) -} - -fn promo_pagetop() -> flex::Container { - flex::Container::new() - .with_classes(ClassesOp::Add, "promo") - .with_justify(flex::Justify::Center) - .add_item( - flex::Item::new() - .with_size(flex::Size::Percent75) - .add_component( - flex::Container::new() - .with_direction(flex::Direction::Column(BreakPoint::MD)) - .add_item( - flex::Item::new() - .with_classes(ClassesOp::Add, "promo-col-text") - .with_size(flex::Size::Percent50) - .add_component(Heading::h2(L10n::l("welcome_promo_title"))) - .add_component( - Paragraph::fluent(L10n::l("welcome_promo_text1").with_arg( - "pagetop", - format!( - "{}", - "https://crates.io/crates/pagetop", "PageTop", - ), - )) - .with_font_size(FontSize::Medium), - ), - ) - .add_item( - flex::Item::with(Image::with("/base/images/pagetop.png")) - .with_classes(ClassesOp::Add, "promo-col-image") - .with_size(flex::Size::Percent50), - ), - ), - ) -} - -fn reporting_issues() -> flex::Container { - flex::Container::new() - .with_classes(ClassesOp::Add, "issues") - .with_justify(flex::Justify::Center) - .add_item( - flex::Item::new() - .with_size(flex::Size::Percent90) - .add_component( - flex::Container::new() - .with_direction(flex::Direction::Column(BreakPoint::MD)) - .add_item( - flex::Item::with(Image::with("/base/images/issues.jpg")) - .with_classes(ClassesOp::Add, "issues-col-image"), - ) - .add_item( - flex::Item::new() - .with_classes(ClassesOp::Add, "issues-col-text") - .with_size(flex::Size::Percent50) - .add_component(Heading::h2(L10n::l("welcome_issues_title"))) - .add_component( - Paragraph::fluent(L10n::l("welcome_issues_text1")) - .with_font_size(FontSize::Medium), - ) - .add_component(Paragraph::fluent( - L10n::l("welcome_issues_text2").with_arg( - "app", - format!( - "{}", - &global::SETTINGS.app.name, - ), - ), - )), - ), - ), - ) -} diff --git a/src/base/theme.rs b/src/base/theme.rs deleted file mode 100644 index 7b9b442f..00000000 --- a/src/base/theme.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod basic; -pub use basic::Basic; - -mod chassis; -pub use chassis::Chassis; - -mod inception; -pub use inception::Inception; diff --git a/src/base/theme/basic.rs b/src/base/theme/basic.rs deleted file mode 100644 index af66ffaf..00000000 --- a/src/base/theme/basic.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::prelude::*; - -pub struct Basic; - -impl PackageTrait for Basic { - fn name(&self) -> L10n { - L10n::n("Basic") - } - - fn theme(&self) -> Option { - Some(&Basic) - } -} - -impl ThemeTrait for Basic { - fn after_prepare_body(&self, page: &mut Page) { - page.set_assets(AssetsOp::SetFavicon(Some( - Favicon::new().with_icon("/base/favicon.ico"), - ))) - .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/normalize.min.css") - .with_version("8.0.1") - .with_weight(-90), - )) - .set_assets(AssetsOp::AddBaseAssets) - .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/basic.css") - .with_version("0.0.1") - .with_weight(-90), - )); - } -} diff --git a/src/base/theme/chassis.rs b/src/base/theme/chassis.rs deleted file mode 100644 index 2776154e..00000000 --- a/src/base/theme/chassis.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::prelude::*; - -pub struct Chassis; - -impl PackageTrait for Chassis { - fn name(&self) -> L10n { - L10n::n("Chassis") - } - - fn theme(&self) -> Option { - Some(&Chassis) - } -} - -impl ThemeTrait for Chassis { - fn after_prepare_body(&self, page: &mut Page) { - page.set_assets(AssetsOp::SetFavicon(Some( - Favicon::new().with_icon("/base/favicon.ico"), - ))) - .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/normalize.min.css") - .with_version("8.0.1") - .with_weight(-90), - )) - .set_assets(AssetsOp::AddBaseAssets) - .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/chassis.css") - .with_version("0.0.1") - .with_weight(-90), - )); - } -} diff --git a/src/base/theme/inception.rs b/src/base/theme/inception.rs deleted file mode 100644 index b786bcea..00000000 --- a/src/base/theme/inception.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::prelude::*; - -pub struct Inception; - -impl PackageTrait for Inception { - fn name(&self) -> L10n { - L10n::n("Inception") - } - - fn theme(&self) -> Option { - Some(&Inception) - } -} - -impl ThemeTrait for Inception { - fn after_prepare_body(&self, page: &mut Page) { - page.set_assets(AssetsOp::SetFavicon(Some( - Favicon::new().with_icon("/base/favicon.ico"), - ))) - .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/normalize.min.css") - .with_version("8.0.1") - .with_weight(-90), - )) - .set_assets(AssetsOp::AddBaseAssets) - .set_assets(AssetsOp::AddStyleSheet( - StyleSheet::from("/base/css/inception.css") - .with_version("0.0.1") - .with_weight(-90), - )); - } -} diff --git a/src/core/component.rs b/src/core/component.rs deleted file mode 100644 index af116771..00000000 --- a/src/core/component.rs +++ /dev/null @@ -1,14 +0,0 @@ -mod context; -pub use context::{AssetsOp, Context, ParamError}; -pub type FnContextualPath = fn(cx: &Context) -> &str; - -mod definition; -pub use definition::{ComponentBase, ComponentTrait}; - -mod classes; -pub use classes::{ComponentClasses, ComponentClassesOp}; - -mod mixed; -pub use mixed::MixedComponents; -pub use mixed::{AnyComponent, AnyOp}; -pub use mixed::{TypedComponent, TypedOp}; diff --git a/src/core/component/classes.rs b/src/core/component/classes.rs deleted file mode 100644 index a61809c6..00000000 --- a/src/core/component/classes.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::core::component::ComponentBase; -use crate::html::{ClassesOp, OptionClasses}; - -pub trait ComponentClassesOp { - fn with_classes(self, op: ClassesOp, classes: impl Into) -> Self; -} - -pub trait ComponentClasses: ComponentBase + ComponentClassesOp { - fn set_classes(&mut self, op: ClassesOp, classes: impl Into) -> &mut Self; - - fn classes(&self) -> &OptionClasses; -} - -impl ComponentClassesOp for C { - fn with_classes(mut self, op: ClassesOp, classes: impl Into) -> Self { - self.set_classes(op, classes); - self - } -} diff --git a/src/core/component/context.rs b/src/core/component/context.rs deleted file mode 100644 index 3fd80d5c..00000000 --- a/src/core/component/context.rs +++ /dev/null @@ -1,206 +0,0 @@ -use crate::base::component::add_base_assets; -use crate::concat_string; -use crate::core::component::AnyOp; -use crate::core::theme::all::{theme_by_short_name, THEME_DEFAULT}; -use crate::core::theme::{ComponentsInRegions, ThemeRef}; -use crate::global::TypeInfo; -use crate::html::{html, Markup}; -use crate::html::{Assets, Favicon, JavaScript, StyleSheet}; -use crate::locale::{LanguageIdentifier, LANGID_DEFAULT}; -use crate::service::HttpRequest; - -use std::collections::HashMap; -use std::error::Error; -use std::str::FromStr; - -use std::fmt; - -pub enum AssetsOp { - LangId(&'static LanguageIdentifier), - Theme(&'static str), - Layout(&'static str), - // Favicon. - SetFavicon(Option), - SetFaviconIfNone(Favicon), - // Stylesheets. - AddStyleSheet(StyleSheet), - RemoveStyleSheet(&'static str), - // JavaScripts. - AddJavaScript(JavaScript), - RemoveJavaScript(&'static str), - // Add assets to properly use base components. - AddBaseAssets, -} - -#[derive(Debug)] -pub enum ParamError { - NotFound, - ParseError(String), -} - -impl fmt::Display for ParamError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ParamError::NotFound => write!(f, "Parameter not found"), - ParamError::ParseError(e) => write!(f, "Parse error: {e}"), - } - } -} - -impl Error for ParamError {} - -#[rustfmt::skip] -pub struct Context { - request : HttpRequest, - langid : &'static LanguageIdentifier, - theme : ThemeRef, - layout : &'static str, - favicon : Option, - stylesheet: Assets, - javascript: Assets, - regions : ComponentsInRegions, - params : HashMap<&'static str, String>, - id_counter: usize, -} - -impl Context { - #[rustfmt::skip] - pub(crate) fn new(request: HttpRequest) -> Self { - Context { - request, - langid : &LANGID_DEFAULT, - theme : *THEME_DEFAULT, - layout : "default", - favicon : None, - stylesheet: Assets::::new(), - javascript: Assets::::new(), - regions : ComponentsInRegions::default(), - params : HashMap::<&str, String>::new(), - id_counter: 0, - } - } - - pub fn set_assets(&mut self, op: AssetsOp) -> &mut Self { - match op { - AssetsOp::LangId(langid) => { - self.langid = langid; - } - AssetsOp::Theme(theme_name) => { - self.theme = theme_by_short_name(theme_name).unwrap_or(*THEME_DEFAULT); - } - AssetsOp::Layout(layout) => { - self.layout = layout; - } - // Favicon. - AssetsOp::SetFavicon(favicon) => { - self.favicon = favicon; - } - AssetsOp::SetFaviconIfNone(icon) => { - if self.favicon.is_none() { - self.favicon = Some(icon); - } - } - // Stylesheets. - AssetsOp::AddStyleSheet(css) => { - self.stylesheet.add(css); - } - AssetsOp::RemoveStyleSheet(path) => { - self.stylesheet.remove(path); - } - // JavaScripts. - AssetsOp::AddJavaScript(js) => { - self.javascript.add(js); - } - AssetsOp::RemoveJavaScript(path) => { - self.javascript.remove(path); - } - // Add assets to properly use base components. - AssetsOp::AddBaseAssets => { - add_base_assets(self); - } - } - self - } - - pub fn set_regions(&mut self, region: &'static str, op: AnyOp) -> &mut Self { - self.regions.set_components(region, op); - self - } - - pub fn set_param(&mut self, key: &'static str, value: &T) -> &mut Self { - self.params.insert(key, value.to_string()); - self - } - - // Context GETTERS. - - pub fn request(&self) -> &HttpRequest { - &self.request - } - - pub fn langid(&self) -> &LanguageIdentifier { - self.langid - } - - pub fn theme(&self) -> ThemeRef { - self.theme - } - - pub fn layout(&self) -> &str { - self.layout - } - - pub fn regions(&self) -> &ComponentsInRegions { - &self.regions - } - - pub fn get_param(&self, key: &'static str) -> Result { - self.params - .get(key) - .ok_or(ParamError::NotFound) - .and_then(|v| T::from_str(v).map_err(|_| ParamError::ParseError(v.clone()))) - } - - // Context PREPARE. - - pub(crate) fn prepare_assets(&mut self) -> Markup { - html! { - @if let Some(favicon) = &self.favicon { - (favicon.prepare()) - } - (self.stylesheet.prepare()) - (self.javascript.prepare()) - } - } - - pub(crate) fn prepare_region(&mut self, region: impl Into) -> Markup { - self.regions - .all_components(self.theme, region.into().as_str()) - .render(self) - } - - // Context EXTRAS. - - pub fn remove_param(&mut self, key: &'static str) -> bool { - self.params.remove(key).is_some() - } - - pub fn required_id(&mut self, id: Option) -> String { - if let Some(id) = id { - id - } else { - let prefix = TypeInfo::ShortName - .of::() - .trim() - .replace(' ', "_") - .to_lowercase(); - let prefix = if prefix.is_empty() { - "prefix".to_owned() - } else { - prefix - }; - self.id_counter += 1; - concat_string!(prefix, "-", self.id_counter.to_string()) - } - } -} diff --git a/src/core/component/definition.rs b/src/core/component/definition.rs deleted file mode 100644 index ee8f1e2f..00000000 --- a/src/core/component/definition.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::base::action; -use crate::core::component::Context; -use crate::core::AnyBase; -use crate::global::TypeInfo; -use crate::html::{html, Markup, PrepareMarkup}; - -pub trait ComponentBase { - fn render(&mut self, cx: &mut Context) -> Markup; -} - -pub trait ComponentTrait: AnyBase + ComponentBase + Send + Sync { - fn new() -> Self - where - Self: Sized; - - fn name(&self) -> &'static str { - TypeInfo::ShortName.of::() - } - - fn description(&self) -> Option { - None - } - - fn id(&self) -> Option { - None - } - - #[allow(unused_variables)] - fn setup_before_prepare(&mut self, cx: &mut Context) {} - - #[allow(unused_variables)] - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - PrepareMarkup::None - } -} - -impl ComponentBase for C { - fn render(&mut self, cx: &mut Context) -> Markup { - if action::component::IsRenderable::dispatch(self, cx) { - // Comprueba el componente antes de prepararlo. - self.setup_before_prepare(cx); - - // Acciones del tema antes de preparar el componente. - action::theme::BeforePrepare::dispatch(self, cx); - - // Acciones de los módulos antes de preparar el componente. - action::component::BeforePrepare::dispatch(self, cx); - - // Renderiza el componente. - let markup = match action::theme::RenderComponent::dispatch(self, cx) { - Some(html) => html, - None => self.prepare_component(cx).render(), - }; - - // Acciones del tema después de preparar el componente. - action::theme::AfterPrepare::dispatch(self, cx); - - // Acciones de los módulos después de preparar el componente. - action::component::AfterPrepare::dispatch(self, cx); - - markup - } else { - html! {} - } - } -} diff --git a/src/core/component/mixed.rs b/src/core/component/mixed.rs deleted file mode 100644 index e93444bb..00000000 --- a/src/core/component/mixed.rs +++ /dev/null @@ -1,213 +0,0 @@ -use crate::core::component::{ComponentTrait, Context}; -use crate::html::{html, Markup}; -use crate::{fn_builder, TypeId}; - -use std::sync::{Arc, RwLock}; - -#[derive(Clone)] -pub struct AnyComponent(Arc>); - -impl AnyComponent { - pub fn with(component: impl ComponentTrait) -> Self { - AnyComponent(Arc::new(RwLock::new(component))) - } - - // AnyComponent RENDER. - - pub fn render(&self, cx: &mut Context) -> Markup { - self.0.write().unwrap().render(cx) - } - - // AnyComponent HELPERS. - - fn type_id(&self) -> TypeId { - self.0.read().unwrap().type_id() - } - - fn id(&self) -> String { - self.0.read().unwrap().id().unwrap_or_default() - } -} - -// ************************************************************************************************* - -pub struct TypedComponent(Arc>); - -impl Clone for TypedComponent { - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl TypedComponent { - pub fn with(component: C) -> Self { - TypedComponent(Arc::new(RwLock::new(component))) - } - - // TypedComponent RENDER. - - pub fn render(&self, cx: &mut Context) -> Markup { - self.0.write().unwrap().render(cx) - } - - // TypedComponent HELPERS. - - fn to_any(&self) -> AnyComponent { - AnyComponent(self.0.clone()) - } -} - -// ************************************************************************************************* - -pub enum AnyOp { - Add(AnyComponent), - InsertAfterId(&'static str, AnyComponent), - InsertBeforeId(&'static str, AnyComponent), - Prepend(AnyComponent), - RemoveById(&'static str), - ReplaceById(&'static str, AnyComponent), - Reset, -} - -pub enum TypedOp { - Add(TypedComponent), - InsertAfterId(&'static str, TypedComponent), - InsertBeforeId(&'static str, TypedComponent), - Prepend(TypedComponent), - RemoveById(&'static str), - ReplaceById(&'static str, TypedComponent), - Reset, -} - -#[derive(Clone, Default)] -pub struct MixedComponents(Vec); - -impl MixedComponents { - pub fn new() -> Self { - MixedComponents::default() - } - - pub fn with(any: AnyComponent) -> Self { - MixedComponents::default().with_value(AnyOp::Add(any)) - } - - pub(crate) fn merge(mixes: &[Option<&MixedComponents>]) -> Self { - let mut opt = MixedComponents::default(); - for m in mixes.iter().flatten() { - opt.0.append(&mut m.0.clone()); - } - opt - } - - // MixedComponents BUILDER. - - #[fn_builder] - pub fn set_value(&mut self, op: AnyOp) -> &mut Self { - match op { - AnyOp::Add(any) => self.add(any), - AnyOp::InsertAfterId(id, any) => self.insert_after_id(id, any), - AnyOp::InsertBeforeId(id, any) => self.insert_before_id(id, any), - AnyOp::Prepend(any) => self.prepend(any), - AnyOp::RemoveById(id) => self.remove_by_id(id), - AnyOp::ReplaceById(id, any) => self.replace_by_id(id, any), - AnyOp::Reset => self.reset(), - }; - self - } - - #[fn_builder] - pub fn set_typed(&mut self, op: TypedOp) -> &mut Self { - match op { - TypedOp::Add(typed) => self.add(typed.to_any()), - TypedOp::InsertAfterId(id, typed) => self.insert_after_id(id, typed.to_any()), - TypedOp::InsertBeforeId(id, typed) => self.insert_before_id(id, typed.to_any()), - TypedOp::Prepend(typed) => self.prepend(typed.to_any()), - TypedOp::RemoveById(id) => self.remove_by_id(id), - TypedOp::ReplaceById(id, typed) => self.replace_by_id(id, typed.to_any()), - TypedOp::Reset => self.reset(), - }; - self - } - - #[inline] - fn add(&mut self, any: AnyComponent) { - self.0.push(any); - } - - #[inline] - fn insert_after_id(&mut self, id: &str, any: AnyComponent) { - match self.0.iter().position(|c| c.id() == id) { - Some(index) => self.0.insert(index + 1, any), - _ => self.0.push(any), - }; - } - - #[inline] - fn insert_before_id(&mut self, id: &str, any: AnyComponent) { - match self.0.iter().position(|c| c.id() == id) { - Some(index) => self.0.insert(index, any), - _ => self.0.insert(0, any), - }; - } - - #[inline] - fn prepend(&mut self, any: AnyComponent) { - self.0.insert(0, any); - } - - #[inline] - fn remove_by_id(&mut self, id: &str) { - if let Some(index) = self.0.iter().position(|c| c.id() == id) { - self.0.remove(index); - } - } - - #[inline] - fn replace_by_id(&mut self, id: &str, any: AnyComponent) { - for c in &mut self.0 { - if c.id() == id { - *c = any; - break; - } - } - } - - #[inline] - fn reset(&mut self) { - self.0.clear(); - } - - // MixedComponents GETTERS. - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn get_by_id(&self, id: impl Into) -> Option<&AnyComponent> { - let id = id.into(); - self.0.iter().find(|c| c.id() == id) - } - - pub fn iter_by_id(&self, id: impl Into) -> impl Iterator { - let id = id.into(); - self.0.iter().filter(move |&c| c.id() == id) - } - - pub fn iter_by_type_id(&self, type_id: TypeId) -> impl Iterator { - self.0.iter().filter(move |&c| c.type_id() == type_id) - } - - // MixedComponents RENDER. - - pub fn render(&self, cx: &mut Context) -> Markup { - html! { - @for c in &self.0 { - (c.render(cx)) - } - } - } -} diff --git a/src/core/theme.rs b/src/core/theme.rs deleted file mode 100644 index 1925071a..00000000 --- a/src/core/theme.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod definition; -pub use definition::{ThemeRef, ThemeTrait}; - -mod regions; -pub(crate) use regions::ComponentsInRegions; -pub use regions::InRegion; - -pub(crate) mod all; diff --git a/src/core/theme/all.rs b/src/core/theme/all.rs deleted file mode 100644 index 1470038e..00000000 --- a/src/core/theme/all.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::core::theme::ThemeRef; -use crate::global; - -use std::sync::{LazyLock, RwLock}; - -// THEMES ****************************************************************************************** - -pub static THEMES: LazyLock>> = LazyLock::new(|| RwLock::new(Vec::new())); - -// DEFAULT THEME *********************************************************************************** - -pub static THEME_DEFAULT: LazyLock = - LazyLock::new(|| match theme_by_short_name(&global::SETTINGS.app.theme) { - Some(theme) => theme, - None => &crate::base::theme::Inception, - }); - -// THEME BY NAME *********************************************************************************** - -pub fn theme_by_short_name(short_name: &str) -> Option { - let short_name = short_name.to_lowercase(); - match THEMES - .read() - .unwrap() - .iter() - .find(|t| t.short_name().to_lowercase() == short_name) - { - Some(theme) => Some(*theme), - _ => None, - } -} diff --git a/src/core/theme/definition.rs b/src/core/theme/definition.rs deleted file mode 100644 index c3541dc8..00000000 --- a/src/core/theme/definition.rs +++ /dev/null @@ -1,108 +0,0 @@ -use crate::base::component::*; -use crate::core::component::{AssetsOp, ComponentBase, ComponentTrait}; -use crate::core::package::PackageTrait; -use crate::html::{html, Favicon, PrepareMarkup}; -use crate::locale::L10n; -use crate::response::page::Page; -use crate::{concat_string, global}; - -pub type ThemeRef = &'static dyn ThemeTrait; - -/// Los temas deben implementar este "trait". -pub trait ThemeTrait: PackageTrait + Send + Sync { - #[rustfmt::skip] - fn regions(&self) -> Vec<(&'static str, L10n)> { - vec![ - ("header", L10n::l("header")), - ("pagetop", L10n::l("pagetop")), - ("sidebar_left", L10n::l("sidebar_left")), - ("content", L10n::l("content")), - ("sidebar_right", L10n::l("sidebar_right")), - ("footer", L10n::l("footer")), - ] - } - - #[allow(unused_variables)] - fn before_prepare_body(&self, page: &mut Page) {} - - fn prepare_body(&self, page: &mut Page) -> PrepareMarkup { - let skip_to_id = page.body_skip_to().get().unwrap_or("content".to_owned()); - - PrepareMarkup::With(html! { - body id=[page.body_id().get()] class=[page.body_classes().get()] { - @if let Some(skip) = L10n::l("skip_to_content").using(page.context().langid()) { - div class="skip__to_content" { - a href=(concat_string!("#", skip_to_id)) { (skip) } - } - } - (flex::Container::new() - .with_id("body__wrapper") - .with_direction(flex::Direction::Column(BreakPoint::None)) - .with_align(flex::Align::Center) - .add_item(flex::Item::region().with_id("header")) - .add_item(flex::Item::region().with_id("pagetop")) - .add_item( - flex::Item::with( - flex::Container::new() - .with_direction(flex::Direction::Row(BreakPoint::None)) - .add_item( - flex::Item::region() - .with_id("sidebar_left") - .with_grow(flex::Grow::Is1), - ) - .add_item( - flex::Item::region() - .with_id("content") - .with_grow(flex::Grow::Is3), - ) - .add_item( - flex::Item::region() - .with_id("sidebar_right") - .with_grow(flex::Grow::Is1), - ), - ) - .with_id("flex__wrapper"), - ) - .add_item(flex::Item::region().with_id("footer")) - .render(page.context())) - } - }) - } - - fn after_prepare_body(&self, page: &mut Page) { - page.set_assets(AssetsOp::SetFaviconIfNone( - Favicon::new().with_icon("/base/favicon.ico"), - )); - } - - fn prepare_head(&self, page: &mut Page) -> PrepareMarkup { - let viewport = "width=device-width, initial-scale=1, shrink-to-fit=no"; - PrepareMarkup::With(html! { - head { - meta charset="utf-8"; - - @if let Some(title) = page.title() { - title { (global::SETTINGS.app.name) (" - ") (title) } - } @else { - title { (global::SETTINGS.app.name) } - } - - @if let Some(description) = page.description() { - meta name="description" content=(description); - } - - meta name="viewport" content=(viewport); - @for (name, content) in page.metadata() { - meta name=(name) content=(content) {} - } - - meta http-equiv="X-UA-Compatible" content="IE=edge"; - @for (property, content) in page.properties() { - meta property=(property) content=(content) {} - } - - (page.context().prepare_assets()) - } - }) - } -} diff --git a/src/core/theme/regions.rs b/src/core/theme/regions.rs deleted file mode 100644 index da2e24ff..00000000 --- a/src/core/theme/regions.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::core::component::{AnyComponent, AnyOp, MixedComponents}; -use crate::core::theme::ThemeRef; -use crate::{fn_builder, AutoDefault, TypeId}; - -use std::collections::HashMap; -use std::sync::{LazyLock, RwLock}; - -static THEME_REGIONS: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); - -static COMMON_REGIONS: LazyLock> = - LazyLock::new(|| RwLock::new(ComponentsInRegions::default())); - -#[derive(AutoDefault)] -pub struct ComponentsInRegions(HashMap<&'static str, MixedComponents>); - -impl ComponentsInRegions { - pub fn new(region: &'static str, any: AnyComponent) -> Self { - ComponentsInRegions::default().with_components(region, AnyOp::Add(any)) - } - - #[fn_builder] - pub fn set_components(&mut self, region: &'static str, op: AnyOp) -> &mut Self { - if let Some(region) = self.0.get_mut(region) { - region.set_value(op); - } else { - self.0.insert(region, MixedComponents::new().with_value(op)); - } - self - } - - pub fn all_components(&self, theme: ThemeRef, region: &str) -> MixedComponents { - let common = COMMON_REGIONS.read().unwrap(); - if let Some(r) = THEME_REGIONS.read().unwrap().get(&theme.type_id()) { - MixedComponents::merge(&[common.0.get(region), self.0.get(region), r.0.get(region)]) - } else { - MixedComponents::merge(&[common.0.get(region), self.0.get(region)]) - } - } -} - -pub enum InRegion { - Content, - Named(&'static str), - OfTheme(&'static str, ThemeRef), -} - -impl InRegion { - pub fn add(&self, any: AnyComponent) -> &Self { - match self { - InRegion::Content => { - COMMON_REGIONS - .write() - .unwrap() - .set_components("content", AnyOp::Add(any)); - } - InRegion::Named(name) => { - COMMON_REGIONS - .write() - .unwrap() - .set_components(name, AnyOp::Add(any)); - } - InRegion::OfTheme(region, theme) => { - let mut regions = THEME_REGIONS.write().unwrap(); - if let Some(r) = regions.get_mut(&theme.type_id()) { - r.set_components(region, AnyOp::Add(any)); - } else { - regions.insert(theme.type_id(), ComponentsInRegions::new(region, any)); - } - } - } - self - } -} diff --git a/src/datetime.rs b/src/datetime.rs deleted file mode 100644 index 732431df..00000000 --- a/src/datetime.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date and time handling -//! ([chrono](https://docs.rs/chrono)). - -pub use chrono::prelude::*; diff --git a/src/html.rs b/src/html.rs deleted file mode 100644 index fbe75750..00000000 --- a/src/html.rs +++ /dev/null @@ -1,46 +0,0 @@ -//! HTML in code. - -mod maud; -pub use maud::{html, html_private, Markup, PreEscaped, DOCTYPE}; - -mod assets; -pub use assets::favicon::Favicon; -pub use assets::javascript::JavaScript; -pub use assets::stylesheet::{StyleSheet, TargetMedia}; -pub(crate) use assets::Assets; - -mod opt_id; -pub use opt_id::OptionId; - -mod opt_name; -pub use opt_name::OptionName; - -mod opt_string; -pub use opt_string::OptionString; - -mod opt_translated; -pub use opt_translated::OptionTranslated; - -mod opt_classes; -pub use opt_classes::{ClassesOp, OptionClasses}; - -mod opt_component; -pub use opt_component::OptionComponent; - -pub mod unit; - -pub enum PrepareMarkup { - None, - Text(&'static str), - With(Markup), -} - -impl PrepareMarkup { - pub fn render(&self) -> Markup { - match self { - PrepareMarkup::None => html! {}, - PrepareMarkup::Text(text) => html! { (text) }, - PrepareMarkup::With(markup) => html! { (markup) }, - } - } -} diff --git a/src/html/assets.rs b/src/html/assets.rs deleted file mode 100644 index 4c8f27ce..00000000 --- a/src/html/assets.rs +++ /dev/null @@ -1,53 +0,0 @@ -pub mod favicon; -pub mod javascript; -pub mod stylesheet; - -use crate::html::{html, Markup}; -use crate::{AutoDefault, Weight}; - -pub trait AssetsTrait { - fn name(&self) -> &String; - - fn weight(&self) -> Weight; - - fn prepare(&self) -> Markup; -} - -#[derive(AutoDefault)] -pub(crate) struct Assets(Vec); - -impl Assets { - pub fn new() -> Self { - Assets::(Vec::::new()) - } - - pub fn add(&mut self, asset: T) -> &mut Self { - match self.0.iter().position(|x| x.name() == asset.name()) { - Some(index) => { - if self.0[index].weight() > asset.weight() { - self.0.remove(index); - self.0.push(asset); - } - } - _ => self.0.push(asset), - }; - self - } - - pub fn remove(&mut self, name: &'static str) -> &mut Self { - if let Some(index) = self.0.iter().position(|x| x.name() == name) { - self.0.remove(index); - }; - self - } - - pub fn prepare(&mut self) -> Markup { - let assets = &mut self.0; - assets.sort_by_key(AssetsTrait::weight); - html! { - @for a in assets { - (a.prepare()) - } - } - } -} diff --git a/src/html/assets/favicon.rs b/src/html/assets/favicon.rs deleted file mode 100644 index 068efcb4..00000000 --- a/src/html/assets/favicon.rs +++ /dev/null @@ -1,93 +0,0 @@ -use crate::html::{html, Markup}; -use crate::AutoDefault; - -#[derive(AutoDefault)] -pub struct Favicon(Vec); - -impl Favicon { - pub fn new() -> Self { - Favicon::default() - } - - // Favicon BUILDER. - - pub fn with_icon(self, image: &str) -> Self { - self.add_icon_item("icon", image, None, None) - } - - pub fn with_icon_for_sizes(self, image: &str, sizes: &str) -> Self { - self.add_icon_item("icon", image, Some(sizes), None) - } - - pub fn with_apple_touch_icon(self, image: &str, sizes: &str) -> Self { - self.add_icon_item("apple-touch-icon", image, Some(sizes), None) - } - - pub fn with_mask_icon(self, image: &str, color: &str) -> Self { - self.add_icon_item("mask-icon", image, None, Some(color)) - } - - pub fn with_manifest(self, file: &str) -> Self { - self.add_icon_item("manifest", file, None, None) - } - - pub fn with_theme_color(mut self, color: &str) -> Self { - self.0.push(html! { - meta name="theme-color" content=(color); - }); - self - } - - pub fn with_ms_tile_color(mut self, color: &str) -> Self { - self.0.push(html! { - meta name="msapplication-TileColor" content=(color); - }); - self - } - - pub fn with_ms_tile_image(mut self, image: &str) -> Self { - self.0.push(html! { - meta name="msapplication-TileImage" content=(image); - }); - self - } - - fn add_icon_item( - mut self, - icon_rel: &str, - icon_source: &str, - icon_sizes: Option<&str>, - icon_color: Option<&str>, - ) -> Self { - let icon_type = match icon_source.rfind('.') { - Some(i) => match icon_source[i..].to_owned().to_lowercase().as_str() { - ".gif" => Some("image/gif"), - ".ico" => Some("image/x-icon"), - ".jpg" => Some("image/jpg"), - ".png" => Some("image/png"), - ".svg" => Some("image/svg+xml"), - _ => None, - }, - _ => None, - }; - self.0.push(html! { - link - rel=(icon_rel) - type=[(icon_type)] - sizes=[(icon_sizes)] - color=[(icon_color)] - href=(icon_source); - }); - self - } - - // Favicon PREPARE. - - pub(crate) fn prepare(&self) -> Markup { - html! { - @for item in &self.0 { - (item) - } - } - } -} diff --git a/src/html/assets/javascript.rs b/src/html/assets/javascript.rs deleted file mode 100644 index 672ab3e0..00000000 --- a/src/html/assets/javascript.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::html::assets::AssetsTrait; -use crate::html::{html, Markup}; -use crate::{concat_string, AutoDefault, Weight}; - -#[derive(AutoDefault)] -enum Source { - #[default] - From(String), - Defer(String), - Async(String), - Inline(String, String), - OnLoad(String, String), -} - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct JavaScript { - source : Source, - prefix : &'static str, - version: &'static str, - weight : Weight, -} - -impl AssetsTrait for JavaScript { - fn name(&self) -> &String { - match &self.source { - Source::From(path) => path, - Source::Defer(path) => path, - Source::Async(path) => path, - Source::Inline(name, _) => name, - Source::OnLoad(name, _) => name, - } - } - - fn weight(&self) -> Weight { - self.weight - } - - fn prepare(&self) -> Markup { - match &self.source { - Source::From(path) => html! { - script src=(concat_string!(path, self.prefix, self.version)) {}; - }, - Source::Defer(path) => html! { - script src=(concat_string!(path, self.prefix, self.version)) defer {}; - }, - Source::Async(path) => html! { - script src=(concat_string!(path, self.prefix, self.version)) async {}; - }, - Source::Inline(_, code) => html! { - script { (code) }; - }, - Source::OnLoad(_, code) => html! { (concat_string!( - "document.addEventListener('DOMContentLoaded',function(){", - code, - "});" - )) }, - } - } -} - -impl JavaScript { - pub fn from(path: impl Into) -> Self { - JavaScript { - source: Source::From(path.into()), - ..Default::default() - } - } - - pub fn defer(path: impl Into) -> Self { - JavaScript { - source: Source::Defer(path.into()), - ..Default::default() - } - } - - pub fn asynchronous(path: impl Into) -> Self { - JavaScript { - source: Source::Async(path.into()), - ..Default::default() - } - } - - pub fn inline(name: impl Into, script: impl Into) -> Self { - JavaScript { - source: Source::Inline(name.into(), script.into()), - ..Default::default() - } - } - - pub fn on_load(name: impl Into, script: impl Into) -> Self { - JavaScript { - source: Source::OnLoad(name.into(), script.into()), - ..Default::default() - } - } - - pub fn with_version(mut self, version: &'static str) -> Self { - (self.prefix, self.version) = if version.is_empty() { - ("", "") - } else { - ("?v=", version) - }; - self - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } -} diff --git a/src/html/assets/stylesheet.rs b/src/html/assets/stylesheet.rs deleted file mode 100644 index 9fd5e191..00000000 --- a/src/html/assets/stylesheet.rs +++ /dev/null @@ -1,95 +0,0 @@ -use crate::html::assets::AssetsTrait; -use crate::html::{html, Markup}; -use crate::{concat_string, AutoDefault, Weight}; - -#[derive(AutoDefault)] -enum Source { - #[default] - From(String), - Inline(String, String), -} - -pub enum TargetMedia { - Default, - Print, - Screen, - Speech, -} - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct StyleSheet { - source : Source, - prefix : &'static str, - version: &'static str, - media : Option<&'static str>, - weight : Weight, -} - -impl AssetsTrait for StyleSheet { - fn name(&self) -> &String { - match &self.source { - Source::From(path) => path, - Source::Inline(name, _) => name, - } - } - - fn weight(&self) -> Weight { - self.weight - } - - fn prepare(&self) -> Markup { - match &self.source { - Source::From(path) => html! { - link - rel="stylesheet" - href=(concat_string!(path, self.prefix, self.version)) - media=[self.media]; - }, - Source::Inline(_, code) => html! { - styles { (code) }; - }, - } - } -} - -impl StyleSheet { - pub fn from(path: impl Into) -> Self { - StyleSheet { - source: Source::From(path.into()), - ..Default::default() - } - } - - pub fn inline(name: impl Into, styles: impl Into) -> Self { - StyleSheet { - source: Source::Inline(name.into(), styles.into()), - ..Default::default() - } - } - - pub fn with_version(mut self, version: &'static str) -> Self { - (self.prefix, self.version) = if version.is_empty() { - ("", "") - } else { - ("?v=", version) - }; - self - } - - pub fn with_weight(mut self, value: Weight) -> Self { - self.weight = value; - self - } - - #[rustfmt::skip] - pub fn for_media(mut self, media: &TargetMedia) -> Self { - self.media = match media { - TargetMedia::Default => None, - TargetMedia::Print => Some("print"), - TargetMedia::Screen => Some("screen"), - TargetMedia::Speech => Some("speech"), - }; - self - } -} diff --git a/src/html/maud.rs b/src/html/maud.rs deleted file mode 100644 index 801895e5..00000000 --- a/src/html/maud.rs +++ /dev/null @@ -1,350 +0,0 @@ -//#![no_std] - -//! A macro for writing HTML templates. -//! -//! This documentation only describes the runtime API. For a general -//! guide, check out the [book] instead. -//! -//! [book]: https://maud.lambda.xyz/ - -//#![doc(html_root_url = "https://docs.rs/maud/0.25.0")] - -extern crate alloc; - -use alloc::{borrow::Cow, boxed::Box, string::String}; -use core::fmt::{self, Arguments, Display, Write}; - -pub use pagetop_macros::html; - -mod escape; - -/// An adapter that escapes HTML special characters. -/// -/// The following characters are escaped: -/// -/// * `&` is escaped as `&` -/// * `<` is escaped as `<` -/// * `>` is escaped as `>` -/// * `"` is escaped as `"` -/// -/// All other characters are passed through unchanged. -/// -/// **Note:** In versions prior to 0.13, the single quote (`'`) was -/// escaped as well. -/// -/// # Example -/// -/// ```rust -/// use maud::Escaper; -/// use std::fmt::Write; -/// let mut s = String::new(); -/// write!(Escaper::new(&mut s), "").unwrap(); -/// assert_eq!(s, "<script>launchMissiles()</script>"); -/// ``` -pub struct Escaper<'a>(&'a mut String); - -impl<'a> Escaper<'a> { - /// Creates an `Escaper` from a `String`. - pub fn new(buffer: &'a mut String) -> Escaper<'a> { - Escaper(buffer) - } -} - -impl<'a> fmt::Write for Escaper<'a> { - fn write_str(&mut self, s: &str) -> fmt::Result { - escape::escape_to_string(s, self.0); - Ok(()) - } -} - -/// Represents a type that can be rendered as HTML. -/// -/// To implement this for your own type, override either the `.render()` -/// or `.render_to()` methods; since each is defined in terms of the -/// other, you only need to implement one of them. See the example below. -/// -/// # Minimal implementation -/// -/// An implementation of this trait must override at least one of -/// `.render()` or `.render_to()`. Since the default definitions of -/// these methods call each other, not doing this will result in -/// infinite recursion. -/// -/// # Example -/// -/// ```rust -/// use maud::{html, Markup, Render}; -/// -/// /// Provides a shorthand for linking to a CSS stylesheet. -/// pub struct Stylesheet(&'static str); -/// -/// impl Render for Stylesheet { -/// fn render(&self) -> Markup { -/// html! { -/// link rel="stylesheet" type="text/css" href=(self.0); -/// } -/// } -/// } -/// ``` -pub trait Render { - /// Renders `self` as a block of `Markup`. - fn render(&self) -> Markup { - let mut buffer = String::new(); - self.render_to(&mut buffer); - PreEscaped(buffer) - } - - /// Appends a representation of `self` to the given buffer. - /// - /// Its default implementation just calls `.render()`, but you may - /// override it with something more efficient. - /// - /// Note that no further escaping is performed on data written to - /// the buffer. If you override this method, you must make sure that - /// any data written is properly escaped, whether by hand or using - /// the [`Escaper`](struct.Escaper.html) wrapper struct. - fn render_to(&self, buffer: &mut String) { - buffer.push_str(&self.render().into_string()); - } -} - -impl Render for str { - fn render_to(&self, w: &mut String) { - escape::escape_to_string(self, w); - } -} - -impl Render for String { - fn render_to(&self, w: &mut String) { - str::render_to(self, w); - } -} - -impl<'a> Render for Cow<'a, str> { - fn render_to(&self, w: &mut String) { - str::render_to(self, w); - } -} - -impl<'a> Render for Arguments<'a> { - fn render_to(&self, w: &mut String) { - let _ = Escaper::new(w).write_fmt(*self); - } -} - -impl<'a, T: Render + ?Sized> Render for &'a T { - fn render_to(&self, w: &mut String) { - T::render_to(self, w); - } -} - -impl<'a, T: Render + ?Sized> Render for &'a mut T { - fn render_to(&self, w: &mut String) { - T::render_to(self, w); - } -} - -impl Render for Box { - fn render_to(&self, w: &mut String) { - T::render_to(self, w); - } -} - -macro_rules! impl_render_with_display { - ($($ty:ty)*) => { - $( - impl Render for $ty { - fn render_to(&self, w: &mut String) { - // TODO: remove the explicit arg when Rust 1.58 is released - format_args!("{self}", self = self).render_to(w); - } - } - )* - }; -} - -impl_render_with_display! { - char f32 f64 -} - -macro_rules! impl_render_with_itoa { - ($($ty:ty)*) => { - $( - impl Render for $ty { - fn render_to(&self, w: &mut String) { - w.push_str(itoa::Buffer::new().format(*self)); - } - } - )* - }; -} - -impl_render_with_itoa! { - i8 i16 i32 i64 i128 isize - u8 u16 u32 u64 u128 usize -} - -/// Renders a value using its [`Display`] impl. -/// -/// # Example -/// -/// ```rust -/// use maud::html; -/// use std::net::Ipv4Addr; -/// -/// let ip_address = Ipv4Addr::new(127, 0, 0, 1); -/// -/// let markup = html! { -/// "My IP address is: " -/// (maud::display(ip_address)) -/// }; -/// -/// assert_eq!(markup.into_string(), "My IP address is: 127.0.0.1"); -/// ``` -pub fn display(value: impl Display) -> impl Render { - struct DisplayWrapper(T); - - impl Render for DisplayWrapper { - fn render_to(&self, w: &mut String) { - format_args!("{0}", self.0).render_to(w); - } - } - - DisplayWrapper(value) -} - -/// A wrapper that renders the inner value without escaping. -#[derive(Debug, Clone, Copy)] -pub struct PreEscaped>(pub T); - -impl> Render for PreEscaped { - fn render_to(&self, w: &mut String) { - w.push_str(self.0.as_ref()); - } -} - -/// A block of markup is a string that does not need to be escaped. -/// -/// The `html!` macro expands to an expression of this type. -pub type Markup = PreEscaped; - -impl Markup { - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } -} - -impl + Into> PreEscaped { - /// Converts the inner value to a string. - pub fn into_string(self) -> String { - self.0.into() - } -} - -impl + Into> From> for String { - fn from(value: PreEscaped) -> String { - value.into_string() - } -} - -impl + Default> Default for PreEscaped { - fn default() -> Self { - Self(Default::default()) - } -} - -/// The literal string ``. -/// -/// # Example -/// -/// A minimal web page: -/// -/// ```rust -/// use maud::{DOCTYPE, html}; -/// -/// let markup = html! { -/// (DOCTYPE) -/// html { -/// head { -/// meta charset="utf-8"; -/// title { "Test page" } -/// } -/// body { -/// p { "Hello, world!" } -/// } -/// } -/// }; -/// ``` -pub const DOCTYPE: PreEscaped<&'static str> = PreEscaped(""); - -mod actix_support { - extern crate alloc; - - use crate::html::PreEscaped; - use actix_web::{http::header, HttpRequest, HttpResponse, Responder}; - use alloc::string::String; - - impl Responder for PreEscaped { - type Body = String; - - fn respond_to(self, _req: &HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_type(header::ContentType::html()) - .message_body(self.0) - .unwrap() - } - } -} - -#[doc(hidden)] -pub mod html_private { - extern crate alloc; - - use super::{display, Render}; - use alloc::string::String; - use core::fmt::Display; - - #[doc(hidden)] - #[macro_export] - macro_rules! render_to { - ($x:expr, $buffer:expr) => {{ - use $crate::html::html_private::*; - match ChooseRenderOrDisplay($x) { - x => (&&x).implements_render_or_display().render_to(x.0, $buffer), - } - }}; - } - - pub use render_to; - - pub struct ChooseRenderOrDisplay(pub T); - - pub struct ViaRenderTag; - pub struct ViaDisplayTag; - - pub trait ViaRender { - fn implements_render_or_display(&self) -> ViaRenderTag { - ViaRenderTag - } - } - pub trait ViaDisplay { - fn implements_render_or_display(&self) -> ViaDisplayTag { - ViaDisplayTag - } - } - - impl ViaRender for &ChooseRenderOrDisplay {} - impl ViaDisplay for ChooseRenderOrDisplay {} - - impl ViaRenderTag { - pub fn render_to(self, value: &T, buffer: &mut String) { - value.render_to(buffer); - } - } - - impl ViaDisplayTag { - pub fn render_to(self, value: &T, buffer: &mut String) { - display(value).render_to(buffer); - } - } -} diff --git a/src/html/maud/escape.rs b/src/html/maud/escape.rs deleted file mode 100644 index 94cdeec1..00000000 --- a/src/html/maud/escape.rs +++ /dev/null @@ -1,34 +0,0 @@ -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// !!!!! PLEASE KEEP THIS IN SYNC WITH `maud_macros/src/escape.rs` !!!!! -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -extern crate alloc; - -use alloc::string::String; - -pub fn escape_to_string(input: &str, output: &mut String) { - for b in input.bytes() { - match b { - b'&' => output.push_str("&"), - b'<' => output.push_str("<"), - b'>' => output.push_str(">"), - b'"' => output.push_str("""), - _ => unsafe { output.as_mut_vec().push(b) }, - } - } -} - -#[cfg(test)] -mod test { - extern crate alloc; - - use super::escape_to_string; - use alloc::string::String; - - #[test] - fn it_works() { - let mut s = String::new(); - escape_to_string("", &mut s); - assert_eq!(s, "<script>launchMissiles()</script>"); - } -} diff --git a/src/html/opt_classes.rs b/src/html/opt_classes.rs deleted file mode 100644 index 453991cd..00000000 --- a/src/html/opt_classes.rs +++ /dev/null @@ -1,111 +0,0 @@ -//! **OptionClasses** implements a *helper* for dynamically adding class names to components. -//! -//! This *helper* differentiates between default classes (generally associated with styles provided -//! by the theme) and user classes (for customizing components based on application styles). -//! -//! Classes can be added using [Add]. Operations to [Remove], [Replace] or [Toggle] a class, as well -//! as [Clear] all classes, are also provided. -//! -//! **OptionClasses** assumes that the order of the classes is irrelevant -//! (), and duplicate classes will not be allowed. - -use crate::{fn_builder, AutoDefault}; - -pub enum ClassesOp { - Add, - Prepend, - Remove, - Replace(String), - Toggle, - Set, -} - -#[derive(AutoDefault)] -pub struct OptionClasses(Vec); - -impl OptionClasses { - pub fn new(classes: impl Into) -> Self { - OptionClasses::default().with_value(ClassesOp::Prepend, classes) - } - - // OptionClasses BUILDER. - - #[fn_builder] - pub fn set_value(&mut self, op: ClassesOp, classes: impl Into) -> &mut Self { - let classes: String = classes.into(); - let classes: Vec<&str> = classes.split_ascii_whitespace().collect(); - - if classes.is_empty() { - return self; - } - - match op { - ClassesOp::Add => { - self.add(&classes, self.0.len()); - } - ClassesOp::Prepend => { - self.add(&classes, 0); - } - ClassesOp::Remove => { - for class in classes { - self.0.retain(|c| c.ne(&class.to_string())); - } - } - ClassesOp::Replace(classes_to_replace) => { - let mut pos = self.0.len(); - let replace: Vec<&str> = classes_to_replace.split_ascii_whitespace().collect(); - for class in replace { - if let Some(replace_pos) = self.0.iter().position(|c| c.eq(class)) { - self.0.remove(replace_pos); - if pos > replace_pos { - pos = replace_pos; - } - } - } - self.add(&classes, pos); - } - ClassesOp::Toggle => { - for class in classes { - if !class.is_empty() { - if let Some(pos) = self.0.iter().position(|c| c.eq(class)) { - self.0.remove(pos); - } else { - self.0.push(class.to_string()); - } - } - } - } - ClassesOp::Set => { - self.0.clear(); - self.add(&classes, 0); - } - } - - self - } - - #[inline] - fn add(&mut self, classes: &[&str], mut pos: usize) { - for &class in classes { - if !class.is_empty() && !self.0.iter().any(|c| c == class) { - self.0.insert(pos, class.to_string()); - pos += 1; - } - } - } - - // OptionClasses GETTERS. - - pub fn get(&self) -> Option { - if self.0.is_empty() { - None - } else { - Some(self.0.join(" ")) - } - } - - pub fn contains(&self, class: impl Into) -> bool { - let class: String = class.into(); - self.0.iter().any(|c| c.eq(&class)) - } -} diff --git a/src/html/opt_component.rs b/src/html/opt_component.rs deleted file mode 100644 index 5082a939..00000000 --- a/src/html/opt_component.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::core::component::{ComponentTrait, Context, TypedComponent}; -use crate::fn_builder; -use crate::html::{html, Markup}; - -pub struct OptionComponent(Option>); - -impl Default for OptionComponent { - fn default() -> Self { - OptionComponent(None) - } -} - -impl OptionComponent { - pub fn new(component: C) -> Self { - OptionComponent::default().with_value(Some(component)) - } - - // OptionComponent BUILDER. - - #[fn_builder] - pub fn set_value(&mut self, component: Option) -> &mut Self { - if let Some(component) = component { - self.0 = Some(TypedComponent::with(component)); - } else { - self.0 = None; - } - self - } - - // OptionComponent GETTERS. - - pub fn get(&self) -> Option> { - if let Some(value) = &self.0 { - return Some(value.clone()); - } - None - } - - pub fn render(&self, cx: &mut Context) -> Markup { - if let Some(component) = &self.0 { - component.render(cx) - } else { - html! {} - } - } -} diff --git a/src/html/opt_id.rs b/src/html/opt_id.rs deleted file mode 100644 index 80e98325..00000000 --- a/src/html/opt_id.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::{fn_builder, AutoDefault}; - -#[derive(AutoDefault)] -pub struct OptionId(Option); - -impl OptionId { - pub fn new(value: impl Into) -> Self { - OptionId::default().with_value(value) - } - - // OptionId BUILDER. - - #[fn_builder] - pub fn set_value(&mut self, value: impl Into) -> &mut Self { - self.0 = Some(value.into().trim().replace(' ', "_")); - self - } - - // OptionId GETTERS. - - pub fn get(&self) -> Option { - if let Some(value) = &self.0 { - if !value.is_empty() { - return Some(value.to_owned()); - } - } - None - } -} diff --git a/src/html/opt_name.rs b/src/html/opt_name.rs deleted file mode 100644 index 5ba0c486..00000000 --- a/src/html/opt_name.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::{fn_builder, AutoDefault}; - -#[derive(AutoDefault)] -pub struct OptionName(Option); - -impl OptionName { - pub fn new(value: impl Into) -> Self { - OptionName::default().with_value(value) - } - - // OptionName BUILDER. - - #[fn_builder] - pub fn set_value(&mut self, value: impl Into) -> &mut Self { - self.0 = Some(value.into().trim().replace(' ', "_")); - self - } - - // OptionName GETTERS. - - pub fn get(&self) -> Option { - if let Some(value) = &self.0 { - if !value.is_empty() { - return Some(value.to_owned()); - } - } - None - } -} diff --git a/src/html/opt_string.rs b/src/html/opt_string.rs deleted file mode 100644 index 7de22486..00000000 --- a/src/html/opt_string.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::{fn_builder, AutoDefault}; - -#[derive(AutoDefault)] -pub struct OptionString(Option); - -impl OptionString { - pub fn new(value: impl Into) -> Self { - OptionString::default().with_value(value) - } - - // OptionString BUILDER. - - #[fn_builder] - pub fn set_value(&mut self, value: impl Into) -> &mut Self { - self.0 = Some(value.into().trim().to_owned()); - self - } - - // OptionString GETTERS. - - pub fn get(&self) -> Option { - if let Some(value) = &self.0 { - if !value.is_empty() { - return Some(value.to_owned()); - } - } - None - } -} diff --git a/src/html/opt_translated.rs b/src/html/opt_translated.rs deleted file mode 100644 index e50a073f..00000000 --- a/src/html/opt_translated.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::html::Markup; -use crate::locale::{L10n, LanguageIdentifier}; -use crate::{fn_builder, AutoDefault}; - -#[derive(AutoDefault)] -pub struct OptionTranslated(L10n); - -impl OptionTranslated { - pub fn new(value: L10n) -> Self { - OptionTranslated(value) - } - - // OptionTranslated BUILDER. - - #[fn_builder] - pub fn set_value(&mut self, value: L10n) -> &mut Self { - self.0 = value; - self - } - - // OptionTranslated GETTERS. - - pub fn using(&self, langid: &LanguageIdentifier) -> Option { - self.0.using(langid) - } - - pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup { - self.0.escaped(langid) - } -} diff --git a/src/html/unit.rs b/src/html/unit.rs deleted file mode 100644 index 5a153c55..00000000 --- a/src/html/unit.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::AutoDefault; - -use std::fmt; - -// About pixels: Pixels (px) are relative to the viewing device. For low-dpi devices, 1px is one -// device pixel (dot) of the display. For printers and high resolution screens 1px implies multiple -// device pixels. - -// About em: 2em means 2 times the size of the current font. The em and rem units are practical in -// creating perfectly scalable layout! - -// About viewport: If the browser window size is 50cm wide, 1vw = 0.5cm. - -#[rustfmt::skip] -#[derive(AutoDefault)] -pub enum Value { - #[default] - None, - Auto, - - Cm(isize), // Centimeters. - In(isize), // Inches (1in = 96px = 2.54cm). - Mm(isize), // Millimeters. - Pc(isize), // Picas (1pc = 12pt). - Pt(isize), // Points (1pt = 1/72 of 1in). - Px(isize), // Pixels (1px = 1/96th of 1in). - - RelEm(f32), // Relative to the font-size of the element. - RelPct(f32), // Percentage relative to the parent element. - RelRem(f32), // Relative to font-size of the root element. - RelVh(f32), // Relative to 1% of the height of the viewport. - RelVw(f32), // Relative to 1% of the value of the viewport. -} - -#[rustfmt::skip] -impl fmt::Display for Value { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Value::None => write!(f, ""), - Value::Auto => write!(f, "auto"), - // Absolute value. - Value::Cm(av) => write!(f, "{av}cm"), - Value::In(av) => write!(f, "{av}in"), - Value::Mm(av) => write!(f, "{av}mm"), - Value::Pc(av) => write!(f, "{av}pc"), - Value::Pt(av) => write!(f, "{av}pt"), - Value::Px(av) => write!(f, "{av}px"), - // Relative value. - Value::RelEm(rv) => write!(f, "{rv}em"), - Value::RelPct(rv) => write!(f, "{rv}%"), - Value::RelRem(rv) => write!(f, "{rv}rem"), - Value::RelVh(rv) => write!(f, "{rv}vh"), - Value::RelVw(rv) => write!(f, "{rv}vw"), - } - } -} diff --git a/src/response/page.rs b/src/response/page.rs deleted file mode 100644 index c3e268b5..00000000 --- a/src/response/page.rs +++ /dev/null @@ -1,192 +0,0 @@ -mod error; -pub use error::ErrorPage; - -pub use actix_web::Result as ResultPage; - -use crate::base::action; -use crate::core::component::{AnyComponent, AnyOp, ComponentTrait}; -use crate::core::component::{AssetsOp, Context}; -use crate::fn_builder; -use crate::html::{html, Markup, DOCTYPE}; -use crate::html::{ClassesOp, OptionClasses, OptionId, OptionTranslated}; -use crate::locale::L10n; -use crate::service::HttpRequest; - -use unic_langid::CharacterDirection; - -#[rustfmt::skip] -pub struct Page { - title : OptionTranslated, - description : OptionTranslated, - metadata : Vec<(&'static str, &'static str)>, - properties : Vec<(&'static str, &'static str)>, - context : Context, - body_id : OptionId, - body_classes: OptionClasses, - body_skip_to: OptionId, -} - -impl Page { - #[rustfmt::skip] - pub fn new(request: HttpRequest) -> Self { - Page { - title : OptionTranslated::default(), - description : OptionTranslated::default(), - metadata : Vec::default(), - properties : Vec::default(), - context : Context::new(request), - body_id : OptionId::default(), - body_classes: OptionClasses::default(), - body_skip_to: OptionId::default(), - } - } - - // Page BUILDER. - - #[fn_builder] - pub fn set_title(&mut self, title: L10n) -> &mut Self { - self.title.set_value(title); - self - } - - #[fn_builder] - pub fn set_description(&mut self, description: L10n) -> &mut Self { - self.description.set_value(description); - self - } - - #[fn_builder] - pub fn set_metadata(&mut self, name: &'static str, content: &'static str) -> &mut Self { - self.metadata.push((name, content)); - self - } - - #[fn_builder] - pub fn set_property(&mut self, property: &'static str, content: &'static str) -> &mut Self { - self.metadata.push((property, content)); - self - } - - #[fn_builder] - pub fn set_assets(&mut self, op: AssetsOp) -> &mut Self { - self.context.set_assets(op); - self - } - - #[fn_builder] - pub fn set_body_id(&mut self, id: impl Into) -> &mut Self { - self.body_id.set_value(id); - self - } - - #[fn_builder] - pub fn set_body_classes(&mut self, op: ClassesOp, classes: impl Into) -> &mut Self { - self.body_classes.set_value(op, classes); - self - } - - #[fn_builder] - pub fn set_body_skip_to(&mut self, id: impl Into) -> &mut Self { - self.body_skip_to.set_value(id); - self - } - - #[fn_builder] - pub fn set_layout(&mut self, layout: &'static str) -> &mut Self { - self.context.set_assets(AssetsOp::Layout(layout)); - self - } - - #[fn_builder] - pub fn set_regions(&mut self, region: &'static str, op: AnyOp) -> &mut Self { - self.context.set_regions(region, op); - self - } - - pub fn with_component(mut self, component: impl ComponentTrait) -> Self { - self.context - .set_regions("content", AnyOp::Add(AnyComponent::with(component))); - self - } - - pub fn with_component_in( - mut self, - region: &'static str, - component: impl ComponentTrait, - ) -> Self { - self.context - .set_regions(region, AnyOp::Add(AnyComponent::with(component))); - self - } - - // Page GETTERS. - - pub fn title(&mut self) -> Option { - self.title.using(self.context.langid()) - } - - pub fn description(&mut self) -> Option { - self.description.using(self.context.langid()) - } - - pub fn metadata(&self) -> &Vec<(&str, &str)> { - &self.metadata - } - - pub fn properties(&self) -> &Vec<(&str, &str)> { - &self.properties - } - - pub fn context(&mut self) -> &mut Context { - &mut self.context - } - - pub fn body_id(&self) -> &OptionId { - &self.body_id - } - - pub fn body_classes(&self) -> &OptionClasses { - &self.body_classes - } - - pub fn body_skip_to(&self) -> &OptionId { - &self.body_skip_to - } - - // Page RENDER. - - pub fn render(&mut self) -> ResultPage { - // Theme operations before preparing the page body. - self.context.theme().before_prepare_body(self); - - // Packages actions before preparing the page body. - action::page::BeforePrepareBody::dispatch(self); - - // Prepare page body. - let body = self.context.theme().prepare_body(self); - - // Theme operations after preparing the page body. - self.context.theme().after_prepare_body(self); - - // Packages actions after preparing the page body. - action::page::AfterPrepareBody::dispatch(self); - - // Prepare page head. - let head = self.context.theme().prepare_head(self); - - // Render the page. - let lang = self.context.langid().language.as_str(); - let dir = match self.context.langid().character_direction() { - CharacterDirection::LTR => "ltr", - CharacterDirection::RTL => "rtl", - CharacterDirection::TTB => "auto", - }; - Ok(html! { - (DOCTYPE) - html lang=(lang) dir=(dir) { - (head.render()) - (body.render()) - } - }) - } -} diff --git a/src/response/page/error.rs b/src/response/page/error.rs deleted file mode 100644 index 8493d58f..00000000 --- a/src/response/page/error.rs +++ /dev/null @@ -1,86 +0,0 @@ -use crate::base::component::{Error403, Error404}; -use crate::locale::L10n; -use crate::response::ResponseError; -use crate::service::http::{header::ContentType, StatusCode}; -use crate::service::{HttpRequest, HttpResponse}; - -use super::Page; - -use std::fmt; - -#[derive(Debug)] -pub enum ErrorPage { - NotModified(HttpRequest), - BadRequest(HttpRequest), - AccessDenied(HttpRequest), - NotFound(HttpRequest), - PreconditionFailed(HttpRequest), - InternalError(HttpRequest), - Timeout(HttpRequest), -} - -impl fmt::Display for ErrorPage { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - // Error 304. - ErrorPage::NotModified(_) => write!(f, "Not Modified"), - // Error 400. - ErrorPage::BadRequest(_) => write!(f, "Bad Client Data"), - // Error 403. - ErrorPage::AccessDenied(request) => { - let error_page = Page::new(request.clone()); - if let Ok(page) = error_page - .with_title(L10n::n("Error FORBIDDEN")) - .with_layout("error") - .with_component(Error403) - .render() - { - write!(f, "{}", page.into_string()) - } else { - write!(f, "Access Denied") - } - } - // Error 404. - ErrorPage::NotFound(request) => { - let error_page = Page::new(request.clone()); - if let Ok(page) = error_page - .with_title(L10n::n("Error RESOURCE NOT FOUND")) - .with_layout("error") - .with_component(Error404) - .render() - { - write!(f, "{}", page.into_string()) - } else { - write!(f, "Not Found") - } - } - // Error 412. - ErrorPage::PreconditionFailed(_) => write!(f, "Precondition Failed"), - // Error 500. - ErrorPage::InternalError(_) => write!(f, "Internal Error"), - // Error 504. - ErrorPage::Timeout(_) => write!(f, "Timeout"), - } - } -} - -impl ResponseError for ErrorPage { - fn error_response(&self) -> HttpResponse { - HttpResponse::build(self.status_code()) - .insert_header(ContentType::html()) - .body(self.to_string()) - } - - #[rustfmt::skip] - fn status_code(&self) -> StatusCode { - match self { - ErrorPage::NotModified(_) => StatusCode::NOT_MODIFIED, - ErrorPage::BadRequest(_) => StatusCode::BAD_REQUEST, - ErrorPage::AccessDenied(_) => StatusCode::FORBIDDEN, - ErrorPage::NotFound(_) => StatusCode::NOT_FOUND, - ErrorPage::PreconditionFailed(_) => StatusCode::PRECONDITION_FAILED, - ErrorPage::InternalError(_) => StatusCode::INTERNAL_SERVER_ERROR, - ErrorPage::Timeout(_) => StatusCode::GATEWAY_TIMEOUT, - } - } -} diff --git a/static/base/css/basic.css b/static/base/css/basic.css deleted file mode 100644 index caccc2c9..00000000 --- a/static/base/css/basic.css +++ /dev/null @@ -1,3 +0,0 @@ -.skip__to_content { - display: none; -} diff --git a/static/base/css/buttons.css b/static/base/css/buttons.css deleted file mode 100644 index b53588d6..00000000 --- a/static/base/css/buttons.css +++ /dev/null @@ -1,1265 +0,0 @@ -.button__tap { - cursor: pointer; - text-align: center; - display: inline-block; - text-decoration: none; - border: 1px solid transparent; - border-radius: var(--val-border-radius); - padding: var(--val-gap-0-35) var(--val-gap-0-75); - transition: background-color .15s ease-in-out; - white-space: nowrap; - user-select: none; -} -.button__tap > span { - margin: 0 var(--val-gap-0-5); -} - -.button__tap.style__default { - color: var(--val-color--white); - background-color: var(--val-color--primary); -} -.button__tap.style__default:hover { - color: var(--val-color--white); - background-color: var(--val-color--primary-dark); -} -.button__tap.style__default:active, -.button__tap.style__default:disabled { - color: var(--val-color--white); - background-color: var(--val-color--primary-light); -} - -.button__tap.style__info:hover { - color: var(--val-color--white); - background-color: var(--val-color--info-dark); -} -.button__tap.style__info:active, -.button__tap.style__info:disabled { - color: var(--val-color--white); - background-color: var(--val-color--info-light); -} - -.button__tap.style__success:hover { - color: var(--val-color--white); - background-color: var(--val-color--success-dark); -} -.button__tap.style__success:active, -.button__tap.style__success:disabled { - color: var(--val-color--white); - background-color: var(--val-color--success-light); -} - -.button__tap.style__warning:hover { - color: var(--val-color--white); - background-color: var(--val-color--warning-dark); -} -.button__tap.style__warning:active, -.button__tap.style__warning:disabled { - color: var(--val-color--white); - background-color: var(--val-color--warning-light); -} - -.button__tap.style__danger:hover { - color: var(--val-color--white); - background-color: var(--val-color--danger-dark); -} -.button__tap.style__danger:active, -.button__tap.style__danger:disabled { - color: var(--val-color--white); - background-color: var(--val-color--danger-light); -} - -.button__tap.style__light:hover { - color: var(--val-color--text); - background-color: var(--val-color--light-dark); -} -.button__tap.style__light:active, -.button__tap.style__light:disabled { - color: var(--val-color--text); - background-color: var(--val-color--light-light); -} - -.button__tap.style__dark:hover { - color: var(--val-color--white); - background-color: var(--val-color--dark-dark); -} -.button__tap.style__dark:active, -.button__tap.style__dark:disabled { - color: var(--val-color--white); - background-color: var(--val-color--dark-light); -} - -/* -.button strong { - color: inherit -} - -.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small { - height: 1.5em; - width: 1.5em -} - -.button .icon:first-child:not(:last-child) { - margin-left: calc(-.5em - 1px); - margin-right: .25em -} - -.button .icon:last-child:not(:first-child) { - margin-left: .25em; - margin-right: calc(-.5em - 1px) -} - -.button .icon:first-child:last-child { - margin-left: calc(-.5em - 1px); - margin-right: calc(-.5em - 1px) -} - -.button__tap.is-hovered,.button:hover { - border-color: #b5b5b5; - color: #363636 -} - -.button__tap.is-focused,.button:focus { - border-color: #485fc7; - color: #363636 -} - -.button__tap.is-focused:not(:active),.button:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(72,95,199,.25) -} - -.button__tap.is-active,.button:active { - border-color: #4a4a4a; - color: #363636 -} - -.button__tap.is-text { - background-color: transparent; - border-color: transparent; - color: #4a4a4a; - text-decoration: underline -} - -.button__tap.is-text.is-focused,.button__tap.is-text.is-hovered,.button__tap.is-text:focus,.button__tap.is-text:hover { - background-color: #f5f5f5; - color: #363636 -} - -.button__tap.is-text.is-active,.button__tap.is-text:active { - background-color: #e8e8e8; - color: #363636 -} - -.button__tap.is-text[disabled],fieldset[disabled] .button__tap.is-text { - background-color: transparent; - border-color: transparent; - box-shadow: none -} - -.button__tap.is-ghost { - background: 0 0; - border-color: transparent; - color: #485fc7; - text-decoration: none -} - -.button__tap.is-ghost.is-hovered,.button__tap.is-ghost:hover { - color: #485fc7; - text-decoration: underline -} - -.button__tap.is-white { - background-color: #fff; - border-color: transparent; - color: #0a0a0a -} - -.button__tap.is-white.is-hovered,.button__tap.is-white:hover { - background-color: #f9f9f9; - border-color: transparent; - color: #0a0a0a -} - -.button__tap.is-white.is-focused,.button__tap.is-white:focus { - border-color: transparent; - color: #0a0a0a -} - -.button__tap.is-white.is-focused:not(:active),.button__tap.is-white:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(255,255,255,.25) -} - -.button__tap.is-white.is-active,.button__tap.is-white:active { - background-color: #f2f2f2; - border-color: transparent; - color: #0a0a0a -} - -.button__tap.is-white[disabled],fieldset[disabled] .button__tap.is-white { - background-color: #fff; - border-color: #fff; - box-shadow: none -} - -.button__tap.is-white.is-inverted { - background-color: #0a0a0a; - color: #fff -} - -.button__tap.is-white.is-inverted.is-hovered,.button__tap.is-white.is-inverted:hover { - background-color: #000 -} - -.button__tap.is-white.is-inverted[disabled],fieldset[disabled] .button__tap.is-white.is-inverted { - background-color: #0a0a0a; - border-color: transparent; - box-shadow: none; - color: #fff -} - -.button__tap.is-white.is-loading::after { - border-color: transparent transparent #0a0a0a #0a0a0a!important -} - -.button__tap.is-white.is-outlined { - background-color: transparent; - border-color: #fff; - color: #fff -} - -.button__tap.is-white.is-outlined.is-focused,.button__tap.is-white.is-outlined.is-hovered,.button__tap.is-white.is-outlined:focus,.button__tap.is-white.is-outlined:hover { - background-color: #fff; - border-color: #fff; - color: #0a0a0a -} - -.button__tap.is-white.is-outlined.is-loading::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-white.is-outlined.is-loading.is-focused::after,.button__tap.is-white.is-outlined.is-loading.is-hovered::after,.button__tap.is-white.is-outlined.is-loading:focus::after,.button__tap.is-white.is-outlined.is-loading:hover::after { - border-color: transparent transparent #0a0a0a #0a0a0a!important -} - -.button__tap.is-white.is-outlined[disabled],fieldset[disabled] .button__tap.is-white.is-outlined { - background-color: transparent; - border-color: #fff; - box-shadow: none; - color: #fff -} - -.button__tap.is-white.is-inverted.is-outlined { - background-color: transparent; - border-color: #0a0a0a; - color: #0a0a0a -} - -.button__tap.is-white.is-inverted.is-outlined.is-focused,.button__tap.is-white.is-inverted.is-outlined.is-hovered,.button__tap.is-white.is-inverted.is-outlined:focus,.button__tap.is-white.is-inverted.is-outlined:hover { - background-color: #0a0a0a; - color: #fff -} - -.button__tap.is-white.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-white.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-white.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-white.is-inverted.is-outlined { - background-color: transparent; - border-color: #0a0a0a; - box-shadow: none; - color: #0a0a0a -} - -.button__tap.is-black { - background-color: #0a0a0a; - border-color: transparent; - color: #fff -} - -.button__tap.is-black.is-hovered,.button__tap.is-black:hover { - background-color: #040404; - border-color: transparent; - color: #fff -} - -.button__tap.is-black.is-focused,.button__tap.is-black:focus { - border-color: transparent; - color: #fff -} - -.button__tap.is-black.is-focused:not(:active),.button__tap.is-black:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(10,10,10,.25) -} - -.button__tap.is-black.is-active,.button__tap.is-black:active { - background-color: #000; - border-color: transparent; - color: #fff -} - -.button__tap.is-black[disabled],fieldset[disabled] .button__tap.is-black { - background-color: #0a0a0a; - border-color: #0a0a0a; - box-shadow: none -} - -.button__tap.is-black.is-inverted { - background-color: #fff; - color: #0a0a0a -} - -.button__tap.is-black.is-inverted.is-hovered,.button__tap.is-black.is-inverted:hover { - background-color: #f2f2f2 -} - -.button__tap.is-black.is-inverted[disabled],fieldset[disabled] .button__tap.is-black.is-inverted { - background-color: #fff; - border-color: transparent; - box-shadow: none; - color: #0a0a0a -} - -.button__tap.is-black.is-loading::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-black.is-outlined { - background-color: transparent; - border-color: #0a0a0a; - color: #0a0a0a -} - -.button__tap.is-black.is-outlined.is-focused,.button__tap.is-black.is-outlined.is-hovered,.button__tap.is-black.is-outlined:focus,.button__tap.is-black.is-outlined:hover { - background-color: #0a0a0a; - border-color: #0a0a0a; - color: #fff -} - -.button__tap.is-black.is-outlined.is-loading::after { - border-color: transparent transparent #0a0a0a #0a0a0a!important -} - -.button__tap.is-black.is-outlined.is-loading.is-focused::after,.button__tap.is-black.is-outlined.is-loading.is-hovered::after,.button__tap.is-black.is-outlined.is-loading:focus::after,.button__tap.is-black.is-outlined.is-loading:hover::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-black.is-outlined[disabled],fieldset[disabled] .button__tap.is-black.is-outlined { - background-color: transparent; - border-color: #0a0a0a; - box-shadow: none; - color: #0a0a0a -} - -.button__tap.is-black.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - color: #fff -} - -.button__tap.is-black.is-inverted.is-outlined.is-focused,.button__tap.is-black.is-inverted.is-outlined.is-hovered,.button__tap.is-black.is-inverted.is-outlined:focus,.button__tap.is-black.is-inverted.is-outlined:hover { - background-color: #fff; - color: #0a0a0a -} - -.button__tap.is-black.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-black.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-black.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #0a0a0a #0a0a0a!important -} - -.button__tap.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-black.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - box-shadow: none; - color: #fff -} - -.button__tap.is-light { - background-color: #f5f5f5; - border-color: transparent; - color: rgba(0,0,0,.7) -} - -.button__tap.is-light.is-hovered,.button__tap.is-light:hover { - background-color: #eee; - border-color: transparent; - color: rgba(0,0,0,.7) -} - -.button__tap.is-light.is-focused,.button__tap.is-light:focus { - border-color: transparent; - color: rgba(0,0,0,.7) -} - -.button__tap.is-light.is-focused:not(:active),.button__tap.is-light:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(245,245,245,.25) -} - -.button__tap.is-light.is-active,.button__tap.is-light:active { - background-color: #e8e8e8; - border-color: transparent; - color: rgba(0,0,0,.7) -} - -.button__tap.is-light[disabled],fieldset[disabled] .button__tap.is-light { - background-color: #f5f5f5; - border-color: #f5f5f5; - box-shadow: none -} - -.button__tap.is-light.is-inverted { - background-color: rgba(0,0,0,.7); - color: #f5f5f5 -} - -.button__tap.is-light.is-inverted.is-hovered,.button__tap.is-light.is-inverted:hover { - background-color: rgba(0,0,0,.7) -} - -.button__tap.is-light.is-inverted[disabled],fieldset[disabled] .button__tap.is-light.is-inverted { - background-color: rgba(0,0,0,.7); - border-color: transparent; - box-shadow: none; - color: #f5f5f5 -} - -.button__tap.is-light.is-loading::after { - border-color: transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important -} - -.button__tap.is-light.is-outlined { - background-color: transparent; - border-color: #f5f5f5; - color: #f5f5f5 -} - -.button__tap.is-light.is-outlined.is-focused,.button__tap.is-light.is-outlined.is-hovered,.button__tap.is-light.is-outlined:focus,.button__tap.is-light.is-outlined:hover { - background-color: #f5f5f5; - border-color: #f5f5f5; - color: rgba(0,0,0,.7) -} - -.button__tap.is-light.is-outlined.is-loading::after { - border-color: transparent transparent #f5f5f5 #f5f5f5!important -} - -.button__tap.is-light.is-outlined.is-loading.is-focused::after,.button__tap.is-light.is-outlined.is-loading.is-hovered::after,.button__tap.is-light.is-outlined.is-loading:focus::after,.button__tap.is-light.is-outlined.is-loading:hover::after { - border-color: transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important -} - -.button__tap.is-light.is-outlined[disabled],fieldset[disabled] .button__tap.is-light.is-outlined { - background-color: transparent; - border-color: #f5f5f5; - box-shadow: none; - color: #f5f5f5 -} - -.button__tap.is-light.is-inverted.is-outlined { - background-color: transparent; - border-color: rgba(0,0,0,.7); - color: rgba(0,0,0,.7) -} - -.button__tap.is-light.is-inverted.is-outlined.is-focused,.button__tap.is-light.is-inverted.is-outlined.is-hovered,.button__tap.is-light.is-inverted.is-outlined:focus,.button__tap.is-light.is-inverted.is-outlined:hover { - background-color: rgba(0,0,0,.7); - color: #f5f5f5 -} - -.button__tap.is-light.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-light.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-light.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #f5f5f5 #f5f5f5!important -} - -.button__tap.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-light.is-inverted.is-outlined { - background-color: transparent; - border-color: rgba(0,0,0,.7); - box-shadow: none; - color: rgba(0,0,0,.7) -} - -.button__tap.is-dark { - background-color: #363636; - border-color: transparent; - color: #fff -} - -.button__tap.is-dark.is-hovered,.button__tap.is-dark:hover { - background-color: #2f2f2f; - border-color: transparent; - color: #fff -} - -.button__tap.is-dark.is-focused,.button__tap.is-dark:focus { - border-color: transparent; - color: #fff -} - -.button__tap.is-dark.is-focused:not(:active),.button__tap.is-dark:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(54,54,54,.25) -} - -.button__tap.is-dark.is-active,.button__tap.is-dark:active { - background-color: #292929; - border-color: transparent; - color: #fff -} - -.button__tap.is-dark[disabled],fieldset[disabled] .button__tap.is-dark { - background-color: #363636; - border-color: #363636; - box-shadow: none -} - -.button__tap.is-dark.is-inverted { - background-color: #fff; - color: #363636 -} - -.button__tap.is-dark.is-inverted.is-hovered,.button__tap.is-dark.is-inverted:hover { - background-color: #f2f2f2 -} - -.button__tap.is-dark.is-inverted[disabled],fieldset[disabled] .button__tap.is-dark.is-inverted { - background-color: #fff; - border-color: transparent; - box-shadow: none; - color: #363636 -} - -.button__tap.is-dark.is-loading::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-dark.is-outlined { - background-color: transparent; - border-color: #363636; - color: #363636 -} - -.button__tap.is-dark.is-outlined.is-focused,.button__tap.is-dark.is-outlined.is-hovered,.button__tap.is-dark.is-outlined:focus,.button__tap.is-dark.is-outlined:hover { - background-color: #363636; - border-color: #363636; - color: #fff -} - -.button__tap.is-dark.is-outlined.is-loading::after { - border-color: transparent transparent #363636 #363636!important -} - -.button__tap.is-dark.is-outlined.is-loading.is-focused::after,.button__tap.is-dark.is-outlined.is-loading.is-hovered::after,.button__tap.is-dark.is-outlined.is-loading:focus::after,.button__tap.is-dark.is-outlined.is-loading:hover::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-dark.is-outlined[disabled],fieldset[disabled] .button__tap.is-dark.is-outlined { - background-color: transparent; - border-color: #363636; - box-shadow: none; - color: #363636 -} - -.button__tap.is-dark.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - color: #fff -} - -.button__tap.is-dark.is-inverted.is-outlined.is-focused,.button__tap.is-dark.is-inverted.is-outlined.is-hovered,.button__tap.is-dark.is-inverted.is-outlined:focus,.button__tap.is-dark.is-inverted.is-outlined:hover { - background-color: #fff; - color: #363636 -} - -.button__tap.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-dark.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-dark.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #363636 #363636!important -} - -.button__tap.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-dark.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - box-shadow: none; - color: #fff -} -*/ -/* -.style__default[disabled],fieldset[disabled] .style__default { - background-color: #00d1b2; - border-color: #00d1b2; - box-shadow: none -} - -.style__default.is-inverted { - background-color: #fff; - color: #00d1b2 -} - -.style__default.is-inverted.is-hovered,.style__default.is-inverted:hover { - background-color: #f2f2f2 -} - -.style__default.is-inverted[disabled],fieldset[disabled] .style__default.is-inverted { - background-color: #fff; - border-color: transparent; - box-shadow: none; - color: #00d1b2 -} - -.style__default.is-loading::after { - border-color: transparent transparent #fff #fff!important -} - -.style__default.is-outlined { - background-color: transparent; - border-color: #00d1b2; - color: #00d1b2 -} - -.style__default.is-outlined.is-focused,.style__default.is-outlined.is-hovered,.style__default.is-outlined:focus,.style__default.is-outlined:hover { - background-color: #00d1b2; - border-color: #00d1b2; - color: #fff -} - -.style__default.is-outlined.is-loading::after { - border-color: transparent transparent #00d1b2 #00d1b2!important -} - -.style__default.is-outlined.is-loading.is-focused::after,.style__default.is-outlined.is-loading.is-hovered::after,.style__default.is-outlined.is-loading:focus::after,.style__default.is-outlined.is-loading:hover::after { - border-color: transparent transparent #fff #fff!important -} - -.style__default.is-outlined[disabled],fieldset[disabled] .style__default.is-outlined { - background-color: transparent; - border-color: #00d1b2; - box-shadow: none; - color: #00d1b2 -} - -.style__default.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - color: #fff -} - -.style__default.is-inverted.is-outlined.is-focused,.style__default.is-inverted.is-outlined.is-hovered,.style__default.is-inverted.is-outlined:focus,.style__default.is-inverted.is-outlined:hover { - background-color: #fff; - color: #00d1b2 -} - -.style__default.is-inverted.is-outlined.is-loading.is-focused::after,.style__default.is-inverted.is-outlined.is-loading.is-hovered::after,.style__default.is-inverted.is-outlined.is-loading:focus::after,.style__default.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #00d1b2 #00d1b2!important -} - -.style__default.is-inverted.is-outlined[disabled],fieldset[disabled] .style__default.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - box-shadow: none; - color: #fff -} - -.style__default.is-light { - background-color: #ebfffc; - color: #00947e -} - -.style__default.is-light.is-hovered,.style__default.is-light:hover { - background-color: #defffa; - border-color: transparent; - color: #00947e -} - -.style__default.is-light.is-active,.style__default.is-light:active { - background-color: #d1fff8; - border-color: transparent; - color: #00947e -} - -.button__tap.is-link { - background-color: #485fc7; - border-color: transparent; - color: #fff -} - -.button__tap.is-link.is-hovered,.button__tap.is-link:hover { - background-color: #3e56c4; - border-color: transparent; - color: #fff -} - -.button__tap.is-link.is-focused,.button__tap.is-link:focus { - border-color: transparent; - color: #fff -} - -.button__tap.is-link.is-focused:not(:active),.button__tap.is-link:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(72,95,199,.25) -} - -.button__tap.is-link.is-active,.button__tap.is-link:active { - background-color: #3a51bb; - border-color: transparent; - color: #fff -} - -.button__tap.is-link[disabled],fieldset[disabled] .button__tap.is-link { - background-color: #485fc7; - border-color: #485fc7; - box-shadow: none -} - -.button__tap.is-link.is-inverted { - background-color: #fff; - color: #485fc7 -} - -.button__tap.is-link.is-inverted.is-hovered,.button__tap.is-link.is-inverted:hover { - background-color: #f2f2f2 -} - -.button__tap.is-link.is-inverted[disabled],fieldset[disabled] .button__tap.is-link.is-inverted { - background-color: #fff; - border-color: transparent; - box-shadow: none; - color: #485fc7 -} - -.button__tap.is-link.is-loading::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-link.is-outlined { - background-color: transparent; - border-color: #485fc7; - color: #485fc7 -} - -.button__tap.is-link.is-outlined.is-focused,.button__tap.is-link.is-outlined.is-hovered,.button__tap.is-link.is-outlined:focus,.button__tap.is-link.is-outlined:hover { - background-color: #485fc7; - border-color: #485fc7; - color: #fff -} - -.button__tap.is-link.is-outlined.is-loading::after { - border-color: transparent transparent #485fc7 #485fc7!important -} - -.button__tap.is-link.is-outlined.is-loading.is-focused::after,.button__tap.is-link.is-outlined.is-loading.is-hovered::after,.button__tap.is-link.is-outlined.is-loading:focus::after,.button__tap.is-link.is-outlined.is-loading:hover::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-link.is-outlined[disabled],fieldset[disabled] .button__tap.is-link.is-outlined { - background-color: transparent; - border-color: #485fc7; - box-shadow: none; - color: #485fc7 -} - -.button__tap.is-link.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - color: #fff -} - -.button__tap.is-link.is-inverted.is-outlined.is-focused,.button__tap.is-link.is-inverted.is-outlined.is-hovered,.button__tap.is-link.is-inverted.is-outlined:focus,.button__tap.is-link.is-inverted.is-outlined:hover { - background-color: #fff; - color: #485fc7 -} - -.button__tap.is-link.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-link.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-link.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #485fc7 #485fc7!important -} - -.button__tap.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-link.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - box-shadow: none; - color: #fff -} - -.button__tap.is-link.is-light { - background-color: #eff1fa; - color: #3850b7 -} - -.button__tap.is-link.is-light.is-hovered,.button__tap.is-link.is-light:hover { - background-color: #e6e9f7; - border-color: transparent; - color: #3850b7 -} - -.button__tap.is-link.is-light.is-active,.button__tap.is-link.is-light:active { - background-color: #dce0f4; - border-color: transparent; - color: #3850b7 -} - -.button__tap.is-info { - background-color: #3e8ed0; - border-color: transparent; - color: #fff -} - -.button__tap.is-info.is-hovered,.button__tap.is-info:hover { - background-color: #3488ce; - border-color: transparent; - color: #fff -} - -.button__tap.is-info.is-focused,.button__tap.is-info:focus { - border-color: transparent; - color: #fff -} - -.button__tap.is-info.is-focused:not(:active),.button__tap.is-info:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(62,142,208,.25) -} - -.button__tap.is-info.is-active,.button__tap.is-info:active { - background-color: #3082c5; - border-color: transparent; - color: #fff -} - -.button__tap.is-info[disabled],fieldset[disabled] .button__tap.is-info { - background-color: #3e8ed0; - border-color: #3e8ed0; - box-shadow: none -} - -.button__tap.is-info.is-inverted { - background-color: #fff; - color: #3e8ed0 -} - -.button__tap.is-info.is-inverted.is-hovered,.button__tap.is-info.is-inverted:hover { - background-color: #f2f2f2 -} - -.button__tap.is-info.is-inverted[disabled],fieldset[disabled] .button__tap.is-info.is-inverted { - background-color: #fff; - border-color: transparent; - box-shadow: none; - color: #3e8ed0 -} - -.button__tap.is-info.is-loading::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-info.is-outlined { - background-color: transparent; - border-color: #3e8ed0; - color: #3e8ed0 -} - -.button__tap.is-info.is-outlined.is-focused,.button__tap.is-info.is-outlined.is-hovered,.button__tap.is-info.is-outlined:focus,.button__tap.is-info.is-outlined:hover { - background-color: #3e8ed0; - border-color: #3e8ed0; - color: #fff -} - -.button__tap.is-info.is-outlined.is-loading::after { - border-color: transparent transparent #3e8ed0 #3e8ed0!important -} - -.button__tap.is-info.is-outlined.is-loading.is-focused::after,.button__tap.is-info.is-outlined.is-loading.is-hovered::after,.button__tap.is-info.is-outlined.is-loading:focus::after,.button__tap.is-info.is-outlined.is-loading:hover::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-info.is-outlined[disabled],fieldset[disabled] .button__tap.is-info.is-outlined { - background-color: transparent; - border-color: #3e8ed0; - box-shadow: none; - color: #3e8ed0 -} - -.button__tap.is-info.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - color: #fff -} - -.button__tap.is-info.is-inverted.is-outlined.is-focused,.button__tap.is-info.is-inverted.is-outlined.is-hovered,.button__tap.is-info.is-inverted.is-outlined:focus,.button__tap.is-info.is-inverted.is-outlined:hover { - background-color: #fff; - color: #3e8ed0 -} - -.button__tap.is-info.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-info.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-info.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #3e8ed0 #3e8ed0!important -} - -.button__tap.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-info.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - box-shadow: none; - color: #fff -} - -.button__tap.is-info.is-light { - background-color: #eff5fb; - color: #296fa8 -} - -.button__tap.is-info.is-light.is-hovered,.button__tap.is-info.is-light:hover { - background-color: #e4eff9; - border-color: transparent; - color: #296fa8 -} - -.button__tap.is-info.is-light.is-active,.button__tap.is-info.is-light:active { - background-color: #dae9f6; - border-color: transparent; - color: #296fa8 -} - -.button__tap.is-success { - background-color: #48c78e; - border-color: transparent; - color: #fff -} - -.button__tap.is-success.is-hovered,.button__tap.is-success:hover { - background-color: #3ec487; - border-color: transparent; - color: #fff -} - -.button__tap.is-success.is-focused,.button__tap.is-success:focus { - border-color: transparent; - color: #fff -} - -.button__tap.is-success.is-focused:not(:active),.button__tap.is-success:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(72,199,142,.25) -} - -.button__tap.is-success.is-active,.button__tap.is-success:active { - background-color: #3abb81; - border-color: transparent; - color: #fff -} - -.button__tap.is-success[disabled],fieldset[disabled] .button__tap.is-success { - background-color: #48c78e; - border-color: #48c78e; - box-shadow: none -} - -.button__tap.is-success.is-inverted { - background-color: #fff; - color: #48c78e -} - -.button__tap.is-success.is-inverted.is-hovered,.button__tap.is-success.is-inverted:hover { - background-color: #f2f2f2 -} - -.button__tap.is-success.is-inverted[disabled],fieldset[disabled] .button__tap.is-success.is-inverted { - background-color: #fff; - border-color: transparent; - box-shadow: none; - color: #48c78e -} - -.button__tap.is-success.is-loading::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-success.is-outlined { - background-color: transparent; - border-color: #48c78e; - color: #48c78e -} - -.button__tap.is-success.is-outlined.is-focused,.button__tap.is-success.is-outlined.is-hovered,.button__tap.is-success.is-outlined:focus,.button__tap.is-success.is-outlined:hover { - background-color: #48c78e; - border-color: #48c78e; - color: #fff -} - -.button__tap.is-success.is-outlined.is-loading::after { - border-color: transparent transparent #48c78e #48c78e!important -} - -.button__tap.is-success.is-outlined.is-loading.is-focused::after,.button__tap.is-success.is-outlined.is-loading.is-hovered::after,.button__tap.is-success.is-outlined.is-loading:focus::after,.button__tap.is-success.is-outlined.is-loading:hover::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-success.is-outlined[disabled],fieldset[disabled] .button__tap.is-success.is-outlined { - background-color: transparent; - border-color: #48c78e; - box-shadow: none; - color: #48c78e -} - -.button__tap.is-success.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - color: #fff -} - -.button__tap.is-success.is-inverted.is-outlined.is-focused,.button__tap.is-success.is-inverted.is-outlined.is-hovered,.button__tap.is-success.is-inverted.is-outlined:focus,.button__tap.is-success.is-inverted.is-outlined:hover { - background-color: #fff; - color: #48c78e -} - -.button__tap.is-success.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-success.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-success.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #48c78e #48c78e!important -} - -.button__tap.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-success.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - box-shadow: none; - color: #fff -} - -.button__tap.is-success.is-light { - background-color: #effaf5; - color: #257953 -} - -.button__tap.is-success.is-light.is-hovered,.button__tap.is-success.is-light:hover { - background-color: #e6f7ef; - border-color: transparent; - color: #257953 -} - -.button__tap.is-success.is-light.is-active,.button__tap.is-success.is-light:active { - background-color: #dcf4e9; - border-color: transparent; - color: #257953 -} - -.button__tap.is-warning { - background-color: #ffe08a; - border-color: transparent; - color: rgba(0,0,0,.7) -} - -.button__tap.is-warning.is-hovered,.button__tap.is-warning:hover { - background-color: #ffdc7d; - border-color: transparent; - color: rgba(0,0,0,.7) -} - -.button__tap.is-warning.is-focused,.button__tap.is-warning:focus { - border-color: transparent; - color: rgba(0,0,0,.7) -} - -.button__tap.is-warning.is-focused:not(:active),.button__tap.is-warning:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(255,224,138,.25) -} - -.button__tap.is-warning.is-active,.button__tap.is-warning:active { - background-color: #ffd970; - border-color: transparent; - color: rgba(0,0,0,.7) -} - -.button__tap.is-warning[disabled],fieldset[disabled] .button__tap.is-warning { - background-color: #ffe08a; - border-color: #ffe08a; - box-shadow: none -} - -.button__tap.is-warning.is-inverted { - background-color: rgba(0,0,0,.7); - color: #ffe08a -} - -.button__tap.is-warning.is-inverted.is-hovered,.button__tap.is-warning.is-inverted:hover { - background-color: rgba(0,0,0,.7) -} - -.button__tap.is-warning.is-inverted[disabled],fieldset[disabled] .button__tap.is-warning.is-inverted { - background-color: rgba(0,0,0,.7); - border-color: transparent; - box-shadow: none; - color: #ffe08a -} - -.button__tap.is-warning.is-loading::after { - border-color: transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important -} - -.button__tap.is-warning.is-outlined { - background-color: transparent; - border-color: #ffe08a; - color: #ffe08a -} - -.button__tap.is-warning.is-outlined.is-focused,.button__tap.is-warning.is-outlined.is-hovered,.button__tap.is-warning.is-outlined:focus,.button__tap.is-warning.is-outlined:hover { - background-color: #ffe08a; - border-color: #ffe08a; - color: rgba(0,0,0,.7) -} - -.button__tap.is-warning.is-outlined.is-loading::after { - border-color: transparent transparent #ffe08a #ffe08a!important -} - -.button__tap.is-warning.is-outlined.is-loading.is-focused::after,.button__tap.is-warning.is-outlined.is-loading.is-hovered::after,.button__tap.is-warning.is-outlined.is-loading:focus::after,.button__tap.is-warning.is-outlined.is-loading:hover::after { - border-color: transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important -} - -.button__tap.is-warning.is-outlined[disabled],fieldset[disabled] .button__tap.is-warning.is-outlined { - background-color: transparent; - border-color: #ffe08a; - box-shadow: none; - color: #ffe08a -} - -.button__tap.is-warning.is-inverted.is-outlined { - background-color: transparent; - border-color: rgba(0,0,0,.7); - color: rgba(0,0,0,.7) -} - -.button__tap.is-warning.is-inverted.is-outlined.is-focused,.button__tap.is-warning.is-inverted.is-outlined.is-hovered,.button__tap.is-warning.is-inverted.is-outlined:focus,.button__tap.is-warning.is-inverted.is-outlined:hover { - background-color: rgba(0,0,0,.7); - color: #ffe08a -} - -.button__tap.is-warning.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-warning.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #ffe08a #ffe08a!important -} - -.button__tap.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-warning.is-inverted.is-outlined { - background-color: transparent; - border-color: rgba(0,0,0,.7); - box-shadow: none; - color: rgba(0,0,0,.7) -} - -.button__tap.is-warning.is-light { - background-color: #fffaeb; - color: #946c00 -} - -.button__tap.is-warning.is-light.is-hovered,.button__tap.is-warning.is-light:hover { - background-color: #fff6de; - border-color: transparent; - color: #946c00 -} - -.button__tap.is-warning.is-light.is-active,.button__tap.is-warning.is-light:active { - background-color: #fff3d1; - border-color: transparent; - color: #946c00 -} - -.button__tap.is-danger { - background-color: #f14668; - border-color: transparent; - color: #fff -} - -.button__tap.is-danger.is-hovered,.button__tap.is-danger:hover { - background-color: #f03a5f; - border-color: transparent; - color: #fff -} - -.button__tap.is-danger.is-focused,.button__tap.is-danger:focus { - border-color: transparent; - color: #fff -} - -.button__tap.is-danger.is-focused:not(:active),.button__tap.is-danger:focus:not(:active) { - box-shadow: 0 0 0 .125em rgba(241,70,104,.25) -} - -.button__tap.is-danger.is-active,.button__tap.is-danger:active { - background-color: #ef2e55; - border-color: transparent; - color: #fff -} - -.button__tap.is-danger[disabled],fieldset[disabled] .button__tap.is-danger { - background-color: #f14668; - border-color: #f14668; - box-shadow: none -} - -.button__tap.is-danger.is-inverted { - background-color: #fff; - color: #f14668 -} - -.button__tap.is-danger.is-inverted.is-hovered,.button__tap.is-danger.is-inverted:hover { - background-color: #f2f2f2 -} - -.button__tap.is-danger.is-inverted[disabled],fieldset[disabled] .button__tap.is-danger.is-inverted { - background-color: #fff; - border-color: transparent; - box-shadow: none; - color: #f14668 -} - -.button__tap.is-danger.is-loading::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-danger.is-outlined { - background-color: transparent; - border-color: #f14668; - color: #f14668 -} - -.button__tap.is-danger.is-outlined.is-focused,.button__tap.is-danger.is-outlined.is-hovered,.button__tap.is-danger.is-outlined:focus,.button__tap.is-danger.is-outlined:hover { - background-color: #f14668; - border-color: #f14668; - color: #fff -} - -.button__tap.is-danger.is-outlined.is-loading::after { - border-color: transparent transparent #f14668 #f14668!important -} - -.button__tap.is-danger.is-outlined.is-loading.is-focused::after,.button__tap.is-danger.is-outlined.is-loading.is-hovered::after,.button__tap.is-danger.is-outlined.is-loading:focus::after,.button__tap.is-danger.is-outlined.is-loading:hover::after { - border-color: transparent transparent #fff #fff!important -} - -.button__tap.is-danger.is-outlined[disabled],fieldset[disabled] .button__tap.is-danger.is-outlined { - background-color: transparent; - border-color: #f14668; - box-shadow: none; - color: #f14668 -} - -.button__tap.is-danger.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - color: #fff -} - -.button__tap.is-danger.is-inverted.is-outlined.is-focused,.button__tap.is-danger.is-inverted.is-outlined.is-hovered,.button__tap.is-danger.is-inverted.is-outlined:focus,.button__tap.is-danger.is-inverted.is-outlined:hover { - background-color: #fff; - color: #f14668 -} - -.button__tap.is-danger.is-inverted.is-outlined.is-loading.is-focused::after,.button__tap.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button__tap.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button__tap.is-danger.is-inverted.is-outlined.is-loading:hover::after { - border-color: transparent transparent #f14668 #f14668!important -} - -.button__tap.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button__tap.is-danger.is-inverted.is-outlined { - background-color: transparent; - border-color: #fff; - box-shadow: none; - color: #fff -} - -.button__tap.is-danger.is-light { - background-color: #feecf0; - color: #cc0f35 -} - -.button__tap.is-danger.is-light.is-hovered,.button__tap.is-danger.is-light:hover { - background-color: #fde0e6; - border-color: transparent; - color: #cc0f35 -} - -.button__tap.is-danger.is-light.is-active,.button__tap.is-danger.is-light:active { - background-color: #fcd4dc; - border-color: transparent; - color: #cc0f35 -} -*/ \ No newline at end of file diff --git a/static/base/css/chassis.css b/static/base/css/chassis.css deleted file mode 100644 index 1cc2f5dc..00000000 --- a/static/base/css/chassis.css +++ /dev/null @@ -1,356 +0,0 @@ -html { - background-color: white; - padding: 1px 3px; -} -body { - padding: 1px 3px; -} -div { - padding: 1px 3px; - margin: 5px; -} -h1, h2, h3, h4,h5, h6, p { - background-color: snow; -} -* * { - outline: 5px solid rgba(255,0,0,.1); -} -* * * { - outline: 3px dashed rgba(255,0,0,.4); -} -* * * * { - outline: 2px dotted rgba(255,0,0,.6); -} -* * * * * { - outline: 1px dotted rgba(255,0,0,.9); -} -* * * * * * { - outline-color: gray; -} - -*::before, *::after { - background: #faa; - border-radius: 3px; - font: normal normal 400 10px/1.2 monospace; - vertical-align: middle; - padding: 1px 3px; - margin: 0 3px; -} -*::before { - content: "("; -} -*::after { - content: ")"; -} - -a::before { content: ""; } -a::after { content: ""; } -abbr::before { content: ""; } -abbr::after { content: ""; } -acronym::before { content: ""; } -acronym::after { content: ""; } -address::before { content: "
"; } -address::after { content: "
"; } -applet::before { content: ""; } -applet::after { content: ""; } -area::before { content: ""; } -area::after { content: ""; } -article::before { content: "
"; } -article::after { content: "
"; } -aside::before { content: ""; } -audio::before { content: ""; } - -b::before { content: ""; } -b::after { content: ""; } -base::before { content: ""; } -base::after { content: ""; } -basefont::before { content: ""; } -basefont::after { content: ""; } -bdi::before { content: ""; } -bdi::after { content: ""; } -bdo::before { content: ""; } -bdo::after { content: ""; } -bgsound::before { content: ""; } -bgsound::after { content: ""; } -big::before { content: ""; } -big::after { content: ""; } -blink::before { content: ""; } -blink::after { content: ""; } -blockquote::before { content: "
"; } -blockquote::after { content: "
"; } -body::before { content: ""; } -body::after { content: ""; } -br::before { content: "
"; } -br::after { content: "
"; } -button::before { content: ""; } - -caption::before { content: ""; } -caption::after { content: ""; } -canvas::before { content: ""; } -canvas::after { content: ""; } -center::before { content: "
"; } -center::after { content: "
"; } -cite::before { content: ""; } -cite::after { content: ""; } -code::before { content: ""; } -code::after { content: ""; } -col::before { content: ""; } -col::after { content: ""; } -colgroup::before { content: ""; } -colgroup::after { content: ""; } -command::before { content: ""; } -command::after { content: ""; } -content::before { content: ""; } -content::after { content: ""; } - -data::before { content: ""; } -data::after { content: ""; } -datalist::before { content: ""; } -datalist::after { content: ""; } -dd::before { content: "
"; } -dd::after { content: "
"; } -del::before { content: ""; } -del::after { content: ""; } -details::before { content: "
"; } -details::after { content: "
"; } -dfn::before { content: ""; } -dfn::after { content: ""; } -dialog::before { content: ""; } -dialog::after { content: ""; } -dir::before { content: ""; } -dir::after { content: ""; } -div::before { content: "
"; } -div::after { content: "
"; } -dl::before { content: "
"; } -dl::after { content: "
"; } -dt::before { content: "
"; } -dt::after { content: "
"; } - -element::before { content: ""; } -element::after { content: ""; } -em::before { content: ""; } -em::after { content: ""; } -embed::before { content: ""; } -embed::after { content: ""; } - -fieldset::before { content: "
"; } -fieldset::after { content: "
"; } -figcaption::before { content: "
"; } -figcaption::after { content: "
"; } -figure::before { content: "
"; } -figure::after { content: "
"; } -font::before { content: ""; } -font::after { content: ""; } -footer::before { content: "
"; } -footer::after { content: "
"; } -form::before { content: "
"; } -form::after { content: "
"; } -frame::before { content: ""; } -frame::after { content: ""; } -frameset::before { content: ""; } -frameset::after { content: ""; } - -h1::before { content: "

"; } -h1::after { content: "

"; } -h2::before { content: "

"; } -h2::after { content: "

"; } -h3::before { content: "

"; } -h3::after { content: "

"; } -h4::before { content: "

"; } -h4::after { content: "

"; } -h5::before { content: "
"; } -h5::after { content: "
"; } -h6::before { content: "
"; } -h6::after { content: "
"; } -head::before { content: ""; } -head::after { content: ""; } -header::before { content: "
"; } -header::after { content: "
"; } -hgroup::before { content: "
"; } -hgroup::after { content: "
"; } -hr::before { content: "
"; } -hr::after { content: ""; } -html::before { content: ""; } -html::after { content: ""; } - -i::before { content: ""; } -i::after { content: ""; } -iframe::before { content: ""; } -image::before { content: ""; } -image::after { content: ""; } -img::before { content: ""; } -img::after { content: ""; } -input::before { content: ""; } -input::after { content: ""; } -ins::before { content: ""; } -ins::after { content: ""; } -isindex::before { content: ""; } -isindex::after { content: ""; } - -kbd::before { content: ""; } -kbd::after { content: ""; } -keygen::before { content: ""; } -keygen::after { content: ""; } - -label::before { content: ""; } -legend::before { content: ""; } -legend::after { content: ""; } -li::before { content: "
  • "; } -li::after { content: "
  • "; } -link::before { content: ""; } -link::after { content: ""; } -listing::before { content: ""; } -listing::after { content: ""; } - -main::before { content: "
    "; } -main::after { content: "
    "; } -map::before { content: ""; } -map::after { content: ""; } -mark::before { content: ""; } -mark::after { content: ""; } -marquee::before { content: ""; } -marquee::after { content: ""; } -menu::before { content: ""; } -menu::after { content: ""; } -menuitem::before { content: ""; } -menuitem::after { content: ""; } -meta::before { content: ""; } -meta::after { content: ""; } -meter::before { content: ""; } -meter::after { content: ""; } -multicol::before { content: ""; } -multicol::after { content: ""; } - -nav::before { content: ""; } -nextid::before { content: ""; } -nextid::after { content: ""; } -nobr::before { content: ""; } -nobr::after { content: ""; } -noembed::before { content: ""; } -noembed::after { content: ""; } -noframes::before { content: ""; } -noframes::after { content: ""; } -noscript::before { content: ""; } - -object::before { content: ""; } -object::after { content: ""; } -ol::before { content: "
      "; } -ol::after { content: "
    "; } -optgroup::before { content: ""; } -optgroup::after { content: ""; } -option::before { content: ""; } -output::before { content: ""; } -output::after { content: ""; } - -p::before { content: "

    "; } -p::after { content: "

    "; } -param::before { content: ""; } -param::after { content: ""; } -picture::before { content: ""; } -picture::after { content: ""; } -plaintext::before { content: ""; } -plaintext::after { content: "</plaintext>"; } -pre::before { content: "<pre>"; } -pre::after { content: "</pre>"; } -progress::before { content: "<progress>"; } -progress::after { content: "</progress>"; } - -q::before { content: "<q>"; } -q::after { content: "</q>"; } - -rb::before { content: "<rb>"; } -rb::after { content: "</rb>"; } -rp::before { content: "<rp>"; } -rp::after { content: "</rp>"; } -rt::before { content: "<rt>"; } -rt::after { content: "</rt>"; } -rtc::before { content: "<rtc>"; } -rtc::after { content: "</rtc>"; } -ruby::before { content: "<ruby>"; } -ruby::after { content: "</ruby>"; } - -s::before { content: "<s>"; } -s::after { content: "</s>"; } -samp::before { content: "<samp>"; } -samp::after { content: "</samp>"; } -script::before { content: "<script>"; } -script::after { content: "</script>"; } -section::before { content: "<section>"; } -section::after { content: "</section>"; } -select::before { content: "<select>"; } -select::after { content: "</select>"; } -shadow::before { content: "<shadow>"; } -shadow::after { content: "</shadow>"; } -slot::before { content: "<slot>"; } -slot::after { content: "</slot>"; } -small::before { content: "<small>"; } -small::after { content: "</small>"; } -source::before { content: "<source>"; } -source::after { content: "</source>"; } -spacer::before { content: "<spacer>"; } -spacer::after { content: "</spacer>"; } -span::before { content: "<span>"; } -span::after { content: "</span>"; } -strike::before { content: "<strike>"; } -strike::after { content: "</strike>"; } -strong::before { content: "<strong>"; } -strong::after { content: "</strong>"; } -style::before { content: "<style>"; } -style::after { content: "<\/style>"; } -sub::before { content: "<sub>"; } -sub::after { content: "</sub>"; } -summary::before { content: "<summary>"; } -summary::after { content: "</summary>"; } -sup::before { content: "<sup>"; } -sup::after { content: "</sup>"; } - -table::before { content: "<table>"; } -table::after { content: "</table>"; } -tbody::before { content: "<tbody>"; } -tbody::after { content: "</tbody>"; } -td::before { content: "<td>"; } -td::after { content: "</td>"; } -template::before { content: "<template>"; } -template::after { content: "</template>"; } -textarea::before { content: "<textarea>"; } -textarea::after { content: "</textarea>"; } -tfoot::before { content: "<tfoot>"; } -tfoot::after { content: "</tfoot>"; } -th::before { content: "<th>"; } -th::after { content: "</th>"; } -thead::before { content: "<thead>"; } -thead::after { content: "</thead>"; } -time::before { content: "<time>"; } -time::after { content: "</time>"; } -title::before { content: "<title>"; } -title::after { content: "</title>"; } -tr::before { content: "<tr>"; } -tr::after { content: "</tr>"; } -track::before { content: "<track>"; } -track::after { content: "</track>"; } -tt::before { content: "<tt>"; } -tt::after { content: "</tt>"; } - -u::before { content: "<u>"; } -u::after { content: "</u>"; } -ul::before { content: "<ul>"; } -ul::after { content: "</ul>"; } - -var::before { content: "<var>"; } -var::after { content: "</var>"; } -video::before { content: "<video>"; } -video::after { content: "</video>"; } - -wbr::before { content: "<wbr>"; } -wbr::after { content: "</wbr>"; } - -xmp::before { content: "<xmp>"; } -xmp::after { content: "</xmp>"; } diff --git a/static/base/css/flex.css b/static/base/css/flex.css deleted file mode 100644 index aa69cae0..00000000 --- a/static/base/css/flex.css +++ /dev/null @@ -1,395 +0,0 @@ -/* CONTAINERS */ - -.flex__container { - display: flex; - flex-wrap: nowrap; - justify-content: flex-start; - position: relative; - max-width: 100%; - width: 100%; - padding: 0 !important; -} -.flex__row, -.flex__col.bp__none { - flex-direction: column; -} -.flex__row.flex__reverse, -.flex__col.flex__reverse.bp__none { - flex-direction: column-reverse; -} -.flex__col, -.flex__row.bp__none { - flex-direction: row; -} -.flex__col.flex__reverse, -.flex__row.flex__reverse.bp__none { - flex-direction: row-reverse; -} - -.flex__wrap { - flex-wrap: wrap; - align-content: flex-start; -} -.flex__wrap-reverse { - flex-wrap: wrap-reverse; - align-content: flex-start; -} - -.flex__align-end { - align-content: flex-end; -} -.flex__align-center { - align-content: center; -} -.flex__align-stretch { - align-content: stretch; -} -.flex__align-space-between { - align-content: space-between; -} -.flex__align-space-around { - align-content: space-around; -} - -.flex__justify-end { - justify-content: flex-end; -} -.flex__justify-center { - justify-content: center; -} -.flex__justify-space-between { - justify-content: space-between; -} -.flex__justify-space-around { - justify-content: space-around; -} -.flex__justify-space-evenly { - justify-content: space-evenly; -} - -.flex__container.flex__end { - align-items: flex-end; -} -.flex__container.flex__center { - align-items: center; -} -.flex__container.flex__stretch { - align-items: stretch; -} -.flex__container.flex__baseline { - align-items: baseline; -} - -/* ITEMS */ - -.flex__item { - padding: 0 !important; - width: 100%; - max-width: 100%; -} -[class*="flex__justify-"] .flex__item { - width: auto; -} - -.flex__grow-1 { - flex-grow: 1; -} -.flex__grow-2 { - flex-grow: 2; -} -.flex__grow-3 { - flex-grow: 3; -} -.flex__grow-4 { - flex-grow: 4; -} -.flex__grow-5 { - flex-grow: 5; -} -.flex__grow-6 { - flex-grow: 6; -} -.flex__grow-7 { - flex-grow: 7; -} -.flex__grow-8 { - flex-grow: 8; -} -.flex__grow-9 { - flex-grow: 9; -} -[class*="flex__grow-"] { - width: auto; -} - -.flex__shrink-1 { - flex-shrink: 1; -} -.flex__shrink-2 { - flex-shrink: 2; -} -.flex__shrink-3 { - flex-shrink: 3; -} -.flex__shrink-4 { - flex-shrink: 4; -} -.flex__shrink-5 { - flex-shrink: 5; -} -.flex__shrink-6 { - flex-shrink: 6; -} -.flex__shrink-7 { - flex-shrink: 7; -} -.flex__shrink-8 { - flex-shrink: 8; -} -.flex__shrink-9 { - flex-shrink: 9; -} -[class*="flex__shrink-"] { - width: auto; -} - -.flex__size-10 { - flex: 0 0 10%; - max-width: 10%; -} -.flex__size-20 { - flex: 0 0 20%; - max-width: 20%; -} -.flex__size-25 { - flex: 0 0 25%; - max-width: 25%; -} -.flex__size-33 { - flex: 0 0 33.3333%; - max-width: 33.3333%; -} -.flex__size-40 { - flex: 0 0 40%; - max-width: 40%; -} -.flex__size-50 { - flex: 0 0 60%; - max-width: 50%; -} -.flex__size-60 { - flex: 0 0 60%; - max-width: 60%; -} -.flex__size-66 { - flex: 0 0 66.6666%; - max-width: 66.6666%; -} -.flex__size-75 { - flex: 0 0 75%; - max-width: 75%; -} -.flex__size-80 { - flex: 0 0 80%; - max-width: 80%; -} -.flex__size-90 { - flex: 0 0 90%; - max-width: 90%; -} -[class*="flex__size-"] { - width: auto; -} - -.flex__offset-10 { - margin-left: 10%; -} -.flex__offset-20 { - margin-left: 20%; -} -.flex__offset-25 { - margin-left: 25%; -} -.flex__offset-33 { - margin-left: 33.3333%; -} -.flex__offset-40 { - margin-left: 40%; -} -.flex__offset-50 { - margin-left: 50%; -} -.flex__offset-60 { - margin-left: 60%; -} -.flex__offset-66 { - margin-left: 66.6666%; -} -.flex__offset-75 { - margin-left: 75%; -} -.flex__offset-80 { - margin-left: 80%; -} -.flex__offset-90 { - margin-left: 90%; -} - -.flex__item.flex__start { - align-self: flex-start; -} -.flex__item.flex__end { - align-self: flex-end; -} -.flex__item.flex__center { - align-self: center; -} -.flex__item.flex__stretch { - align-self: stretch; -} -.flex__item.flex__baseline { - align-self: baseline; -} - -/* BREAKPOINTS */ - -/* SM - Applies <= 568px */ -@media screen and (max-width: 35.5rem) { - .flex__row.bp__sm { - flex-direction: row; - } - .flex__row.flex__reverse.bp__sm { - flex-direction: row-reverse; - } - .flex__col.bp__sm { - flex-direction: column; - } - .flex__col.flex__reverse.bp__sm { - flex-direction: column-reverse; - } - .flex__col.bp__sm .flex__item { - flex: 1 1 auto; - max-width: 100%; - margin-left: 0; - } -} -/* MD - Applies <= 768px */ -@media screen and (max-width: 48rem) { - .flex__row.bp__md { - flex-direction: row; - } - .flex__row.flex__reverse.bp__md { - flex-direction: row-reverse; - } - .flex__col.bp__md { - flex-direction: column; - } - .flex__col.flex__reverse.bp__md { - flex-direction: column-reverse; - } - .flex__col.bp__md .flex__item { - flex: 1 1 auto; - max-width: 100%; - margin-left: 0; - } -} -/* LG - Applies <= 992px */ -@media screen and (max-width: 62rem) { - .flex__row.bp__lg { - flex-direction: row; - } - .flex__row.flex__reverse.bp__lg { - flex-direction: row-reverse; - } - .flex__col.bp__lg { - flex-direction: column; - } - .flex__col.flex__reverse.bp__lg { - flex-direction: column-reverse; - } - .flex__col.bp__lg .flex__item { - flex: 1 1 auto; - max-width: 100%; - margin-left: 0; - } -} -/* XL - Applies <= 1280px */ -@media screen and (max-width: 80rem) { - .flex__row.bp__xl { - flex-direction: row; - } - .flex__row.flex__reverse.bp__xl { - flex-direction: row-reverse; - } - .flex__col.bp__xl { - flex-direction: column; - } - .flex__col.flex__reverse.bp__xl { - flex-direction: column-reverse; - } - .flex__col.bp__xl .flex__item { - flex: 1 1 auto; - max-width: 100%; - margin-left: 0; - } -} -/* X2L - Applies <= 1440px */ -@media screen and (max-width: 90rem) { - .flex__row.bp__x2l { - flex-direction: row; - } - .flex__row.flex__reverse.bp__x2l { - flex-direction: row-reverse; - } - .flex__col.bp__x2l { - flex-direction: column; - } - .flex__col.flex__reverse.bp__x2l { - flex-direction: column-reverse; - } - .flex__col.bp__x2l .flex__item { - flex: 1 1 auto; - max-width: 100%; - margin-left: 0; - } -} -/* X3L - Applies <= 1920px */ -@media screen and (max-width: 120rem) { - .flex__row.bp__x3l { - flex-direction: row; - } - .flex__row.flex__reverse.bp__x3l { - flex-direction: row-reverse; - } - .flex__col.bp__x3l { - flex-direction: column; - } - .flex__col.flex__reverse.bp__x3l { - flex-direction: column-reverse; - } - .flex__col.bp__x3l .flex__item { - flex: 1 1 auto; - max-width: 100%; - margin-left: 0; - } -} -/* X2K - Applies <= 2560px */ -@media screen and (max-width: 160rem) { - .flex__row.bp__x2k { - flex-direction: row; - } - .flex__row.flex__reverse.bp__x2k { - flex-direction: row-reverse; - } - .flex__col.bp__x2k { - flex-direction: column; - } - .flex__col.flex__reverse.bp__x2k { - flex-direction: column-reverse; - } - .flex__col.bp__x2k .flex__item { - flex: 1 1 auto; - max-width: 100%; - margin-left: 0; - } -} diff --git a/static/base/css/icons.min.css b/static/base/css/icons.min.css deleted file mode 100644 index 481fffb0..00000000 --- a/static/base/css/icons.min.css +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Bootstrap Icons v1.11.1 (https://icons.getbootstrap.com/) - * Copyright 2019-2023 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/icons/blob/main/LICENSE) - */@font-face{font-display:block;font-family:bootstrap-icons;src:url("../fonts/icons.woff2?v=1.11.1") format("woff2"),url("../fonts/icons.woff?v=1.11.1") format("woff")}.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{display:inline-block;font-family:bootstrap-icons!important;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;vertical-align:-.125em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.bi-123::before{content:"\f67f"}.bi-alarm-fill::before{content:"\f101"}.bi-alarm::before{content:"\f102"}.bi-align-bottom::before{content:"\f103"}.bi-align-center::before{content:"\f104"}.bi-align-end::before{content:"\f105"}.bi-align-middle::before{content:"\f106"}.bi-align-start::before{content:"\f107"}.bi-align-top::before{content:"\f108"}.bi-alt::before{content:"\f109"}.bi-app-indicator::before{content:"\f10a"}.bi-app::before{content:"\f10b"}.bi-archive-fill::before{content:"\f10c"}.bi-archive::before{content:"\f10d"}.bi-arrow-90deg-down::before{content:"\f10e"}.bi-arrow-90deg-left::before{content:"\f10f"}.bi-arrow-90deg-right::before{content:"\f110"}.bi-arrow-90deg-up::before{content:"\f111"}.bi-arrow-bar-down::before{content:"\f112"}.bi-arrow-bar-left::before{content:"\f113"}.bi-arrow-bar-right::before{content:"\f114"}.bi-arrow-bar-up::before{content:"\f115"}.bi-arrow-clockwise::before{content:"\f116"}.bi-arrow-counterclockwise::before{content:"\f117"}.bi-arrow-down-circle-fill::before{content:"\f118"}.bi-arrow-down-circle::before{content:"\f119"}.bi-arrow-down-left-circle-fill::before{content:"\f11a"}.bi-arrow-down-left-circle::before{content:"\f11b"}.bi-arrow-down-left-square-fill::before{content:"\f11c"}.bi-arrow-down-left-square::before{content:"\f11d"}.bi-arrow-down-left::before{content:"\f11e"}.bi-arrow-down-right-circle-fill::before{content:"\f11f"}.bi-arrow-down-right-circle::before{content:"\f120"}.bi-arrow-down-right-square-fill::before{content:"\f121"}.bi-arrow-down-right-square::before{content:"\f122"}.bi-arrow-down-right::before{content:"\f123"}.bi-arrow-down-short::before{content:"\f124"}.bi-arrow-down-square-fill::before{content:"\f125"}.bi-arrow-down-square::before{content:"\f126"}.bi-arrow-down-up::before{content:"\f127"}.bi-arrow-down::before{content:"\f128"}.bi-arrow-left-circle-fill::before{content:"\f129"}.bi-arrow-left-circle::before{content:"\f12a"}.bi-arrow-left-right::before{content:"\f12b"}.bi-arrow-left-short::before{content:"\f12c"}.bi-arrow-left-square-fill::before{content:"\f12d"}.bi-arrow-left-square::before{content:"\f12e"}.bi-arrow-left::before{content:"\f12f"}.bi-arrow-repeat::before{content:"\f130"}.bi-arrow-return-left::before{content:"\f131"}.bi-arrow-return-right::before{content:"\f132"}.bi-arrow-right-circle-fill::before{content:"\f133"}.bi-arrow-right-circle::before{content:"\f134"}.bi-arrow-right-short::before{content:"\f135"}.bi-arrow-right-square-fill::before{content:"\f136"}.bi-arrow-right-square::before{content:"\f137"}.bi-arrow-right::before{content:"\f138"}.bi-arrow-up-circle-fill::before{content:"\f139"}.bi-arrow-up-circle::before{content:"\f13a"}.bi-arrow-up-left-circle-fill::before{content:"\f13b"}.bi-arrow-up-left-circle::before{content:"\f13c"}.bi-arrow-up-left-square-fill::before{content:"\f13d"}.bi-arrow-up-left-square::before{content:"\f13e"}.bi-arrow-up-left::before{content:"\f13f"}.bi-arrow-up-right-circle-fill::before{content:"\f140"}.bi-arrow-up-right-circle::before{content:"\f141"}.bi-arrow-up-right-square-fill::before{content:"\f142"}.bi-arrow-up-right-square::before{content:"\f143"}.bi-arrow-up-right::before{content:"\f144"}.bi-arrow-up-short::before{content:"\f145"}.bi-arrow-up-square-fill::before{content:"\f146"}.bi-arrow-up-square::before{content:"\f147"}.bi-arrow-up::before{content:"\f148"}.bi-arrows-angle-contract::before{content:"\f149"}.bi-arrows-angle-expand::before{content:"\f14a"}.bi-arrows-collapse::before{content:"\f14b"}.bi-arrows-expand::before{content:"\f14c"}.bi-arrows-fullscreen::before{content:"\f14d"}.bi-arrows-move::before{content:"\f14e"}.bi-aspect-ratio-fill::before{content:"\f14f"}.bi-aspect-ratio::before{content:"\f150"}.bi-asterisk::before{content:"\f151"}.bi-at::before{content:"\f152"}.bi-award-fill::before{content:"\f153"}.bi-award::before{content:"\f154"}.bi-back::before{content:"\f155"}.bi-backspace-fill::before{content:"\f156"}.bi-backspace-reverse-fill::before{content:"\f157"}.bi-backspace-reverse::before{content:"\f158"}.bi-backspace::before{content:"\f159"}.bi-badge-3d-fill::before{content:"\f15a"}.bi-badge-3d::before{content:"\f15b"}.bi-badge-4k-fill::before{content:"\f15c"}.bi-badge-4k::before{content:"\f15d"}.bi-badge-8k-fill::before{content:"\f15e"}.bi-badge-8k::before{content:"\f15f"}.bi-badge-ad-fill::before{content:"\f160"}.bi-badge-ad::before{content:"\f161"}.bi-badge-ar-fill::before{content:"\f162"}.bi-badge-ar::before{content:"\f163"}.bi-badge-cc-fill::before{content:"\f164"}.bi-badge-cc::before{content:"\f165"}.bi-badge-hd-fill::before{content:"\f166"}.bi-badge-hd::before{content:"\f167"}.bi-badge-tm-fill::before{content:"\f168"}.bi-badge-tm::before{content:"\f169"}.bi-badge-vo-fill::before{content:"\f16a"}.bi-badge-vo::before{content:"\f16b"}.bi-badge-vr-fill::before{content:"\f16c"}.bi-badge-vr::before{content:"\f16d"}.bi-badge-wc-fill::before{content:"\f16e"}.bi-badge-wc::before{content:"\f16f"}.bi-bag-check-fill::before{content:"\f170"}.bi-bag-check::before{content:"\f171"}.bi-bag-dash-fill::before{content:"\f172"}.bi-bag-dash::before{content:"\f173"}.bi-bag-fill::before{content:"\f174"}.bi-bag-plus-fill::before{content:"\f175"}.bi-bag-plus::before{content:"\f176"}.bi-bag-x-fill::before{content:"\f177"}.bi-bag-x::before{content:"\f178"}.bi-bag::before{content:"\f179"}.bi-bar-chart-fill::before{content:"\f17a"}.bi-bar-chart-line-fill::before{content:"\f17b"}.bi-bar-chart-line::before{content:"\f17c"}.bi-bar-chart-steps::before{content:"\f17d"}.bi-bar-chart::before{content:"\f17e"}.bi-basket-fill::before{content:"\f17f"}.bi-basket::before{content:"\f180"}.bi-basket2-fill::before{content:"\f181"}.bi-basket2::before{content:"\f182"}.bi-basket3-fill::before{content:"\f183"}.bi-basket3::before{content:"\f184"}.bi-battery-charging::before{content:"\f185"}.bi-battery-full::before{content:"\f186"}.bi-battery-half::before{content:"\f187"}.bi-battery::before{content:"\f188"}.bi-bell-fill::before{content:"\f189"}.bi-bell::before{content:"\f18a"}.bi-bezier::before{content:"\f18b"}.bi-bezier2::before{content:"\f18c"}.bi-bicycle::before{content:"\f18d"}.bi-binoculars-fill::before{content:"\f18e"}.bi-binoculars::before{content:"\f18f"}.bi-blockquote-left::before{content:"\f190"}.bi-blockquote-right::before{content:"\f191"}.bi-book-fill::before{content:"\f192"}.bi-book-half::before{content:"\f193"}.bi-book::before{content:"\f194"}.bi-bookmark-check-fill::before{content:"\f195"}.bi-bookmark-check::before{content:"\f196"}.bi-bookmark-dash-fill::before{content:"\f197"}.bi-bookmark-dash::before{content:"\f198"}.bi-bookmark-fill::before{content:"\f199"}.bi-bookmark-heart-fill::before{content:"\f19a"}.bi-bookmark-heart::before{content:"\f19b"}.bi-bookmark-plus-fill::before{content:"\f19c"}.bi-bookmark-plus::before{content:"\f19d"}.bi-bookmark-star-fill::before{content:"\f19e"}.bi-bookmark-star::before{content:"\f19f"}.bi-bookmark-x-fill::before{content:"\f1a0"}.bi-bookmark-x::before{content:"\f1a1"}.bi-bookmark::before{content:"\f1a2"}.bi-bookmarks-fill::before{content:"\f1a3"}.bi-bookmarks::before{content:"\f1a4"}.bi-bookshelf::before{content:"\f1a5"}.bi-bootstrap-fill::before{content:"\f1a6"}.bi-bootstrap-reboot::before{content:"\f1a7"}.bi-bootstrap::before{content:"\f1a8"}.bi-border-all::before{content:"\f1a9"}.bi-border-bottom::before{content:"\f1aa"}.bi-border-center::before{content:"\f1ab"}.bi-border-inner::before{content:"\f1ac"}.bi-border-left::before{content:"\f1ad"}.bi-border-middle::before{content:"\f1ae"}.bi-border-outer::before{content:"\f1af"}.bi-border-right::before{content:"\f1b0"}.bi-border-style::before{content:"\f1b1"}.bi-border-top::before{content:"\f1b2"}.bi-border-width::before{content:"\f1b3"}.bi-border::before{content:"\f1b4"}.bi-bounding-box-circles::before{content:"\f1b5"}.bi-bounding-box::before{content:"\f1b6"}.bi-box-arrow-down-left::before{content:"\f1b7"}.bi-box-arrow-down-right::before{content:"\f1b8"}.bi-box-arrow-down::before{content:"\f1b9"}.bi-box-arrow-in-down-left::before{content:"\f1ba"}.bi-box-arrow-in-down-right::before{content:"\f1bb"}.bi-box-arrow-in-down::before{content:"\f1bc"}.bi-box-arrow-in-left::before{content:"\f1bd"}.bi-box-arrow-in-right::before{content:"\f1be"}.bi-box-arrow-in-up-left::before{content:"\f1bf"}.bi-box-arrow-in-up-right::before{content:"\f1c0"}.bi-box-arrow-in-up::before{content:"\f1c1"}.bi-box-arrow-left::before{content:"\f1c2"}.bi-box-arrow-right::before{content:"\f1c3"}.bi-box-arrow-up-left::before{content:"\f1c4"}.bi-box-arrow-up-right::before{content:"\f1c5"}.bi-box-arrow-up::before{content:"\f1c6"}.bi-box-seam::before{content:"\f1c7"}.bi-box::before{content:"\f1c8"}.bi-braces::before{content:"\f1c9"}.bi-bricks::before{content:"\f1ca"}.bi-briefcase-fill::before{content:"\f1cb"}.bi-briefcase::before{content:"\f1cc"}.bi-brightness-alt-high-fill::before{content:"\f1cd"}.bi-brightness-alt-high::before{content:"\f1ce"}.bi-brightness-alt-low-fill::before{content:"\f1cf"}.bi-brightness-alt-low::before{content:"\f1d0"}.bi-brightness-high-fill::before{content:"\f1d1"}.bi-brightness-high::before{content:"\f1d2"}.bi-brightness-low-fill::before{content:"\f1d3"}.bi-brightness-low::before{content:"\f1d4"}.bi-broadcast-pin::before{content:"\f1d5"}.bi-broadcast::before{content:"\f1d6"}.bi-brush-fill::before{content:"\f1d7"}.bi-brush::before{content:"\f1d8"}.bi-bucket-fill::before{content:"\f1d9"}.bi-bucket::before{content:"\f1da"}.bi-bug-fill::before{content:"\f1db"}.bi-bug::before{content:"\f1dc"}.bi-building::before{content:"\f1dd"}.bi-bullseye::before{content:"\f1de"}.bi-calculator-fill::before{content:"\f1df"}.bi-calculator::before{content:"\f1e0"}.bi-calendar-check-fill::before{content:"\f1e1"}.bi-calendar-check::before{content:"\f1e2"}.bi-calendar-date-fill::before{content:"\f1e3"}.bi-calendar-date::before{content:"\f1e4"}.bi-calendar-day-fill::before{content:"\f1e5"}.bi-calendar-day::before{content:"\f1e6"}.bi-calendar-event-fill::before{content:"\f1e7"}.bi-calendar-event::before{content:"\f1e8"}.bi-calendar-fill::before{content:"\f1e9"}.bi-calendar-minus-fill::before{content:"\f1ea"}.bi-calendar-minus::before{content:"\f1eb"}.bi-calendar-month-fill::before{content:"\f1ec"}.bi-calendar-month::before{content:"\f1ed"}.bi-calendar-plus-fill::before{content:"\f1ee"}.bi-calendar-plus::before{content:"\f1ef"}.bi-calendar-range-fill::before{content:"\f1f0"}.bi-calendar-range::before{content:"\f1f1"}.bi-calendar-week-fill::before{content:"\f1f2"}.bi-calendar-week::before{content:"\f1f3"}.bi-calendar-x-fill::before{content:"\f1f4"}.bi-calendar-x::before{content:"\f1f5"}.bi-calendar::before{content:"\f1f6"}.bi-calendar2-check-fill::before{content:"\f1f7"}.bi-calendar2-check::before{content:"\f1f8"}.bi-calendar2-date-fill::before{content:"\f1f9"}.bi-calendar2-date::before{content:"\f1fa"}.bi-calendar2-day-fill::before{content:"\f1fb"}.bi-calendar2-day::before{content:"\f1fc"}.bi-calendar2-event-fill::before{content:"\f1fd"}.bi-calendar2-event::before{content:"\f1fe"}.bi-calendar2-fill::before{content:"\f1ff"}.bi-calendar2-minus-fill::before{content:"\f200"}.bi-calendar2-minus::before{content:"\f201"}.bi-calendar2-month-fill::before{content:"\f202"}.bi-calendar2-month::before{content:"\f203"}.bi-calendar2-plus-fill::before{content:"\f204"}.bi-calendar2-plus::before{content:"\f205"}.bi-calendar2-range-fill::before{content:"\f206"}.bi-calendar2-range::before{content:"\f207"}.bi-calendar2-week-fill::before{content:"\f208"}.bi-calendar2-week::before{content:"\f209"}.bi-calendar2-x-fill::before{content:"\f20a"}.bi-calendar2-x::before{content:"\f20b"}.bi-calendar2::before{content:"\f20c"}.bi-calendar3-event-fill::before{content:"\f20d"}.bi-calendar3-event::before{content:"\f20e"}.bi-calendar3-fill::before{content:"\f20f"}.bi-calendar3-range-fill::before{content:"\f210"}.bi-calendar3-range::before{content:"\f211"}.bi-calendar3-week-fill::before{content:"\f212"}.bi-calendar3-week::before{content:"\f213"}.bi-calendar3::before{content:"\f214"}.bi-calendar4-event::before{content:"\f215"}.bi-calendar4-range::before{content:"\f216"}.bi-calendar4-week::before{content:"\f217"}.bi-calendar4::before{content:"\f218"}.bi-camera-fill::before{content:"\f219"}.bi-camera-reels-fill::before{content:"\f21a"}.bi-camera-reels::before{content:"\f21b"}.bi-camera-video-fill::before{content:"\f21c"}.bi-camera-video-off-fill::before{content:"\f21d"}.bi-camera-video-off::before{content:"\f21e"}.bi-camera-video::before{content:"\f21f"}.bi-camera::before{content:"\f220"}.bi-camera2::before{content:"\f221"}.bi-capslock-fill::before{content:"\f222"}.bi-capslock::before{content:"\f223"}.bi-card-checklist::before{content:"\f224"}.bi-card-heading::before{content:"\f225"}.bi-card-image::before{content:"\f226"}.bi-card-list::before{content:"\f227"}.bi-card-text::before{content:"\f228"}.bi-caret-down-fill::before{content:"\f229"}.bi-caret-down-square-fill::before{content:"\f22a"}.bi-caret-down-square::before{content:"\f22b"}.bi-caret-down::before{content:"\f22c"}.bi-caret-left-fill::before{content:"\f22d"}.bi-caret-left-square-fill::before{content:"\f22e"}.bi-caret-left-square::before{content:"\f22f"}.bi-caret-left::before{content:"\f230"}.bi-caret-right-fill::before{content:"\f231"}.bi-caret-right-square-fill::before{content:"\f232"}.bi-caret-right-square::before{content:"\f233"}.bi-caret-right::before{content:"\f234"}.bi-caret-up-fill::before{content:"\f235"}.bi-caret-up-square-fill::before{content:"\f236"}.bi-caret-up-square::before{content:"\f237"}.bi-caret-up::before{content:"\f238"}.bi-cart-check-fill::before{content:"\f239"}.bi-cart-check::before{content:"\f23a"}.bi-cart-dash-fill::before{content:"\f23b"}.bi-cart-dash::before{content:"\f23c"}.bi-cart-fill::before{content:"\f23d"}.bi-cart-plus-fill::before{content:"\f23e"}.bi-cart-plus::before{content:"\f23f"}.bi-cart-x-fill::before{content:"\f240"}.bi-cart-x::before{content:"\f241"}.bi-cart::before{content:"\f242"}.bi-cart2::before{content:"\f243"}.bi-cart3::before{content:"\f244"}.bi-cart4::before{content:"\f245"}.bi-cash-stack::before{content:"\f246"}.bi-cash::before{content:"\f247"}.bi-cast::before{content:"\f248"}.bi-chat-dots-fill::before{content:"\f249"}.bi-chat-dots::before{content:"\f24a"}.bi-chat-fill::before{content:"\f24b"}.bi-chat-left-dots-fill::before{content:"\f24c"}.bi-chat-left-dots::before{content:"\f24d"}.bi-chat-left-fill::before{content:"\f24e"}.bi-chat-left-quote-fill::before{content:"\f24f"}.bi-chat-left-quote::before{content:"\f250"}.bi-chat-left-text-fill::before{content:"\f251"}.bi-chat-left-text::before{content:"\f252"}.bi-chat-left::before{content:"\f253"}.bi-chat-quote-fill::before{content:"\f254"}.bi-chat-quote::before{content:"\f255"}.bi-chat-right-dots-fill::before{content:"\f256"}.bi-chat-right-dots::before{content:"\f257"}.bi-chat-right-fill::before{content:"\f258"}.bi-chat-right-quote-fill::before{content:"\f259"}.bi-chat-right-quote::before{content:"\f25a"}.bi-chat-right-text-fill::before{content:"\f25b"}.bi-chat-right-text::before{content:"\f25c"}.bi-chat-right::before{content:"\f25d"}.bi-chat-square-dots-fill::before{content:"\f25e"}.bi-chat-square-dots::before{content:"\f25f"}.bi-chat-square-fill::before{content:"\f260"}.bi-chat-square-quote-fill::before{content:"\f261"}.bi-chat-square-quote::before{content:"\f262"}.bi-chat-square-text-fill::before{content:"\f263"}.bi-chat-square-text::before{content:"\f264"}.bi-chat-square::before{content:"\f265"}.bi-chat-text-fill::before{content:"\f266"}.bi-chat-text::before{content:"\f267"}.bi-chat::before{content:"\f268"}.bi-check-all::before{content:"\f269"}.bi-check-circle-fill::before{content:"\f26a"}.bi-check-circle::before{content:"\f26b"}.bi-check-square-fill::before{content:"\f26c"}.bi-check-square::before{content:"\f26d"}.bi-check::before{content:"\f26e"}.bi-check2-all::before{content:"\f26f"}.bi-check2-circle::before{content:"\f270"}.bi-check2-square::before{content:"\f271"}.bi-check2::before{content:"\f272"}.bi-chevron-bar-contract::before{content:"\f273"}.bi-chevron-bar-down::before{content:"\f274"}.bi-chevron-bar-expand::before{content:"\f275"}.bi-chevron-bar-left::before{content:"\f276"}.bi-chevron-bar-right::before{content:"\f277"}.bi-chevron-bar-up::before{content:"\f278"}.bi-chevron-compact-down::before{content:"\f279"}.bi-chevron-compact-left::before{content:"\f27a"}.bi-chevron-compact-right::before{content:"\f27b"}.bi-chevron-compact-up::before{content:"\f27c"}.bi-chevron-contract::before{content:"\f27d"}.bi-chevron-double-down::before{content:"\f27e"}.bi-chevron-double-left::before{content:"\f27f"}.bi-chevron-double-right::before{content:"\f280"}.bi-chevron-double-up::before{content:"\f281"}.bi-chevron-down::before{content:"\f282"}.bi-chevron-expand::before{content:"\f283"}.bi-chevron-left::before{content:"\f284"}.bi-chevron-right::before{content:"\f285"}.bi-chevron-up::before{content:"\f286"}.bi-circle-fill::before{content:"\f287"}.bi-circle-half::before{content:"\f288"}.bi-circle-square::before{content:"\f289"}.bi-circle::before{content:"\f28a"}.bi-clipboard-check::before{content:"\f28b"}.bi-clipboard-data::before{content:"\f28c"}.bi-clipboard-minus::before{content:"\f28d"}.bi-clipboard-plus::before{content:"\f28e"}.bi-clipboard-x::before{content:"\f28f"}.bi-clipboard::before{content:"\f290"}.bi-clock-fill::before{content:"\f291"}.bi-clock-history::before{content:"\f292"}.bi-clock::before{content:"\f293"}.bi-cloud-arrow-down-fill::before{content:"\f294"}.bi-cloud-arrow-down::before{content:"\f295"}.bi-cloud-arrow-up-fill::before{content:"\f296"}.bi-cloud-arrow-up::before{content:"\f297"}.bi-cloud-check-fill::before{content:"\f298"}.bi-cloud-check::before{content:"\f299"}.bi-cloud-download-fill::before{content:"\f29a"}.bi-cloud-download::before{content:"\f29b"}.bi-cloud-drizzle-fill::before{content:"\f29c"}.bi-cloud-drizzle::before{content:"\f29d"}.bi-cloud-fill::before{content:"\f29e"}.bi-cloud-fog-fill::before{content:"\f29f"}.bi-cloud-fog::before{content:"\f2a0"}.bi-cloud-fog2-fill::before{content:"\f2a1"}.bi-cloud-fog2::before{content:"\f2a2"}.bi-cloud-hail-fill::before{content:"\f2a3"}.bi-cloud-hail::before{content:"\f2a4"}.bi-cloud-haze-fill::before{content:"\f2a6"}.bi-cloud-haze::before{content:"\f2a7"}.bi-cloud-haze2-fill::before{content:"\f2a8"}.bi-cloud-lightning-fill::before{content:"\f2a9"}.bi-cloud-lightning-rain-fill::before{content:"\f2aa"}.bi-cloud-lightning-rain::before{content:"\f2ab"}.bi-cloud-lightning::before{content:"\f2ac"}.bi-cloud-minus-fill::before{content:"\f2ad"}.bi-cloud-minus::before{content:"\f2ae"}.bi-cloud-moon-fill::before{content:"\f2af"}.bi-cloud-moon::before{content:"\f2b0"}.bi-cloud-plus-fill::before{content:"\f2b1"}.bi-cloud-plus::before{content:"\f2b2"}.bi-cloud-rain-fill::before{content:"\f2b3"}.bi-cloud-rain-heavy-fill::before{content:"\f2b4"}.bi-cloud-rain-heavy::before{content:"\f2b5"}.bi-cloud-rain::before{content:"\f2b6"}.bi-cloud-slash-fill::before{content:"\f2b7"}.bi-cloud-slash::before{content:"\f2b8"}.bi-cloud-sleet-fill::before{content:"\f2b9"}.bi-cloud-sleet::before{content:"\f2ba"}.bi-cloud-snow-fill::before{content:"\f2bb"}.bi-cloud-snow::before{content:"\f2bc"}.bi-cloud-sun-fill::before{content:"\f2bd"}.bi-cloud-sun::before{content:"\f2be"}.bi-cloud-upload-fill::before{content:"\f2bf"}.bi-cloud-upload::before{content:"\f2c0"}.bi-cloud::before{content:"\f2c1"}.bi-clouds-fill::before{content:"\f2c2"}.bi-clouds::before{content:"\f2c3"}.bi-cloudy-fill::before{content:"\f2c4"}.bi-cloudy::before{content:"\f2c5"}.bi-code-slash::before{content:"\f2c6"}.bi-code-square::before{content:"\f2c7"}.bi-code::before{content:"\f2c8"}.bi-collection-fill::before{content:"\f2c9"}.bi-collection-play-fill::before{content:"\f2ca"}.bi-collection-play::before{content:"\f2cb"}.bi-collection::before{content:"\f2cc"}.bi-columns-gap::before{content:"\f2cd"}.bi-columns::before{content:"\f2ce"}.bi-command::before{content:"\f2cf"}.bi-compass-fill::before{content:"\f2d0"}.bi-compass::before{content:"\f2d1"}.bi-cone-striped::before{content:"\f2d2"}.bi-cone::before{content:"\f2d3"}.bi-controller::before{content:"\f2d4"}.bi-cpu-fill::before{content:"\f2d5"}.bi-cpu::before{content:"\f2d6"}.bi-credit-card-2-back-fill::before{content:"\f2d7"}.bi-credit-card-2-back::before{content:"\f2d8"}.bi-credit-card-2-front-fill::before{content:"\f2d9"}.bi-credit-card-2-front::before{content:"\f2da"}.bi-credit-card-fill::before{content:"\f2db"}.bi-credit-card::before{content:"\f2dc"}.bi-crop::before{content:"\f2dd"}.bi-cup-fill::before{content:"\f2de"}.bi-cup-straw::before{content:"\f2df"}.bi-cup::before{content:"\f2e0"}.bi-cursor-fill::before{content:"\f2e1"}.bi-cursor-text::before{content:"\f2e2"}.bi-cursor::before{content:"\f2e3"}.bi-dash-circle-dotted::before{content:"\f2e4"}.bi-dash-circle-fill::before{content:"\f2e5"}.bi-dash-circle::before{content:"\f2e6"}.bi-dash-square-dotted::before{content:"\f2e7"}.bi-dash-square-fill::before{content:"\f2e8"}.bi-dash-square::before{content:"\f2e9"}.bi-dash::before{content:"\f2ea"}.bi-diagram-2-fill::before{content:"\f2eb"}.bi-diagram-2::before{content:"\f2ec"}.bi-diagram-3-fill::before{content:"\f2ed"}.bi-diagram-3::before{content:"\f2ee"}.bi-diamond-fill::before{content:"\f2ef"}.bi-diamond-half::before{content:"\f2f0"}.bi-diamond::before{content:"\f2f1"}.bi-dice-1-fill::before{content:"\f2f2"}.bi-dice-1::before{content:"\f2f3"}.bi-dice-2-fill::before{content:"\f2f4"}.bi-dice-2::before{content:"\f2f5"}.bi-dice-3-fill::before{content:"\f2f6"}.bi-dice-3::before{content:"\f2f7"}.bi-dice-4-fill::before{content:"\f2f8"}.bi-dice-4::before{content:"\f2f9"}.bi-dice-5-fill::before{content:"\f2fa"}.bi-dice-5::before{content:"\f2fb"}.bi-dice-6-fill::before{content:"\f2fc"}.bi-dice-6::before{content:"\f2fd"}.bi-disc-fill::before{content:"\f2fe"}.bi-disc::before{content:"\f2ff"}.bi-discord::before{content:"\f300"}.bi-display-fill::before{content:"\f301"}.bi-display::before{content:"\f302"}.bi-distribute-horizontal::before{content:"\f303"}.bi-distribute-vertical::before{content:"\f304"}.bi-door-closed-fill::before{content:"\f305"}.bi-door-closed::before{content:"\f306"}.bi-door-open-fill::before{content:"\f307"}.bi-door-open::before{content:"\f308"}.bi-dot::before{content:"\f309"}.bi-download::before{content:"\f30a"}.bi-droplet-fill::before{content:"\f30b"}.bi-droplet-half::before{content:"\f30c"}.bi-droplet::before{content:"\f30d"}.bi-earbuds::before{content:"\f30e"}.bi-easel-fill::before{content:"\f30f"}.bi-easel::before{content:"\f310"}.bi-egg-fill::before{content:"\f311"}.bi-egg-fried::before{content:"\f312"}.bi-egg::before{content:"\f313"}.bi-eject-fill::before{content:"\f314"}.bi-eject::before{content:"\f315"}.bi-emoji-angry-fill::before{content:"\f316"}.bi-emoji-angry::before{content:"\f317"}.bi-emoji-dizzy-fill::before{content:"\f318"}.bi-emoji-dizzy::before{content:"\f319"}.bi-emoji-expressionless-fill::before{content:"\f31a"}.bi-emoji-expressionless::before{content:"\f31b"}.bi-emoji-frown-fill::before{content:"\f31c"}.bi-emoji-frown::before{content:"\f31d"}.bi-emoji-heart-eyes-fill::before{content:"\f31e"}.bi-emoji-heart-eyes::before{content:"\f31f"}.bi-emoji-laughing-fill::before{content:"\f320"}.bi-emoji-laughing::before{content:"\f321"}.bi-emoji-neutral-fill::before{content:"\f322"}.bi-emoji-neutral::before{content:"\f323"}.bi-emoji-smile-fill::before{content:"\f324"}.bi-emoji-smile-upside-down-fill::before{content:"\f325"}.bi-emoji-smile-upside-down::before{content:"\f326"}.bi-emoji-smile::before{content:"\f327"}.bi-emoji-sunglasses-fill::before{content:"\f328"}.bi-emoji-sunglasses::before{content:"\f329"}.bi-emoji-wink-fill::before{content:"\f32a"}.bi-emoji-wink::before{content:"\f32b"}.bi-envelope-fill::before{content:"\f32c"}.bi-envelope-open-fill::before{content:"\f32d"}.bi-envelope-open::before{content:"\f32e"}.bi-envelope::before{content:"\f32f"}.bi-eraser-fill::before{content:"\f330"}.bi-eraser::before{content:"\f331"}.bi-exclamation-circle-fill::before{content:"\f332"}.bi-exclamation-circle::before{content:"\f333"}.bi-exclamation-diamond-fill::before{content:"\f334"}.bi-exclamation-diamond::before{content:"\f335"}.bi-exclamation-octagon-fill::before{content:"\f336"}.bi-exclamation-octagon::before{content:"\f337"}.bi-exclamation-square-fill::before{content:"\f338"}.bi-exclamation-square::before{content:"\f339"}.bi-exclamation-triangle-fill::before{content:"\f33a"}.bi-exclamation-triangle::before{content:"\f33b"}.bi-exclamation::before{content:"\f33c"}.bi-exclude::before{content:"\f33d"}.bi-eye-fill::before{content:"\f33e"}.bi-eye-slash-fill::before{content:"\f33f"}.bi-eye-slash::before{content:"\f340"}.bi-eye::before{content:"\f341"}.bi-eyedropper::before{content:"\f342"}.bi-eyeglasses::before{content:"\f343"}.bi-facebook::before{content:"\f344"}.bi-file-arrow-down-fill::before{content:"\f345"}.bi-file-arrow-down::before{content:"\f346"}.bi-file-arrow-up-fill::before{content:"\f347"}.bi-file-arrow-up::before{content:"\f348"}.bi-file-bar-graph-fill::before{content:"\f349"}.bi-file-bar-graph::before{content:"\f34a"}.bi-file-binary-fill::before{content:"\f34b"}.bi-file-binary::before{content:"\f34c"}.bi-file-break-fill::before{content:"\f34d"}.bi-file-break::before{content:"\f34e"}.bi-file-check-fill::before{content:"\f34f"}.bi-file-check::before{content:"\f350"}.bi-file-code-fill::before{content:"\f351"}.bi-file-code::before{content:"\f352"}.bi-file-diff-fill::before{content:"\f353"}.bi-file-diff::before{content:"\f354"}.bi-file-earmark-arrow-down-fill::before{content:"\f355"}.bi-file-earmark-arrow-down::before{content:"\f356"}.bi-file-earmark-arrow-up-fill::before{content:"\f357"}.bi-file-earmark-arrow-up::before{content:"\f358"}.bi-file-earmark-bar-graph-fill::before{content:"\f359"}.bi-file-earmark-bar-graph::before{content:"\f35a"}.bi-file-earmark-binary-fill::before{content:"\f35b"}.bi-file-earmark-binary::before{content:"\f35c"}.bi-file-earmark-break-fill::before{content:"\f35d"}.bi-file-earmark-break::before{content:"\f35e"}.bi-file-earmark-check-fill::before{content:"\f35f"}.bi-file-earmark-check::before{content:"\f360"}.bi-file-earmark-code-fill::before{content:"\f361"}.bi-file-earmark-code::before{content:"\f362"}.bi-file-earmark-diff-fill::before{content:"\f363"}.bi-file-earmark-diff::before{content:"\f364"}.bi-file-earmark-easel-fill::before{content:"\f365"}.bi-file-earmark-easel::before{content:"\f366"}.bi-file-earmark-excel-fill::before{content:"\f367"}.bi-file-earmark-excel::before{content:"\f368"}.bi-file-earmark-fill::before{content:"\f369"}.bi-file-earmark-font-fill::before{content:"\f36a"}.bi-file-earmark-font::before{content:"\f36b"}.bi-file-earmark-image-fill::before{content:"\f36c"}.bi-file-earmark-image::before{content:"\f36d"}.bi-file-earmark-lock-fill::before{content:"\f36e"}.bi-file-earmark-lock::before{content:"\f36f"}.bi-file-earmark-lock2-fill::before{content:"\f370"}.bi-file-earmark-lock2::before{content:"\f371"}.bi-file-earmark-medical-fill::before{content:"\f372"}.bi-file-earmark-medical::before{content:"\f373"}.bi-file-earmark-minus-fill::before{content:"\f374"}.bi-file-earmark-minus::before{content:"\f375"}.bi-file-earmark-music-fill::before{content:"\f376"}.bi-file-earmark-music::before{content:"\f377"}.bi-file-earmark-person-fill::before{content:"\f378"}.bi-file-earmark-person::before{content:"\f379"}.bi-file-earmark-play-fill::before{content:"\f37a"}.bi-file-earmark-play::before{content:"\f37b"}.bi-file-earmark-plus-fill::before{content:"\f37c"}.bi-file-earmark-plus::before{content:"\f37d"}.bi-file-earmark-post-fill::before{content:"\f37e"}.bi-file-earmark-post::before{content:"\f37f"}.bi-file-earmark-ppt-fill::before{content:"\f380"}.bi-file-earmark-ppt::before{content:"\f381"}.bi-file-earmark-richtext-fill::before{content:"\f382"}.bi-file-earmark-richtext::before{content:"\f383"}.bi-file-earmark-ruled-fill::before{content:"\f384"}.bi-file-earmark-ruled::before{content:"\f385"}.bi-file-earmark-slides-fill::before{content:"\f386"}.bi-file-earmark-slides::before{content:"\f387"}.bi-file-earmark-spreadsheet-fill::before{content:"\f388"}.bi-file-earmark-spreadsheet::before{content:"\f389"}.bi-file-earmark-text-fill::before{content:"\f38a"}.bi-file-earmark-text::before{content:"\f38b"}.bi-file-earmark-word-fill::before{content:"\f38c"}.bi-file-earmark-word::before{content:"\f38d"}.bi-file-earmark-x-fill::before{content:"\f38e"}.bi-file-earmark-x::before{content:"\f38f"}.bi-file-earmark-zip-fill::before{content:"\f390"}.bi-file-earmark-zip::before{content:"\f391"}.bi-file-earmark::before{content:"\f392"}.bi-file-easel-fill::before{content:"\f393"}.bi-file-easel::before{content:"\f394"}.bi-file-excel-fill::before{content:"\f395"}.bi-file-excel::before{content:"\f396"}.bi-file-fill::before{content:"\f397"}.bi-file-font-fill::before{content:"\f398"}.bi-file-font::before{content:"\f399"}.bi-file-image-fill::before{content:"\f39a"}.bi-file-image::before{content:"\f39b"}.bi-file-lock-fill::before{content:"\f39c"}.bi-file-lock::before{content:"\f39d"}.bi-file-lock2-fill::before{content:"\f39e"}.bi-file-lock2::before{content:"\f39f"}.bi-file-medical-fill::before{content:"\f3a0"}.bi-file-medical::before{content:"\f3a1"}.bi-file-minus-fill::before{content:"\f3a2"}.bi-file-minus::before{content:"\f3a3"}.bi-file-music-fill::before{content:"\f3a4"}.bi-file-music::before{content:"\f3a5"}.bi-file-person-fill::before{content:"\f3a6"}.bi-file-person::before{content:"\f3a7"}.bi-file-play-fill::before{content:"\f3a8"}.bi-file-play::before{content:"\f3a9"}.bi-file-plus-fill::before{content:"\f3aa"}.bi-file-plus::before{content:"\f3ab"}.bi-file-post-fill::before{content:"\f3ac"}.bi-file-post::before{content:"\f3ad"}.bi-file-ppt-fill::before{content:"\f3ae"}.bi-file-ppt::before{content:"\f3af"}.bi-file-richtext-fill::before{content:"\f3b0"}.bi-file-richtext::before{content:"\f3b1"}.bi-file-ruled-fill::before{content:"\f3b2"}.bi-file-ruled::before{content:"\f3b3"}.bi-file-slides-fill::before{content:"\f3b4"}.bi-file-slides::before{content:"\f3b5"}.bi-file-spreadsheet-fill::before{content:"\f3b6"}.bi-file-spreadsheet::before{content:"\f3b7"}.bi-file-text-fill::before{content:"\f3b8"}.bi-file-text::before{content:"\f3b9"}.bi-file-word-fill::before{content:"\f3ba"}.bi-file-word::before{content:"\f3bb"}.bi-file-x-fill::before{content:"\f3bc"}.bi-file-x::before{content:"\f3bd"}.bi-file-zip-fill::before{content:"\f3be"}.bi-file-zip::before{content:"\f3bf"}.bi-file::before{content:"\f3c0"}.bi-files-alt::before{content:"\f3c1"}.bi-files::before{content:"\f3c2"}.bi-film::before{content:"\f3c3"}.bi-filter-circle-fill::before{content:"\f3c4"}.bi-filter-circle::before{content:"\f3c5"}.bi-filter-left::before{content:"\f3c6"}.bi-filter-right::before{content:"\f3c7"}.bi-filter-square-fill::before{content:"\f3c8"}.bi-filter-square::before{content:"\f3c9"}.bi-filter::before{content:"\f3ca"}.bi-flag-fill::before{content:"\f3cb"}.bi-flag::before{content:"\f3cc"}.bi-flower1::before{content:"\f3cd"}.bi-flower2::before{content:"\f3ce"}.bi-flower3::before{content:"\f3cf"}.bi-folder-check::before{content:"\f3d0"}.bi-folder-fill::before{content:"\f3d1"}.bi-folder-minus::before{content:"\f3d2"}.bi-folder-plus::before{content:"\f3d3"}.bi-folder-symlink-fill::before{content:"\f3d4"}.bi-folder-symlink::before{content:"\f3d5"}.bi-folder-x::before{content:"\f3d6"}.bi-folder::before{content:"\f3d7"}.bi-folder2-open::before{content:"\f3d8"}.bi-folder2::before{content:"\f3d9"}.bi-fonts::before{content:"\f3da"}.bi-forward-fill::before{content:"\f3db"}.bi-forward::before{content:"\f3dc"}.bi-front::before{content:"\f3dd"}.bi-fullscreen-exit::before{content:"\f3de"}.bi-fullscreen::before{content:"\f3df"}.bi-funnel-fill::before{content:"\f3e0"}.bi-funnel::before{content:"\f3e1"}.bi-gear-fill::before{content:"\f3e2"}.bi-gear-wide-connected::before{content:"\f3e3"}.bi-gear-wide::before{content:"\f3e4"}.bi-gear::before{content:"\f3e5"}.bi-gem::before{content:"\f3e6"}.bi-geo-alt-fill::before{content:"\f3e7"}.bi-geo-alt::before{content:"\f3e8"}.bi-geo-fill::before{content:"\f3e9"}.bi-geo::before{content:"\f3ea"}.bi-gift-fill::before{content:"\f3eb"}.bi-gift::before{content:"\f3ec"}.bi-github::before{content:"\f3ed"}.bi-globe::before{content:"\f3ee"}.bi-globe2::before{content:"\f3ef"}.bi-google::before{content:"\f3f0"}.bi-graph-down::before{content:"\f3f1"}.bi-graph-up::before{content:"\f3f2"}.bi-grid-1x2-fill::before{content:"\f3f3"}.bi-grid-1x2::before{content:"\f3f4"}.bi-grid-3x2-gap-fill::before{content:"\f3f5"}.bi-grid-3x2-gap::before{content:"\f3f6"}.bi-grid-3x2::before{content:"\f3f7"}.bi-grid-3x3-gap-fill::before{content:"\f3f8"}.bi-grid-3x3-gap::before{content:"\f3f9"}.bi-grid-3x3::before{content:"\f3fa"}.bi-grid-fill::before{content:"\f3fb"}.bi-grid::before{content:"\f3fc"}.bi-grip-horizontal::before{content:"\f3fd"}.bi-grip-vertical::before{content:"\f3fe"}.bi-hammer::before{content:"\f3ff"}.bi-hand-index-fill::before{content:"\f400"}.bi-hand-index-thumb-fill::before{content:"\f401"}.bi-hand-index-thumb::before{content:"\f402"}.bi-hand-index::before{content:"\f403"}.bi-hand-thumbs-down-fill::before{content:"\f404"}.bi-hand-thumbs-down::before{content:"\f405"}.bi-hand-thumbs-up-fill::before{content:"\f406"}.bi-hand-thumbs-up::before{content:"\f407"}.bi-handbag-fill::before{content:"\f408"}.bi-handbag::before{content:"\f409"}.bi-hash::before{content:"\f40a"}.bi-hdd-fill::before{content:"\f40b"}.bi-hdd-network-fill::before{content:"\f40c"}.bi-hdd-network::before{content:"\f40d"}.bi-hdd-rack-fill::before{content:"\f40e"}.bi-hdd-rack::before{content:"\f40f"}.bi-hdd-stack-fill::before{content:"\f410"}.bi-hdd-stack::before{content:"\f411"}.bi-hdd::before{content:"\f412"}.bi-headphones::before{content:"\f413"}.bi-headset::before{content:"\f414"}.bi-heart-fill::before{content:"\f415"}.bi-heart-half::before{content:"\f416"}.bi-heart::before{content:"\f417"}.bi-heptagon-fill::before{content:"\f418"}.bi-heptagon-half::before{content:"\f419"}.bi-heptagon::before{content:"\f41a"}.bi-hexagon-fill::before{content:"\f41b"}.bi-hexagon-half::before{content:"\f41c"}.bi-hexagon::before{content:"\f41d"}.bi-hourglass-bottom::before{content:"\f41e"}.bi-hourglass-split::before{content:"\f41f"}.bi-hourglass-top::before{content:"\f420"}.bi-hourglass::before{content:"\f421"}.bi-house-door-fill::before{content:"\f422"}.bi-house-door::before{content:"\f423"}.bi-house-fill::before{content:"\f424"}.bi-house::before{content:"\f425"}.bi-hr::before{content:"\f426"}.bi-hurricane::before{content:"\f427"}.bi-image-alt::before{content:"\f428"}.bi-image-fill::before{content:"\f429"}.bi-image::before{content:"\f42a"}.bi-images::before{content:"\f42b"}.bi-inbox-fill::before{content:"\f42c"}.bi-inbox::before{content:"\f42d"}.bi-inboxes-fill::before{content:"\f42e"}.bi-inboxes::before{content:"\f42f"}.bi-info-circle-fill::before{content:"\f430"}.bi-info-circle::before{content:"\f431"}.bi-info-square-fill::before{content:"\f432"}.bi-info-square::before{content:"\f433"}.bi-info::before{content:"\f434"}.bi-input-cursor-text::before{content:"\f435"}.bi-input-cursor::before{content:"\f436"}.bi-instagram::before{content:"\f437"}.bi-intersect::before{content:"\f438"}.bi-journal-album::before{content:"\f439"}.bi-journal-arrow-down::before{content:"\f43a"}.bi-journal-arrow-up::before{content:"\f43b"}.bi-journal-bookmark-fill::before{content:"\f43c"}.bi-journal-bookmark::before{content:"\f43d"}.bi-journal-check::before{content:"\f43e"}.bi-journal-code::before{content:"\f43f"}.bi-journal-medical::before{content:"\f440"}.bi-journal-minus::before{content:"\f441"}.bi-journal-plus::before{content:"\f442"}.bi-journal-richtext::before{content:"\f443"}.bi-journal-text::before{content:"\f444"}.bi-journal-x::before{content:"\f445"}.bi-journal::before{content:"\f446"}.bi-journals::before{content:"\f447"}.bi-joystick::before{content:"\f448"}.bi-justify-left::before{content:"\f449"}.bi-justify-right::before{content:"\f44a"}.bi-justify::before{content:"\f44b"}.bi-kanban-fill::before{content:"\f44c"}.bi-kanban::before{content:"\f44d"}.bi-key-fill::before{content:"\f44e"}.bi-key::before{content:"\f44f"}.bi-keyboard-fill::before{content:"\f450"}.bi-keyboard::before{content:"\f451"}.bi-ladder::before{content:"\f452"}.bi-lamp-fill::before{content:"\f453"}.bi-lamp::before{content:"\f454"}.bi-laptop-fill::before{content:"\f455"}.bi-laptop::before{content:"\f456"}.bi-layer-backward::before{content:"\f457"}.bi-layer-forward::before{content:"\f458"}.bi-layers-fill::before{content:"\f459"}.bi-layers-half::before{content:"\f45a"}.bi-layers::before{content:"\f45b"}.bi-layout-sidebar-inset-reverse::before{content:"\f45c"}.bi-layout-sidebar-inset::before{content:"\f45d"}.bi-layout-sidebar-reverse::before{content:"\f45e"}.bi-layout-sidebar::before{content:"\f45f"}.bi-layout-split::before{content:"\f460"}.bi-layout-text-sidebar-reverse::before{content:"\f461"}.bi-layout-text-sidebar::before{content:"\f462"}.bi-layout-text-window-reverse::before{content:"\f463"}.bi-layout-text-window::before{content:"\f464"}.bi-layout-three-columns::before{content:"\f465"}.bi-layout-wtf::before{content:"\f466"}.bi-life-preserver::before{content:"\f467"}.bi-lightbulb-fill::before{content:"\f468"}.bi-lightbulb-off-fill::before{content:"\f469"}.bi-lightbulb-off::before{content:"\f46a"}.bi-lightbulb::before{content:"\f46b"}.bi-lightning-charge-fill::before{content:"\f46c"}.bi-lightning-charge::before{content:"\f46d"}.bi-lightning-fill::before{content:"\f46e"}.bi-lightning::before{content:"\f46f"}.bi-link-45deg::before{content:"\f470"}.bi-link::before{content:"\f471"}.bi-linkedin::before{content:"\f472"}.bi-list-check::before{content:"\f473"}.bi-list-nested::before{content:"\f474"}.bi-list-ol::before{content:"\f475"}.bi-list-stars::before{content:"\f476"}.bi-list-task::before{content:"\f477"}.bi-list-ul::before{content:"\f478"}.bi-list::before{content:"\f479"}.bi-lock-fill::before{content:"\f47a"}.bi-lock::before{content:"\f47b"}.bi-mailbox::before{content:"\f47c"}.bi-mailbox2::before{content:"\f47d"}.bi-map-fill::before{content:"\f47e"}.bi-map::before{content:"\f47f"}.bi-markdown-fill::before{content:"\f480"}.bi-markdown::before{content:"\f481"}.bi-mask::before{content:"\f482"}.bi-megaphone-fill::before{content:"\f483"}.bi-megaphone::before{content:"\f484"}.bi-menu-app-fill::before{content:"\f485"}.bi-menu-app::before{content:"\f486"}.bi-menu-button-fill::before{content:"\f487"}.bi-menu-button-wide-fill::before{content:"\f488"}.bi-menu-button-wide::before{content:"\f489"}.bi-menu-button::before{content:"\f48a"}.bi-menu-down::before{content:"\f48b"}.bi-menu-up::before{content:"\f48c"}.bi-mic-fill::before{content:"\f48d"}.bi-mic-mute-fill::before{content:"\f48e"}.bi-mic-mute::before{content:"\f48f"}.bi-mic::before{content:"\f490"}.bi-minecart-loaded::before{content:"\f491"}.bi-minecart::before{content:"\f492"}.bi-moisture::before{content:"\f493"}.bi-moon-fill::before{content:"\f494"}.bi-moon-stars-fill::before{content:"\f495"}.bi-moon-stars::before{content:"\f496"}.bi-moon::before{content:"\f497"}.bi-mouse-fill::before{content:"\f498"}.bi-mouse::before{content:"\f499"}.bi-mouse2-fill::before{content:"\f49a"}.bi-mouse2::before{content:"\f49b"}.bi-mouse3-fill::before{content:"\f49c"}.bi-mouse3::before{content:"\f49d"}.bi-music-note-beamed::before{content:"\f49e"}.bi-music-note-list::before{content:"\f49f"}.bi-music-note::before{content:"\f4a0"}.bi-music-player-fill::before{content:"\f4a1"}.bi-music-player::before{content:"\f4a2"}.bi-newspaper::before{content:"\f4a3"}.bi-node-minus-fill::before{content:"\f4a4"}.bi-node-minus::before{content:"\f4a5"}.bi-node-plus-fill::before{content:"\f4a6"}.bi-node-plus::before{content:"\f4a7"}.bi-nut-fill::before{content:"\f4a8"}.bi-nut::before{content:"\f4a9"}.bi-octagon-fill::before{content:"\f4aa"}.bi-octagon-half::before{content:"\f4ab"}.bi-octagon::before{content:"\f4ac"}.bi-option::before{content:"\f4ad"}.bi-outlet::before{content:"\f4ae"}.bi-paint-bucket::before{content:"\f4af"}.bi-palette-fill::before{content:"\f4b0"}.bi-palette::before{content:"\f4b1"}.bi-palette2::before{content:"\f4b2"}.bi-paperclip::before{content:"\f4b3"}.bi-paragraph::before{content:"\f4b4"}.bi-patch-check-fill::before{content:"\f4b5"}.bi-patch-check::before{content:"\f4b6"}.bi-patch-exclamation-fill::before{content:"\f4b7"}.bi-patch-exclamation::before{content:"\f4b8"}.bi-patch-minus-fill::before{content:"\f4b9"}.bi-patch-minus::before{content:"\f4ba"}.bi-patch-plus-fill::before{content:"\f4bb"}.bi-patch-plus::before{content:"\f4bc"}.bi-patch-question-fill::before{content:"\f4bd"}.bi-patch-question::before{content:"\f4be"}.bi-pause-btn-fill::before{content:"\f4bf"}.bi-pause-btn::before{content:"\f4c0"}.bi-pause-circle-fill::before{content:"\f4c1"}.bi-pause-circle::before{content:"\f4c2"}.bi-pause-fill::before{content:"\f4c3"}.bi-pause::before{content:"\f4c4"}.bi-peace-fill::before{content:"\f4c5"}.bi-peace::before{content:"\f4c6"}.bi-pen-fill::before{content:"\f4c7"}.bi-pen::before{content:"\f4c8"}.bi-pencil-fill::before{content:"\f4c9"}.bi-pencil-square::before{content:"\f4ca"}.bi-pencil::before{content:"\f4cb"}.bi-pentagon-fill::before{content:"\f4cc"}.bi-pentagon-half::before{content:"\f4cd"}.bi-pentagon::before{content:"\f4ce"}.bi-people-fill::before{content:"\f4cf"}.bi-people::before{content:"\f4d0"}.bi-percent::before{content:"\f4d1"}.bi-person-badge-fill::before{content:"\f4d2"}.bi-person-badge::before{content:"\f4d3"}.bi-person-bounding-box::before{content:"\f4d4"}.bi-person-check-fill::before{content:"\f4d5"}.bi-person-check::before{content:"\f4d6"}.bi-person-circle::before{content:"\f4d7"}.bi-person-dash-fill::before{content:"\f4d8"}.bi-person-dash::before{content:"\f4d9"}.bi-person-fill::before{content:"\f4da"}.bi-person-lines-fill::before{content:"\f4db"}.bi-person-plus-fill::before{content:"\f4dc"}.bi-person-plus::before{content:"\f4dd"}.bi-person-square::before{content:"\f4de"}.bi-person-x-fill::before{content:"\f4df"}.bi-person-x::before{content:"\f4e0"}.bi-person::before{content:"\f4e1"}.bi-phone-fill::before{content:"\f4e2"}.bi-phone-landscape-fill::before{content:"\f4e3"}.bi-phone-landscape::before{content:"\f4e4"}.bi-phone-vibrate-fill::before{content:"\f4e5"}.bi-phone-vibrate::before{content:"\f4e6"}.bi-phone::before{content:"\f4e7"}.bi-pie-chart-fill::before{content:"\f4e8"}.bi-pie-chart::before{content:"\f4e9"}.bi-pin-angle-fill::before{content:"\f4ea"}.bi-pin-angle::before{content:"\f4eb"}.bi-pin-fill::before{content:"\f4ec"}.bi-pin::before{content:"\f4ed"}.bi-pip-fill::before{content:"\f4ee"}.bi-pip::before{content:"\f4ef"}.bi-play-btn-fill::before{content:"\f4f0"}.bi-play-btn::before{content:"\f4f1"}.bi-play-circle-fill::before{content:"\f4f2"}.bi-play-circle::before{content:"\f4f3"}.bi-play-fill::before{content:"\f4f4"}.bi-play::before{content:"\f4f5"}.bi-plug-fill::before{content:"\f4f6"}.bi-plug::before{content:"\f4f7"}.bi-plus-circle-dotted::before{content:"\f4f8"}.bi-plus-circle-fill::before{content:"\f4f9"}.bi-plus-circle::before{content:"\f4fa"}.bi-plus-square-dotted::before{content:"\f4fb"}.bi-plus-square-fill::before{content:"\f4fc"}.bi-plus-square::before{content:"\f4fd"}.bi-plus::before{content:"\f4fe"}.bi-power::before{content:"\f4ff"}.bi-printer-fill::before{content:"\f500"}.bi-printer::before{content:"\f501"}.bi-puzzle-fill::before{content:"\f502"}.bi-puzzle::before{content:"\f503"}.bi-question-circle-fill::before{content:"\f504"}.bi-question-circle::before{content:"\f505"}.bi-question-diamond-fill::before{content:"\f506"}.bi-question-diamond::before{content:"\f507"}.bi-question-octagon-fill::before{content:"\f508"}.bi-question-octagon::before{content:"\f509"}.bi-question-square-fill::before{content:"\f50a"}.bi-question-square::before{content:"\f50b"}.bi-question::before{content:"\f50c"}.bi-rainbow::before{content:"\f50d"}.bi-receipt-cutoff::before{content:"\f50e"}.bi-receipt::before{content:"\f50f"}.bi-reception-0::before{content:"\f510"}.bi-reception-1::before{content:"\f511"}.bi-reception-2::before{content:"\f512"}.bi-reception-3::before{content:"\f513"}.bi-reception-4::before{content:"\f514"}.bi-record-btn-fill::before{content:"\f515"}.bi-record-btn::before{content:"\f516"}.bi-record-circle-fill::before{content:"\f517"}.bi-record-circle::before{content:"\f518"}.bi-record-fill::before{content:"\f519"}.bi-record::before{content:"\f51a"}.bi-record2-fill::before{content:"\f51b"}.bi-record2::before{content:"\f51c"}.bi-reply-all-fill::before{content:"\f51d"}.bi-reply-all::before{content:"\f51e"}.bi-reply-fill::before{content:"\f51f"}.bi-reply::before{content:"\f520"}.bi-rss-fill::before{content:"\f521"}.bi-rss::before{content:"\f522"}.bi-rulers::before{content:"\f523"}.bi-save-fill::before{content:"\f524"}.bi-save::before{content:"\f525"}.bi-save2-fill::before{content:"\f526"}.bi-save2::before{content:"\f527"}.bi-scissors::before{content:"\f528"}.bi-screwdriver::before{content:"\f529"}.bi-search::before{content:"\f52a"}.bi-segmented-nav::before{content:"\f52b"}.bi-server::before{content:"\f52c"}.bi-share-fill::before{content:"\f52d"}.bi-share::before{content:"\f52e"}.bi-shield-check::before{content:"\f52f"}.bi-shield-exclamation::before{content:"\f530"}.bi-shield-fill-check::before{content:"\f531"}.bi-shield-fill-exclamation::before{content:"\f532"}.bi-shield-fill-minus::before{content:"\f533"}.bi-shield-fill-plus::before{content:"\f534"}.bi-shield-fill-x::before{content:"\f535"}.bi-shield-fill::before{content:"\f536"}.bi-shield-lock-fill::before{content:"\f537"}.bi-shield-lock::before{content:"\f538"}.bi-shield-minus::before{content:"\f539"}.bi-shield-plus::before{content:"\f53a"}.bi-shield-shaded::before{content:"\f53b"}.bi-shield-slash-fill::before{content:"\f53c"}.bi-shield-slash::before{content:"\f53d"}.bi-shield-x::before{content:"\f53e"}.bi-shield::before{content:"\f53f"}.bi-shift-fill::before{content:"\f540"}.bi-shift::before{content:"\f541"}.bi-shop-window::before{content:"\f542"}.bi-shop::before{content:"\f543"}.bi-shuffle::before{content:"\f544"}.bi-signpost-2-fill::before{content:"\f545"}.bi-signpost-2::before{content:"\f546"}.bi-signpost-fill::before{content:"\f547"}.bi-signpost-split-fill::before{content:"\f548"}.bi-signpost-split::before{content:"\f549"}.bi-signpost::before{content:"\f54a"}.bi-sim-fill::before{content:"\f54b"}.bi-sim::before{content:"\f54c"}.bi-skip-backward-btn-fill::before{content:"\f54d"}.bi-skip-backward-btn::before{content:"\f54e"}.bi-skip-backward-circle-fill::before{content:"\f54f"}.bi-skip-backward-circle::before{content:"\f550"}.bi-skip-backward-fill::before{content:"\f551"}.bi-skip-backward::before{content:"\f552"}.bi-skip-end-btn-fill::before{content:"\f553"}.bi-skip-end-btn::before{content:"\f554"}.bi-skip-end-circle-fill::before{content:"\f555"}.bi-skip-end-circle::before{content:"\f556"}.bi-skip-end-fill::before{content:"\f557"}.bi-skip-end::before{content:"\f558"}.bi-skip-forward-btn-fill::before{content:"\f559"}.bi-skip-forward-btn::before{content:"\f55a"}.bi-skip-forward-circle-fill::before{content:"\f55b"}.bi-skip-forward-circle::before{content:"\f55c"}.bi-skip-forward-fill::before{content:"\f55d"}.bi-skip-forward::before{content:"\f55e"}.bi-skip-start-btn-fill::before{content:"\f55f"}.bi-skip-start-btn::before{content:"\f560"}.bi-skip-start-circle-fill::before{content:"\f561"}.bi-skip-start-circle::before{content:"\f562"}.bi-skip-start-fill::before{content:"\f563"}.bi-skip-start::before{content:"\f564"}.bi-slack::before{content:"\f565"}.bi-slash-circle-fill::before{content:"\f566"}.bi-slash-circle::before{content:"\f567"}.bi-slash-square-fill::before{content:"\f568"}.bi-slash-square::before{content:"\f569"}.bi-slash::before{content:"\f56a"}.bi-sliders::before{content:"\f56b"}.bi-smartwatch::before{content:"\f56c"}.bi-snow::before{content:"\f56d"}.bi-snow2::before{content:"\f56e"}.bi-snow3::before{content:"\f56f"}.bi-sort-alpha-down-alt::before{content:"\f570"}.bi-sort-alpha-down::before{content:"\f571"}.bi-sort-alpha-up-alt::before{content:"\f572"}.bi-sort-alpha-up::before{content:"\f573"}.bi-sort-down-alt::before{content:"\f574"}.bi-sort-down::before{content:"\f575"}.bi-sort-numeric-down-alt::before{content:"\f576"}.bi-sort-numeric-down::before{content:"\f577"}.bi-sort-numeric-up-alt::before{content:"\f578"}.bi-sort-numeric-up::before{content:"\f579"}.bi-sort-up-alt::before{content:"\f57a"}.bi-sort-up::before{content:"\f57b"}.bi-soundwave::before{content:"\f57c"}.bi-speaker-fill::before{content:"\f57d"}.bi-speaker::before{content:"\f57e"}.bi-speedometer::before{content:"\f57f"}.bi-speedometer2::before{content:"\f580"}.bi-spellcheck::before{content:"\f581"}.bi-square-fill::before{content:"\f582"}.bi-square-half::before{content:"\f583"}.bi-square::before{content:"\f584"}.bi-stack::before{content:"\f585"}.bi-star-fill::before{content:"\f586"}.bi-star-half::before{content:"\f587"}.bi-star::before{content:"\f588"}.bi-stars::before{content:"\f589"}.bi-stickies-fill::before{content:"\f58a"}.bi-stickies::before{content:"\f58b"}.bi-sticky-fill::before{content:"\f58c"}.bi-sticky::before{content:"\f58d"}.bi-stop-btn-fill::before{content:"\f58e"}.bi-stop-btn::before{content:"\f58f"}.bi-stop-circle-fill::before{content:"\f590"}.bi-stop-circle::before{content:"\f591"}.bi-stop-fill::before{content:"\f592"}.bi-stop::before{content:"\f593"}.bi-stoplights-fill::before{content:"\f594"}.bi-stoplights::before{content:"\f595"}.bi-stopwatch-fill::before{content:"\f596"}.bi-stopwatch::before{content:"\f597"}.bi-subtract::before{content:"\f598"}.bi-suit-club-fill::before{content:"\f599"}.bi-suit-club::before{content:"\f59a"}.bi-suit-diamond-fill::before{content:"\f59b"}.bi-suit-diamond::before{content:"\f59c"}.bi-suit-heart-fill::before{content:"\f59d"}.bi-suit-heart::before{content:"\f59e"}.bi-suit-spade-fill::before{content:"\f59f"}.bi-suit-spade::before{content:"\f5a0"}.bi-sun-fill::before{content:"\f5a1"}.bi-sun::before{content:"\f5a2"}.bi-sunglasses::before{content:"\f5a3"}.bi-sunrise-fill::before{content:"\f5a4"}.bi-sunrise::before{content:"\f5a5"}.bi-sunset-fill::before{content:"\f5a6"}.bi-sunset::before{content:"\f5a7"}.bi-symmetry-horizontal::before{content:"\f5a8"}.bi-symmetry-vertical::before{content:"\f5a9"}.bi-table::before{content:"\f5aa"}.bi-tablet-fill::before{content:"\f5ab"}.bi-tablet-landscape-fill::before{content:"\f5ac"}.bi-tablet-landscape::before{content:"\f5ad"}.bi-tablet::before{content:"\f5ae"}.bi-tag-fill::before{content:"\f5af"}.bi-tag::before{content:"\f5b0"}.bi-tags-fill::before{content:"\f5b1"}.bi-tags::before{content:"\f5b2"}.bi-telegram::before{content:"\f5b3"}.bi-telephone-fill::before{content:"\f5b4"}.bi-telephone-forward-fill::before{content:"\f5b5"}.bi-telephone-forward::before{content:"\f5b6"}.bi-telephone-inbound-fill::before{content:"\f5b7"}.bi-telephone-inbound::before{content:"\f5b8"}.bi-telephone-minus-fill::before{content:"\f5b9"}.bi-telephone-minus::before{content:"\f5ba"}.bi-telephone-outbound-fill::before{content:"\f5bb"}.bi-telephone-outbound::before{content:"\f5bc"}.bi-telephone-plus-fill::before{content:"\f5bd"}.bi-telephone-plus::before{content:"\f5be"}.bi-telephone-x-fill::before{content:"\f5bf"}.bi-telephone-x::before{content:"\f5c0"}.bi-telephone::before{content:"\f5c1"}.bi-terminal-fill::before{content:"\f5c2"}.bi-terminal::before{content:"\f5c3"}.bi-text-center::before{content:"\f5c4"}.bi-text-indent-left::before{content:"\f5c5"}.bi-text-indent-right::before{content:"\f5c6"}.bi-text-left::before{content:"\f5c7"}.bi-text-paragraph::before{content:"\f5c8"}.bi-text-right::before{content:"\f5c9"}.bi-textarea-resize::before{content:"\f5ca"}.bi-textarea-t::before{content:"\f5cb"}.bi-textarea::before{content:"\f5cc"}.bi-thermometer-half::before{content:"\f5cd"}.bi-thermometer-high::before{content:"\f5ce"}.bi-thermometer-low::before{content:"\f5cf"}.bi-thermometer-snow::before{content:"\f5d0"}.bi-thermometer-sun::before{content:"\f5d1"}.bi-thermometer::before{content:"\f5d2"}.bi-three-dots-vertical::before{content:"\f5d3"}.bi-three-dots::before{content:"\f5d4"}.bi-toggle-off::before{content:"\f5d5"}.bi-toggle-on::before{content:"\f5d6"}.bi-toggle2-off::before{content:"\f5d7"}.bi-toggle2-on::before{content:"\f5d8"}.bi-toggles::before{content:"\f5d9"}.bi-toggles2::before{content:"\f5da"}.bi-tools::before{content:"\f5db"}.bi-tornado::before{content:"\f5dc"}.bi-trash-fill::before{content:"\f5dd"}.bi-trash::before{content:"\f5de"}.bi-trash2-fill::before{content:"\f5df"}.bi-trash2::before{content:"\f5e0"}.bi-tree-fill::before{content:"\f5e1"}.bi-tree::before{content:"\f5e2"}.bi-triangle-fill::before{content:"\f5e3"}.bi-triangle-half::before{content:"\f5e4"}.bi-triangle::before{content:"\f5e5"}.bi-trophy-fill::before{content:"\f5e6"}.bi-trophy::before{content:"\f5e7"}.bi-tropical-storm::before{content:"\f5e8"}.bi-truck-flatbed::before{content:"\f5e9"}.bi-truck::before{content:"\f5ea"}.bi-tsunami::before{content:"\f5eb"}.bi-tv-fill::before{content:"\f5ec"}.bi-tv::before{content:"\f5ed"}.bi-twitch::before{content:"\f5ee"}.bi-twitter::before{content:"\f5ef"}.bi-type-bold::before{content:"\f5f0"}.bi-type-h1::before{content:"\f5f1"}.bi-type-h2::before{content:"\f5f2"}.bi-type-h3::before{content:"\f5f3"}.bi-type-italic::before{content:"\f5f4"}.bi-type-strikethrough::before{content:"\f5f5"}.bi-type-underline::before{content:"\f5f6"}.bi-type::before{content:"\f5f7"}.bi-ui-checks-grid::before{content:"\f5f8"}.bi-ui-checks::before{content:"\f5f9"}.bi-ui-radios-grid::before{content:"\f5fa"}.bi-ui-radios::before{content:"\f5fb"}.bi-umbrella-fill::before{content:"\f5fc"}.bi-umbrella::before{content:"\f5fd"}.bi-union::before{content:"\f5fe"}.bi-unlock-fill::before{content:"\f5ff"}.bi-unlock::before{content:"\f600"}.bi-upc-scan::before{content:"\f601"}.bi-upc::before{content:"\f602"}.bi-upload::before{content:"\f603"}.bi-vector-pen::before{content:"\f604"}.bi-view-list::before{content:"\f605"}.bi-view-stacked::before{content:"\f606"}.bi-vinyl-fill::before{content:"\f607"}.bi-vinyl::before{content:"\f608"}.bi-voicemail::before{content:"\f609"}.bi-volume-down-fill::before{content:"\f60a"}.bi-volume-down::before{content:"\f60b"}.bi-volume-mute-fill::before{content:"\f60c"}.bi-volume-mute::before{content:"\f60d"}.bi-volume-off-fill::before{content:"\f60e"}.bi-volume-off::before{content:"\f60f"}.bi-volume-up-fill::before{content:"\f610"}.bi-volume-up::before{content:"\f611"}.bi-vr::before{content:"\f612"}.bi-wallet-fill::before{content:"\f613"}.bi-wallet::before{content:"\f614"}.bi-wallet2::before{content:"\f615"}.bi-watch::before{content:"\f616"}.bi-water::before{content:"\f617"}.bi-whatsapp::before{content:"\f618"}.bi-wifi-1::before{content:"\f619"}.bi-wifi-2::before{content:"\f61a"}.bi-wifi-off::before{content:"\f61b"}.bi-wifi::before{content:"\f61c"}.bi-wind::before{content:"\f61d"}.bi-window-dock::before{content:"\f61e"}.bi-window-sidebar::before{content:"\f61f"}.bi-window::before{content:"\f620"}.bi-wrench::before{content:"\f621"}.bi-x-circle-fill::before{content:"\f622"}.bi-x-circle::before{content:"\f623"}.bi-x-diamond-fill::before{content:"\f624"}.bi-x-diamond::before{content:"\f625"}.bi-x-octagon-fill::before{content:"\f626"}.bi-x-octagon::before{content:"\f627"}.bi-x-square-fill::before{content:"\f628"}.bi-x-square::before{content:"\f629"}.bi-x::before{content:"\f62a"}.bi-youtube::before{content:"\f62b"}.bi-zoom-in::before{content:"\f62c"}.bi-zoom-out::before{content:"\f62d"}.bi-bank::before{content:"\f62e"}.bi-bank2::before{content:"\f62f"}.bi-bell-slash-fill::before{content:"\f630"}.bi-bell-slash::before{content:"\f631"}.bi-cash-coin::before{content:"\f632"}.bi-check-lg::before{content:"\f633"}.bi-coin::before{content:"\f634"}.bi-currency-bitcoin::before{content:"\f635"}.bi-currency-dollar::before{content:"\f636"}.bi-currency-euro::before{content:"\f637"}.bi-currency-exchange::before{content:"\f638"}.bi-currency-pound::before{content:"\f639"}.bi-currency-yen::before{content:"\f63a"}.bi-dash-lg::before{content:"\f63b"}.bi-exclamation-lg::before{content:"\f63c"}.bi-file-earmark-pdf-fill::before{content:"\f63d"}.bi-file-earmark-pdf::before{content:"\f63e"}.bi-file-pdf-fill::before{content:"\f63f"}.bi-file-pdf::before{content:"\f640"}.bi-gender-ambiguous::before{content:"\f641"}.bi-gender-female::before{content:"\f642"}.bi-gender-male::before{content:"\f643"}.bi-gender-trans::before{content:"\f644"}.bi-headset-vr::before{content:"\f645"}.bi-info-lg::before{content:"\f646"}.bi-mastodon::before{content:"\f647"}.bi-messenger::before{content:"\f648"}.bi-piggy-bank-fill::before{content:"\f649"}.bi-piggy-bank::before{content:"\f64a"}.bi-pin-map-fill::before{content:"\f64b"}.bi-pin-map::before{content:"\f64c"}.bi-plus-lg::before{content:"\f64d"}.bi-question-lg::before{content:"\f64e"}.bi-recycle::before{content:"\f64f"}.bi-reddit::before{content:"\f650"}.bi-safe-fill::before{content:"\f651"}.bi-safe2-fill::before{content:"\f652"}.bi-safe2::before{content:"\f653"}.bi-sd-card-fill::before{content:"\f654"}.bi-sd-card::before{content:"\f655"}.bi-skype::before{content:"\f656"}.bi-slash-lg::before{content:"\f657"}.bi-translate::before{content:"\f658"}.bi-x-lg::before{content:"\f659"}.bi-safe::before{content:"\f65a"}.bi-apple::before{content:"\f65b"}.bi-microsoft::before{content:"\f65d"}.bi-windows::before{content:"\f65e"}.bi-behance::before{content:"\f65c"}.bi-dribbble::before{content:"\f65f"}.bi-line::before{content:"\f660"}.bi-medium::before{content:"\f661"}.bi-paypal::before{content:"\f662"}.bi-pinterest::before{content:"\f663"}.bi-signal::before{content:"\f664"}.bi-snapchat::before{content:"\f665"}.bi-spotify::before{content:"\f666"}.bi-stack-overflow::before{content:"\f667"}.bi-strava::before{content:"\f668"}.bi-wordpress::before{content:"\f669"}.bi-vimeo::before{content:"\f66a"}.bi-activity::before{content:"\f66b"}.bi-easel2-fill::before{content:"\f66c"}.bi-easel2::before{content:"\f66d"}.bi-easel3-fill::before{content:"\f66e"}.bi-easel3::before{content:"\f66f"}.bi-fan::before{content:"\f670"}.bi-fingerprint::before{content:"\f671"}.bi-graph-down-arrow::before{content:"\f672"}.bi-graph-up-arrow::before{content:"\f673"}.bi-hypnotize::before{content:"\f674"}.bi-magic::before{content:"\f675"}.bi-person-rolodex::before{content:"\f676"}.bi-person-video::before{content:"\f677"}.bi-person-video2::before{content:"\f678"}.bi-person-video3::before{content:"\f679"}.bi-person-workspace::before{content:"\f67a"}.bi-radioactive::before{content:"\f67b"}.bi-webcam-fill::before{content:"\f67c"}.bi-webcam::before{content:"\f67d"}.bi-yin-yang::before{content:"\f67e"}.bi-bandaid-fill::before{content:"\f680"}.bi-bandaid::before{content:"\f681"}.bi-bluetooth::before{content:"\f682"}.bi-body-text::before{content:"\f683"}.bi-boombox::before{content:"\f684"}.bi-boxes::before{content:"\f685"}.bi-dpad-fill::before{content:"\f686"}.bi-dpad::before{content:"\f687"}.bi-ear-fill::before{content:"\f688"}.bi-ear::before{content:"\f689"}.bi-envelope-check-fill::before{content:"\f68b"}.bi-envelope-check::before{content:"\f68c"}.bi-envelope-dash-fill::before{content:"\f68e"}.bi-envelope-dash::before{content:"\f68f"}.bi-envelope-exclamation-fill::before{content:"\f691"}.bi-envelope-exclamation::before{content:"\f692"}.bi-envelope-plus-fill::before{content:"\f693"}.bi-envelope-plus::before{content:"\f694"}.bi-envelope-slash-fill::before{content:"\f696"}.bi-envelope-slash::before{content:"\f697"}.bi-envelope-x-fill::before{content:"\f699"}.bi-envelope-x::before{content:"\f69a"}.bi-explicit-fill::before{content:"\f69b"}.bi-explicit::before{content:"\f69c"}.bi-git::before{content:"\f69d"}.bi-infinity::before{content:"\f69e"}.bi-list-columns-reverse::before{content:"\f69f"}.bi-list-columns::before{content:"\f6a0"}.bi-meta::before{content:"\f6a1"}.bi-nintendo-switch::before{content:"\f6a4"}.bi-pc-display-horizontal::before{content:"\f6a5"}.bi-pc-display::before{content:"\f6a6"}.bi-pc-horizontal::before{content:"\f6a7"}.bi-pc::before{content:"\f6a8"}.bi-playstation::before{content:"\f6a9"}.bi-plus-slash-minus::before{content:"\f6aa"}.bi-projector-fill::before{content:"\f6ab"}.bi-projector::before{content:"\f6ac"}.bi-qr-code-scan::before{content:"\f6ad"}.bi-qr-code::before{content:"\f6ae"}.bi-quora::before{content:"\f6af"}.bi-quote::before{content:"\f6b0"}.bi-robot::before{content:"\f6b1"}.bi-send-check-fill::before{content:"\f6b2"}.bi-send-check::before{content:"\f6b3"}.bi-send-dash-fill::before{content:"\f6b4"}.bi-send-dash::before{content:"\f6b5"}.bi-send-exclamation-fill::before{content:"\f6b7"}.bi-send-exclamation::before{content:"\f6b8"}.bi-send-fill::before{content:"\f6b9"}.bi-send-plus-fill::before{content:"\f6ba"}.bi-send-plus::before{content:"\f6bb"}.bi-send-slash-fill::before{content:"\f6bc"}.bi-send-slash::before{content:"\f6bd"}.bi-send-x-fill::before{content:"\f6be"}.bi-send-x::before{content:"\f6bf"}.bi-send::before{content:"\f6c0"}.bi-steam::before{content:"\f6c1"}.bi-terminal-dash::before{content:"\f6c3"}.bi-terminal-plus::before{content:"\f6c4"}.bi-terminal-split::before{content:"\f6c5"}.bi-ticket-detailed-fill::before{content:"\f6c6"}.bi-ticket-detailed::before{content:"\f6c7"}.bi-ticket-fill::before{content:"\f6c8"}.bi-ticket-perforated-fill::before{content:"\f6c9"}.bi-ticket-perforated::before{content:"\f6ca"}.bi-ticket::before{content:"\f6cb"}.bi-tiktok::before{content:"\f6cc"}.bi-window-dash::before{content:"\f6cd"}.bi-window-desktop::before{content:"\f6ce"}.bi-window-fullscreen::before{content:"\f6cf"}.bi-window-plus::before{content:"\f6d0"}.bi-window-split::before{content:"\f6d1"}.bi-window-stack::before{content:"\f6d2"}.bi-window-x::before{content:"\f6d3"}.bi-xbox::before{content:"\f6d4"}.bi-ethernet::before{content:"\f6d5"}.bi-hdmi-fill::before{content:"\f6d6"}.bi-hdmi::before{content:"\f6d7"}.bi-usb-c-fill::before{content:"\f6d8"}.bi-usb-c::before{content:"\f6d9"}.bi-usb-fill::before{content:"\f6da"}.bi-usb-plug-fill::before{content:"\f6db"}.bi-usb-plug::before{content:"\f6dc"}.bi-usb-symbol::before{content:"\f6dd"}.bi-usb::before{content:"\f6de"}.bi-boombox-fill::before{content:"\f6df"}.bi-displayport::before{content:"\f6e1"}.bi-gpu-card::before{content:"\f6e2"}.bi-memory::before{content:"\f6e3"}.bi-modem-fill::before{content:"\f6e4"}.bi-modem::before{content:"\f6e5"}.bi-motherboard-fill::before{content:"\f6e6"}.bi-motherboard::before{content:"\f6e7"}.bi-optical-audio-fill::before{content:"\f6e8"}.bi-optical-audio::before{content:"\f6e9"}.bi-pci-card::before{content:"\f6ea"}.bi-router-fill::before{content:"\f6eb"}.bi-router::before{content:"\f6ec"}.bi-thunderbolt-fill::before{content:"\f6ef"}.bi-thunderbolt::before{content:"\f6f0"}.bi-usb-drive-fill::before{content:"\f6f1"}.bi-usb-drive::before{content:"\f6f2"}.bi-usb-micro-fill::before{content:"\f6f3"}.bi-usb-micro::before{content:"\f6f4"}.bi-usb-mini-fill::before{content:"\f6f5"}.bi-usb-mini::before{content:"\f6f6"}.bi-cloud-haze2::before{content:"\f6f7"}.bi-device-hdd-fill::before{content:"\f6f8"}.bi-device-hdd::before{content:"\f6f9"}.bi-device-ssd-fill::before{content:"\f6fa"}.bi-device-ssd::before{content:"\f6fb"}.bi-displayport-fill::before{content:"\f6fc"}.bi-mortarboard-fill::before{content:"\f6fd"}.bi-mortarboard::before{content:"\f6fe"}.bi-terminal-x::before{content:"\f6ff"}.bi-arrow-through-heart-fill::before{content:"\f700"}.bi-arrow-through-heart::before{content:"\f701"}.bi-badge-sd-fill::before{content:"\f702"}.bi-badge-sd::before{content:"\f703"}.bi-bag-heart-fill::before{content:"\f704"}.bi-bag-heart::before{content:"\f705"}.bi-balloon-fill::before{content:"\f706"}.bi-balloon-heart-fill::before{content:"\f707"}.bi-balloon-heart::before{content:"\f708"}.bi-balloon::before{content:"\f709"}.bi-box2-fill::before{content:"\f70a"}.bi-box2-heart-fill::before{content:"\f70b"}.bi-box2-heart::before{content:"\f70c"}.bi-box2::before{content:"\f70d"}.bi-braces-asterisk::before{content:"\f70e"}.bi-calendar-heart-fill::before{content:"\f70f"}.bi-calendar-heart::before{content:"\f710"}.bi-calendar2-heart-fill::before{content:"\f711"}.bi-calendar2-heart::before{content:"\f712"}.bi-chat-heart-fill::before{content:"\f713"}.bi-chat-heart::before{content:"\f714"}.bi-chat-left-heart-fill::before{content:"\f715"}.bi-chat-left-heart::before{content:"\f716"}.bi-chat-right-heart-fill::before{content:"\f717"}.bi-chat-right-heart::before{content:"\f718"}.bi-chat-square-heart-fill::before{content:"\f719"}.bi-chat-square-heart::before{content:"\f71a"}.bi-clipboard-check-fill::before{content:"\f71b"}.bi-clipboard-data-fill::before{content:"\f71c"}.bi-clipboard-fill::before{content:"\f71d"}.bi-clipboard-heart-fill::before{content:"\f71e"}.bi-clipboard-heart::before{content:"\f71f"}.bi-clipboard-minus-fill::before{content:"\f720"}.bi-clipboard-plus-fill::before{content:"\f721"}.bi-clipboard-pulse::before{content:"\f722"}.bi-clipboard-x-fill::before{content:"\f723"}.bi-clipboard2-check-fill::before{content:"\f724"}.bi-clipboard2-check::before{content:"\f725"}.bi-clipboard2-data-fill::before{content:"\f726"}.bi-clipboard2-data::before{content:"\f727"}.bi-clipboard2-fill::before{content:"\f728"}.bi-clipboard2-heart-fill::before{content:"\f729"}.bi-clipboard2-heart::before{content:"\f72a"}.bi-clipboard2-minus-fill::before{content:"\f72b"}.bi-clipboard2-minus::before{content:"\f72c"}.bi-clipboard2-plus-fill::before{content:"\f72d"}.bi-clipboard2-plus::before{content:"\f72e"}.bi-clipboard2-pulse-fill::before{content:"\f72f"}.bi-clipboard2-pulse::before{content:"\f730"}.bi-clipboard2-x-fill::before{content:"\f731"}.bi-clipboard2-x::before{content:"\f732"}.bi-clipboard2::before{content:"\f733"}.bi-emoji-kiss-fill::before{content:"\f734"}.bi-emoji-kiss::before{content:"\f735"}.bi-envelope-heart-fill::before{content:"\f736"}.bi-envelope-heart::before{content:"\f737"}.bi-envelope-open-heart-fill::before{content:"\f738"}.bi-envelope-open-heart::before{content:"\f739"}.bi-envelope-paper-fill::before{content:"\f73a"}.bi-envelope-paper-heart-fill::before{content:"\f73b"}.bi-envelope-paper-heart::before{content:"\f73c"}.bi-envelope-paper::before{content:"\f73d"}.bi-filetype-aac::before{content:"\f73e"}.bi-filetype-ai::before{content:"\f73f"}.bi-filetype-bmp::before{content:"\f740"}.bi-filetype-cs::before{content:"\f741"}.bi-filetype-css::before{content:"\f742"}.bi-filetype-csv::before{content:"\f743"}.bi-filetype-doc::before{content:"\f744"}.bi-filetype-docx::before{content:"\f745"}.bi-filetype-exe::before{content:"\f746"}.bi-filetype-gif::before{content:"\f747"}.bi-filetype-heic::before{content:"\f748"}.bi-filetype-html::before{content:"\f749"}.bi-filetype-java::before{content:"\f74a"}.bi-filetype-jpg::before{content:"\f74b"}.bi-filetype-js::before{content:"\f74c"}.bi-filetype-jsx::before{content:"\f74d"}.bi-filetype-key::before{content:"\f74e"}.bi-filetype-m4p::before{content:"\f74f"}.bi-filetype-md::before{content:"\f750"}.bi-filetype-mdx::before{content:"\f751"}.bi-filetype-mov::before{content:"\f752"}.bi-filetype-mp3::before{content:"\f753"}.bi-filetype-mp4::before{content:"\f754"}.bi-filetype-otf::before{content:"\f755"}.bi-filetype-pdf::before{content:"\f756"}.bi-filetype-php::before{content:"\f757"}.bi-filetype-png::before{content:"\f758"}.bi-filetype-ppt::before{content:"\f75a"}.bi-filetype-psd::before{content:"\f75b"}.bi-filetype-py::before{content:"\f75c"}.bi-filetype-raw::before{content:"\f75d"}.bi-filetype-rb::before{content:"\f75e"}.bi-filetype-sass::before{content:"\f75f"}.bi-filetype-scss::before{content:"\f760"}.bi-filetype-sh::before{content:"\f761"}.bi-filetype-svg::before{content:"\f762"}.bi-filetype-tiff::before{content:"\f763"}.bi-filetype-tsx::before{content:"\f764"}.bi-filetype-ttf::before{content:"\f765"}.bi-filetype-txt::before{content:"\f766"}.bi-filetype-wav::before{content:"\f767"}.bi-filetype-woff::before{content:"\f768"}.bi-filetype-xls::before{content:"\f76a"}.bi-filetype-xml::before{content:"\f76b"}.bi-filetype-yml::before{content:"\f76c"}.bi-heart-arrow::before{content:"\f76d"}.bi-heart-pulse-fill::before{content:"\f76e"}.bi-heart-pulse::before{content:"\f76f"}.bi-heartbreak-fill::before{content:"\f770"}.bi-heartbreak::before{content:"\f771"}.bi-hearts::before{content:"\f772"}.bi-hospital-fill::before{content:"\f773"}.bi-hospital::before{content:"\f774"}.bi-house-heart-fill::before{content:"\f775"}.bi-house-heart::before{content:"\f776"}.bi-incognito::before{content:"\f777"}.bi-magnet-fill::before{content:"\f778"}.bi-magnet::before{content:"\f779"}.bi-person-heart::before{content:"\f77a"}.bi-person-hearts::before{content:"\f77b"}.bi-phone-flip::before{content:"\f77c"}.bi-plugin::before{content:"\f77d"}.bi-postage-fill::before{content:"\f77e"}.bi-postage-heart-fill::before{content:"\f77f"}.bi-postage-heart::before{content:"\f780"}.bi-postage::before{content:"\f781"}.bi-postcard-fill::before{content:"\f782"}.bi-postcard-heart-fill::before{content:"\f783"}.bi-postcard-heart::before{content:"\f784"}.bi-postcard::before{content:"\f785"}.bi-search-heart-fill::before{content:"\f786"}.bi-search-heart::before{content:"\f787"}.bi-sliders2-vertical::before{content:"\f788"}.bi-sliders2::before{content:"\f789"}.bi-trash3-fill::before{content:"\f78a"}.bi-trash3::before{content:"\f78b"}.bi-valentine::before{content:"\f78c"}.bi-valentine2::before{content:"\f78d"}.bi-wrench-adjustable-circle-fill::before{content:"\f78e"}.bi-wrench-adjustable-circle::before{content:"\f78f"}.bi-wrench-adjustable::before{content:"\f790"}.bi-filetype-json::before{content:"\f791"}.bi-filetype-pptx::before{content:"\f792"}.bi-filetype-xlsx::before{content:"\f793"}.bi-1-circle-fill::before{content:"\f796"}.bi-1-circle::before{content:"\f797"}.bi-1-square-fill::before{content:"\f798"}.bi-1-square::before{content:"\f799"}.bi-2-circle-fill::before{content:"\f79c"}.bi-2-circle::before{content:"\f79d"}.bi-2-square-fill::before{content:"\f79e"}.bi-2-square::before{content:"\f79f"}.bi-3-circle-fill::before{content:"\f7a2"}.bi-3-circle::before{content:"\f7a3"}.bi-3-square-fill::before{content:"\f7a4"}.bi-3-square::before{content:"\f7a5"}.bi-4-circle-fill::before{content:"\f7a8"}.bi-4-circle::before{content:"\f7a9"}.bi-4-square-fill::before{content:"\f7aa"}.bi-4-square::before{content:"\f7ab"}.bi-5-circle-fill::before{content:"\f7ae"}.bi-5-circle::before{content:"\f7af"}.bi-5-square-fill::before{content:"\f7b0"}.bi-5-square::before{content:"\f7b1"}.bi-6-circle-fill::before{content:"\f7b4"}.bi-6-circle::before{content:"\f7b5"}.bi-6-square-fill::before{content:"\f7b6"}.bi-6-square::before{content:"\f7b7"}.bi-7-circle-fill::before{content:"\f7ba"}.bi-7-circle::before{content:"\f7bb"}.bi-7-square-fill::before{content:"\f7bc"}.bi-7-square::before{content:"\f7bd"}.bi-8-circle-fill::before{content:"\f7c0"}.bi-8-circle::before{content:"\f7c1"}.bi-8-square-fill::before{content:"\f7c2"}.bi-8-square::before{content:"\f7c3"}.bi-9-circle-fill::before{content:"\f7c6"}.bi-9-circle::before{content:"\f7c7"}.bi-9-square-fill::before{content:"\f7c8"}.bi-9-square::before{content:"\f7c9"}.bi-airplane-engines-fill::before{content:"\f7ca"}.bi-airplane-engines::before{content:"\f7cb"}.bi-airplane-fill::before{content:"\f7cc"}.bi-airplane::before{content:"\f7cd"}.bi-alexa::before{content:"\f7ce"}.bi-alipay::before{content:"\f7cf"}.bi-android::before{content:"\f7d0"}.bi-android2::before{content:"\f7d1"}.bi-box-fill::before{content:"\f7d2"}.bi-box-seam-fill::before{content:"\f7d3"}.bi-browser-chrome::before{content:"\f7d4"}.bi-browser-edge::before{content:"\f7d5"}.bi-browser-firefox::before{content:"\f7d6"}.bi-browser-safari::before{content:"\f7d7"}.bi-c-circle-fill::before{content:"\f7da"}.bi-c-circle::before{content:"\f7db"}.bi-c-square-fill::before{content:"\f7dc"}.bi-c-square::before{content:"\f7dd"}.bi-capsule-pill::before{content:"\f7de"}.bi-capsule::before{content:"\f7df"}.bi-car-front-fill::before{content:"\f7e0"}.bi-car-front::before{content:"\f7e1"}.bi-cassette-fill::before{content:"\f7e2"}.bi-cassette::before{content:"\f7e3"}.bi-cc-circle-fill::before{content:"\f7e6"}.bi-cc-circle::before{content:"\f7e7"}.bi-cc-square-fill::before{content:"\f7e8"}.bi-cc-square::before{content:"\f7e9"}.bi-cup-hot-fill::before{content:"\f7ea"}.bi-cup-hot::before{content:"\f7eb"}.bi-currency-rupee::before{content:"\f7ec"}.bi-dropbox::before{content:"\f7ed"}.bi-escape::before{content:"\f7ee"}.bi-fast-forward-btn-fill::before{content:"\f7ef"}.bi-fast-forward-btn::before{content:"\f7f0"}.bi-fast-forward-circle-fill::before{content:"\f7f1"}.bi-fast-forward-circle::before{content:"\f7f2"}.bi-fast-forward-fill::before{content:"\f7f3"}.bi-fast-forward::before{content:"\f7f4"}.bi-filetype-sql::before{content:"\f7f5"}.bi-fire::before{content:"\f7f6"}.bi-google-play::before{content:"\f7f7"}.bi-h-circle-fill::before{content:"\f7fa"}.bi-h-circle::before{content:"\f7fb"}.bi-h-square-fill::before{content:"\f7fc"}.bi-h-square::before{content:"\f7fd"}.bi-indent::before{content:"\f7fe"}.bi-lungs-fill::before{content:"\f7ff"}.bi-lungs::before{content:"\f800"}.bi-microsoft-teams::before{content:"\f801"}.bi-p-circle-fill::before{content:"\f804"}.bi-p-circle::before{content:"\f805"}.bi-p-square-fill::before{content:"\f806"}.bi-p-square::before{content:"\f807"}.bi-pass-fill::before{content:"\f808"}.bi-pass::before{content:"\f809"}.bi-prescription::before{content:"\f80a"}.bi-prescription2::before{content:"\f80b"}.bi-r-circle-fill::before{content:"\f80e"}.bi-r-circle::before{content:"\f80f"}.bi-r-square-fill::before{content:"\f810"}.bi-r-square::before{content:"\f811"}.bi-repeat-1::before{content:"\f812"}.bi-repeat::before{content:"\f813"}.bi-rewind-btn-fill::before{content:"\f814"}.bi-rewind-btn::before{content:"\f815"}.bi-rewind-circle-fill::before{content:"\f816"}.bi-rewind-circle::before{content:"\f817"}.bi-rewind-fill::before{content:"\f818"}.bi-rewind::before{content:"\f819"}.bi-train-freight-front-fill::before{content:"\f81a"}.bi-train-freight-front::before{content:"\f81b"}.bi-train-front-fill::before{content:"\f81c"}.bi-train-front::before{content:"\f81d"}.bi-train-lightrail-front-fill::before{content:"\f81e"}.bi-train-lightrail-front::before{content:"\f81f"}.bi-truck-front-fill::before{content:"\f820"}.bi-truck-front::before{content:"\f821"}.bi-ubuntu::before{content:"\f822"}.bi-unindent::before{content:"\f823"}.bi-unity::before{content:"\f824"}.bi-universal-access-circle::before{content:"\f825"}.bi-universal-access::before{content:"\f826"}.bi-virus::before{content:"\f827"}.bi-virus2::before{content:"\f828"}.bi-wechat::before{content:"\f829"}.bi-yelp::before{content:"\f82a"}.bi-sign-stop-fill::before{content:"\f82b"}.bi-sign-stop-lights-fill::before{content:"\f82c"}.bi-sign-stop-lights::before{content:"\f82d"}.bi-sign-stop::before{content:"\f82e"}.bi-sign-turn-left-fill::before{content:"\f82f"}.bi-sign-turn-left::before{content:"\f830"}.bi-sign-turn-right-fill::before{content:"\f831"}.bi-sign-turn-right::before{content:"\f832"}.bi-sign-turn-slight-left-fill::before{content:"\f833"}.bi-sign-turn-slight-left::before{content:"\f834"}.bi-sign-turn-slight-right-fill::before{content:"\f835"}.bi-sign-turn-slight-right::before{content:"\f836"}.bi-sign-yield-fill::before{content:"\f837"}.bi-sign-yield::before{content:"\f838"}.bi-ev-station-fill::before{content:"\f839"}.bi-ev-station::before{content:"\f83a"}.bi-fuel-pump-diesel-fill::before{content:"\f83b"}.bi-fuel-pump-diesel::before{content:"\f83c"}.bi-fuel-pump-fill::before{content:"\f83d"}.bi-fuel-pump::before{content:"\f83e"}.bi-0-circle-fill::before{content:"\f83f"}.bi-0-circle::before{content:"\f840"}.bi-0-square-fill::before{content:"\f841"}.bi-0-square::before{content:"\f842"}.bi-rocket-fill::before{content:"\f843"}.bi-rocket-takeoff-fill::before{content:"\f844"}.bi-rocket-takeoff::before{content:"\f845"}.bi-rocket::before{content:"\f846"}.bi-stripe::before{content:"\f847"}.bi-subscript::before{content:"\f848"}.bi-superscript::before{content:"\f849"}.bi-trello::before{content:"\f84a"}.bi-envelope-at-fill::before{content:"\f84b"}.bi-envelope-at::before{content:"\f84c"}.bi-regex::before{content:"\f84d"}.bi-text-wrap::before{content:"\f84e"}.bi-sign-dead-end-fill::before{content:"\f84f"}.bi-sign-dead-end::before{content:"\f850"}.bi-sign-do-not-enter-fill::before{content:"\f851"}.bi-sign-do-not-enter::before{content:"\f852"}.bi-sign-intersection-fill::before{content:"\f853"}.bi-sign-intersection-side-fill::before{content:"\f854"}.bi-sign-intersection-side::before{content:"\f855"}.bi-sign-intersection-t-fill::before{content:"\f856"}.bi-sign-intersection-t::before{content:"\f857"}.bi-sign-intersection-y-fill::before{content:"\f858"}.bi-sign-intersection-y::before{content:"\f859"}.bi-sign-intersection::before{content:"\f85a"}.bi-sign-merge-left-fill::before{content:"\f85b"}.bi-sign-merge-left::before{content:"\f85c"}.bi-sign-merge-right-fill::before{content:"\f85d"}.bi-sign-merge-right::before{content:"\f85e"}.bi-sign-no-left-turn-fill::before{content:"\f85f"}.bi-sign-no-left-turn::before{content:"\f860"}.bi-sign-no-parking-fill::before{content:"\f861"}.bi-sign-no-parking::before{content:"\f862"}.bi-sign-no-right-turn-fill::before{content:"\f863"}.bi-sign-no-right-turn::before{content:"\f864"}.bi-sign-railroad-fill::before{content:"\f865"}.bi-sign-railroad::before{content:"\f866"}.bi-building-add::before{content:"\f867"}.bi-building-check::before{content:"\f868"}.bi-building-dash::before{content:"\f869"}.bi-building-down::before{content:"\f86a"}.bi-building-exclamation::before{content:"\f86b"}.bi-building-fill-add::before{content:"\f86c"}.bi-building-fill-check::before{content:"\f86d"}.bi-building-fill-dash::before{content:"\f86e"}.bi-building-fill-down::before{content:"\f86f"}.bi-building-fill-exclamation::before{content:"\f870"}.bi-building-fill-gear::before{content:"\f871"}.bi-building-fill-lock::before{content:"\f872"}.bi-building-fill-slash::before{content:"\f873"}.bi-building-fill-up::before{content:"\f874"}.bi-building-fill-x::before{content:"\f875"}.bi-building-fill::before{content:"\f876"}.bi-building-gear::before{content:"\f877"}.bi-building-lock::before{content:"\f878"}.bi-building-slash::before{content:"\f879"}.bi-building-up::before{content:"\f87a"}.bi-building-x::before{content:"\f87b"}.bi-buildings-fill::before{content:"\f87c"}.bi-buildings::before{content:"\f87d"}.bi-bus-front-fill::before{content:"\f87e"}.bi-bus-front::before{content:"\f87f"}.bi-ev-front-fill::before{content:"\f880"}.bi-ev-front::before{content:"\f881"}.bi-globe-americas::before{content:"\f882"}.bi-globe-asia-australia::before{content:"\f883"}.bi-globe-central-south-asia::before{content:"\f884"}.bi-globe-europe-africa::before{content:"\f885"}.bi-house-add-fill::before{content:"\f886"}.bi-house-add::before{content:"\f887"}.bi-house-check-fill::before{content:"\f888"}.bi-house-check::before{content:"\f889"}.bi-house-dash-fill::before{content:"\f88a"}.bi-house-dash::before{content:"\f88b"}.bi-house-down-fill::before{content:"\f88c"}.bi-house-down::before{content:"\f88d"}.bi-house-exclamation-fill::before{content:"\f88e"}.bi-house-exclamation::before{content:"\f88f"}.bi-house-gear-fill::before{content:"\f890"}.bi-house-gear::before{content:"\f891"}.bi-house-lock-fill::before{content:"\f892"}.bi-house-lock::before{content:"\f893"}.bi-house-slash-fill::before{content:"\f894"}.bi-house-slash::before{content:"\f895"}.bi-house-up-fill::before{content:"\f896"}.bi-house-up::before{content:"\f897"}.bi-house-x-fill::before{content:"\f898"}.bi-house-x::before{content:"\f899"}.bi-person-add::before{content:"\f89a"}.bi-person-down::before{content:"\f89b"}.bi-person-exclamation::before{content:"\f89c"}.bi-person-fill-add::before{content:"\f89d"}.bi-person-fill-check::before{content:"\f89e"}.bi-person-fill-dash::before{content:"\f89f"}.bi-person-fill-down::before{content:"\f8a0"}.bi-person-fill-exclamation::before{content:"\f8a1"}.bi-person-fill-gear::before{content:"\f8a2"}.bi-person-fill-lock::before{content:"\f8a3"}.bi-person-fill-slash::before{content:"\f8a4"}.bi-person-fill-up::before{content:"\f8a5"}.bi-person-fill-x::before{content:"\f8a6"}.bi-person-gear::before{content:"\f8a7"}.bi-person-lock::before{content:"\f8a8"}.bi-person-slash::before{content:"\f8a9"}.bi-person-up::before{content:"\f8aa"}.bi-scooter::before{content:"\f8ab"}.bi-taxi-front-fill::before{content:"\f8ac"}.bi-taxi-front::before{content:"\f8ad"}.bi-amd::before{content:"\f8ae"}.bi-database-add::before{content:"\f8af"}.bi-database-check::before{content:"\f8b0"}.bi-database-dash::before{content:"\f8b1"}.bi-database-down::before{content:"\f8b2"}.bi-database-exclamation::before{content:"\f8b3"}.bi-database-fill-add::before{content:"\f8b4"}.bi-database-fill-check::before{content:"\f8b5"}.bi-database-fill-dash::before{content:"\f8b6"}.bi-database-fill-down::before{content:"\f8b7"}.bi-database-fill-exclamation::before{content:"\f8b8"}.bi-database-fill-gear::before{content:"\f8b9"}.bi-database-fill-lock::before{content:"\f8ba"}.bi-database-fill-slash::before{content:"\f8bb"}.bi-database-fill-up::before{content:"\f8bc"}.bi-database-fill-x::before{content:"\f8bd"}.bi-database-fill::before{content:"\f8be"}.bi-database-gear::before{content:"\f8bf"}.bi-database-lock::before{content:"\f8c0"}.bi-database-slash::before{content:"\f8c1"}.bi-database-up::before{content:"\f8c2"}.bi-database-x::before{content:"\f8c3"}.bi-database::before{content:"\f8c4"}.bi-houses-fill::before{content:"\f8c5"}.bi-houses::before{content:"\f8c6"}.bi-nvidia::before{content:"\f8c7"}.bi-person-vcard-fill::before{content:"\f8c8"}.bi-person-vcard::before{content:"\f8c9"}.bi-sina-weibo::before{content:"\f8ca"}.bi-tencent-qq::before{content:"\f8cb"}.bi-wikipedia::before{content:"\f8cc"}.bi-alphabet-uppercase::before{content:"\f2a5"}.bi-alphabet::before{content:"\f68a"}.bi-amazon::before{content:"\f68d"}.bi-arrows-collapse-vertical::before{content:"\f690"}.bi-arrows-expand-vertical::before{content:"\f695"}.bi-arrows-vertical::before{content:"\f698"}.bi-arrows::before{content:"\f6a2"}.bi-ban-fill::before{content:"\f6a3"}.bi-ban::before{content:"\f6b6"}.bi-bing::before{content:"\f6c2"}.bi-cake::before{content:"\f6e0"}.bi-cake2::before{content:"\f6ed"}.bi-cookie::before{content:"\f6ee"}.bi-copy::before{content:"\f759"}.bi-crosshair::before{content:"\f769"}.bi-crosshair2::before{content:"\f794"}.bi-emoji-astonished-fill::before{content:"\f795"}.bi-emoji-astonished::before{content:"\f79a"}.bi-emoji-grimace-fill::before{content:"\f79b"}.bi-emoji-grimace::before{content:"\f7a0"}.bi-emoji-grin-fill::before{content:"\f7a1"}.bi-emoji-grin::before{content:"\f7a6"}.bi-emoji-surprise-fill::before{content:"\f7a7"}.bi-emoji-surprise::before{content:"\f7ac"}.bi-emoji-tear-fill::before{content:"\f7ad"}.bi-emoji-tear::before{content:"\f7b2"}.bi-envelope-arrow-down-fill::before{content:"\f7b3"}.bi-envelope-arrow-down::before{content:"\f7b8"}.bi-envelope-arrow-up-fill::before{content:"\f7b9"}.bi-envelope-arrow-up::before{content:"\f7be"}.bi-feather::before{content:"\f7bf"}.bi-feather2::before{content:"\f7c4"}.bi-floppy-fill::before{content:"\f7c5"}.bi-floppy::before{content:"\f7d8"}.bi-floppy2-fill::before{content:"\f7d9"}.bi-floppy2::before{content:"\f7e4"}.bi-gitlab::before{content:"\f7e5"}.bi-highlighter::before{content:"\f7f8"}.bi-marker-tip::before{content:"\f802"}.bi-nvme-fill::before{content:"\f803"}.bi-nvme::before{content:"\f80c"}.bi-opencollective::before{content:"\f80d"}.bi-pci-card-network::before{content:"\f8cd"}.bi-pci-card-sound::before{content:"\f8ce"}.bi-radar::before{content:"\f8cf"}.bi-send-arrow-down-fill::before{content:"\f8d0"}.bi-send-arrow-down::before{content:"\f8d1"}.bi-send-arrow-up-fill::before{content:"\f8d2"}.bi-send-arrow-up::before{content:"\f8d3"}.bi-sim-slash-fill::before{content:"\f8d4"}.bi-sim-slash::before{content:"\f8d5"}.bi-sourceforge::before{content:"\f8d6"}.bi-substack::before{content:"\f8d7"}.bi-threads-fill::before{content:"\f8d8"}.bi-threads::before{content:"\f8d9"}.bi-transparency::before{content:"\f8da"}.bi-twitter-x::before{content:"\f8db"}.bi-type-h4::before{content:"\f8dc"}.bi-type-h5::before{content:"\f8dd"}.bi-type-h6::before{content:"\f8de"}.bi-backpack-fill::before{content:"\f8df"}.bi-backpack::before{content:"\f8e0"}.bi-backpack2-fill::before{content:"\f8e1"}.bi-backpack2::before{content:"\f8e2"}.bi-backpack3-fill::before{content:"\f8e3"}.bi-backpack3::before{content:"\f8e4"}.bi-backpack4-fill::before{content:"\f8e5"}.bi-backpack4::before{content:"\f8e6"}.bi-brilliance::before{content:"\f8e7"}.bi-cake-fill::before{content:"\f8e8"}.bi-cake2-fill::before{content:"\f8e9"}.bi-duffle-fill::before{content:"\f8ea"}.bi-duffle::before{content:"\f8eb"}.bi-exposure::before{content:"\f8ec"}.bi-gender-neuter::before{content:"\f8ed"}.bi-highlights::before{content:"\f8ee"}.bi-luggage-fill::before{content:"\f8ef"}.bi-luggage::before{content:"\f8f0"}.bi-mailbox-flag::before{content:"\f8f1"}.bi-mailbox2-flag::before{content:"\f8f2"}.bi-noise-reduction::before{content:"\f8f3"}.bi-passport-fill::before{content:"\f8f4"}.bi-passport::before{content:"\f8f5"}.bi-person-arms-up::before{content:"\f8f6"}.bi-person-raised-hand::before{content:"\f8f7"}.bi-person-standing-dress::before{content:"\f8f8"}.bi-person-standing::before{content:"\f8f9"}.bi-person-walking::before{content:"\f8fa"}.bi-person-wheelchair::before{content:"\f8fb"}.bi-shadows::before{content:"\f8fc"}.bi-suitcase-fill::before{content:"\f8fd"}.bi-suitcase-lg-fill::before{content:"\f8fe"}.bi-suitcase-lg::before{content:"\f8ff"}.bi-suitcase::before{content:"\f900"}.bi-suitcase2-fill::before{content:"\f901"}.bi-suitcase2::before{content:"\f902"}.bi-vignette::before{content:"\f903"} \ No newline at end of file diff --git a/static/base/css/inception.css b/static/base/css/inception.css deleted file mode 100644 index fb54d69c..00000000 --- a/static/base/css/inception.css +++ /dev/null @@ -1,96 +0,0 @@ -html { - scroll-behavior: smooth; -} - -body { - margin: 0; - font-family: var(--val-font-family); - font-size: var(--val-fs--base); - font-weight: var(--val-fw--base); - line-height: var(--val-lh--base); - color: var(--val-color--text); - background-color: var(--val-color--bg); - -webkit-text-size-adjust: 100%; - -webkit-tap-highlight-color: transparent; -} - -/* TYPOGRAPHY */ - -h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: var(--val-gap-0-35); - font-weight: var(--val-fw--bold); - line-height: var(--val-lh--header); -} -h1 { - font-size: var(--val-fs--x3l); -} -h2 { - font-size: var(--val-fs--x2l); -} -h3 { - font-size: var(--val-fs--xl); -} -h4 { - font-size: var(--val-fs--l); -} -h5 { - font-size: var(--val-fs--m); -} -h6 { - font-size: var(--val-fs--base); -} -/* LG - Applies <= 992px */ -@media screen and (max-width: 62rem) { - h1 { - font-size: calc(var(--val-fs--l) + 1.25vw); - } - h2 { - font-size: calc(var(--val-fs--l) + 0.6vw); - } - h3 { - font-size: calc(var(--val-fs--m) + 0.6vw); - } - h4 { - font-size: calc(var(--val-fs--m) + 0.3vw); - } -} - -p { - margin: var(--val-gap-0-75) 0; -} - -a { - color: var(--val-color--primary-link); - transition: color .15s ease-in-out; -} -a:hover { - color: var(--val-color--primary-link-hover); -} -a:active { - color: var(--val-color--primary-link-active); -} - -/* LAYOUT */ - -#body__wrapper > .flex__item { - max-width: var(--val-max-width); - background: var(--val-color--white); -} -#header > .flex__content { - margin: var(--val-gap); -} -#body__wrapper > #footer { - max-width: 100%; - background: linear-gradient(180deg, var(--val-color--gray-5) 0%, var(--val-color--gray-10) 100%); -} -#footer > .flex__content { - max-width: var(--val-max-width); - margin: 0 auto; - color: var(--val-color--gray-65); - background: var(--val-color--gray-20); - padding: calc(3 * var(--val-gap)) 0 calc(12 * var(--val-gap)); -} -#footer > .flex__content a { - color: var(--val-color--white); -} diff --git a/static/base/css/looks.css b/static/base/css/looks.css deleted file mode 100644 index f2a44357..00000000 --- a/static/base/css/looks.css +++ /dev/null @@ -1,299 +0,0 @@ -/* SKIP TO MAIN CONTENT */ - -.skip__to_content { - display: flex; - justify-content: center; - margin-top: -1px; -} -.skip__to_content a { - display: block; - padding: var(--val-gap-0-5) var(--val-gap-1-5); - color: var(--val-color--white); - background-color: var(--val-color--gray-5); - text-decoration: none; - outline: 0; - position: absolute; - transform: translateY(-100%); - transition: all 0.3s ease-in-out; - z-index: 9999; -} -.skip__to_content a:after { - content: "\0020 âž”"; -} -.skip__to_content a:focus { - transform: translateY(0%); -} - -/* STYLES BASE */ - -.style__info { - color: var(--val-color--white); - background-color: var(--val-color--info); -} -.style__info a { - color: var(--val-color--info-link); - font-weight: 700; -} -.style__info a:hover { - color: var(--val-color--info-link-hover); -} -.style__info a:active { - color: var(--val-color--info-link-active); -} - -.style__success { - color: var(--val-color--white); - background-color: var(--val-color--success); -} -.style__success a { - color: var(--val-color--success-link); - font-weight: 700; -} -.style__success a:hover { - color: var(--val-color--success-link-hover); -} -.style__success a:active { - color: var(--val-color--success-link-active); -} - -.style__warning { - color: var(--val-color--white); - background-color: var(--val-color--warning); -} -.style__warning a { - color: var(--val-color--warning-link); - font-weight: 700; -} -.style__warning a:hover { - color: var(--val-color--warning-link-hover); -} -.style__warning a:active { - color: var(--val-color--warning-link-active); -} - -.style__danger { - color: var(--val-color--white); - background-color: var(--val-color--danger); -} -.style__danger a { - color: var(--val-color--danger-link); - font-weight: 700; -} -.style__danger a:hover { - color: var(--val-color--danger-link-hover); -} -.style__danger a:active { - color: var(--val-color--danger-link-active); -} - -.style__light { - color: var(--val-color--text); - background-color: var(--val-color--light); -} - -.style__dark { - color: var(--val-color--white); - background-color: var(--val-color--dark); -} -.style__dark a { - color: var(--val-color--dark-link); - font-weight: 700; -} -.style__dark a:hover { - color: var(--val-color--dark-link-hover); -} -.style__dark a:active { - color: var(--val-color--dark-link-active); -} - -.style__link { - color: var(--val-color--primary); - background-color: transparent; -} - -/* TYPOGRAPHY */ - -.fs__x3l { - font-size: var(--val-fs--x3l) !important; -} -.fs__x2l { - font-size: var(--val-fs--x2l) !important; -} -.fs__xl { - font-size: var(--val-fs--xl) !important; -} -.fs__l { - font-size: var(--val-fs--l) !important; -} -.fs__m { - font-size: var(--val-fs--m) !important; -} -.fs__s { - font-size: var(--val-fs--s) !important; -} -.fs__xs { - font-size: var(--val-fs--xs) !important; -} -.fs__x2s { - font-size: var(--val-fs--x2s) !important; -} -.fs__x3s { - font-size: var(--val-fs--x3s) !important; -} -/* LG - Applies <= 992px */ -@media screen and (max-width: 62rem) { - .fs__x3l { - font-size: calc(var(--val-fs--l) + 1.25vw) !important; - } - .fs__x2l { - font-size: calc(var(--val-fs--l) + 0.6vw) !important; - } - .fs__xl { - font-size: calc(var(--val-fs--m) + 0.6vw) !important; - } - .fs__l { - font-size: calc(var(--val-fs--m) + 0.3vw) !important; - } -} - -/* COMPONENT STYLES */ - -/* Heading component */ - -.heading__title-x3l, -.heading__title-x2l, -.heading__title-xl, -.heading__title-l, -.heading__title-m, -.heading__subtitle { - font-weight: var(--val-fw--light); -} -.heading__title-x3l { - font-size: calc(var(--val-fs--x3l) * 2); -} -.heading__title-x2l { - font-size: calc(var(--val-fs--x3l) * 1.8); -} -.heading__title-xl { - font-size: calc(var(--val-fs--x3l) * 1.6); -} -.heading__title-l { - font-size: calc(var(--val-fs--x3l) * 1.4); -} -.heading__title-m { - font-size: calc(var(--val-fs--x3l) * 1.2); -} -.heading__subtitle { - margin-top: calc(-1 * var(--val-gap-0-5)); -} -/* LG - Applies <= 992px */ -@media screen and (max-width: 62rem) { - .heading__title-x3l { - font-size: calc((var(--val-fs--x3l) / 1.5) + 4.5vw); - } - .heading__title-x2l { - font-size: calc((var(--val-fs--x3l) / 1.6) + 3.9vw); - } - .heading__title-xl { - font-size: calc((var(--val-fs--x3l) / 1.6) + 3.3vw); - } - .heading__title-l { - font-size: calc((var(--val-fs--x3l) / 1.7) + 2.7vw); - } - .heading__title-m { - font-size: calc((var(--val-fs--x3l) / 1.7) + 2.1vw); - } -} - -/* Image component */ - -.img__fluid { - max-width: 100%; - height: auto; -} - -/* Block component */ - -.block__title { - font-size: var(--val-fs--m); - background-color: var(--val-color--gray-90); - padding: var(--val-gap-0-35) var(--val-gap); - margin: 0 -} -.block__container.style__info .block__title { - background-color: var(--val-color--info-dark); -} -.block__container.style__success .block__title { - background-color: var(--val-color--success-dark); -} -.block__container.style__warning .block__title { - background-color: var(--val-color--warning-dark); -} -.block__container.style__danger .block__title { - background-color: var(--val-color--danger-dark); -} -.block__container.style__dark .block__title { - color: var(--val-color--dark-dark); -} - -.block__content { - padding: var(--val-gap-0-35) var(--val-gap); -} -.block__container.style__info .block__content { - border-left: var(--val-gap-0-5) solid var(--val-color--info-dark); -} -.block__container.style__success .block__content { - border-left: var(--val-gap-0-5) solid var(--val-color--success-dark); -} -.block__container.style__warning .block__content { - border-left: var(--val-gap-0-5) solid var(--val-color--warning-dark); -} -.block__container.style__danger .block__content { - border-left: var(--val-gap-0-5) solid var(--val-color--danger-dark); -} - -.block__container > .block__title + .block__content { - border-left: 0; -} - -/* Branding component */ - -.branding__content { - display: flex; - align-items: flex-end; - column-gap: var(--val-gap-0-75); -} -.branding__name { - letter-spacing: 0.02em; - font-size: var(--val-fs--l); - font-weight: 700; - text-decoration: none; -} -.branding__slogan { - font-size: var(--val-fs--m); -} - -/* SM - Applies <= 568px */ -@media (max-width: 35.5rem) { - .branding__logo { - display: none; - } -} -/* LG - Applies <= 992px */ -@media (max-width: 62rem) { - .branding__slogan { - font-size: var(--val-fs--base); - } -} - -/* PoweredBy component */ - -.poweredby__container { - text-align: center; -} -.poweredby__logo img, -.poweredby__logo svg { - margin-left: .275em; - height: 1.275em; - vertical-align: middle; -} diff --git a/static/base/css/menu.css b/static/base/css/menu.css deleted file mode 100644 index b4461a3c..00000000 --- a/static/base/css/menu.css +++ /dev/null @@ -1,309 +0,0 @@ -.menu__container { - width: 100%; - height: auto; - margin: 0; - padding: 0; - z-index: 999; - border: none; - outline: none; - background: var(--val-menu--color-bg); -} - -.menu__content { - padding-right: var(--val-gap); -} -.menu__content a, -.menu__content button { - cursor: pointer; - border: none; - background: none; - text-decoration: none; -} - -.menu__nav ul { - margin: 0; - padding: 0; -} -.menu__nav li { - display: inline-block; - margin: 0 0 0 1.5rem; - padding: var(--val-menu--line-padding) 0; - line-height: var(--val-menu--line-height); - list-style: none; - list-style-type: none; -} - -.menu__nav li.menu__label, -.menu__nav li > a { - position: relative; - font-weight: 500; - color: var(--val-color--text); - text-rendering: optimizeLegibility; -} -.menu__nav li > a { - border: none; - transition: color 0.3s ease-in-out; -} -.menu__nav li:hover > a, -.menu__nav li > a:focus { - color: var(--val-menu--color-highlight); -} -.menu__nav li > a > i.menu__icon { - margin-left: 0.25rem; -} - -.menu__nav li .menu__subs { - position: absolute; - max-width: 100%; - height: auto; - padding: 1rem 2rem; - border: none; - outline: none; - background: var(--val-menu--color-bg); - border-radius: var(--val-menu--border-radius); - border-top: 3px solid var(--val-menu--color-highlight); - z-index: 500; - opacity: 0; - visibility: hidden; - box-shadow: 0 4px 6px -1px var(--val-menu--color-border), 0 2px 4px -1px var(--val-menu--color-shadow); - transition: all 0.5s ease-in-out; -} - -.menu__nav li.menu__children:hover > .menu__subs, -.menu__nav li.menu__children > a:focus + .menu__subs, -.menu__nav li.menu__children .menu__subs:focus-within { - margin-top: 0.4rem; - opacity: 1; - visibility: visible; -} - -.menu__nav li .menu__items { - min-width: var(--val-menu--item-width-min); - max-width: var(--val-menu--item-width-max); -} -.menu__nav li .menu__items .menu__title { - font-family: inherit; - font-size: 1rem; - font-weight: 500; - margin: 0; - padding: var(--val-menu--line-padding) 0; - line-height: var(--val-menu--line-height); - border: none; - outline: none; - color: var(--val-menu--color-highlight); - text-transform: uppercase; - text-rendering: optimizeLegibility; -} -.menu__nav li .menu__items li { - display: block; - margin-left: 0; -} - -.menu__nav li .menu__mega { - left: 50%; - transform: translateX(-50%); -} - -.menu__nav li .menu__groups { - display: flex; - flex-wrap: nowrap; -} - -.menu__header, -.menu__trigger { - display: none; -} - -/* Applies <= 992px */ -@media only screen and (max-width: 62rem) { - .menu__container { - border-radius: var(--val-border-radius); - } - .menu__content { - padding-right: var(--val-gap-0-5); - } - .menu__content button { - margin: var(--val-gap-0-5) 0 var(--val-gap-0-5) var(--val-gap-0-5); - } - .menu__trigger { - cursor: pointer; - width: var(--val-menu--trigger-width); - height: var(--val-menu--item-height); - border: none; - outline: none; - background: none; - display: flex; - flex-direction: column; - justify-content: center; - } - .menu__trigger span { - width: 100%; - height: 2px; - margin: 12.675% 0; - border-radius: var(--val-border-radius); - background: var(--val-color--text); - } - - .menu__nav { - position: fixed; - top: 0; - left: 0; - width: var(--val-menu--side-width); - height: 100%; - z-index: 1099; - overflow: hidden; - background: var(--val-menu--color-bg); - transform: translate(-100%); - transition: all 0.5s ease-in-out; - } - .menu__main .menu__nav.active { - transform: translate(0%); - } - - .menu__nav li { - display: block; - margin: 0; - padding: 0; - } - .menu__nav li.menu__label, - .menu__nav li > a { - display: block; - padding: var(--val-menu--line-padding) var(--val-menu--item-height) var(--val-menu--line-padding) var(--val-menu--item-gap); - border-bottom: 1px solid var(--val-menu--color-border); - } - .menu__nav li ul li.menu__label, - .menu__nav li ul li > a { - border-bottom: 0; - } - .menu__nav li > a > i.menu__icon { - position: absolute; - top: var(--val-menu--line-padding); - right: var(--val-menu--line-padding); - font-size: 1.25rem; - transform: rotate(-90deg); - } - - .menu__nav li .menu__subs { - position: absolute; - display: none; - top: 0; - left: 0; - max-width: none; - min-width: auto; - width: 100%; - height: 100%; - margin: 0 !important; - padding: 0; - border-top: 0; - opacity: 1; - overflow-y: auto; - visibility: visible; - transform: translateX(0%); - box-shadow: none; - } - .menu__nav li .menu__subs.active { - display: block; - } - .menu__nav li .menu__subs > :first-child { - margin-top: 4rem; - } - - .menu__nav li .menu__items .menu__title { - padding: var(--val-menu--line-padding) var(--val-menu--item-height) var(--val-menu--line-padding) var(--val-menu--item-gap); - } - - .menu__nav li .menu__groups { - display: block; - } - - .menu__nav .menu__header { - position: sticky; - display: flex; - align-items: center; - justify-content: space-between; - top: 0; - height: var(--val-menu--item-height); - border-bottom: 1px solid var(--val-menu--color-border); - background: var(--val-menu--color-bg); - z-index: 501; - } - .menu__nav .menu__header .menu__title { - padding: var(--val-menu--line-padding); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - .menu__nav .menu__header .menu__close, - .menu__nav .menu__header .menu__arrow { - width: var(--val-menu--item-height); - min-width: var(--val-menu--item-height); - height: var(--val-menu--item-height); - line-height: var(--val-menu--item-height); - color: var(--val-color--text); - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - } - .menu__nav .menu__header .menu__close { - font-size: 2.25rem; - border-left: 1px solid var(--val-menu--color-border); - } - .menu__nav .menu__header .menu__arrow { - font-size: 1.25rem; - border-right: 1px solid var(--val-menu--color-border); - display: none; - } - .menu__nav .menu__header.active .menu__arrow { - display: flex; - } - - .menu__nav .menu__section { - height: 100%; - overflow-y: auto; - overflow-x: hidden; - padding: 0; - margin: 0; - } - - .menu__overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1098; - opacity: 0; - visibility: hidden; - background: rgba(0, 0, 0, 0.55); - transition: all 0.5s ease-in-out; - } - .menu__overlay.active { - opacity: 1; - visibility: visible; - } -} - -/* ANIMATIONS */ - -@keyframes slideLeft { - 0% { - opacity: 0; - transform: translateX(100%); - } - 100% { - opacity: 1; - transform: translateX(0%); - } -} - -@keyframes slideRight { - 0% { - opacity: 1; - transform: translateX(0%); - } - 100% { - opacity: 0; - transform: translateX(100%); - } -} diff --git a/static/base/css/normalize.min.css b/static/base/css/normalize.min.css deleted file mode 100644 index e1b546a5..00000000 --- a/static/base/css/normalize.min.css +++ /dev/null @@ -1,2 +0,0 @@ -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ -html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;}main{display:block;}h1{font-size:2em;margin:.67em 0;}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder;}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sub{bottom:-.25em;}sup{top:-.5em;}img{border-style:none;}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible;}button,select{text-transform:none;}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button;}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0;}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText;}fieldset{padding:.35em .75em .625em;}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline;}textarea{overflow:auto;}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto;}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block;}summary{display:list-item;}template{display:none;}[hidden]{display:none;} \ No newline at end of file diff --git a/static/base/css/root.css b/static/base/css/root.css deleted file mode 100644 index bc55a443..00000000 --- a/static/base/css/root.css +++ /dev/null @@ -1,211 +0,0 @@ -:root { - --val-font-sans: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; - --val-font-serif: "Lora","georgia",serif; - --val-font-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; - --val-font-family: var(--val-font-sans); - - /* Font size */ - --val-fs--x3l: 2.5rem; - --val-fs--x2l: 2rem; - --val-fs--xl: 1.75rem; - --val-fs--l: 1.5rem; - --val-fs--m: 1.25rem; - --val-fs--base: 1rem; - --val-fs--s: 0.875rem; - --val-fs--xs: 0.75rem; - --val-fs--x2s: 0.5625rem; - --val-fs--x3s: 0.375rem; - - /* Font weight */ - --val-fw--light: 300; - --val-fw--base: 400; - --val-fw--bold: 500; - - /* Line height */ - --val-lh--base: 1.5; - --val-lh--header: 1.2; - - --val-max-width: 90rem; -/* - --val-color-rgb: 33,37,41; - --val-main--bg-rgb: 255,255,255; - --val-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); - - --line-height-base: 1.6875rem; - --line-height-s: 1.125rem; - --max-bg-color: 98.125rem; -*/ - --val-gap: 1.125rem; -/* - --content-left: 5.625rem; - --site-header-height-wide: var(--val-gap10); - --container-padding: var(--val-gap); -*/ -} -/* -@media (min-width: 75rem) { - :root { - --container-padding:var(--val-gap2); - } -} - -:root { - --scrollbar-width: 0px; - --grid-col-count: 6; - --grid-gap: var(--val-gap); - --grid-gap-count: calc(var(--grid-col-count) - 1); - --grid-full-width: calc(100vw - var(--val-gap2) - var(--scrollbar-width)); - --grid-col-width: calc((var(--grid-full-width) - (var(--grid-gap-count) * var(--grid-gap))) / var(--grid-col-count)); -} - -@media (min-width: 43.75rem) { - :root { - --grid-col-count:14; - --grid-gap: var(--val-gap2); - } -} - -@media (min-width: 62.5rem) { - :root { - --scrollbar-width:0.9375rem; - } -} - -@media (min-width: 75rem) { - :root { - --grid-full-width:calc(100vw - var(--scrollbar-width) - var(--content-left) - var(--val-gap4)); - } -} - -@media (min-width: 90rem) { - :root { - --grid-full-width:calc(var(--max-width) - var(--val-gap4)); - } -} -*/ -:root { - --val-gap-0-15: calc(0.15 * var(--val-gap)); - --val-gap-0-25: calc(0.25 * var(--val-gap)); - --val-gap-0-35: calc(0.35 * var(--val-gap)); - --val-gap-0-5: calc(0.5 * var(--val-gap)); - --val-gap-0-75: calc(0.75 * var(--val-gap)); - --val-gap-1-5: calc(1.5 * var(--val-gap)); - --val-gap-2: calc(2 * var(--val-gap)); - - --primary-hue: 216; - --primary-sat: 60%; - --val-color--primary: hsl(var(--primary-hue), var(--primary-sat), 50%); - --val-color--primary-light: hsl(var(--primary-hue), var(--primary-sat), 60%); - --val-color--primary-dark: hsl(var(--primary-hue), var(--primary-sat), 40%); - --val-color--primary-link: hsl(var(--primary-hue), var(--primary-sat), 55%); - --val-color--primary-link-hover: hsl(var(--primary-hue), var(--primary-sat), 30%); - --val-color--primary-link-active: hsl(var(--primary-hue), var(--primary-sat), 70%); - - --info-hue: 190; - --info-sat: 90%; - --val-color--info: hsl(var(--info-hue), var(--info-sat), 54%); - --val-color--info-light: hsl(var(--info-hue), var(--info-sat), 70%); - --val-color--info-dark: hsl(var(--info-hue), var(--info-sat), 45%); - --val-color--info-link: hsl(var(--info-hue), var(--info-sat), 30%); - --val-color--info-link-hover: hsl(var(--info-hue), var(--info-sat), 20%); - --val-color--info-link-active: hsl(var(--info-hue), var(--info-sat), 40%); - - --success-hue: 150; - --success-sat: 50%; - --val-color--success: hsl(var(--success-hue), var(--success-sat), 50%); - --val-color--success-light: hsl(var(--success-hue), var(--success-sat), 68%); - --val-color--success-dark: hsl(var(--success-hue), var(--success-sat), 38%); - --val-color--success-link: hsl(var(--success-hue), var(--success-sat), 26%); - --val-color--success-link-hover: hsl(var(--success-hue), var(--success-sat), 18%); - --val-color--success-link-active: hsl(var(--success-hue), var(--success-sat), 36%); - - --warning-hue: 44; - --warning-sat: 100%; - --val-color--warning: hsl(var(--warning-hue), var(--warning-sat), 50%); - --val-color--warning-light: hsl(var(--warning-hue), var(--warning-sat), 60%); - --val-color--warning-dark: hsl(var(--warning-hue), var(--warning-sat), 40%); - --val-color--warning-link: hsl(var(--warning-hue), var(--warning-sat), 30%); - --val-color--warning-link-hover: hsl(var(--warning-hue), var(--warning-sat), 20%); - --val-color--warning-link-active: hsl(var(--warning-hue), var(--warning-sat), 38%); - - --danger-hue: 348; - --danger-sat: 86%; - --val-color--danger: hsl(var(--danger-hue), var(--danger-sat), 50%); - --val-color--danger-light: hsl(var(--danger-hue), var(--danger-sat), 60%); - --val-color--danger-dark: hsl(var(--danger-hue), var(--danger-sat), 35%); - --val-color--danger-link: hsl(var(--danger-hue), var(--danger-sat), 25%); - --val-color--danger-link-hover: hsl(var(--danger-hue), var(--danger-sat), 10%); - --val-color--danger-link-active: hsl(var(--danger-hue), var(--danger-sat), 30%); - - --light-hue: 0; - --light-sat: 0%; - --val-color--light: hsl(var(--light-hue), var(--light-sat), 96%); - --val-color--light-light: hsl(var(--light-hue), var(--light-sat), 98%); - --val-color--light-dark: hsl(var(--light-hue), var(--light-sat), 92%); - - --dark-hue: 0; - --dark-sat: 0%; - --val-color--dark: hsl(var(--dark-hue), var(--dark-sat), 25%); - --val-color--dark-light: hsl(var(--dark-hue), var(--dark-sat), 40%); - --val-color--dark-dark: hsl(var(--dark-hue), var(--dark-sat), 8%); - --val-color--dark-link: hsl(var(--dark-hue), var(--dark-sat), 90%); - --val-color--dark-link-hover: hsl(var(--dark-hue), var(--dark-sat), 100%); - --val-color--dark-link-active: hsl(var(--dark-hue), var(--dark-sat), 70%); - - - - - --gray-hue: 201; - --gray-sat: 15%; - --val-color--gray-5: hsl(var(--gray-hue), var(--gray-sat), 5%); - --val-color--gray-10: hsl(var(--gray-hue), var(--gray-sat) ,11%); - --val-color--gray-20: hsl(var(--gray-hue), var(--gray-sat),20%); - --val-color--gray-45: hsl(var(--gray-hue), var(--gray-sat), 44%); - --val-color--gray-60: hsl(var(--gray-hue), var(--gray-sat), 57%); - --val-color--gray-65: hsl(var(--gray-hue), var(--gray-sat), 63%); - --val-color--gray-70: hsl(var(--gray-hue), var(--gray-sat), 72%); - --val-color--gray-90: hsl(var(--gray-hue), var(--gray-sat), 88%); - --val-color--gray-95: hsl(var(--gray-hue), var(--gray-sat), 93%); - --val-color--gray-100: hsl(var(--gray-hue), var(--gray-sat), 97%); - - - - - --val-color--bg: #fafafa; - --val-color--text: #212529; - --val-color--white: #fff; - -/* - - - --color-text-neutral-soft: var(--color--gray-45); - --color-text-neutral-medium: var(--color--gray-20); - --color-text-neutral-loud: var(--color--gray-5); - --color-text-primary-medium: var(--val-color--primary-40); - --color-text-primary-loud: var(--val-color--primary-30); - --color--black: #000; -*/ -/* - --color--red: #e33f1e; - --color--gold: #fdca40; - --color--green: #3fa21c; - --header-height-wide-when-fixed: calc(6 * var(--val-gap)); - --mobile-nav-width: 31.25rem; -*/ - --val-border-radius: 0.375rem; - - /* Menu component */ - --val-menu--color-bg: var(--val-color--bg); - --val-menu--color-highlight: #e91e63; - --val-menu--color-border: rgba(0, 0, 0, 0.1); - --val-menu--color-shadow: rgba(0, 0, 0, 0.06); - --val-menu--line-padding: 0.625rem; - --val-menu--line-height: calc(1.875rem + 1px); - --val-menu--item-height: calc(var(--val-menu--line-padding) + var(--val-menu--line-height)); - --val-menu--item-width-min: 14rem; - --val-menu--item-width-max: 20rem; - --val-menu--item-gap: 1rem; - --val-menu--border-radius: 0.625rem; - --val-menu--trigger-width: var(--val-menu--item-height); - --val-menu--side-width: 20rem; -} diff --git a/static/base/css/welcome.css b/static/base/css/welcome.css deleted file mode 100644 index 37cec138..00000000 --- a/static/base/css/welcome.css +++ /dev/null @@ -1,84 +0,0 @@ -#welcome span.app-name { - font-weight: 500; - color: inherit; -} - -#welcome .welcome, -#welcome .pagetop, -#welcome .issues { - margin: 3.2rem auto; -} - -#welcome [class$="-col-text"] > .flex__content { - margin: 5%; - text-align: center; -} - -#welcome [class$="-col-image"] > .flex__content { - margin: 1rem 5%; -} - -#welcome .welcome > .flex__item { - border-radius: 28px; - background: url("/base/images/welcome.jpg") center center no-repeat; - background-size: auto; - background-size: cover; - color: #fff; -} -#welcome .welcome > .flex__item > .flex__content { - margin: 2rem 1rem; - text-align: center; - color: #fff; -} -#welcome .welcome > .flex__item > .flex__content > h2 { - color: #fff; -} -#welcome .welcome > .flex__item > .flex__content > h3 { - color: #ccc; -} - -#welcome .promo-col-image > .flex__content { - padding: 0 5%; -} - -#welcome .issues-col-image > .flex__content img { - border-radius: 40px; -} - -/* BREAKPOINTS */ - -/* MD - Applies > 768px */ -@media screen and (min-width: 48.0625rem) { - #welcome .hello-world { - margin-top: 2rem; - } - - #welcome .promo-col-image > .flex__content { - padding: 0; - } - - #welcome .issues-col-text > .flex__content { - text-align: left; - } -} -/* LG - Applies > 992px */ -@media screen and (min-width: 62.0625rem) { - #welcome .hello-col-text > .flex__content { - text-align: left; - } - - #welcome .promo-col-text > .flex__content { - margin-right: 0; - text-align: right; - } -} -/* XL - Applies > 1280px */ -@media screen and (min-width: 80.0625rem) { - #welcome .hello-col-text > .flex__content { - margin-left: 20%; - } - - #welcome .pagetop-col-text > .flex__content { - text-align: left; - } -} diff --git a/static/base/favicon.ico b/static/base/favicon.ico deleted file mode 100644 index 95e1affa..00000000 Binary files a/static/base/favicon.ico and /dev/null differ diff --git a/static/base/fonts/icons.woff b/static/base/fonts/icons.woff deleted file mode 100644 index dbeeb055..00000000 Binary files a/static/base/fonts/icons.woff and /dev/null differ diff --git a/static/base/fonts/icons.woff2 b/static/base/fonts/icons.woff2 deleted file mode 100644 index 87032d17..00000000 Binary files a/static/base/fonts/icons.woff2 and /dev/null differ diff --git a/static/base/images/about.svg b/static/base/images/about.svg deleted file mode 100644 index d06680b3..00000000 --- a/static/base/images/about.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 698.629 654.126"><defs><style>.cls-1{isolation:isolate;}.cls-2,.cls-6{fill:#e1e2fe;}.cls-2,.cls-4{opacity:0.5;}.cls-10,.cls-3{opacity:0.66;}.cls-5{fill:#c9ccf7;}.cls-7{fill:#3e479b;}.cls-8{opacity:0.81;}.cls-10,.cls-9{fill:#fff;}.cls-11{fill:#ea8b9b;opacity:0.39;}.cls-12{fill:#f7a9b4;}.cls-13{fill:#e58898;}.cls-14{fill:#ccc;}.cls-15{fill:#6c63ff;}.cls-16{fill:#9e9eef;}.cls-17{fill:#db7183;}.cls-18{fill:#599af2;}.cls-19{fill:#293d7c;}.cls-20{fill:#1a2b63;}.cls-21{fill:#445ea0;}.cls-22{fill:#69cdff;}.cls-23{fill:#52bbef;}.cls-24{fill:#d9eafc;}.cls-25{opacity:0.12;mix-blend-mode:multiply;}.cls-26,.cls-27,.cls-28{fill:none;stroke-linecap:round;stroke-miterlimit:10;}.cls-26,.cls-28{stroke:#9e9eef;}.cls-26{stroke-width:2px;}.cls-27{stroke:#f7a9b4;}.cls-27,.cls-28{stroke-width:1.311px;}.cls-28{stroke-dasharray:3 6;}</style></defs><title>details-1</title><g class="cls-1"><g id="Layer_1" data-name="Layer 1"><path class="cls-2" d="M650.949,632.81s-55.6,48.672-145.533-1.079S393.365,529.949,275.74,537.814s-143.365,26.7-218.732-30.089-72.48-175.274-12.056-239c33.01-34.808,67.739-44.639,104.007-51.425,6.314-1.18,12.674-2.27,19.078-3.382,15.629-2.708,31.527-5.562,47.683-10.224a219.368,219.368,0,0,0,25.954-9.236c0.258-.112.517-0.213,0.775-0.337,7.348-3.191,14.539-6.809,21.527-10.707,5.067-2.82,10.033-5.8,14.865-8.876,0.663-.416,1.326-0.843,1.977-1.27,7.719-4.989,15.112-10.247,22.1-15.572,7.314-5.562,14.179-11.191,20.527-16.7A432.8,432.8,0,0,0,369.77,94.574S443.228-29,557.459,6.365,690.071,122.731,664.218,211.1,638.792,351.912,666.6,416.842C694.431,481.772,728.609,567.206,650.949,632.81Z"/><g class="cls-3"><g class="cls-4"><path class="cls-5" d="M266.019,199.966l-11.96-.92a61.036,61.036,0,0,0-3.62-15.39c-0.13-.36-0.27-0.72-0.41-1.08-0.44.73-.89,1.47-1.35,2.21-3.52,5.7-7.36,11.59-11.51,17.52a42.5,42.5,0,0,1-.02,6.48,44.8,44.8,0,0,1-41.91,41.31,193.288,193.288,0,0,1-19.49,14.88c0.37,0.11.74,0.21,1.12,0.31l-0.91,11.96a10.991,10.991,0,0,0,10.13,11.8c0.29,0.02.58,0.03,0.86,0.03a11,11,0,0,0,10.94-10.16l0.91-11.95a61.627,61.627,0,0,0,25-8.19l7.81,9.1a11,11,0,0,0,16.7-14.33l-7.81-9.1a61.529,61.529,0,0,0,11.88-23.46l11.96,0.91a11.007,11.007,0,0,0,11.81-10.13c0.02-.28.03-0.57,0.03-0.84A11,11,0,0,0,266.019,199.966Z"/></g><g class="cls-4"><path class="cls-6" d="M254.969,166.246l-9.1,7.81a60.468,60.468,0,0,1,4.16,8.52c-0.44.73-.89,1.47-1.35,2.21-4.3,2.74-8.72,5.39-13.23,7.9a44.81,44.81,0,1,0-85.39,27.15c-5.7.99-11.36,1.96-16.98,3.01a61.354,61.354,0,0,1-2.19-11.14l-11.95-.91a11,11,0,0,1-10.16-10.94c0-.28.01-0.57,0.03-0.86a10.985,10.985,0,0,1,11.8-10.13l11.96,0.91a61.449,61.449,0,0,1,11.89-23.47l-7.81-9.1a11,11,0,1,1,16.69-14.32l7.81,9.1a61.525,61.525,0,0,1,25-8.19l0.91-11.96a11.006,11.006,0,0,1,10.96-10.16q0.42,0,.84.03a11,11,0,0,1,10.13,11.81l-0.91,11.95a61.733,61.733,0,0,1,23.47,11.89l9.1-7.81A11,11,0,0,1,254.969,166.246Z"/></g><g class="cls-4"><path class="cls-5" d="M195.239,250.1a193.288,193.288,0,0,1-19.49,14.88,61.382,61.382,0,0,1-22.34-11.58l-9.11,7.81a11,11,0,0,1-14.32-16.69l9.1-7.81a61.3,61.3,0,0,1-6-13.86c5.62-1.05,11.28-2.02,16.98-3.01a44.771,44.771,0,0,0,39,30.22A44.016,44.016,0,0,0,195.239,250.1Z"/></g><g class="cls-4"><path class="cls-5" d="M248.679,184.786c-3.52,5.7-7.36,11.59-11.51,17.52a44.473,44.473,0,0,0-1.72-9.62C239.959,190.176,244.379,187.526,248.679,184.786Z"/></g><path class="cls-7" d="M521.5,537.152a9.178,9.178,0,0,1-8.725-6.4l-2.148-6.783a43.972,43.972,0,0,1-16.435-1.417l-3.278,6.315a9.164,9.164,0,1,1-16.268-8.443l3.277-6.315A44.02,44.02,0,0,1,467.3,501.482l-6.783,2.148a9.164,9.164,0,1,1-5.533-17.473l6.783-2.148a44.012,44.012,0,0,1,1.417-16.437l-6.315-3.278a9.164,9.164,0,0,1,8.443-16.268l6.315,3.278a44.07,44.07,0,0,1,12.625-10.62L482.1,433.9a9.164,9.164,0,1,1,17.473-5.533l2.148,6.783a43.951,43.951,0,0,1,16.437,1.417l3.278-6.317a9.165,9.165,0,0,1,16.268,8.444l-3.278,6.314a44.054,44.054,0,0,1,10.62,12.626l6.783-2.148a9.164,9.164,0,1,1,5.532,17.473l-6.783,2.148a44.012,44.012,0,0,1-1.417,16.437l6.317,3.277a9.165,9.165,0,1,1-8.445,16.268l-6.314-3.276A44.066,44.066,0,0,1,528.1,518.434l2.148,6.783A9.18,9.18,0,0,1,521.5,537.152Zm-8.761-16.472,2.9,9.163a6.16,6.16,0,0,0,11.744-3.72l-2.9-9.162,1.112-.586a41.165,41.165,0,0,0,13.534-11.383L539.89,504l8.531,4.426a6.159,6.159,0,0,0,5.674-10.933l-8.531-4.427,0.373-1.2a41.151,41.151,0,0,0,1.52-17.618L547.294,473l9.163-2.9a6.159,6.159,0,0,0-3.718-11.744l-9.162,2.9-0.586-1.112a41.139,41.139,0,0,0-11.385-13.534l-1-.766,4.428-8.531a6.159,6.159,0,0,0-10.933-5.674l-4.428,8.531-1.2-.373a41.2,41.2,0,0,0-17.618-1.52l-1.247.163-2.9-9.163a6.16,6.16,0,1,0-11.744,3.72l2.9,9.16-1.112.585a41.168,41.168,0,0,0-13.533,11.385l-0.766,1-8.532-4.428a6.158,6.158,0,1,0-5.673,10.933l8.529,4.428-0.373,1.2a41.149,41.149,0,0,0-1.52,17.618l0.163,1.247-9.163,2.9a6.16,6.16,0,0,0,3.72,11.744l9.162-2.9,0.585,1.112a41.148,41.148,0,0,0,11.383,13.533l0.995,0.766-4.425,8.532a6.159,6.159,0,0,0,10.933,5.673l4.428-8.53,1.2,0.373a41.2,41.2,0,0,0,17.617,1.52Zm-6.6-8.389a32.809,32.809,0,1,1,9.915-1.542A32.572,32.572,0,0,1,506.136,512.292Zm0.072-62.458a29.76,29.76,0,1,0,13.652,3.354A29.792,29.792,0,0,0,506.208,449.834Z"/><path class="cls-7" d="M600.4,481.063a11.813,11.813,0,0,1-11.684-13.5l1.435-9.881a58.753,58.753,0,0,1-19.6-11.664l-8,5.971a11.8,11.8,0,0,1-14.114-18.914l8-5.971A58.719,58.719,0,0,1,550.83,405l-9.879-1.437a11.8,11.8,0,1,1,3.391-23.354l9.882,1.435a58.7,58.7,0,0,1,11.664-19.6l-5.972-8a11.8,11.8,0,1,1,18.914-14.116l5.972,8a58.736,58.736,0,0,1,22.1-5.607l1.436-9.879a11.8,11.8,0,1,1,23.354,3.391l-1.435,9.882a58.706,58.706,0,0,1,19.6,11.664l8-5.972a11.8,11.8,0,1,1,14.114,18.914l-8,5.972a58.712,58.712,0,0,1,5.607,22.1l9.881,1.437a11.8,11.8,0,1,1-3.392,23.354l-9.881-1.435a58.729,58.729,0,0,1-11.664,19.6l5.97,8a11.8,11.8,0,1,1-18.914,14.114l-5.97-8a58.729,58.729,0,0,1-22.1,5.607l-1.436,9.881A11.819,11.819,0,0,1,600.4,481.063ZM570.76,442.116l0.918,0.858a55.831,55.831,0,0,0,20.611,12.271l1.192,0.4L591.686,468a8.8,8.8,0,1,0,17.408,2.53l1.794-12.356,1.256-.041a55.814,55.814,0,0,0,23.251-5.9l1.124-.562,7.467,10.006a8.794,8.794,0,1,0,14.1-10.521l-7.466-10.005,0.858-.919a55.812,55.812,0,0,0,12.271-20.611l0.4-1.192L676.5,420.22a8.8,8.8,0,1,0,2.53-17.408l-12.356-1.794-0.041-1.256a55.8,55.8,0,0,0-5.9-23.25l-0.562-1.124,10-7.469a8.794,8.794,0,0,0-10.521-14.095h0l-10.006,7.467-0.918-.858a55.79,55.79,0,0,0-20.611-12.271l-1.192-.4,1.795-12.355a8.8,8.8,0,0,0-17.408-2.528l-1.794,12.355-1.256.041a55.819,55.819,0,0,0-23.25,5.9l-1.124.562-7.469-10a8.794,8.794,0,0,0-14.1,10.521l7.467,10-0.858.918a55.786,55.786,0,0,0-12.271,20.611l-0.4,1.191-12.355-1.794a8.8,8.8,0,0,0-2.528,17.408l12.355,1.795,0.041,1.256a55.813,55.813,0,0,0,5.9,23.251l0.562,1.124-10.007,7.467a8.795,8.795,0,1,0,10.522,14.095Zm39.5,3.024a43.414,43.414,0,1,1,25.936-8.612h0A43.229,43.229,0,0,1,610.258,445.14Zm-0.139-83.894a40.453,40.453,0,1,0,24.28,72.873h0a40.449,40.449,0,0,0-18.38-72.444A41.088,41.088,0,0,0,610.119,361.246ZM635.3,435.324h0Z"/></g><g class="cls-8"><path class="cls-9" d="M406.124,487.112H375.259a1.5,1.5,0,0,1,0-3.005h30.865A1.5,1.5,0,0,1,406.124,487.112Z"/><path class="cls-9" d="M406.124,519.2H375.259a1.5,1.5,0,0,1,0-3.005h30.865A1.5,1.5,0,0,1,406.124,519.2Z"/><path class="cls-9" d="M429.424,551.6H238.8a4.078,4.078,0,0,1-4.074-4.073V448.585a4.079,4.079,0,0,1,4.074-4.075H429.424a4.08,4.08,0,0,1,4.075,4.075v98.939A4.079,4.079,0,0,1,429.424,551.6ZM238.8,447.515a1.071,1.071,0,0,0-1.069,1.07v98.939a1.07,1.07,0,0,0,1.069,1.068H429.424a1.071,1.071,0,0,0,1.07-1.068V448.585a1.071,1.071,0,0,0-1.07-1.07H238.8Z"/><path class="cls-10" d="M429.424,551.6H238.8a4.078,4.078,0,0,1-4.074-4.073V448.585a4.079,4.079,0,0,1,4.074-4.075H429.424a4.08,4.08,0,0,1,4.075,4.075v98.939A4.079,4.079,0,0,1,429.424,551.6ZM238.8,447.515a1.071,1.071,0,0,0-1.069,1.07v98.939a1.07,1.07,0,0,0,1.069,1.068H429.424a1.071,1.071,0,0,0,1.07-1.068V448.585a1.071,1.071,0,0,0-1.07-1.07H238.8Z"/><path class="cls-9" d="M406.124,471.543H259.043a1.5,1.5,0,0,1,0-3.005H406.124A1.5,1.5,0,0,1,406.124,471.543Z"/><path class="cls-9" d="M406.124,502.683H259.043a1.5,1.5,0,0,1,0-3.005H406.124A1.5,1.5,0,0,1,406.124,502.683Z"/><path class="cls-9" d="M338.34,487.112h-79.3a1.5,1.5,0,0,1,0-3.005h79.3A1.5,1.5,0,0,1,338.34,487.112Z"/><path class="cls-9" d="M338.34,519.2h-79.3a1.5,1.5,0,0,1,0-3.005h79.3A1.5,1.5,0,0,1,338.34,519.2Z"/><path class="cls-9" d="M312.521,534.061H259.043a1.5,1.5,0,0,1,0-3.005h53.478A1.5,1.5,0,0,1,312.521,534.061Z"/></g><g class="cls-8"><path class="cls-9" d="M110.813,390.912H76.122a1.5,1.5,0,0,1,0-3.005h34.691A1.5,1.5,0,0,1,110.813,390.912Z"/><path class="cls-9" d="M110.813,354.852H76.122a1.5,1.5,0,1,1,0-3.005h34.691A1.5,1.5,0,1,1,110.813,354.852Z"/><path class="cls-9" d="M264.5,435.417H49.615a4.079,4.079,0,0,1-4.074-4.075V319.5a4.079,4.079,0,0,1,4.074-4.075H264.5a4.079,4.079,0,0,1,4.074,4.075V431.343A4.079,4.079,0,0,1,264.5,435.417ZM49.615,318.434a1.071,1.071,0,0,0-1.069,1.07V431.343a1.071,1.071,0,0,0,1.069,1.07H264.5a1.071,1.071,0,0,0,1.069-1.07V319.5a1.071,1.071,0,0,0-1.069-1.07H49.615Z"/><path class="cls-10" d="M264.5,435.417H49.615a4.079,4.079,0,0,1-4.074-4.075V319.5a4.079,4.079,0,0,1,4.074-4.075H264.5a4.079,4.079,0,0,1,4.074,4.075V431.343A4.079,4.079,0,0,1,264.5,435.417ZM49.615,318.434a1.071,1.071,0,0,0-1.069,1.07V431.343a1.071,1.071,0,0,0,1.069,1.07H264.5a1.071,1.071,0,0,0,1.069-1.07V319.5a1.071,1.071,0,0,0-1.069-1.07H49.615Z"/><path class="cls-9" d="M241.431,408.412H76.122a1.5,1.5,0,1,1,0-3.005h165.31A1.5,1.5,0,1,1,241.431,408.412Z"/><path class="cls-9" d="M241.431,373.412H76.122a1.5,1.5,0,0,1,0-3.005h165.31A1.5,1.5,0,0,1,241.431,373.412Z"/><path class="cls-9" d="M241.431,390.912H152.307a1.5,1.5,0,0,1,0-3.005h89.125A1.5,1.5,0,0,1,241.431,390.912Z"/><path class="cls-9" d="M241.431,354.852H152.307a1.5,1.5,0,0,1,0-3.005h89.125A1.5,1.5,0,1,1,241.431,354.852Z"/><path class="cls-9" d="M241.431,338.146H181.326a1.5,1.5,0,0,1,0-3.005h60.106A1.5,1.5,0,0,1,241.431,338.146Z"/></g><path class="cls-11" d="M554.7,549.817H177.169A13.907,13.907,0,0,1,163.28,535.2l13.27-259.122a13.907,13.907,0,0,1,13.888-13.2h45.819a13.907,13.907,0,0,1,7.982,2.519l51.293,35.953a13.907,13.907,0,0,0,7.982,2.519H567.731a13.907,13.907,0,0,1,13.882,14.736L568.58,536.739A13.907,13.907,0,0,1,554.7,549.817Z"/><path class="cls-12" d="M575.139,209.076a17.555,17.555,0,0,1-.77,5.16,0.048,0.048,0,0,0-.01.04l-1.16,2.8L472.959,460.5a3.352,3.352,0,0,1-4.37,1.82l-234.24-96.47a3.341,3.341,0,0,1-1.81-4.36l100.5-244.02,0.7-1.71a0.145,0.145,0,0,0,.02-0.04,17.492,17.492,0,0,1,19.87-9.41l4.95,2.04,203.61,83.84,4.15,1.72a3.846,3.846,0,0,1,.39.22A17.49,17.49,0,0,1,575.139,209.076Z"/><path class="cls-13" d="M389.072,229.757l-58.1-23.926a3.011,3.011,0,0,1-1.636-3.927l23.926-58.1a3.011,3.011,0,0,1,3.927-1.636l58.1,23.926a3.011,3.011,0,0,1,1.636,3.927L393,228.121A3.011,3.011,0,0,1,389.072,229.757Z"/><path class="cls-9" d="M500.972,309.092L319.267,234.261a3.008,3.008,0,1,1,2.291-5.562h0L503.263,303.53a3.008,3.008,0,0,1-2.291,5.562h0Z"/><path class="cls-9" d="M449.2,310.18l-137.824-56.76a3.008,3.008,0,0,1,2.291-5.562h0l137.824,56.76A3.008,3.008,0,1,1,449.2,310.18Z"/><path class="cls-9" d="M529.37,238.381l-80.346-33.089a3.008,3.008,0,1,1,2.291-5.562h0l80.346,33.089a3.008,3.008,0,0,1-2.291,5.562h0Z"/><path class="cls-9" d="M501.428,249.282l-60.294-24.831a3.008,3.008,0,1,1,2.291-5.562l60.294,24.831a3.008,3.008,0,1,1-2.291,5.562h0Z"/><path class="cls-9" d="M485.192,347.411L303.487,272.58a3.008,3.008,0,0,1,2.291-5.562h0l181.705,74.831a3.008,3.008,0,0,1-2.291,5.562h0Z"/><path class="cls-9" d="M433.42,348.5L295.6,291.739a3.008,3.008,0,0,1,2.291-5.562h0l137.824,56.76a3.008,3.008,0,1,1-2.291,5.562h0Z"/><path class="cls-9" d="M469.411,385.73L287.706,310.9A3.008,3.008,0,0,1,290,305.336L471.7,380.168A3.008,3.008,0,0,1,469.411,385.73Z"/><path class="cls-14" d="M461.52,404.889L279.815,330.058a3.008,3.008,0,0,1,2.291-5.562l181.705,74.831a3.008,3.008,0,0,1-2.291,5.562h0Z"/><path class="cls-15" d="M372.876,403.466a65.513,65.513,0,0,0,10.9-.333c3.258-.381,6.652-0.905,9.508-2.618a9.036,9.036,0,0,0,4.5-6.833,6.359,6.359,0,0,0-3.848-6.448,7.586,7.586,0,0,0-7.7,1.078,10.023,10.023,0,0,0-3.442,8.006c0.15,6.191,5.048,12.3,10.487,14.88,6.126,2.9,14.492.436,16.061-6.707,0.326-1.486-1.7-2-2.543-1.047a6.745,6.745,0,0,0,9.414,9.628l-2.277-.938a16.234,16.234,0,0,0,11.166,11.793,15.058,15.058,0,0,0,4.155.633c1.711,0,3.468.863,5.1,1.4l11.79,3.841c1.734,0.565,2.835-2.068,1.086-2.637l-10.678-3.479c-1.779-.58-3.555-1.175-5.339-1.739-1.276-.4-2.672-0.185-4-0.422a13.371,13.371,0,0,1-10.456-9.78,1.443,1.443,0,0,0-2.277-.938,3.9,3.9,0,0,1-5.431-5.61l-2.543-1.047c-1.012,4.608-6.633,6.337-10.684,5a16.185,16.185,0,0,1-9.775-10.367,8.361,8.361,0,0,1,.608-6.653,4.983,4.983,0,0,1,5.221-2.557,3.575,3.575,0,0,1,3.055,3.921,6.4,6.4,0,0,1-3.561,4.845c-2.55,1.369-5.6,1.709-8.435,2.02a60.944,60.944,0,0,1-9.725.277c-1.821-.092-2.186,2.739-0.346,2.832h0Z"/><path class="cls-16" d="M567.8,337.351V535.673a14.143,14.143,0,0,1-14.143,14.143H176.675a14.143,14.143,0,0,1-14.143-14.143V296.36a14.143,14.143,0,0,1,14.143-14.143h44.813a14.143,14.143,0,0,1,8.118,2.562l51.168,35.867a14.143,14.143,0,0,0,8.118,2.562H553.655A14.143,14.143,0,0,1,567.8,337.351Z"/><rect class="cls-7" x="187.281" y="507.279" width="165.51" height="13.148" rx="6.574" ry="6.574"/><rect class="cls-7" x="187.281" y="481.757" width="82.755" height="13.148" rx="6.574" ry="6.574"/><path class="cls-17" d="M408.686,229.522L350.59,205.6a3.346,3.346,0,0,1-1.818-4.363l23.926-58.1a3.346,3.346,0,0,1,4.363-1.818l58.1,23.926a3.346,3.346,0,0,1,1.818,4.363l-23.926,58.1A3.346,3.346,0,0,1,408.686,229.522Zm-32.134-86.966a2.007,2.007,0,0,0-2.618,1.091l-23.926,58.1a2.007,2.007,0,0,0,1.091,2.618l58.1,23.926a2.007,2.007,0,0,0,2.618-1.091l23.926-58.1a2.007,2.007,0,0,0-1.09-2.618Z"/><path class="cls-18" d="M568.856,465.353l-25.865,26.528,46.921,48.495a18.371,18.371,0,0,0,26.4-.044l0.258-.266a18.305,18.305,0,0,0-.049-25.452Z"/><path class="cls-19" d="M581.977,463.212L564.384,445.62a104.094,104.094,0,0,1-42.425,42.491l17.56,17.559a5.178,5.178,0,0,0,7.3,0l35.155-35.155A5.18,5.18,0,0,0,581.977,463.212Z"/><path class="cls-20" d="M551.568,493.62L536.551,478.6a103.162,103.162,0,0,1-14.593,9.506l17.56,17.559a5.178,5.178,0,0,0,7.3,0l12.049-12.049A5.177,5.177,0,0,1,551.568,493.62Z"/><path class="cls-21" d="M547.759,322.165a105.563,105.563,0,1,1-149.29,0A105.564,105.564,0,0,1,547.759,322.165Z"/><path class="cls-22" d="M525.452,449.146a74.016,74.016,0,1,1,0-104.673A74.015,74.015,0,0,1,525.452,449.146Z"/><path class="cls-23" d="M525.452,449.146a74.505,74.505,0,0,0,7.171-8.32A74.019,74.019,0,0,1,429.1,337.3,74.017,74.017,0,1,0,525.452,449.146Z"/><circle class="cls-24" cx="485.827" cy="347.25" r="12.393"/><circle class="cls-24" cx="511.864" cy="360.129" r="8.779"/><image class="cls-25" width="372" height="116" transform="translate(2.129 319.626)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXQAAAB0CAYAAACVFMnnAAAACXBIWXMAAAsSAAALEgHS3X78AAAgAElEQVR4Xu2dCbxlVZXedyuvikonGjsx0bSxYwfHUqMgatnKJFIM9d4991wuCHRJMViCiCAiiIIWoDKKDOIMgiIqIFEGCTaDgCLa2Aq2IrZTg7NoGzttzGjvbw3nrLvfOXff+6a6j1r5/b5flXq1w913/c93vr322uEPf/hDcLlcLtfyV/YDLpfL5Voeyn7A5XK5XMtD2Q9sSYr/749cLtfyUq6utyRlP7AclfsBuFyuLVs5hixXZT8w6cotnMvlco2qHG8mXdkPTJpyCzKiHjFcm1wu10QrjKIcB7LK8WjSlP3A5lbuC2+QWdDcj8Llcm15CqocS5Yd3LMf2FzKfbl5ePcf6XK5XLM1f8jn+LW5lP3AUir3JTbDe9jC7bTV4mi7KZfLtZjK1eBcNSrow0iAzzFtqZX9wFJoPIiPCu6mH8nGBvVXuFyuh4Oa6nvjGA+LNsAHq4kGe/YDi6k8xBXkwwDeBO10ofdYOZp22trlci035eoaansADAN9E+DDRIM9+4HFUB7kmxKIt7nv1UOgnS56f1Ve0//C5XItN+XqekPmIWAh3wb4VrA3wj3HwMVS9gMLqbmD3H7JKcDboG0XfLc/HtT6qP6/dLlcD0etlxq3NT/sIZBCXhmzekUe7pMF9uwHFkqjg3yYE7cQT8HdBOuZf1Vrj0fVOiCq/2iXy/Vw1AGPGqx3y4EU/Bb2wwDfBPfJA3v2A/PV+CAfFeIW3im0dWGLf11rr8fU6v/JcHX/jcvlmnQNq2Fb75YDKfQt6JsAb+E+Ftg3C9SzH5irFgbkTRC37juFtwW2Lvr0v621x2Pjfybq/rt2zfx7l8s16WqrX61x1Lut//RBYGEPhqSAb4K7GsxhYN+02dx69gNz0XCYpxm5BXnqxpucuEJcAZ7C28Iai77n41hrHx9CKZr5D4Na96cDWqXqu1yuiZKpz4G6TWu6NPWuDLAPAoW+gn4Y4C3cc2Bv3DxdMqhnPzCu2mHe5sqbHLl148MgbgGOheo/rgY2Fjn+AEL5hBA6/zGsgqafSNq6/LNBFf/J5XItZyU1rbWOukf9Ewcghb/Cvv+4GvJ7tAB+HLC3uvUlgXr2A+NodJjbjpUcyFOI75EAXOGt4FZg60L3nxS27v15WFn8Z9bMNqx+VO/JtbpPcblcy1G2jiGtcal51D9xYPpJFfxX9Z9Yg75vIA8nrw5e4a5gV9feBnabsadQXxqwZz8wqtpB3gRz68o3CMzbQK5OXCGuDhyLgAWJC0OLNG3APbNNDemZp4YVvaexuk8PKzrPqNVbXav7TJfLtRxl63h6dV3fqHco1j44UMG/v80g6AXyFeBTuJOJFNc+KthHd+s5to6j7AdGUd6VW5g3uXJk5MNAvufjBiGuDlwBLvBeMW2grZDuPCv+/dlhqvtfWMVzwtTMc8NUT1RuW6vYzuVyLSfZ+oVQ06hv1DkUax71TxxQ+CvsFfTi6gnwMIYp3DWW6Sdg3/XRg1FME9Sb3PriQT37gZzyMLd5eQpzdeWakacg10gFX+x0fEVSiKsDh/vGwkwLvGcE3DPPrQE987z49+3j35/P6rwg/usXkrbqrqnVeVGzZv6CVbpcrs0ircG2GrV1HEX1jTqHUPOo/97z6geAAL8CvUIegKe3eoF75E3QaIZi3ccPgj3N2K1btweUlg7q2Q8sDMw3GpjbrNy6cjz1UkdO+RaDnJz4OgNxWoRn1QBXeAu0K0jjB9F9cfz7S+KPYof49x1ZxU6smZ1Z3V0GtLWqeKnL5ZoEmbocqFetYUjrGjVe7sB1D4EBe79oEPhk9ATyCnh6q38Gve0T3BHNRNce1LVTs4VEMdSUIZun1q0Pi2AWF+rZD4wH9FFhrln5rsaV46mnGblx5BqpUJxC2ZhAnF6tBOBw2/SkFnArsLHY8YewVW/X+PeXxf+t3cLKztq4ULuzij1YnT0HVe7lcrkmWWnNai1rbffWcr3HukftEwfAg3LnGvYW8gA8XLzCPb7tc2z79Nq1K9g1itGMPXXrwyKYxYV69gOjw9y68xzMbcRi45V1kpFrtLJOQI5IBXEK5WLb1RCH+1aAY6Fo0eLiAdoKalr86fjnTFycTlhRFKyyy+qWrKI3qM7e8T93uVwTpY7I1qrWMISa7kmNx3pH3VP9d9dFyAv4I+y3irBno7cLmz8Ant7m1zBfYBZhGpHB0+br0wcdOwxn38Qw6tbnD/Uce5cC6A1RyzCY4x96rUQs1pVjszN+Wdx29NTakc+IG0eUQrmZQByLgUVRgAu8CdydLi82fgTdfvzX+8Y/Xx7/vf1Y5f7xXx/AKv5yQFPFelbpcrkmSlKbac1WtYy67uzPNY56L2PdF/swA4gHXYI9gR6Qh+mLjr5y8YA7+BLhzntt2we4dopjqJPmaZQYUMauMQwdZjLZepqr56C+cC49+4G5wXy7EWC+h0Qs+DLil7K1xivoVqFOlWfVjtyCHDlZRyBOi7GOAY6Foif3PryQtKh/yT+C7ivi/86G+OdBUQezykOiDo1/f2WtYuOgekblq1wu1+aQrcO0Rm39op6h4hCp81jvJer+QGIAgb8U2JPB68vbecEufmavCHaBO+XzO9Zg77FjpygmGk3qjtEYBm5ds3W7Yaq5eg7qC+fSsx/IwFyAPg7M+wJz3fgEzK0rn17NGTllWc+fDXLkY9GJE8TpNavPT+EIcHp60+IdJIv6Sv4RdA+L//rw+L/56vj3I+LfXxP/fmR8GLyWVRxldDSrHKLu61wu12JqWP1pjdq6lVpGXVN9o85R773Duf7xYFDoA/YweNHssbN/ORtBinAY7o+Mb/wUy1DuznEMd81sxxm7xjDi1ql5o282THNQX5zoJfuBDNCT3HwcmOOJhlOdgDmycjr480x25dRq+ELetKBXIAE53Dhl4D1+wirEsTgAeCHwxkLSomKBBcDF6+Ofx0a9If73j4v/t44XvZFVnFCrfNN46r7Z5XLNR7kaS2XrVWtYazrWN+qc6r1E3R9DD4KpCH4CPpm6w+XN+1B5c48OXuFOWX23BjscO/boKOpFl8z2g269+5Q6gqHo+PHDoT5a9JJj8byBnoe5DtjCU6gtZhGY0xH9vf6cO1g0Yuk9t3bleCoi00K0oo4ckQq+8PjFkxNXiGNxAHAsGD3dX19DuzyBfzDFifHPt8Q/3xq1Kf77Ud2T499PqVWeWqv7NpfLNYmydVqcWtcv6hl1jfpGnaPey5NC9cAA9MvjxNgdQ2aPAA8DSPHOoRzRUEaPDB5v/wx2imJgLGkD1bh1bJpOr+YIBhumbVDXjdK0T31ho5fsB4YDvSlqsYeGqC/z0e0wR15ODf3P5ogFWTl2mqnl8GWy0YnuFOxe78uZOL0qHSqvUEcQxLfCExjOm57Sb+ZFpAU9uYZz8Y7452lRp8e/nxH/PDPqLNJUcTar+06jc1wu10TK1GnJtau1zHV9ptR4rPUSdf92YcApYuTeIpw4gQEfDWAFd5hDyuQP4kiGGij25igmGssqholunbJ1pAl0GjUDddv9AqhvkOglnf0SBqCeY/KcgZ535zZqUZjvaloTdQO0CebU3C8RC7Uf7saunFqP8JTcP5Ajp9ejwyQDPzp+/tga4rRIJ8sT/B2yoGeFGs7nRp0X/7vnx//uBfHv7yatLC6Mek/8vyfqvjfR+1wu10QoqU2tWdQv1fGFXNeob9Q56h11X7yLOEDAL88QY/d2AXw0fuWJEt8cR+aQotpeDXbeTN2XjCW3QO7O6QH1sq+RU6jPaYZ6XzZKtaURXFxv8vSFjV6yH2gHunXnGrVsSKIWPTREg7XMBigy8xTmlE/twgcCqPWQXTlvdB7MjrwC+Rsk6z6phjiexhXAz5UFxeK+J/4Zfwzl++NCfCB+2R+Kf/9Q/OxFURfH/50Ps7qXJLq0WcVHXC7XUqitBtNaLbWGL5a6vojrvPtBqfv3RQa8NzLhQjFz57HJg7Mn4ydwr5y7gF0dOxnJA0Pl1tHfjmyd+th3pIiYT50OQp0OIWGjFMkEEgokFf0R8vS5u/TsB5ph3uTONWrRQVt4GinMpc+cWhPXSWY+k8A8PvHohBciFtpt3q925Z1XS7QSHbmCnHIzvE6dKRA/T1w3Fu79tJgVsBXE3cvinx+Lujz+Hfp4/PsnWN1PGl3RoCtdLtdmUVM9mnotPik1/HHR5VznqPfuR0P9ELhYQP+BGvAwftHBc1xzmuTyb+XMPTp27Mnx/txGduu0cYqe9oIOKnGLo0C9Z+IX2SillkbtU0dSkebpG1q6Xubm0rMfaAZ6kzu3w7Zsbk6vHH9KryBoTaRuFmyAamaewpxOhO3PWTlteL6GvtQVHexeY2Pz5BrkeJWiCAUu/AOBns70tBZ4K7ArIH8q6ur47/3X+Lmo7qejPsMqrmGVUd1rG3Sdy+XaLGqox/Kauma1hqmeP831jTpHvRdXBap/QJ94ANAD8gz4qWj8CO5kBs+VPD6CHZut1ERxAnXIUQyDuLd7cODDTPvQidQBqGv8Aqij+wUtjehTp8mNSZ5uo5eFc+nZDyRAH+LO064W/H9cc3PMLKcpiRis9cy6mwWZOWIWC3PqYDlIIpYj6cvk1iS8DmFj4wx5XbpAFuKD7MLpNe1jAnCBNy0sYC1ALq6Pf97AKv4bq3sjaar7OVbxV7W6N7lcrknSQH1+rhLVcXGjqWvU+GdD/UBQ4F8tkAfgL6/gPlV+KExRNBPBXpwbyLHDOHYQ6b45UBskuuioo+4Q3jDtGagjfil34I3SYjsZ9PV0PnyEqY1pnk53ITdskM7Ppec/MJY7164W+v/wY/mppLm5bIJSn3m5vYzG3Jkz8970IMzpSYiDAsfyqw+1Ir0jcCfKeeLIBeS0IHjNuoIXixbtWoa3ALuG8y3x77fGhYnqfl50m+h20R1GX3C5XBMlW59SswX+1DqONV18nmqc6r17cwV/5oFC/jNs+Mqr2ASSc7+0BjsZxnMCd8UhhjlJOmLQDYM2R4E6HUgqOFOnNuuXRMP6AkogYF6rPL1vohfb9TJsg3R8l57/QCPQh7lz29VCw2skaqGRt5yb89ziHbmbhQ4L9aSThWHOp77eELh//BT6UrlT5d2Uj/Pmh4L8SlmYa3ix4qLxAsaF7GJRbwsK5xXFF+Nn7oz6Equ4K/73orpfFn2FVfz1oMoWde92uVwLqbZaK5Oa1FolSf2inqGqvu+sHwIR+lMR9mzqbgr8Zo63dcAdJhBv9HDtiGovIcM4VbxH3DpaIdF4gZTg+ICDinx48ZDAc2QwQqATeCbMLpQ88P0Lz+EedeTpNnoZ5tLnl6WPCfM0brGdLdad60Yo3HkatfQkN+/sKgeGMEthv8D95a8SZ44ulhMZ5ohYKCu/MPBG5yWBNzWvYJDT69QN8up1syza7QJvgbZCmn40X41//5v4A4nqfk30ddE9RveOoG+4XK4FVa7mogr8aWtV61fqGfUNUa2j5hX6AP2dBHgYPYJ7+VeBnbuAneIYZO3Yh7tI3Pr5gTdN0c8uUKeTp2htPDjwULC9+QAS+tTpdPuLqEfdRi9V10u6QWqz9Ma+9MUCetOpUO1saXLn6GoRd87zWSRqiU8xHKnlMbb7BhqeRcOxMF/l2FA5c8rLz6WIhVoNKSdHRo6nKTtyBvkt4sS/IIv2ZVnIr8oi3yM/Avxg/lb0TdG3RPexim+zusN0v8vlWlQNqb+qRu8z0jrWukaN6wNCoE+QF8DT2/kXIzfukDf5mwTs14pRRISLrrgPR3f//sDdMGeHAajTyfTDAveq7xeoTx2HjzRPR/SCEQGIXuDS+xmX3jTnZdNYscsYQM9thjZl59ad051/L6yjlo7k5jQREYO0jgg4jruigyO6Jw/AnHtLEbF8Ur5sbHDeKI78tkBuHNEJufCv8uLRQiq4BdT0Q/kOq/i7+N+J6n5X9L1axfdrlS3q/sDlci2G2mrO1qWt16qGv8s1jdqmOtcHgwJfIX+PvKED7nDud9JbPRtDZO1onkAMc2X83McCOufQz147dTRnnERJAnW/UEvjgYFPsxcy/2UXmdS4feCZ6g0u3Xa87Ja49LnFLiPCvC1usZuhtrNl3WB2XrlzGrb10vDIzp6B5xLvF3i8JQZqHR14SBaO5p4mMYuF+RX8Jccvm135rfTqxLHKX8sC3SML9i0BuIAbC139EPCj+SGr+HtW9wGjB0fUj1wu16IoV3sqU7fl35t6Rn3Lw6GCP4APyCvgAXeYPrzBC9iLL0pki4wdXTLXxP9dRDCXM9QLhTpGC6Ct8c3c0kgHHg8NfKLURC/RvPJMddkgbXLp+z9mtktvnPGy0EBvO+ZvN0O179x2tjS58xkcHton8KxyjLQ8UjZB8Srz9vgFvZMz8wInOsWZ0xPzs7ThiZ1szsjxdIUjv0cWCE/h+wXi3wsVvAsL6viDKX4c/zegnxj9NNHPXC7XJKrAn7ZWbR1zbQ8+HB4Q0CvgFe4AO97gBez0hv8l2UC9OVAEUwrU4dSLD0umjo1SnExHknBC4MNHh9fRSzSrMK1DXTo6XtK+9LbN0dFjlxGBPmrcokf8+0+kVp2qs8Vm53Dn2AjF6Fs60v9qOmbLJ7Pw1DtLWoZwUAgnPD8R6BBQeb3A/LbAnSpf4UVQR04gFydOT+gHZEGxuALsQn8UP4/6Ra3il/HPQa3oPuRyuSZUab0O1DPV98+l1hn6KyrIG7iT6VOwwxAiqr07IF/njdNbGOq0X4ezLZcF2ihF9wtaGumAIw4fHRd4LO8ruZWx25/t0pGl6wlSupv0CTwSYNjm6PixyxyBPixuwalQbIbSxc6r+fo4dLbQOFzJzuM/MF8ntZEyKJ5h/NbAUcu59BTkHnO0JaK3/LpBmNOT9GuyCPexI69A/iA5cIJ4YeBdWEj/ilX8Ov5p9Q9D9BuXy7VZNKwuIVvDvzIS8JNhY8CvqOD+oAE7HDsMIdw63va/aqAenTq1N346cGfdRwK3NF4Q+PDRqWRGafZLz7j0TncwS0fHC+anTz+NRwLkNkcbe9LnBvTh+Xl/SHeLxi26GUrXyG0n88135s6WjmTndKvQ4ezOaSDOqYEPDqHXHFELnoZXytPxRsrMKWYZgPm3ZTGwKOrINS75hThtC+4EzMV/j3+qfpvRP7pcrs2iXG2aOqaaTh4EhYL+ocrBD4CdjKC6dbztC9Sr+AUdMNgohbn8OOXpHL28K/DkxujSy9qlV1l6dx2PBcBhI+1Lp+vrtuFpjG2xy9xz9BGBrrZ/lO6W6TpuGdgM1b7zjna2HEpfAF1Eoe68K+5coxZ6Kt5AT0luSdSYxcJcXDllZwzy2oULwAtd6AY4F/8jfvlG3X9yuVzLRVq3hajpQVBBXuH+UOXa8SbP+2pw6ynU7w7cAfP5wOMFrg0avcB0wnzySF526ZSl03jvDdzx0u3QBT18v8Oawc1RjV20J72p22VRgD5Kfm5G5FZDuPSYf8fELboZSvd+HhZ46Bay81MCj74Vd04zWa4KGrVMFbcHPiCEp+Y3AmdeNcx5M+TntSO3IFeAVwtufxC/M/qfs1W6XK6JUlOdDtTx78IA7Acg/9swC+zk2KNbLy3UNX75eoCJhJmkPF2jFzKbl9QuveQsndoYaTLjIYEuo6b56XsOxi6dZ1F6UcUu/SE5en9FAvQs1OcAdHvFXFt+brpb6Jh/fELhWCzfB7ofb4ZS3/mxgWYk0JwWDKF/b+CToMadF7cGHADgo/Z4aqIlEV0siFkSmBcSqxDIFeIpvOVHQD+O3yf6Xy6Xa1kpreHfJ+A3kK/grmBPoD7g1JEARPNIp8rviiy7jcwlHzyC2byMs/TygsCjATDE642BrsGkKbHrQxW74KCRxi7a7aLzXZpy9HS2y+gbo3ME+ppkQ1Tzc8w87z+pzs/jE0m7W1ZqdwsGcKVxCx3vx4UU6GxBm+KV9MVV7hyHhqjPHFHL/YE3QJGZ/ziB+W9C7cgV4rKwRRu4//dslS6Xa6LVVLetsLdwV7BrFIO3+V8ZqCO+/YGYRoleaJbMF2uXTqO3MR7gw4EHBeI2pLcF7AXS5ihNZNxAF9ljimzV7UL3kEqO3k9y9FE2RvOxSw7oyYboxqTDRTdEJT9fJRuiNPNc2xWRn8cnFA3hik8suoGInmBHBT5IVMctdIiI5rRcHTD6ssrOC+vONWr5EXexFAnMq1hFYF5YgNvF/z9z1P91uVxLolwttqhsgvzvhQUAu8QxZPwU6g+ZTP0BMY3RPMJE0myY6NKpy+7GwI0aOOh4acCwQOz9UexSnkSpA911THPT9ws0iZGurDM5OtoXMSsdY3XXNZwa3SxA1wNFZkN0VbohipnnMzvQTi/fRFTn55hYxneBvi3wjUPvDTzXXOIWTE3EASKazaLZuXXnP5EFkMy80M3OfwrtIF8IMP8/l8u1JMrV4ggPggJ/Wrgr1H8nUJf4JZpCbnFEayO65X5oXLpm6WhjvCnQ6JGSY5eV1MJ4fqCr7Oh+Uul2wclRut3I5OgY2IVZ6U0bo+kYgNa5LuMBfTBuSYGenhBNDhQ1bojGV42VnbUBO74rui8PfHnFq+mmbbqcteT8fKV2t1Cv5zW0q7ySNkNxGvRrgTcpvhM4Oxd3rlGLZuaVM1eYpyB3OLtcD2+1wb0J6iZ+qaIXcemapdMgsHsDHzjS2OWzgVMEpAkXharbRXN0ut1I2hc7e/PALrpUumFj1B4wskBfM6dOlwzQNzUAfcgJUQK6PVCE4/7DNkTpqD/aFc8LuOdvRfHRUHe33BR4VgtaFSVuoZks+KJ/LF/8Q7IQGrVoZv77UGXhjTA3P4BS1P3/LpdrOaq0ddwGdwt2hbp2xMAMikundkbJ0ovvhyp2kb50Sg1oKiOaNiRHp8unzw7cvniCXIKBUeCvCHRqFBujnV15Tnq5PY/U7fEBI8TUs06M2tbFjWONAFhAoK8zJ0R7q2d3uGAYF4774/qm4jWBZ56j//x0emXhWec4TITRuNcHnqWgB4nu5SclPTEfCNzZgn7zX4V6I7TJnWdAnvuhuFyu5aWhYLf5unHpBHS85Uvs0tXYBWnAdyQdQEqA06OSo9ONR5gxdUngqzBlY7R8E8XJ3JZ9YEDMTGMAZuSAkc51iUBHPL1KT4xiDtaSAD3Xg54D+szOdD0TAR23EmFUbu81lDVx5nRG/PfO50FcdA2UbojewkCn5n688nxbnpgP0BN0ZfkLWoDBuMW481nO3EHucm0xmgV269QTlz4QuzxkgK45ugC9+2UCOo/YxcYogH5p/PcA9HOCdro0AX2lPTFqWhex7zhZQDcjc0cF+kq0LBLQNwnQL5ALLATo3c/GL+CWwEO4AHS7IfogA50OEaG7xQCd+k+b3LnD3OXa4tQG9DIBepkCHa3QGAsQgV7ajVEA/XYDdO50WUmXSwPouPwCQD9mfKD3xwZ6E9QnHOilOnQHusvlGlOjOvSRgC4OvVgkoE+MQx83cpEMvTpUVPKhojpy+ZRHLi6Xa34aKXKR9sVRI5fyrobI5ZK5RS6aoS850MfZFNUuFwC9l3S56A1FY2yKVoeKCt8UdblcI6gV5BbmY26KpoeLCt0U/USYdVpUN0Vtlws2RTu7Vpuis7pcJhLoaR+6ti2iD723NtRtiweFqm2xPCnolMWqbZGO/ev8c21bRH61yG2LDniXa/lppJZFhblx54VuiCZti2QU07ZFRL5oW7wz0GwpuvRCjv93L+a2RVwgXZ4S0LY41TsqamOgyy50nstc2xYXtA89jHmwaM/mSYsri90CHSwq96UZB5h1gLv4VhQnBr5yDoO5Gg4W0dMQUxYbDhZpjj6vg0UJ3F0u1zLXMJDb7NwcLCoG83Oak07GMRpIukDnXkkK0oNFmAp7UTKg6/gwcLCo6LUfLML9om0HixbopGgC9QTo9ui/vdxi2NH/+JpBR/9xU1F69B/XzuFiCxz9x4XQ1S1FevQ/Pg2p00WP/kvsMnD0X1x6CvVqGFfb0f82wI+i3I/K5XLNT7kaHCZb4xbk6szT7Lw+VLRCpy5WA7pgJLnDZQpH/2ni4nWBD0B+NGCgIA5G0h2jNGjwuDBrhC5uLip3Hv3o/+LNcvmjdqDb4Vx4uiAHahvO1ZHhXJ2G4Vz0VDsz4Phs3emS5Og2dqEvWYZz0T2hOgPdTFocZThX2QT4UZX7QblcrvkpV4PDZOp8FsiTI/90+Y2O0bXu/HuB9+00bpFTonqoqKuHimQmeiHDucrX02gTuoqu+/Jgh3MN3C3aNJwLiceSAn3Y+Nw9ZXzutBmfq9fPpeNzO4fG/8zeVnQ6PeVofG7xkUA5esmxy5TGLtiUsC691CzdzHSpLrWQWeh2Bnrr+NwE9Bb4Lpdr8tRUrxbeVazy+wTkkplbZ961MMekRRmfW91cZC+5uDlUcUsXc1xsfp7cWqQdLjMyPrfcYXB8bnoN3bDxueAvFBYD6HZjNL3gYp254KLp+D82RnVAV+fVgzl69xzaLa5iF9p0uIEyq3qErm6Oxi+7xIaFdrwktxXpTUUDtxQZuLdecNEEe5fLNZlqqN/Wyy0U5Doy9zfGmZsLLujt/7uBb0VDu7S6c21XvDbwXccSt1STFjeFWfl5Z/aGqG1ZDPZQ0f6PCeGAR4Xqgoslu7FonE4XewXdQI7+Cm7rKY6O//qEUMUu5QVhqmpflEsu1KVXY3Tv5S+bGv7trUU/q+OXAbcuMUz2CjoDe6vclVgul2tp1FSfs2rY1PfAPaPggIC8mqz4SzGDFubx7b8ayKXH/Y071+4WtCt2tf/87aFxFnqny/m5HZ1rN0SbrqAb2uEytGVxRKCHR9SW3wJdO10OGJyJXl0SneboxUvjP8heAbu+dewi/eh0a7a5hq64JNQuXS+6uIO+3Cp6Qb5VQV1vL/qpPG3Vrf86zL5fVHN2kS66XxLtci0v2cvdh10QXQrJCCQAABSYSURBVAyCvHbl6DfXmMXAvPhmoDSg0JuK0Kp4Y+DDROrOMQddultwSU80plPVlEWJW3BbES6Jxm1FTfl5v+Fyi7l3uLQCPYF60umyekX7xqjN0fVeUeToErtsZWMXaV+c0m4XvbmocunSk44vER0v1P+Jk6PYIMWTE3n6fYE2SRG/0EbGj2iBeFb6L8SxPxQG4S6AryBv9dsR9I8ul2vJlKtHdd4W3CrUOtqaUfvqyBXk0ZUXON4PM6gxi8L8nsAn1O8MdDJUO1uoWUOyc3XnuhmqF0TjYgvbrthpuE90ZpvIyRHz84UHesvGKP6P2o3RNEdf9+TB2GXGxC7a7dJ9ZcDtHpVLH7gs+mL58uKXKNHLSppFLFAvDNRpA+N7sjBYIAE7OfafV3Bn566AV/3a6B9G0G9cLteSKVePtn5tXT9E4rr/BXOgEEdOIBdXjsNDeNOnjhbELF8PDPMvydyWm0IVtdBtapfW2bl157oZirtEpbsFBhajT2bFLbjYoumE6PwuiJ4H0DM5ehW7TD8trJh59sBl0Y/EXJeOjAHA5qi6dM3SO2hhPC/grj60BXFfOnaVr2uAOo7jIlPHU/Xb7NYV7OTYsWgW7j/lrJ0gL6Cv9MtZ0h+Fy+WaHM2uVVvHWts/kzd15OMW4uLI6RSouHJqtIA5jCaRmi8szG8IfJkFBnF9lGZOocV6qsBR/7fHzze4c90MxfwW7W6ZeS5d/DMrbkkPFGl+vnrsDdExgG5z9DR2WZ+JXexcl+6O1MJDLr3bp394fAmcpR8buOPlbdQGRBMYEb2gjZFmJuAJeb1skt4aqPOlxCnSuwM/Vb8hC2PAToumcH8g1IBHD/uPRT8x+mmin7lcrkmSQHpQtoZ/LPD+kdT7g1L/4MAPhAt/JyDH2z1c+T1sDinOlZilgjl6ztGggUaNiwIOQFLfefe0wC3Xb6TmjtSdP1IPE+0d3XnveWRsq+6W/hOHxy1zy8+HAj2B+iNmu3Sbo9vYRV26drvoqVFsjlqXXrUwHigdL0cFtP1U0QvaGIsLeQpjGaFe4nWHnTqa+7md8fbA3S/i1iuwf1MW635ZvO+GGvBY1B+GCvRQqcBXPTiGfuRyuRZMuXqzMjWrtay1TSc9v187cYU4RSswfgLyMnKjxLH+uwJ3s9wqmTn6zeHMsY+Hw46am58bqE2R0gQM4jqGDxLhZCguhUZ2bt157wX1Zqg9HZp2twzLz0dz5+MAfYzYRbtdcGrUbo6W27JL1xZGnBxFxwtG6uKeUVwcrdEL9XSeNgh1deoE9WsDjwa4KeD0Fp8mFbBTa+PXeLGoG+abvIC0kPeLvsMLXCrsVd+rpT8GytiGiB4QLpdrQdRWZ0UiW6tav5SFo6a/I1KA3ycciBCniBbGL3KCuljukk4WuPKbA09SxNF+dNghZrksAOY88xxH/JGbnxp4TO6xHLXQXuD6gM4WzKzaasZk55jd0jPu3G6Gpt0tTXHLogE9JEBv6nZJNketS6cWxvjqgVcQehXpraW2HkQv+DKq6AWHjdD1Qr3pp9dQp84XDO9CO+NVgcdXXh/Yrd9swI7ZL1/mxaJF+5osoACehKfzN0XfEt1XCz8C+iHkdL/L5VpwZepOIV1Ja1hr+m9F36gBThwADxDRRj4gJ4cjp6z8ltqVU2vip8Q8otPuInHmAnOcCC1ODJSb4xCRtikiaim7dCKeBnGhs0Wz8yZ3roeJRupuyfafzxHoTbHLqC4dWTpG6mJgl/alI3rpFYGmMCJ6oRkvRwYerZtAHbNeuh8IdJKUXoEwS+FqXoACr0c3imO/lRapgntxV6gBf7cs6t+wyMkr8BX6VveOqG+4XK55K1dnKlujWrtSy6XWNt7U75a6/4pwADyAG7+dDCAbwc8FzsqvFVeOiAXddZfyBigyc8QsCnOM/C6Oi//ZUYGP+B9EKcNA1IK9wu6aqrNlVnbe1Htu3fnc4pYs0Mdz6euHuHQ9aCTzXQail3KvQDNe6PKLDQz10kBd45cCExnPDzxm96LAEQy+eLwWIYZRx35D4I3TCPfiVnbuBPg7aDFXFHDwX2JhkRX4pK/UonGZRuUQ0YPC5XLNS8NqzNairVOt3VJrWWpb4A1jxx0rtwkPbmY3jpnmlJMLyOmtHx11cOWY0fJ+MpHca35G4PbEE2uYU3fewYFyc8w8L2fo3gdKHzAmV4/5Y26LdrZYdz7yZuhSAD116RtaXHpfOl70ajr0pWODFNELhnbhsBG6XjRPT6Fevj5Qpk67ybiv76z4n51LEQwN8qJedQU7HHt8VSqxOHhtwubpDYGz9gj44iZ5It8SF+TWKEQ0n6cdbRJBX3WH0RdcLtdE6I5Et0vdSg13paYJ3LdIvd8kccqNwoPrGeK04QkjeGUNcjrO/8FAEQvMI4ZudU4LnBQgM3/DIMzRoohuvW4n0ERFHPHHzBYcIkLUgjG52nc+/cTRsvO5u/ORgJ5A/RGzXXp/SJZu+tLxD1VFLzhspF0v8Ym2srNW5rwkUKd2xmMCjdkt8KqDzYjT2a1Tr/p7arBTvn6ZLE507eVVsmCfFsBfy4tJ8QyDnnVj4Ljmc7XiD6DWTfyjcLlcm1cDdRkl9cqwvrGuaYpQPivwvk7q/zPsxOmgImIVtEJ/TAyhBTlOqp9D52HoSjmacX5C5BPmtGDwFmKWBOZoUdTcHF0t5bYctUybjVDbd97U2ZK686UB+hCXbrP0XR9d96XjH6JfRy80WhddLz2Tp2O8bi+BOl2E8UppCTo60Kjd+JRcUSCCQUP/GYEuxiCwX0ivSNQNU8EdT9zLGfDFJ2URr5IFvVoW99Oiz8iCX8Mq5QHQqOtcLteSqaEGy2vqWtXa1VqmN3TU9tVS73DgVzDAaeTtZRXEacOzfH+gO0HJkaO/HF0s7wjkyhGxdI6PfDqGzOVUBxugmHN+QJgF85kdeF4LcnN0tcgR/ypq0amKGrWM5M5H3gwdC+gJ1Btcetrxgv/PtkUv6HrRPB2tjBgLoFBXp05z01/O3S+4VJqeiq+NX9zrA7v1EyVbF7DjIFL3XJ4DQ679fYE2UJG1E+Av4UWkfOwyfjJ3BfYE/E/Ign/S6IoWXelyuZZMTTVo6hRmrapf1PPlbOSoxj8qdX9pBfCVNFRLIA5egBt0wbOAHFk5bXyeEJmEtsSjaNQ3mUt0s3T2rzNzA3PaBJ15XhjIzdHVgiP+adSyOO58rkAf0aWn0YvtesGcF7QyplBH/KKZeonxAOjrPCDwiICNgUZTxi8YX/QA2Gn3+R2BR/CeHXgezHkC+AvpVWqlQB4Lyk7+olABH4tdYsEvSXRpu+gp73K5FkWttZfUKOqWYH2x6CK6+YzqHPVOm5vvZYDTkf3oxMt31RDHiU9EK3DkFcjfEGhyIh3nfxVFLJg9xadAe2Q6+RaiFpijRdHm5jZq2dVshC6sOx8L6AnUMy7dQt1GL/iHGwZ1ZOo0lfFlcsNRh56GHMG8gr9Y+oIF7Ng0xelS6oY5qYY7baCeTgvG7v2dAvlzJaI5X57O744LfqHoPfGHIKIHQKr3uVyuzaakHktTr1LD3JXybs7BqSPuPKn7c4gDDPDTxfwJxHEyHVFuNIjkyBXkSAXKQ9iVU1viPjzfnC6sWMsboMjMJWZJYb4KLYro8sMoFAzgWtsQtTT1nc/dnc8H6C0u3c5K1+glzdPboK6ZOl1Zt6PcQ7o7RzDq1ulUqYC9t5HzddqoeF2gNkeFO82EeQsDnsbyvk0gfxovKB3dPVN0VuDumbPZ3VMub3WOy+WaGJnapLfxswXWZ4nOlPo+neu9EHhTQwVy8beK+XsTQRydK5yRo6/8CDaMCnJqSdyXXTkiFhwaQp85mc4Xy5VykpkbmG+tm6B906KoXS1o785GLXNy52MDPYG6celN0Uuap+MJ1QZ1ZOo0O126XzA/PT796ClIw7z2lFOlZQL2gwJnW4fxYtDJraMDOmN4JO/xtGgV5LGQNCsGO9ebJIc/maFf6VSJcE6VB4HL5ZooaX2iVrVuyW2fzHVNbc5vkQgF5u7Ngae5Hk9coIucadzta9mNow2RIt2DZ4GcNj5prvlajlhwfobG4T6fu1lmMjBvys03CMyHnwpdaqAL1De1tDFqnm4PHLVBHRulGLWLlkb0qeMVRiMYmtD4UvpCcePRANhxzRMmNlJHzMEMdxr0dbg8bY+kJ+9KcvDH0ELCyRPsqWvm+FBBnzL5E2p13iRRzhiiVzeXyzWWcnWVCrWpdaq1Szqe6pqgLeBmc/c6ceACcHqzP4x5gaYLapNezxuexBUBOZ383J0vqVBXTjcPPS/wZc/PCtTNgg1QZOaIWXIwt/eFLlzUMmegN0O9KXpJDxwp1PsNUEf3i7Y0xqcdzVCnkbvi1mlUwE412OHYZ2Z4rnpn7wTur+AForz9UH7yUu4eF7B3uCzmEbKwOJH6WhbAX+noWuUQ0YPC5XItqIbVnK1NrVepYTZwR0oGfgTXOswdmbyNwoND5M3+wMCzyyPEO/syRzCLBdEKHLmCnIZsvWTAlfNFz6u5zxytiehmmZbMvA3mtkWxFeaTAvRNQ6CebpKmTh3dL9Sn+Wd8+KgnuToiGHXr1K+egL3Yjcbw4ilKcMc4Xnqy9nmBAHgaZymQpzG9G2QxD+aFRVaGRabYRkQHmhL1RJSvuVyuJVPP1F9TbWrdoo4rYB/MdU71fqCYvPXMAwCculX2YYjDFIob5zbE3YQvO9Ugl6x8wJV3n0ImlPrMtTWRztyYzDyFedsm6PyjlnkBff5Q75uNUm1pxKsKTpRKBFO5dZr/8pzZYEeWhbkJ9DqEVsfd2bljYUoBPEUzAnnK3veVxdyPhd1rOiTA4LeiK/JUpcvl2uySekxrtaph1DPFJvtxnVMOvo+YvL2ZBwpwtB5GJ04QRz4OjtDR/R3lXMwaduQW5MjKI5cqV468XA8NaWviMJirOwcf23PzSQB6C9Q3tkBdN0oBdbya4KmG9h6JYCq3vu7Js8FOc9W3pyO23BEjcKeMKy5IzwAeDh6LBsjTAs7QYhLsacpjlxdZRadUjegJjlcxl8u12aX1mNap1i/qmTriCoY2DcyaFpO3lxi+3aXt8GWyybmzdNWJG0dGDr5YkE9LvLJOsnJ15RqxwJQC5mv/pDkz36llE3R2bj4fmM8L6Hmo61OoCerrTUujzdWtW8cXFr+4WWDvPpNnq9Mo3u34y6eDSWt4ExULo4CnxdpFnr4v4/52wL63loGv0Iew2Fb4AbhcrslTWqtawxTB7i5jRNZSrVPdk8l7qXTN7VQDnJou1jDE1Y33nssZuThyAnnvyRSvEMiRlVtXrnn5XjLbnMzqiDBfuKhlQYDeDPVNDVBv2iilVxGTq1u3rtm6xDAV2BHF0ICvpw3CXZ07TmsJ4PkO0zV8oQZcPD2BBfbUObMTC5seKnrlYm2dKv4gXC7XZpKpRVunZNq0frWmKTbZkU9xUvvzi8XsvYgBTpn484UX27I5VIhjs5PmsDyVjaSCvC8gR4qwp3HlNmKxfeZ2A3Q0mE8o0NWlD8vUtU/dRjBNbt2CXaMYZOzoiOmJa7dwpwURwGORsFj01BXQYxGxmAL8CvoqLHibZv5CpkO6XK4l04xoWG2aGqa6nn5hDW3UPQR40xv9tswHBThx4xk1xMWNV9HKtAG5jVesK0/z8qY+88WHOfE494FRNH+oW7eu2XoT2OnCjCfw5ilce1/gLs69AjydPn2GPG0N6Klr5jk18HsiyuW3rR8ALpdrecjWLmqZolipcWovfLYc/hF4gwkW4ODGuhriW6sbh4GkKbGPH3TkXQF5mysfFrEsLsyJxbkPjKoGqCeZuoV6G9g1W28Cu0Yx+HLVtSvc4dwF8BTNAPL9bfhpm4JeYa/CAquw4C6Xa3lJ63d6dV3XWuu4/o06UwTe9Ga/TQ3w+MZPpzunDcTVjWtG3gbyJlfeNGxLQb64MCcO5z4wjkaHuoJdB3o1ZetNYMeXauHeF7jTAgjg46JgME4FeSyYBb06ekihr8KCu1yu5SNbvwprAXYFbQU3eABFNqxSgIMZ68SJK8ThxveQzU5wpw3kba58tLx8oWFODM59YFyNBvVR3HoT2HXzNIW7xjIKeIW8RjQKeigu5Cp19Va62C6Xa3kpqWWtcZJCW8G9Thx4CnDrxC3ENSPPgdy68s0Dc+Jv7gNzUTvUc269Cew5uDcB3kJeYxpo7eMHgW+lix21yqrvcrkmQqYubb3OquXS1LnWvrKALppIAJ6DOKLgcUEOhSWFObE394H5aDjYU7feBvbUta9P4G4Bbx28Ql5Br9rjsYPQb5P+AFwu1+SprW61tvcQad1bcCu8LcBTiKduvA3kQzc+lxTmxNzcB+ar0d16CnYbxSjcN7Q4dwW8Qv6AR9WLpKC3jt5Cv036A3C5XJOnYbVr61yhbcGt8G4CeBvE20DeGK8sOcgr3uY+sFCaH9ita0+dewp4C3kLeuvoU+i7XK6Hhw541GCdK7RVygUbo6QAHwXikwXyirO5Dyy05gb2YXC3gG+CfAp71foE/C6X6+Gh9X88u94tC5QRFuApxG3HSltGPhzkSw1z4mvuA4uhtn/4drC3wV1jmX4G8inshyl9ELhcrslVrp5TaFtwpwBvc+KTD/KKrbkPLKbyYB8F7ingN07VA8HaYD9MTQ8Cl8s1mcrVswW21capQW60xSmNEJ84kFdMzX1gKTQE7CPAvQnwTaC3sE/VtOAul2v5qK22UwY0ue8mgCvEN2UhPgkgV2U/sJTKgL0B7qqmxcjBfr5q+qG4XK75K1d789EwVmwyTAlZiE8SyFXZD2wu5b7I2ZDf1KBhi+dyubZMpZwIVjneTBzErbIfmATlvuB2yLeB3uVybZkKVjmOLBuQq7IfmDTlvvQxlC5ug3I/DpfLtfQKoyhX/1nlWDSJyn5g0pVbFJfL5RpFOdYsB2U/sFyVWzyXy7VlKseO5azsB7Y05X4MLpdrcpSr5y1N2Q+4XC6Xa3ko+wGXy+VyLQ9lP+ByuVyu5aF/BuOUWo/I2FvgAAAAAElFTkSuQmCC"/><path class="cls-9" d="M51.383,342.373H308.264a27.174,27.174,0,0,1,27.174,27.174v0a27.174,27.174,0,0,1-27.174,27.174H51.382a27.173,27.173,0,0,1-27.173-27.173v0a27.174,27.174,0,0,1,27.174-27.174Z"/><path class="cls-18" d="M308.264,396.72H266.483l-0.2-54.347h41.983a27.174,27.174,0,0,1,27.174,27.174h0A27.174,27.174,0,0,1,308.264,396.72Z"/><path class="cls-9" d="M297.69,379.069a11.887,11.887,0,1,1,8.4-3.481A11.9,11.9,0,0,1,297.69,379.069Zm0-20.767a8.881,8.881,0,1,0,8.882,8.881A8.891,8.891,0,0,0,297.69,358.3Z"/><path class="cls-9" d="M314.412,385.509a1.5,1.5,0,0,1-1.062-.44l-9.43-9.43a1.5,1.5,0,1,1,2.125-2.125l9.429,9.43A1.5,1.5,0,0,1,314.412,385.509Z"/><rect class="cls-2" x="48.546" y="362.247" width="194.388" height="14.599" rx="7.299" ry="7.299"/><path class="cls-26" d="M488.844,95.305l10.688,11.957a2.449,2.449,0,0,0,3.652,0l8.861-9.914a2.449,2.449,0,0,1,3.652,0l8.858,9.913a2.449,2.449,0,0,0,3.653,0l8.861-9.914a2.449,2.449,0,0,1,3.652,0l8.865,9.915a2.449,2.449,0,0,0,3.652,0l8.862-9.915a2.449,2.449,0,0,1,3.652,0l8.87,9.917a2.449,2.449,0,0,0,3.651,0l10.7-11.959"/><circle class="cls-27" cx="103.757" cy="502.683" r="19.585"/><circle class="cls-28" cx="329.113" cy="33.96" r="19.585"/></g></g></svg> \ No newline at end of file diff --git a/static/base/images/header.svg b/static/base/images/header.svg deleted file mode 100644 index 060757ee..00000000 --- a/static/base/images/header.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 317.059 189.688"><defs><style>.cls-1{isolation:isolate;}.cls-2{fill:url(#linear-gradient);}.cls-3{fill:#e0e3fd;}.cls-4{fill:#d1d4fc;}.cls-5{fill:#b2b8fa;}.cls-6{fill:#f3f4fe;}.cls-55,.cls-7{fill:#c1c6fb;}.cls-8{fill:#ffcebd;}.cls-9{fill:#ff5574;}.cls-10,.cls-145{fill:#191c3c;}.cls-11{fill:#6168ff;}.cls-12,.cls-22{fill:#fff;}.cls-13{fill:#4d5068;}.cls-14,.cls-18{fill:#231f20;}.cls-14{opacity:0.15;}.cls-15{fill:#474963;}.cls-16{fill:#75778a;}.cls-17{fill:#3b479a;}.cls-145,.cls-18{opacity:0.3;}.cls-19{fill:#ffc043;}.cls-20,.cls-30{fill:#f0f1fe;}.cls-21{mix-blend-mode:multiply;}.cls-22,.cls-66{opacity:0;}.cls-23,.cls-68{fill:#fdfdff;}.cls-23,.cls-67{opacity:0.024;}.cls-24,.cls-70{fill:#fbfcff;}.cls-24,.cls-69{opacity:0.049;}.cls-25,.cls-72{fill:#f9faff;}.cls-25,.cls-71{opacity:0.073;}.cls-26,.cls-74{fill:#f7f8ff;}.cls-26,.cls-73{opacity:0.098;}.cls-27,.cls-76{fill:#f6f6fe;}.cls-27,.cls-75{opacity:0.122;}.cls-28,.cls-78{fill:#f4f5fe;}.cls-28,.cls-77{opacity:0.146;}.cls-29,.cls-80{fill:#f2f3fe;}.cls-29,.cls-79{opacity:0.171;}.cls-30,.cls-81{opacity:0.195;}.cls-31,.cls-83{fill:#eeeffe;}.cls-31,.cls-82{opacity:0.22;}.cls-32,.cls-85{fill:#eceefe;}.cls-32,.cls-84{opacity:0.244;}.cls-33,.cls-87{fill:#eaecfe;}.cls-33,.cls-86{opacity:0.268;}.cls-34,.cls-89{fill:#e8eafe;}.cls-34,.cls-88{opacity:0.293;}.cls-35,.cls-91{fill:#e7e8fd;}.cls-35,.cls-90{opacity:0.317;}.cls-36,.cls-93{fill:#e5e7fd;}.cls-36,.cls-92{opacity:0.341;}.cls-37,.cls-95{fill:#e3e5fd;}.cls-37,.cls-94{opacity:0.366;}.cls-38,.cls-97{fill:#e1e3fd;}.cls-38,.cls-96{opacity:0.39;}.cls-39,.cls-99{fill:#dfe2fd;}.cls-39,.cls-98{opacity:0.415;}.cls-101,.cls-40{fill:#dde0fd;}.cls-100,.cls-40{opacity:0.439;}.cls-103,.cls-41{fill:#dbdefd;}.cls-102,.cls-41{opacity:0.463;}.cls-105,.cls-42{fill:#d9dcfd;}.cls-104,.cls-42{opacity:0.488;}.cls-107,.cls-43{fill:#d8dbfc;}.cls-106,.cls-43{opacity:0.512;}.cls-109,.cls-44{fill:#d6d9fc;}.cls-108,.cls-44{opacity:0.537;}.cls-111,.cls-45{fill:#d4d7fc;}.cls-110,.cls-45{opacity:0.561;}.cls-113,.cls-46{fill:#d2d5fc;}.cls-112,.cls-46{opacity:0.585;}.cls-115,.cls-47{fill:#d0d4fc;}.cls-114,.cls-47{opacity:0.61;}.cls-117,.cls-48{fill:#ced2fc;}.cls-116,.cls-48{opacity:0.634;}.cls-119,.cls-49{fill:#ccd0fc;}.cls-118,.cls-49{opacity:0.659;}.cls-121,.cls-50{fill:#cacffc;}.cls-120,.cls-50{opacity:0.683;}.cls-123,.cls-51{fill:#c9cdfb;}.cls-122,.cls-51{opacity:0.707;}.cls-125,.cls-52{fill:#c7cbfb;}.cls-124,.cls-52{opacity:0.732;}.cls-127,.cls-53{fill:#c5c9fb;}.cls-126,.cls-53{opacity:0.756;}.cls-129,.cls-54{fill:#c3c8fb;}.cls-128,.cls-54{opacity:0.78;}.cls-130,.cls-55{opacity:0.805;}.cls-132,.cls-56{fill:#bfc4fb;}.cls-131,.cls-56{opacity:0.829;}.cls-134,.cls-57{fill:#bdc2fb;}.cls-133,.cls-57{opacity:0.854;}.cls-136,.cls-58{fill:#bbc1fb;}.cls-135,.cls-58{opacity:0.878;}.cls-138,.cls-59{fill:#babffa;}.cls-137,.cls-59{opacity:0.902;}.cls-140,.cls-60{fill:#b8bdfa;}.cls-139,.cls-60{opacity:0.927;}.cls-142,.cls-61{fill:#b6bbfa;}.cls-141,.cls-61{opacity:0.951;}.cls-144,.cls-62{fill:#b4bafa;}.cls-143,.cls-62{opacity:0.976;}.cls-63{fill:#ffdfd6;}.cls-64{fill:#717386;}.cls-65{fill:#3a3c4e;}.cls-146{fill:#fe5e31;}.cls-147{opacity:0.35;}.cls-148{fill:#ff5f00;}.cls-149{fill:#ff7f33;}</style><linearGradient id="linear-gradient" x1="35.199" y1="214.99" x2="282.198" y2="54.991" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#dfe1fd"/><stop offset="0.454" stop-color="#ebecfe"/><stop offset="1" stop-color="#f4f5fe"/></linearGradient></defs><title>header-illustration</title><g class="cls-1"><g id="Graphics"><g id="Layer_8" data-name="Layer 8"><path class="cls-2" d="M311.36,131.746c5.5,8.781,8.206,19.733,2.628,28.063-4.8,7.174-14.327,10.048-19.137,17.218-2.43,3.621-3.709,8.358-7.5,10.507-2.33,1.32-5.145,1.355-7.822,1.355l-242.153.024c-2.706,0-5.518-.022-7.958-1.194-2.927-1.405-4.879-4.26-6.327-7.167a40.233,40.233,0,0,1,5.029-42.707c5.92-7.08,14.329-12.083,18.9-20.1,3.979-6.984,4.514-15.317,5.829-23.247C54.509,84.448,58.633,74.2,68.311,69.88c11.6-5.184,23.242-9.56,32.252-18.972,9.73-10.166,15.217-24.632,27.315-31.82,11.6-6.89,26.347-5.225,39.267-1.353s25.442,9.757,38.892,10.761c16.491,1.231,33.543-4.96,49.327-.024a37.007,37.007,0,0,1,23.519,22.784c5.28,15.178.224,32.69,6.431,47.513,4.646,11.1,14.781,18.742,22.455,28.006A46.526,46.526,0,0,1,311.36,131.746Z"/></g><g id="Layer_6" data-name="Layer 6"><rect class="cls-3" x="193.476" y="114.758" width="63.825" height="74.808" rx="3.34" ry="3.34"/><rect class="cls-4" x="198.555" y="120.566" width="53.667" height="17.333" rx="1.813" ry="1.813"/><rect class="cls-4" x="198.555" y="143.399" width="53.667" height="17.333" rx="1.813" ry="1.813"/><rect class="cls-4" x="198.555" y="166.233" width="53.667" height="17.333" rx="1.813" ry="1.813"/><circle class="cls-3" cx="225.389" cy="129.233" r="1.833"/><circle class="cls-3" cx="225.389" cy="152.162" r="1.833"/><circle class="cls-3" cx="225.389" cy="175.091" r="1.833"/><path class="cls-4" d="M77.631,80.66c-14.357,8.89-9.89,29.678-9.7,44.046q0.32,23.762.64,47.524a0.742,0.742,0,0,1-1.482,0q-0.383-28.4-.765-56.8c-0.18-13.368-2.467-27.989,10.556-36.053a0.742,0.742,0,0,1,.748,1.28h0Z"/><path class="cls-4" d="M69.658,87.891a18.1,18.1,0,0,1,2.316-3.934,19.26,19.26,0,0,1,5.607-4.1l0.3,0.16a17.793,17.793,0,0,1,1.172,9.617,10.681,10.681,0,0,1-5.521,7.682c-2.163,1.04-4.719,1.176-6.737,2.474C66.223,95.687,67.884,91.631,69.658,87.891Z"/><path class="cls-4" d="M54.619,62.676c14.259,5.656,11.19,27.286,11.765,39.475,0.974,20.671,1.5,41.341,1.366,62.037a0.742,0.742,0,0,1-1.482,0q0.169-25.811-.891-51.607c-0.326-7.769-.716-15.536-1.084-23.3-0.426-9.018-.011-21.184-10.068-25.173-0.876-.348-0.494-1.782.394-1.429h0Z"/><path class="cls-4" d="M64.38,87.554c0.026-.071.044-0.145,0.069-0.217a6.7,6.7,0,0,1,.577,1.09Z"/><path class="cls-4" d="M53.807,63.935a0.732,0.732,0,0,1,1.089-.492,15.576,15.576,0,0,1,9.887,9.88,21.46,21.46,0,0,1-.333,14.014c-1.772-2.8-5.372-4.2-7.893-6.519C52.082,76.7,51.395,69.519,53.807,63.935Z"/><path class="cls-5" d="M60.281,164.207h12.93a5.822,5.822,0,0,1,5.822,5.822V189a0,0,0,0,1,0,0H54.459a0,0,0,0,1,0,0V170.028A5.822,5.822,0,0,1,60.281,164.207Z" transform="translate(133.493 353.202) rotate(180)"/><path class="cls-4" d="M66.1,134.774c0.223-5.728.483-12.512-3.771-17-3.321-3.5-11.838-5.92-16.612-6.044a0.742,0.742,0,0,1,0-1.482c3.641,0.094,7.439,1.538,10.868,2.7,2.523,0.856,4.91,1.8,6.792,3.776,4.57,4.788,4.444,11.9,4.205,18.05a0.742,0.742,0,0,1-1.482,0h0Z"/><path class="cls-4" d="M44.119,109.65a0.463,0.463,0,0,1,.363-0.1l5.376,0.046a18.955,18.955,0,0,1,4.624.419c3.03,0.788,5.484,3.027,7.4,5.5l0.558,0.085c-2.8.892-5.542,2.063-8.462,2.367s-6.155-.436-7.984-2.732a11.122,11.122,0,0,1-1.926-5.2A0.462,0.462,0,0,1,44.119,109.65Z"/><g id="_Group_" data-name="&lt;Group&gt;"><g id="_Group_2" data-name="&lt;Group&gt;"><g id="_Group_3" data-name="&lt;Group&gt;"><path id="_Path_" data-name="&lt;Path&gt;" class="cls-3" d="M232.03,104.1H222.024v3.042a8.623,8.623,0,0,0,2.277,5.838h0V114.5h5.451v-1.518h0a8.623,8.623,0,0,0,2.277-5.838V104.1Z"/></g></g><g id="_Group_4" data-name="&lt;Group&gt;"><g id="_Group_5" data-name="&lt;Group&gt;"><path id="_Path_2" data-name="&lt;Path&gt;" class="cls-6" d="M229.972,104.1v3.042a8.623,8.623,0,0,1-2.277,5.838h0V114.5h1.176v-1.518h0a8.623,8.623,0,0,0,2.277-5.838V104.1h-1.176Z"/></g></g><g id="_Group_6" data-name="&lt;Group&gt;"><g id="_Group_7" data-name="&lt;Group&gt;"><g id="_Group_8" data-name="&lt;Group&gt;"><path id="_Path_3" data-name="&lt;Path&gt;" class="cls-3" d="M223.108,110.429h-1.646a2.714,2.714,0,1,1,0-5.428h1.058v1.15h-1.058a1.564,1.564,0,1,0,0,3.128h1.646v1.15Z"/></g></g></g><path id="_Path_4" data-name="&lt;Path&gt;" class="cls-4" d="M223.547,104.124v2.6a0.753,0.753,0,0,0,.753.753h0a0.753,0.753,0,0,0,.753-0.753v-0.1a0.641,0.641,0,0,1,.641-0.641h0a0.64,0.64,0,0,1,.64.641v4.247a0.736,0.736,0,0,0,.736.736h0a0.736,0.736,0,0,0,.736-0.736v-1.763a0.722,0.722,0,0,1,.722-0.722h0a0.75,0.75,0,0,0,.75-0.75v-3.513h-5.732Z"/></g><path class="cls-3" d="M292.388,141.31a11.256,11.256,0,0,0-.885-4.378,23.868,23.868,0,0,0-4.61,20.924l1.393,1.294a14.47,14.47,0,0,0,4.029-8.385A43.082,43.082,0,0,0,292.388,141.31Z"/><path class="cls-3" d="M305.092,149.429a0.734,0.734,0,0,0-.407-0.19,10.624,10.624,0,0,0-12.943,10.375l0.939,1.134c1.981,0.54,4.051-.469,5.695-1.7a20.268,20.268,0,0,0,6.714-8.856A0.759,0.759,0,0,0,305.092,149.429Z"/><path class="cls-3" d="M274.342,149.258c-2.106-1.711-4.557-3.384-7.266-3.219a0.861,0.861,0,0,0-.75.339c-0.3.561,0.652,0.984,0.836,1.591a2.282,2.282,0,0,1-.14,1.086,3.54,3.54,0,0,0,.328,1.974,15.509,15.509,0,0,0,16.114,9.324l0.824-1.294A73.172,73.172,0,0,0,274.342,149.258Z"/><path class="cls-3" d="M282.105,159.452c4.725,4.487,5.332,11.144,4.517,17.287-0.177,1.337,1.927,1.324,2.1,0,0.887-6.691-.026-13.924-5.133-18.773a1.052,1.052,0,0,0-1.487,1.487h0Z"/><path class="cls-3" d="M286.72,157.32c1,5.906-.275,11.872.356,17.806,0.142,1.332,2.246,1.346,2.1,0-0.652-6.129.6-12.257-.431-18.365-0.225-1.331-2.252-.767-2.028.559h0Z"/><path class="cls-3" d="M292.882,156.9a29.613,29.613,0,0,0-4.3,8.494c-0.88,3.311-.628,7.035-0.78,10.436a1.052,1.052,0,0,0,2.1,0c0.143-3.205-.089-6.762.705-9.877a27.463,27.463,0,0,1,4.085-7.992c0.752-1.129-1.068-2.183-1.816-1.061h0Z"/><path class="cls-5" d="M295.251,189.073H283.514a1.063,1.063,0,0,1-1.027-.791l-4-15.082a1.063,1.063,0,0,1,1.027-1.335h19.728a1.063,1.063,0,0,1,1.027,1.335l-4,15.082A1.063,1.063,0,0,1,295.251,189.073Z"/><path class="cls-7" d="M290.969,139.2c-1.563,5.891-1.576,12.034-3,17.952a0.152,0.152,0,0,0,.293.081c1.423-5.918,1.436-12.062,3-17.952a0.152,0.152,0,0,0-.293-0.081h0Z"/><path class="cls-7" d="M292.9,158.927a20.1,20.1,0,0,1,10.417-8.243c0.183-.064.1-0.358-0.081-0.293a20.431,20.431,0,0,0-10.6,8.383,0.152,0.152,0,0,0,.262.153h0Z"/><path class="cls-7" d="M267.778,147.92a12.182,12.182,0,0,0,4.69,5.493c3,2.1,6.853,3.135,9.6,5.49,0.173,0.149.427-.1,0.252-0.252-1.911-1.639-4.346-2.315-6.51-3.55-3.107-1.773-6.314-3.82-7.689-7.275-0.084-.211-0.429-0.119-0.344.095h0Z"/><rect class="cls-8" x="246.49" y="175.423" width="4.657" height="7.091" transform="translate(497.637 357.937) rotate(180)"/><path class="cls-9" d="M251.775,180.688a29.085,29.085,0,0,0,1.072,5.476,3.129,3.129,0,0,1,.366.911v2.613H242.2V188.3a2.971,2.971,0,0,1,.588-1.768c0.937-1.269,3.725-3.892,3.287-5.844h5.7Z"/><path class="cls-10" d="M251.749,180.688h0.026l-0.013.071C251.759,180.736,251.752,180.71,251.749,180.688Z"/><path class="cls-10" d="M253.213,187.8v1.884H242.2V188.3a2.935,2.935,0,0,1,.044-0.5h10.973Z"/><rect class="cls-10" x="246.856" y="182.174" width="3.035" height="0.68" rx="0.271" ry="0.271" transform="translate(496.747 365.028) rotate(180)"/><rect class="cls-10" x="246.49" y="183.691" width="3.035" height="0.68" rx="0.271" ry="0.271" transform="translate(496.015 368.063) rotate(180)"/><rect class="cls-8" x="276.786" y="175.423" width="4.657" height="7.091" transform="translate(558.229 357.937) rotate(180)"/><path class="cls-11" d="M268.728,115.127c-1.3,3.207-9.181,31.063-9.181,31.063l-7.106,33.372H245.5l3.58-37.87,2.616-40.211,15.044,1.79,2.721,7.45Z"/><polygon class="cls-11" points="284.494 109.055 284.06 142.656 282.407 179.562 275.797 179.562 273.134 150.138 266.742 115.49 266.742 103.271 283.234 104.785 284.494 109.055"/><path class="cls-8" d="M267.672,60.9h9.915V47.842H266.742C269.256,51.106,267.672,60.9,267.672,60.9Z"/><path class="cls-12" d="M283.234,107.54c-0.322,7.734-25.339-4.731-30.793-1.836l6.61-45.492s6.056-2.408,8.621-.526c3.535,2.594,9.915,0,9.915,0l4.453,1.767S283.509,100.93,283.234,107.54Z"/><path class="cls-9" d="M268.123,52.721s1.8,30.026-13.055,49.035c0,0-4.539,11.222-8.212,11.773,0,0-3.834-9.732.848-17.419,2.876-4.722,8.43-15.067,8.76-20.586l0.945-15.839Z"/><path class="cls-9" d="M277.587,52.721s-4.34,19.673-4.453,29.724c-0.092,8.171,12.6,35.42,12.6,35.42s7.833-8.175,3.7-17.624c-2.723-6.229-5.762-11.154-5.375-15.245l-0.1-28.117Z"/><path class="cls-8" d="M263.306,45.366a17.024,17.024,0,0,1,.725-3.887,3.15,3.15,0,0,0-1.136-.244,0.517,0.517,0,0,1-.322-0.856c1.206-1.343,3.415-3.539,3.783-4.343a6.387,6.387,0,0,1,.718-1.335,10.1,10.1,0,0,0,.565-0.992,1.768,1.768,0,0,1,1.21-.952,4.1,4.1,0,0,1,1.483.166,27.692,27.692,0,0,1,5.949,1.857,11.555,11.555,0,0,1,2.071,1.2A6.278,6.278,0,0,1,280.4,38.8a11.211,11.211,0,0,1,.015,5.97,5.147,5.147,0,0,1-.432,1.405,4.476,4.476,0,0,1-1.719,1.627c-1.181.725-2.409,1.369-3.646,1.991a13.466,13.466,0,0,1-2.285.975,13.119,13.119,0,0,1-3.989.32,6.321,6.321,0,0,1-3.034-.6,4.014,4.014,0,0,1-1.72-2.255A7.72,7.72,0,0,1,263.306,45.366Z"/><path class="cls-13" d="M266.378,27.073a12.941,12.941,0,0,0,6.894,2.494,36.564,36.564,0,0,1,7.327,1.18c1.456,0.494,3.722,1.408,4.421,2.9,0.979,2.091.822,5.194,0.285,7.371a10.972,10.972,0,0,1-2.288,4.5,12.452,12.452,0,0,1-4.347,2.914c-0.139.068-.276,0.138-0.413,0.212a2.111,2.111,0,0,1-.431.25c-0.277.057-.339-0.42-0.337-0.635a2.432,2.432,0,0,1,.381-1.191,7.178,7.178,0,0,1,.706-0.864A4.941,4.941,0,0,0,279.3,43.3a3.683,3.683,0,0,0-.094-1.485,1.4,1.4,0,0,0-1.037-.977,1.857,1.857,0,0,0-1.41.587,7.55,7.55,0,0,0-1.866,2.468q-0.041-1.307-.081-2.614a6.391,6.391,0,0,0-.225-1.784c-0.244-.751-0.774-1.487-0.586-2.254a8.052,8.052,0,0,0,.358-1.02,1.36,1.36,0,0,0-.79-1.253,5.035,5.035,0,0,0-1.513-.4c-0.81-.143-1.571-0.411-2.357-0.627a4.965,4.965,0,0,1-2.046-.979A3.945,3.945,0,0,1,266.52,30.9a10.716,10.716,0,0,1-.2-2.381A11.631,11.631,0,0,1,266.378,27.073Z"/><path class="cls-8" d="M296.132,74.122l5.327,13.74a4.852,4.852,0,0,1-.375,4.282L284.151,113.7l-3-4.51,10.859-17.183a5.137,5.137,0,0,0-.115-4.685l-5.26-9.255S293.01,80.442,296.132,74.122Z"/><path class="cls-8" d="M281.147,109.192l-1.939.345-1.34,1.234a1.208,1.208,0,0,0-.092,1.683l0.4,0.456-0.6.96a1.108,1.108,0,0,0,.08,1.287l1.873,2.3a1.108,1.108,0,0,0,1.444.242l2.03-1.26a1.9,1.9,0,0,0,.862-1.25l0.29-1.486Z"/><path class="cls-9" d="M282.071,180.688a6.575,6.575,0,0,0,1.623,5.476,1.385,1.385,0,0,1,.366.911v2.613H273.594V188.3a2.972,2.972,0,0,1,.588-1.768c0.937-1.269,2.623-3.892,2.186-5.844h5.7Z"/><path class="cls-10" d="M282.045,180.688h0.026l-0.013.071C282.055,180.736,282.048,180.71,282.045,180.688Z"/><path class="cls-10" d="M284.06,187.8v1.884H273.594V188.3a2.935,2.935,0,0,1,.044-0.5H284.06Z"/><rect class="cls-10" x="277.152" y="182.174" width="3.035" height="0.68" rx="0.271" ry="0.271" transform="translate(557.34 365.028) rotate(180)"/><rect class="cls-10" x="276.786" y="183.691" width="3.035" height="0.68" rx="0.271" ry="0.271" transform="translate(556.607 368.063) rotate(180)"/><path class="cls-9" d="M277.587,52.721l6.907,4.509,3.078,1.464a8.646,8.646,0,0,1,4.342,4.669l5.549,12.625c-6,1.163-6.243,6.58-10.515,5.57l-6.132-14.6-3.229-7.276V52.721Z"/><path class="cls-9" d="M268.123,52.721L261.2,55.692,257.34,56.7a8.194,8.194,0,0,0-5.395,4.551L245.5,74.062c4.131,0,8.425,5.535,9.089,4.467l7.918-13.886Z"/><path class="cls-14" d="M265.934,49.735a1.944,1.944,0,0,1,.96-1.934h0a1.04,1.04,0,0,0,.46-0.548l0.611-1.688a2.833,2.833,0,0,0,.138-1.38l-0.195-1.309a1.092,1.092,0,0,0-1.529-.835l-2.227,1.005-1.374,1.348-0.009.019a9.021,9.021,0,0,0,.293,3.519,4.479,4.479,0,0,0,1.919,2.516,4.217,4.217,0,0,0,1.1.417Z"/><path class="cls-8" d="M246.261,74.584l15.044-24.178V46.364a1.885,1.885,0,0,1,.565-1.346l1.7-1.662,2-.9a0.979,0.979,0,0,1,1.371.748l0.174,1.173a2.538,2.538,0,0,1-.124,1.237l-0.548,1.514a0.933,0.933,0,0,1-.412.491h0a1.743,1.743,0,0,0-.86,1.734l0.147,1.138,2.653,0.524-3.324,2.558L253.8,78.54a4.27,4.27,0,0,1-5.73,2.167h0A4.271,4.271,0,0,1,246.261,74.584Z"/><path class="cls-10" d="M166.722,186.321l0.008,0a0.488,0.488,0,0,0,.664-0.187l15.432-27.483a0.488,0.488,0,0,0-.186-0.665l-0.008,0a0.487,0.487,0,0,0-.664.186l-15.433,27.484A0.488,0.488,0,0,0,166.722,186.321Z"/><path class="cls-15" d="M129.607,186.1H169.1a1.041,1.041,0,0,1,1.041,1.041v1.2a1.042,1.042,0,0,1-1.042,1.042H129.606a1.041,1.041,0,0,1-1.041-1.041v-1.2a1.042,1.042,0,0,1,1.042-1.042Z" transform="translate(298.604 375.561) rotate(-179.969)"/><path class="cls-10" d="M128.565,187.615a1.5,1.5,0,0,1,.371-0.966,1.528,1.528,0,0,0,1.526,1.522l38.517,0.021a1.5,1.5,0,0,0,1.158-.561v0.235a1.529,1.529,0,0,1-1.53,1.528l-38.517-.021a1.529,1.529,0,0,1-1.528-1.53v-0.228Z"/><rect class="cls-16" x="139.329" y="186.971" width="3.022" height="1.159"/><rect class="cls-16" x="135.748" y="186.969" width="3.022" height="1.159"/><rect class="cls-16" x="161.172" y="186.983" width="3.022" height="1.159"/><rect class="cls-8" x="19.685" y="154.12" width="6.235" height="9.087" transform="translate(-87.475 42.332) rotate(-35.292)"/><path class="cls-11" d="M19.067,158.782L6.534,160.109,3.793,161.65a1.829,1.829,0,0,1-2.389-.537l-1.085-1.532,17.672-12.509a2.185,2.185,0,0,1,3.046.521l0.976,1.379a11.216,11.216,0,0,1,1.94,4.839l0.2,1.369h0a2.483,2.483,0,0,0-3.461-.592l-1.036.733a2.483,2.483,0,0,0-.592,3.461h0Z"/><path class="cls-13" d="M18.995,148.552L1.658,160.823A0.766,0.766,0,0,1,.59,160.64L0,159.806l17.962-12.714a2.2,2.2,0,0,1,3.075.5l0.976,1.379c0.012,0.017.021,0.036,0.032,0.053A2.2,2.2,0,0,0,18.995,148.552Z"/><polygon class="cls-17" points="50.007 185.331 48.228 181.081 25.909 156.76 20.159 161.062 41.408 189.463 45.444 187.549 50.007 185.331"/><rect class="cls-8" x="46.36" y="151.731" width="6.235" height="9.087" transform="translate(35.289 -7.03) rotate(12.602)"/><path class="cls-11" d="M46.885,153.583L37.5,145.175l-2.981-1a1.829,1.829,0,0,1-1.2-2.133l0.41-1.832,21.129,4.724a2.185,2.185,0,0,1,1.655,2.609l-0.369,1.649a11.216,11.216,0,0,1-2.289,4.684l-0.88,1.068h0a2.483,2.483,0,0,0-1.881-2.965L49.85,151.7a2.483,2.483,0,0,0-2.965,1.881h0Z"/><path class="cls-13" d="M54.462,146.678l-20.828-4.7a0.775,0.775,0,0,1-.586-0.925l0.221-.989,21.583,4.869a2.185,2.185,0,0,1,1.656,2.609l-0.369,1.649c0,0.02-.013.039-0.017,0.059A2.183,2.183,0,0,0,54.462,146.678Z"/><path class="cls-18" d="M45.51,178.118l-7.739-8.433-3.947,9.64L41.4,189.454h0.026l4.017-1.905,4.563-2.217-1.779-4.251-1.305-1.423a1.119,1.119,0,0,1-1.466-1.348Z"/><path class="cls-17" d="M79.44,169.065l-2.555.229a47.964,47.964,0,0,0-17.564,5.069l-10.267,5.251a1.126,1.126,0,0,1-1.6-1.3l6.518-23.525h-8.1L35.72,179.578a7.169,7.169,0,0,0,6.783,9.883l39.17-.315Z"/><path class="cls-11" d="M120.372,174.029l-3.9,6.323a6.105,6.105,0,0,1-8,2.223l-1.948-1.005-11.65,5.158a18.047,18.047,0,0,1-6.471,1.526L78.8,189.526s-5.245-12.8-1.081-20.9h0a32.21,32.21,0,0,0,27.79-5.749l8.148-6.326Z"/><polygon class="cls-8" points="130.051 162.437 121.602 168.622 120.372 163.112 126.449 157.384 130.051 162.437"/><path class="cls-8" d="M124.414,159.355c-0.075-2.366,1.679-3.555,3.413-4.4a23.454,23.454,0,0,1,12.3-2.263l1.006,0.244a8.506,8.506,0,0,1-.764,3.611,9.272,9.272,0,0,0,.079,4.639,0.2,0.2,0,0,1-.18.28,14.26,14.26,0,0,0-2.346.163c-0.222.368-.38,0.771-0.57,1.157a5.567,5.567,0,0,1-.849,1.371c-1.112,1.2-2.99,1.186-4.608.959-2.289-.322-4.652-0.956-6.224-2.727A4.857,4.857,0,0,1,124.414,159.355Z"/><path class="cls-8" d="M122.982,165.822l2.664,15.366a1.93,1.93,0,0,0,1.642,1.582l22.92,2.492,4.864,0.769,4.443,1.164,3.51,0.112h0a1.9,1.9,0,0,1-1.6,1.995h-2.588L152.671,189l-27.963.69a4.657,4.657,0,0,1-4.494-3.013l-7.606-20.185Z"/><path class="cls-19" d="M102.559,164.849a12.2,12.2,0,0,1,2.525-3.536,16.731,16.731,0,0,1,3.291-2.827c1.775-1.1,3.563-1.41,5.154-2.823a17.06,17.06,0,0,0,3.685-4.649c0.49-.909.9-1.863,1.436-2.745a12.5,12.5,0,0,1,8.029-5.4,26.361,26.361,0,0,1,5.684-.879,20.341,20.341,0,0,1,6.441,1.141,10.543,10.543,0,0,1,4.128,2.163,5.072,5.072,0,0,1,1.19,5.222,5.5,5.5,0,0,1-.9,2c-1.644,2.178-5.16,2.3-7.631,2.85-1.526.337-3.134-.15-4.606,0.46a9.724,9.724,0,0,0-3.2,2.781,25.882,25.882,0,0,0-3.654,4.753c-0.52.951-.918,1.962-1.361,2.951a17.719,17.719,0,0,1-5.915,7.7,10.357,10.357,0,0,1-10.746.608C102.844,172.706,101.092,168.337,102.559,164.849Z"/><rect id="_Rectangle_" data-name="&lt;Rectangle&gt;" class="cls-12" x="125.891" y="36.047" width="76.607" height="92.263" rx="2.858" ry="2.858"/><path id="_Path_5" data-name="&lt;Path&gt;" class="cls-9" d="M202.5,45.795V38.7a2.654,2.654,0,0,0-2.654-2.654h-71.3a2.654,2.654,0,0,0-2.654,2.654v7.093H202.5Z"/><circle id="_Path_6" data-name="&lt;Path&gt;" class="cls-12" cx="131.696" cy="40.921" r="0.836"/><circle id="_Path_7" data-name="&lt;Path&gt;" class="cls-12" cx="135.446" cy="40.921" r="0.836"/><circle id="_Path_8" data-name="&lt;Path&gt;" class="cls-12" cx="139.196" cy="40.921" r="0.836"/><circle class="cls-3" cx="141.137" cy="90.542" r="6.833"/><circle class="cls-3" cx="141.137" cy="109.192" r="6.833"/><rect class="cls-20" x="155.946" y="86.125" width="38.012" height="1.417"/><rect class="cls-20" x="155.946" y="91.708" width="21" height="1.417"/><rect class="cls-20" x="155.946" y="104.958" width="38.012" height="1.417"/><rect class="cls-20" x="155.946" y="110.542" width="21" height="1.417"/><circle class="cls-3" cx="141.137" cy="70.542" r="6.833"/><rect class="cls-20" x="155.946" y="66.125" width="38.012" height="1.417"/><rect class="cls-20" x="155.946" y="71.708" width="21" height="1.417"/><g class="cls-21"><path class="cls-22" d="M199.951,35.974H181.774V69.4a4.938,4.938,0,0,0,4.938,4.938H202.5V38.521A2.547,2.547,0,0,0,199.951,35.974Z"/><path class="cls-23" d="M199.969,35.974H181.915V69.311a4.9,4.9,0,0,0,4.9,4.9H202.5V38.5A2.529,2.529,0,0,0,199.969,35.974Z"/><path class="cls-24" d="M199.986,35.974H182.055V69.226a4.871,4.871,0,0,0,4.871,4.871H202.5V38.486A2.512,2.512,0,0,0,199.986,35.974Z"/><path class="cls-25" d="M200,35.974H182.2V69.141a4.838,4.838,0,0,0,4.838,4.838H202.5V38.469A2.5,2.5,0,0,0,200,35.974Z"/><path class="cls-26" d="M200.02,35.974H182.336V69.056a4.8,4.8,0,0,0,4.8,4.8H202.5V38.452A2.478,2.478,0,0,0,200.02,35.974Z"/><path class="cls-27" d="M200.038,35.974H182.476v33a4.771,4.771,0,0,0,4.771,4.771H202.5V38.434A2.46,2.46,0,0,0,200.038,35.974Z"/><path class="cls-28" d="M200.055,35.974H182.617V68.887a4.737,4.737,0,0,0,4.737,4.737H202.5V38.417A2.443,2.443,0,0,0,200.055,35.974Z"/><path class="cls-29" d="M200.072,35.974H182.757V68.8a4.7,4.7,0,0,0,4.7,4.7H202.5V38.4A2.426,2.426,0,0,0,200.072,35.974Z"/><path class="cls-30" d="M200.089,35.974H182.9V68.718a4.67,4.67,0,0,0,4.67,4.67H202.5V38.383A2.409,2.409,0,0,0,200.089,35.974Z"/><path class="cls-31" d="M200.107,35.974H183.038V68.633a4.637,4.637,0,0,0,4.637,4.637H202.5v-34.9A2.391,2.391,0,0,0,200.107,35.974Z"/><path class="cls-32" d="M200.124,35.974H183.178V68.548a4.6,4.6,0,0,0,4.6,4.6H202.5v-34.8A2.374,2.374,0,0,0,200.124,35.974Z"/><path class="cls-33" d="M200.141,35.974H183.319V68.463a4.57,4.57,0,0,0,4.57,4.57H202.5v-34.7A2.357,2.357,0,0,0,200.141,35.974Z"/><path class="cls-34" d="M200.158,35.974h-16.7v32.4A4.536,4.536,0,0,0,188,72.915h14.5v-34.6A2.34,2.34,0,0,0,200.158,35.974Z"/><path class="cls-35" d="M200.176,35.974H183.6v32.32a4.5,4.5,0,0,0,4.5,4.5h14.4V38.3A2.322,2.322,0,0,0,200.176,35.974Z"/><path class="cls-36" d="M200.193,35.974H183.74V68.209a4.47,4.47,0,0,0,4.47,4.47H202.5v-34.4A2.305,2.305,0,0,0,200.193,35.974Z"/><path class="cls-37" d="M200.21,35.974H183.88v32.15a4.436,4.436,0,0,0,4.436,4.436H202.5v-34.3A2.288,2.288,0,0,0,200.21,35.974Z"/><path class="cls-38" d="M200.227,35.974H184.021V68.04a4.4,4.4,0,0,0,4.4,4.4H202.5v-34.2A2.271,2.271,0,0,0,200.227,35.974Z"/><path class="cls-39" d="M200.245,35.974H184.161V67.955a4.369,4.369,0,0,0,4.369,4.369H202.5v-34.1A2.253,2.253,0,0,0,200.245,35.974Z"/><path class="cls-40" d="M200.262,35.974H184.3v31.9a4.336,4.336,0,0,0,4.336,4.336H202.5v-34A2.236,2.236,0,0,0,200.262,35.974Z"/><path class="cls-41" d="M200.279,35.974H184.442V67.786a4.3,4.3,0,0,0,4.3,4.3H202.5v-33.9A2.219,2.219,0,0,0,200.279,35.974Z"/><path class="cls-42" d="M200.3,35.974H184.582V67.7a4.269,4.269,0,0,0,4.269,4.269H202.5V38.176A2.2,2.2,0,0,0,200.3,35.974Z"/><path class="cls-43" d="M200.314,35.974H184.723V67.616a4.235,4.235,0,0,0,4.235,4.235H202.5V38.158A2.184,2.184,0,0,0,200.314,35.974Z"/><path class="cls-44" d="M200.331,35.974H184.863V67.532a4.2,4.2,0,0,0,4.2,4.2H202.5V38.141A2.167,2.167,0,0,0,200.331,35.974Z"/><path class="cls-45" d="M200.348,35.974H185V67.447a4.168,4.168,0,0,0,4.168,4.168H202.5V38.124A2.15,2.15,0,0,0,200.348,35.974Z"/><path class="cls-46" d="M200.365,35.974H185.144V67.362a4.135,4.135,0,0,0,4.135,4.135H202.5V38.107A2.132,2.132,0,0,0,200.365,35.974Z"/><path class="cls-47" d="M200.383,35.974h-15.1v31.3a4.1,4.1,0,0,0,4.1,4.1H202.5V38.089A2.115,2.115,0,0,0,200.383,35.974Z"/><path class="cls-48" d="M200.4,35.974H185.424V67.193a4.068,4.068,0,0,0,4.068,4.068H202.5V38.072A2.1,2.1,0,0,0,200.4,35.974Z"/><path class="cls-49" d="M200.417,35.974H185.565V67.108a4.035,4.035,0,0,0,4.035,4.035h12.9V38.055A2.081,2.081,0,0,0,200.417,35.974Z"/><path class="cls-50" d="M200.434,35.974H185.705V67.023a4,4,0,0,0,4,4H202.5V38.038A2.063,2.063,0,0,0,200.434,35.974Z"/><path class="cls-51" d="M200.452,35.974H185.846V66.938a3.968,3.968,0,0,0,3.968,3.968H202.5V38.02A2.046,2.046,0,0,0,200.452,35.974Z"/><path class="cls-52" d="M200.469,35.974H185.986v30.88a3.934,3.934,0,0,0,3.934,3.934H202.5V38A2.029,2.029,0,0,0,200.469,35.974Z"/><path class="cls-53" d="M200.486,35.974h-14.36V66.769a3.9,3.9,0,0,0,3.9,3.9H202.5V37.986A2.012,2.012,0,0,0,200.486,35.974Z"/><path class="cls-54" d="M200.5,35.974H186.267v30.71a3.867,3.867,0,0,0,3.867,3.867H202.5V37.969A1.994,1.994,0,0,0,200.5,35.974Z"/><path class="cls-55" d="M200.521,35.974H186.407V66.6a3.834,3.834,0,0,0,3.834,3.834H202.5V37.951A1.977,1.977,0,0,0,200.521,35.974Z"/><path class="cls-56" d="M200.538,35.974h-13.99V66.515a3.8,3.8,0,0,0,3.8,3.8H202.5V37.934A1.96,1.96,0,0,0,200.538,35.974Z"/><path class="cls-57" d="M200.555,35.974H186.688V66.43a3.767,3.767,0,0,0,3.767,3.767H202.5V37.917A1.943,1.943,0,0,0,200.555,35.974Z"/><path class="cls-58" d="M200.572,35.974H186.828V66.345a3.734,3.734,0,0,0,3.734,3.734H202.5V37.9A1.925,1.925,0,0,0,200.572,35.974Z"/><path class="cls-59" d="M200.59,35.974H186.969V66.261a3.7,3.7,0,0,0,3.7,3.7H202.5V37.882A1.908,1.908,0,0,0,200.59,35.974Z"/><path class="cls-60" d="M200.607,35.974h-13.5v30.2a3.667,3.667,0,0,0,3.667,3.667H202.5V37.865A1.891,1.891,0,0,0,200.607,35.974Z"/><path class="cls-61" d="M200.624,35.974H187.25V66.091a3.633,3.633,0,0,0,3.633,3.633H202.5V37.848A1.874,1.874,0,0,0,200.624,35.974Z"/><path class="cls-62" d="M200.641,35.974H187.39V66.007a3.6,3.6,0,0,0,3.6,3.6H202.5V37.831A1.856,1.856,0,0,0,200.641,35.974Z"/><path class="cls-5" d="M200.659,35.974H187.53V65.922a3.566,3.566,0,0,0,3.566,3.566h11.4V37.813A1.839,1.839,0,0,0,200.659,35.974Z"/></g><rect class="cls-12" x="186.896" y="22.275" width="55.3" height="48.256" rx="5.147" ry="5.147"/><path class="cls-9" d="M237.591,22.275H191.5a4.6,4.6,0,0,0-4.6,4.6v5.243h55.3V26.88A4.6,4.6,0,0,0,237.591,22.275Z"/><circle class="cls-12" cx="193.115" cy="27.199" r="0.844"/><circle class="cls-12" cx="196.779" cy="27.199" r="0.844"/><circle class="cls-12" cx="196.779" cy="27.199" r="0.844"/><circle class="cls-12" cx="200.444" cy="27.199" r="0.844"/><circle class="cls-4" cx="197.623" cy="45.032" r="6.596"/><rect class="cls-20" x="207.772" y="41.479" width="30.204" height="1.777"/><rect class="cls-20" x="207.772" y="46.652" width="30.204" height="1.777"/><rect class="cls-63" x="207.772" y="51.825" width="11.326" height="1.777"/><path class="cls-19" d="M286.646,9.058a9.058,9.058,0,1,0-14.01,7.579v5.78h9.9v-5.78A9.045,9.045,0,0,0,286.646,9.058Z"/><polygon id="_Path_9" data-name="&lt;Path&gt;" class="cls-13" points="283.182 22.821 279.888 25.575 274.986 25.575 271.993 22.821 271.993 18.494 283.182 18.494 283.182 22.821"/><rect id="_Rectangle_2" data-name="&lt;Rectangle&gt;" class="cls-64" x="271.507" y="18.889" width="12.137" height="0.83" rx="0.365" ry="0.365"/><rect id="_Rectangle_3" data-name="&lt;Rectangle&gt;" class="cls-64" x="271.507" y="20.275" width="12.137" height="0.83" rx="0.365" ry="0.365"/><rect id="_Rectangle_4" data-name="&lt;Rectangle&gt;" class="cls-64" x="271.507" y="21.662" width="12.137" height="0.83" rx="0.365" ry="0.365"/><path id="_Rectangle_5" data-name="&lt;Rectangle&gt;" class="cls-65" d="M274.845,25.446h5.082a0,0,0,0,1,0,0v0.2a1.43,1.43,0,0,1-1.43,1.43h-2.222a1.43,1.43,0,0,1-1.43-1.43v-0.2A0,0,0,0,1,274.845,25.446Z"/><polygon class="cls-12" points="277.022 11.422 274.702 9.103 275.409 8.396 277.022 10.008 280.55 6.48 281.257 7.186 277.022 11.422"/><path class="cls-22" d="M152.4,54.256H125.891V84.768H152.4a3.55,3.55,0,0,0,3.55-3.55V57.806A3.55,3.55,0,0,0,152.4,54.256Z"/><path class="cls-23" d="M152.258,54.256H125.891V84.608h26.367a3.531,3.531,0,0,0,3.531-3.531V57.787A3.531,3.531,0,0,0,152.258,54.256Z"/><path class="cls-24" d="M152.119,54.256H125.891V84.449h26.228a3.513,3.513,0,0,0,3.513-3.513V57.769A3.513,3.513,0,0,0,152.119,54.256Z"/><path class="cls-25" d="M151.981,54.256h-26.09V84.29h26.09a3.494,3.494,0,0,0,3.494-3.494V57.75A3.494,3.494,0,0,0,151.981,54.256Z"/><path class="cls-26" d="M151.842,54.256H125.891V84.13h25.951a3.476,3.476,0,0,0,3.476-3.476V57.732A3.476,3.476,0,0,0,151.842,54.256Z"/><path class="cls-27" d="M151.7,54.256H125.891V83.971H151.7a3.457,3.457,0,0,0,3.457-3.457v-22.8A3.457,3.457,0,0,0,151.7,54.256Z"/><path class="cls-28" d="M151.565,54.256H125.891V83.812h25.674A3.438,3.438,0,0,0,155,80.373V57.695A3.438,3.438,0,0,0,151.565,54.256Z"/><path class="cls-29" d="M151.427,54.256H125.891v29.4h25.536a3.42,3.42,0,0,0,3.42-3.42V57.676A3.42,3.42,0,0,0,151.427,54.256Z"/><path class="cls-30" d="M151.288,54.256h-25.4V83.493h25.4a3.4,3.4,0,0,0,3.4-3.4V57.657A3.4,3.4,0,0,0,151.288,54.256Z"/><path class="cls-31" d="M151.15,54.256H125.891V83.333H151.15a3.383,3.383,0,0,0,3.383-3.383V57.639A3.383,3.383,0,0,0,151.15,54.256Z"/><path class="cls-32" d="M151.012,54.256H125.891V83.174h25.121a3.364,3.364,0,0,0,3.364-3.364V57.62A3.364,3.364,0,0,0,151.012,54.256Z"/><path class="cls-33" d="M150.873,54.256H125.891V83.015h24.982a3.346,3.346,0,0,0,3.346-3.346V57.6A3.346,3.346,0,0,0,150.873,54.256Z"/><path class="cls-34" d="M150.735,54.256H125.891v28.6h24.844a3.327,3.327,0,0,0,3.327-3.327V57.583A3.327,3.327,0,0,0,150.735,54.256Z"/><path class="cls-35" d="M150.6,54.256H125.891V82.7H150.6a3.309,3.309,0,0,0,3.309-3.309V57.565A3.309,3.309,0,0,0,150.6,54.256Z"/><path class="cls-36" d="M150.458,54.256H125.891V82.536h24.567a3.29,3.29,0,0,0,3.29-3.29v-21.7A3.29,3.29,0,0,0,150.458,54.256Z"/><path class="cls-37" d="M150.319,54.256H125.891V82.377h24.428a3.272,3.272,0,0,0,3.272-3.272V57.528A3.272,3.272,0,0,0,150.319,54.256Z"/><path class="cls-38" d="M150.181,54.256h-24.29V82.218h24.29a3.253,3.253,0,0,0,3.253-3.253V57.509A3.253,3.253,0,0,0,150.181,54.256Z"/><path class="cls-39" d="M150.042,54.256H125.891v27.8h24.151a3.235,3.235,0,0,0,3.234-3.235V57.491A3.235,3.235,0,0,0,150.042,54.256Z"/><path class="cls-40" d="M149.9,54.256H125.891V81.9H149.9a3.216,3.216,0,0,0,3.216-3.216V57.472A3.216,3.216,0,0,0,149.9,54.256Z"/><path class="cls-41" d="M149.765,54.256H125.891V81.74h23.875a3.2,3.2,0,0,0,3.2-3.2V57.453A3.2,3.2,0,0,0,149.765,54.256Z"/><path class="cls-42" d="M149.627,54.256H125.891V81.58h23.736a3.179,3.179,0,0,0,3.179-3.179V57.435A3.179,3.179,0,0,0,149.627,54.256Z"/><path class="cls-43" d="M149.488,54.256h-23.6V81.421h23.6a3.16,3.16,0,0,0,3.16-3.16V57.416A3.16,3.16,0,0,0,149.488,54.256Z"/><path class="cls-44" d="M149.35,54.256H125.891V81.261H149.35a3.142,3.142,0,0,0,3.142-3.142V57.4A3.142,3.142,0,0,0,149.35,54.256Z"/><path class="cls-45" d="M149.212,54.256H125.891V81.1h23.321a3.123,3.123,0,0,0,3.123-3.123v-20.6A3.123,3.123,0,0,0,149.212,54.256Z"/><path class="cls-46" d="M149.073,54.256H125.891V80.943h23.182a3.1,3.1,0,0,0,3.1-3.1V57.361A3.1,3.1,0,0,0,149.073,54.256Z"/><path class="cls-47" d="M148.935,54.256H125.891V80.783h23.044a3.086,3.086,0,0,0,3.086-3.086V57.342A3.086,3.086,0,0,0,148.935,54.256Z"/><path class="cls-48" d="M148.8,54.256H125.891V80.624H148.8a3.068,3.068,0,0,0,3.068-3.068V57.324A3.068,3.068,0,0,0,148.8,54.256Z"/><path class="cls-49" d="M148.658,54.256H125.891V80.464h22.767a3.049,3.049,0,0,0,3.049-3.049V57.305A3.049,3.049,0,0,0,148.658,54.256Z"/><path class="cls-50" d="M148.519,54.256H125.891V80.305h22.628a3.031,3.031,0,0,0,3.031-3.031V57.287A3.031,3.031,0,0,0,148.519,54.256Z"/><path class="cls-51" d="M148.381,54.256h-22.49v25.89h22.49a3.012,3.012,0,0,0,3.012-3.012V57.268A3.012,3.012,0,0,0,148.381,54.256Z"/><path class="cls-52" d="M148.242,54.256H125.891v25.73h22.351a2.994,2.994,0,0,0,2.994-2.993V57.249A2.994,2.994,0,0,0,148.242,54.256Z"/><path class="cls-53" d="M148.1,54.256H125.891V79.827H148.1a2.975,2.975,0,0,0,2.975-2.975V57.231A2.975,2.975,0,0,0,148.1,54.256Z"/><path class="cls-54" d="M147.965,54.256H125.891V79.668h22.075a2.957,2.957,0,0,0,2.956-2.957v-19.5A2.956,2.956,0,0,0,147.965,54.256Z"/><path class="cls-55" d="M147.827,54.256H125.891V79.508h21.936a2.938,2.938,0,0,0,2.938-2.938V57.194A2.938,2.938,0,0,0,147.827,54.256Z"/><path class="cls-56" d="M147.689,54.256h-21.8V79.349h21.8a2.919,2.919,0,0,0,2.919-2.919V57.175A2.919,2.919,0,0,0,147.689,54.256Z"/><path class="cls-57" d="M147.55,54.256H125.891V79.189H147.55a2.9,2.9,0,0,0,2.9-2.9V57.157A2.9,2.9,0,0,0,147.55,54.256Z"/><path class="cls-58" d="M147.412,54.256H125.891V79.03h21.521a2.882,2.882,0,0,0,2.882-2.882V57.138A2.882,2.882,0,0,0,147.412,54.256Z"/><path class="cls-59" d="M147.273,54.256H125.891V78.871h21.382a2.864,2.864,0,0,0,2.864-2.864V57.12A2.864,2.864,0,0,0,147.273,54.256Z"/><path class="cls-60" d="M147.135,54.256H125.891V78.711h21.244a2.845,2.845,0,0,0,2.845-2.845V57.1A2.845,2.845,0,0,0,147.135,54.256Z"/><path class="cls-61" d="M147,54.256H125.891v24.3H147a2.827,2.827,0,0,0,2.827-2.827V57.083A2.827,2.827,0,0,0,147,54.256Z"/><path class="cls-62" d="M146.858,54.256H125.891V78.392h20.967a2.808,2.808,0,0,0,2.808-2.808V57.064A2.808,2.808,0,0,0,146.858,54.256Z"/><path class="cls-5" d="M146.719,54.256H125.891V78.233h20.828a2.79,2.79,0,0,0,2.79-2.79v-18.4A2.79,2.79,0,0,0,146.719,54.256Z"/><rect class="cls-12" x="100.573" y="49.764" width="50.635" height="29.763" rx="3.463" ry="3.463"/><circle id="_Path_10" data-name="&lt;Path&gt;" class="cls-9" cx="113.674" cy="64.645" r="8.194"/><path id="_Path_11" data-name="&lt;Path&gt;" class="cls-12" d="M116.7,65.108l-5.273,3.044a0.534,0.534,0,0,1-.8-0.462V61.6a0.534,0.534,0,0,1,.8-0.462l5.273,3.044A0.534,0.534,0,0,1,116.7,65.108Z"/><rect class="cls-20" x="124.866" y="58.066" width="22.464" height="2"/><rect class="cls-20" x="124.866" y="63.645" width="22.464" height="2"/><rect class="cls-11" x="124.866" y="69.224" width="11.232" height="2"/><g class="cls-66"><path class="cls-12" d="M202.5,83.625H184.636a2.188,2.188,0,0,0-2.188,2.188v20.966a2.188,2.188,0,0,0,2.188,2.188H202.5V83.625Z"/></g><g class="cls-67"><path class="cls-68" d="M202.5,83.625H184.755a2.173,2.173,0,0,0-2.173,2.173v20.826a2.173,2.173,0,0,0,2.173,2.173H202.5V83.625Z"/></g><g class="cls-69"><path class="cls-70" d="M202.5,83.625H184.874a2.159,2.159,0,0,0-2.159,2.159V106.47a2.158,2.158,0,0,0,2.159,2.159H202.5v-25Z"/></g><g class="cls-71"><path class="cls-72" d="M202.5,83.625h-17.5a2.144,2.144,0,0,0-2.144,2.144v20.546a2.144,2.144,0,0,0,2.144,2.144h17.5V83.625Z"/></g><g class="cls-73"><path class="cls-74" d="M202.5,83.625H185.113a2.129,2.129,0,0,0-2.13,2.129v20.407a2.129,2.129,0,0,0,2.13,2.129H202.5V83.625Z"/></g><g class="cls-75"><path class="cls-76" d="M202.5,83.625H185.232a2.115,2.115,0,0,0-2.115,2.115v20.267a2.115,2.115,0,0,0,2.115,2.115H202.5v-24.5Z"/></g><g class="cls-77"><path class="cls-78" d="M202.5,83.625H185.351a2.1,2.1,0,0,0-2.1,2.1v20.127a2.1,2.1,0,0,0,2.1,2.1H202.5V83.625Z"/></g><g class="cls-79"><path class="cls-80" d="M202.5,83.625H185.47a2.086,2.086,0,0,0-2.086,2.086V105.7a2.086,2.086,0,0,0,2.086,2.086H202.5V83.625Z"/></g><g class="cls-81"><path class="cls-20" d="M202.5,83.625H185.589a2.071,2.071,0,0,0-2.071,2.071v19.847a2.071,2.071,0,0,0,2.071,2.071H202.5V83.625Z"/></g><g class="cls-82"><path class="cls-83" d="M202.5,83.625H185.708a2.057,2.057,0,0,0-2.056,2.057v19.707a2.056,2.056,0,0,0,2.056,2.056H202.5V83.625Z"/></g><g class="cls-84"><path class="cls-85" d="M202.5,83.625h-16.67a2.042,2.042,0,0,0-2.042,2.042v19.567a2.042,2.042,0,0,0,2.042,2.042H202.5V83.625Z"/></g><g class="cls-86"><path class="cls-87" d="M202.5,83.625H185.947a2.027,2.027,0,0,0-2.027,2.027V105.08a2.027,2.027,0,0,0,2.027,2.027H202.5V83.625Z"/></g><g class="cls-88"><path class="cls-89" d="M202.5,83.625H186.066a2.013,2.013,0,0,0-2.013,2.013v19.288a2.013,2.013,0,0,0,2.013,2.013H202.5V83.625Z"/></g><g class="cls-90"><path class="cls-91" d="M202.5,83.625H186.185a2,2,0,0,0-2,2v19.148a2,2,0,0,0,2,2H202.5V83.625Z"/></g><g class="cls-92"><path class="cls-93" d="M202.5,83.625H186.3a1.984,1.984,0,0,0-1.984,1.984v19.008A1.983,1.983,0,0,0,186.3,106.6H202.5V83.625Z"/></g><g class="cls-94"><path class="cls-95" d="M202.5,83.625H186.423a1.969,1.969,0,0,0-1.969,1.969v18.868a1.969,1.969,0,0,0,1.969,1.969H202.5V83.625Z"/></g><g class="cls-96"><path class="cls-97" d="M202.5,83.625H186.543a1.954,1.954,0,0,0-1.954,1.954v18.728a1.954,1.954,0,0,0,1.954,1.954H202.5V83.625Z"/></g><g class="cls-98"><path class="cls-99" d="M202.5,83.625H186.662a1.94,1.94,0,0,0-1.94,1.94v18.588a1.94,1.94,0,0,0,1.94,1.94H202.5V83.625Z"/></g><g class="cls-100"><path class="cls-101" d="M202.5,83.625H186.781a1.925,1.925,0,0,0-1.925,1.925V104a1.925,1.925,0,0,0,1.925,1.925H202.5v-22.3Z"/></g><g class="cls-102"><path class="cls-103" d="M202.5,83.625H186.9a1.911,1.911,0,0,0-1.911,1.91v18.308a1.91,1.91,0,0,0,1.911,1.91h15.6V83.625Z"/></g><g class="cls-104"><path class="cls-105" d="M202.5,83.625H187.019a1.9,1.9,0,0,0-1.9,1.9v18.168a1.9,1.9,0,0,0,1.9,1.9H202.5V83.625Z"/></g><g class="cls-106"><path class="cls-107" d="M202.5,83.625H187.138a1.881,1.881,0,0,0-1.881,1.881v18.029a1.881,1.881,0,0,0,1.881,1.881H202.5V83.625Z"/></g><g class="cls-108"><path class="cls-109" d="M202.5,83.625h-15.24a1.867,1.867,0,0,0-1.867,1.867V103.38a1.867,1.867,0,0,0,1.867,1.867H202.5V83.625Z"/></g><g class="cls-110"><path class="cls-111" d="M202.5,83.625H187.377a1.852,1.852,0,0,0-1.852,1.852v17.749a1.852,1.852,0,0,0,1.852,1.852H202.5V83.625Z"/></g><g class="cls-112"><path class="cls-113" d="M202.5,83.625h-15a1.838,1.838,0,0,0-1.838,1.838v17.609a1.837,1.837,0,0,0,1.838,1.838h15V83.625Z"/></g><g class="cls-114"><path class="cls-115" d="M202.5,83.625H187.615a1.823,1.823,0,0,0-1.823,1.823v17.469a1.823,1.823,0,0,0,1.823,1.823H202.5V83.625Z"/></g><g class="cls-116"><path class="cls-117" d="M202.5,83.625H187.734a1.808,1.808,0,0,0-1.808,1.808v17.329a1.808,1.808,0,0,0,1.808,1.808H202.5V83.625Z"/></g><g class="cls-118"><path class="cls-119" d="M202.5,83.625H187.853a1.794,1.794,0,0,0-1.794,1.794v17.189a1.794,1.794,0,0,0,1.794,1.794H202.5V83.625Z"/></g><g class="cls-120"><path class="cls-121" d="M202.5,83.625H187.973a1.779,1.779,0,0,0-1.779,1.779v17.049a1.779,1.779,0,0,0,1.779,1.779H202.5V83.625Z"/></g><g class="cls-122"><path class="cls-123" d="M202.5,83.625H188.092a1.765,1.765,0,0,0-1.765,1.765V102.3a1.765,1.765,0,0,0,1.765,1.764H202.5V83.625Z"/></g><g class="cls-124"><path class="cls-125" d="M202.5,83.625H188.211a1.75,1.75,0,0,0-1.75,1.75v16.77a1.75,1.75,0,0,0,1.75,1.75H202.5V83.625Z"/></g><g class="cls-126"><path class="cls-127" d="M202.5,83.625H188.33a1.735,1.735,0,0,0-1.735,1.735v16.63a1.735,1.735,0,0,0,1.735,1.735H202.5v-20.1Z"/></g><g class="cls-128"><path class="cls-129" d="M202.5,83.625H188.449a1.721,1.721,0,0,0-1.721,1.721v16.49a1.721,1.721,0,0,0,1.721,1.721H202.5V83.625Z"/></g><g class="cls-130"><path class="cls-7" d="M202.5,83.625H188.569a1.706,1.706,0,0,0-1.706,1.706v16.35a1.706,1.706,0,0,0,1.706,1.706H202.5V83.625Z"/></g><g class="cls-131"><path class="cls-132" d="M202.5,83.625h-13.81A1.692,1.692,0,0,0,187,85.317v16.21a1.691,1.691,0,0,0,1.691,1.692H202.5V83.625Z"/></g><g class="cls-133"><path class="cls-134" d="M202.5,83.625H188.807A1.677,1.677,0,0,0,187.13,85.3v16.07a1.677,1.677,0,0,0,1.677,1.677H202.5V83.625Z"/></g><g class="cls-135"><path class="cls-136" d="M202.5,83.625H188.926a1.662,1.662,0,0,0-1.662,1.662v15.93a1.662,1.662,0,0,0,1.662,1.662H202.5V83.625Z"/></g><g class="cls-137"><path class="cls-138" d="M202.5,83.625H189.045a1.648,1.648,0,0,0-1.648,1.648v15.79a1.648,1.648,0,0,0,1.648,1.648H202.5V83.625Z"/></g><g class="cls-139"><path class="cls-140" d="M202.5,83.625H189.164a1.633,1.633,0,0,0-1.633,1.633v15.65a1.633,1.633,0,0,0,1.633,1.633H202.5V83.625Z"/></g><g class="cls-141"><path class="cls-142" d="M202.5,83.625H189.284a1.619,1.619,0,0,0-1.619,1.619v15.511a1.619,1.619,0,0,0,1.619,1.618H202.5V83.625Z"/></g><g class="cls-143"><path class="cls-144" d="M202.5,83.625H189.4a1.6,1.6,0,0,0-1.6,1.6V100.6a1.6,1.6,0,0,0,1.6,1.6h13.1V83.625Z"/></g><path class="cls-5" d="M202.5,83.625H189.522a1.589,1.589,0,0,0-1.589,1.589v15.231a1.589,1.589,0,0,0,1.589,1.589H202.5V83.625Z"/><rect class="cls-12" x="186.896" y="80.062" width="33.507" height="23.292" rx="2.011" ry="2.011"/><rect class="cls-3" x="189.395" y="82.3" width="28.51" height="17.779"/><polygon class="cls-5" points="193.803 88.84 189.417 95.173 189.395 100.079 200.686 100.079 193.803 88.84"/><polygon class="cls-12" points="194.497 92.139 194.891 92.791 195.586 91.787 193.803 88.84 191.781 91.759 192.406 92.791 192.884 92.101 193.649 93.364 194.497 92.139"/><polygon class="cls-5" points="199.155 97.635 202.491 92.664 207.083 100.079 200.674 100.079 199.155 97.635"/><circle class="cls-4" cx="209.486" cy="88.355" r="3.13"/><polygon class="cls-12" points="203.225 95.963 203.62 96.615 204.315 95.611 202.491 92.664 200.51 95.582 201.134 96.615 201.612 95.924 202.377 97.188 203.225 95.963"/><rect class="cls-12" x="79.679" y="107.534" width="41.923" height="36.584" rx="3.684" ry="3.684"/><path class="cls-9" d="M118.111,107.534H83.17a3.491,3.491,0,0,0-3.491,3.491V115H121.6v-3.975A3.491,3.491,0,0,0,118.111,107.534Z"/><circle class="cls-12" cx="84.393" cy="111.267" r="0.639"/><circle class="cls-12" cx="87.171" cy="111.267" r="0.639"/><circle class="cls-12" cx="87.171" cy="111.267" r="0.639"/><circle class="cls-12" cx="89.949" cy="111.267" r="0.64"/><polygon class="cls-11" points="98.111 128.187 93.283 130.87 94.347 142.737 106.025 142.737 107.805 131.184 102.411 128.187 98.111 128.187"/><polygon class="cls-8" points="102.411 128.32 100.261 132.253 98.111 128.32 98.111 125.528 102.411 125.528 102.411 128.32"/><path class="cls-13" d="M104.265,119.731a2.327,2.327,0,0,0-.216-0.521l-0.527-1.029a1.4,1.4,0,0,0-1.209-.714,6.072,6.072,0,0,0-1.536-.54,1.985,1.985,0,0,0-.992.268,1.836,1.836,0,0,1-.392.177,3.36,3.36,0,0,1-.725.008,1.369,1.369,0,0,0-1.249,1,0.96,0.96,0,0,1-.088.272,0.943,0.943,0,0,1-.167.179c-0.737.705-.3,1.887-0.185,2.754a1.946,1.946,0,0,0,.41,1.354l-0.2-.049a3.464,3.464,0,0,0,1.814.88,10.324,10.324,0,0,0,2.04.113l2.463-.026a0.723,0.723,0,0,0,.447-0.1,0.708,0.708,0,0,0,.2-0.479c0.13-.936.044-1.87,0.123-2.82A2.328,2.328,0,0,0,104.265,119.731Z"/><path class="cls-145" d="M98.111,127.132l0.6,1.046a2.212,2.212,0,0,0,3.7.21v-2.861h-4.3v1.6Z"/><path class="cls-8" d="M97.765,121.216v3.276a4.208,4.208,0,0,0,.563,2.1l0.632,1.095a2.216,2.216,0,0,0,1.92,1.109h0a2.217,2.217,0,0,0,1.894-1.066l0.128-.21a4.208,4.208,0,0,0,.611-2.183V119.3H97.846Z"/><path class="cls-8" d="M97.809,124.977l-0.658-.347a2.156,2.156,0,0,1-.373-1.707s0.24-.587.693-0.32l0.64,0.64Z"/><path class="cls-8" d="M103.354,124.977l0.658-.347a2.156,2.156,0,0,0,.373-1.707s-0.24-.587-0.694-0.32l-0.64.64Z"/><path class="cls-13" d="M97.582,121.745a10.891,10.891,0,0,1,.124,1.54c-0.006.2-.091,0.8,0.344,0.641a0.358,0.358,0,0,0,.187-0.333c0.033-.5-0.379-0.921-0.143-1.379a3.885,3.885,0,0,0,.649-0.929,2.748,2.748,0,0,0-.127-0.824,0.806,0.806,0,0,1,.154-0.609,0.545,0.545,0,0,1,.578-0.185,1.444,1.444,0,0,1,.471.405,1.289,1.289,0,0,0,1.343.269,4.79,4.79,0,0,0,.75-0.467,1.056,1.056,0,0,1,.837-0.191,1.215,1.215,0,0,1,.674,1.008,4.739,4.739,0,0,1,.146,1.4,9.656,9.656,0,0,1-.335,1.059,0.914,0.914,0,0,0-.034.264,0.988,0.988,0,0,0,.181.442,0.1,0.1,0,0,0,.045.047,0.1,0.1,0,0,0,.1-0.033,1.489,1.489,0,0,0,.373-0.88,2.351,2.351,0,0,0,.111-1.136c-0.164-.871.044-1.778-0.1-2.653a0.543,0.543,0,0,0-.09-0.252,0.56,0.56,0,0,0-.27-0.159,10.618,10.618,0,0,0-3.9-.327,2.743,2.743,0,0,0-1.341.285,1.878,1.878,0,0,0-.794,1.37A6.527,6.527,0,0,0,97.582,121.745Z"/><path class="cls-8" d="M86.258,137.9l-0.192-.548-5.788-3.708h0a1.017,1.017,0,0,1,1.256-.144l1.149,0.715,0.414-.09a1.3,1.3,0,0,1,.975.175l0.568,0.363,1.915,0.577a1.735,1.735,0,0,1,1.12,1.042l0.409,1.069Z"/><path class="cls-8" d="M114.265,137.9l0.192-.548,5.788-3.708h0a1.017,1.017,0,0,0-1.256-.144l-1.149.715-0.414-.09a1.3,1.3,0,0,0-.975.175l-0.567.363-1.915.577a1.735,1.735,0,0,0-1.12,1.042l-0.408,1.069Z"/><path class="cls-11" d="M98.111,128.187l-5.7,3.168a3.432,3.432,0,0,0-1.755,2.74l-0.471,6.2-1.834-3.016-2.446.734,2.178,4.828,4.77-.1,1.326-6.6,3.934-5.839v-2.109Z"/><path class="cls-11" d="M102.411,128.187l5.7,3.168a3.432,3.432,0,0,1,1.755,2.74l0.471,6.2,1.834-3.016,2.446,0.734-2.18,4.833-4.762-.078-1.332-6.63-3.934-5.839v-2.109Z"/><polygon class="cls-12" points="98.111 128.187 96.845 128.89 98.336 134.201 100.261 132.253 98.111 128.187"/><polygon class="cls-12" points="102.411 128.187 103.677 128.89 102.187 134.201 100.261 132.253 102.411 128.187"/><path class="cls-13" d="M99.368,125.815c-0.08.158-.107,0.339-0.191,0.5a0.4,0.4,0,0,1-.428.239,0.548,0.548,0,0,1-.279-0.5,7.862,7.862,0,0,0-.122-1.658,2.1,2.1,0,0,1-.129-0.428c-0.016-.136,0-0.276-0.023-0.41a0.31,0.31,0,0,0-.267-0.269,0.283,0.283,0,0,0-.248.233,0.876,0.876,0,0,0,.022.363,6.335,6.335,0,0,1,.132,1.785,4.282,4.282,0,0,0,.367,1.727,2.72,2.72,0,0,0,.249.565,2.1,2.1,0,0,0,1.275.859,6.25,6.25,0,0,0,1.564.139,2.522,2.522,0,0,0,1.01-.134c0.922-.394,1.214-2.129,1.313-2.983a5.148,5.148,0,0,0-.066-1.077,6.954,6.954,0,0,1,.166-1.36,0.183,0.183,0,0,0-.032-0.165,0.293,0.293,0,0,1-.164-0.108,1.017,1.017,0,0,0-.346.507,1.2,1.2,0,0,0-.018.279,3.731,3.731,0,0,1-.076,1.095,10.535,10.535,0,0,0-.3,1.258,0.53,0.53,0,0,1-.287.493,0.352,0.352,0,0,1-.374-0.237,1.3,1.3,0,0,1-.055-0.476,0.726,0.726,0,0,0-.123-0.457,0.822,0.822,0,0,0-.6-0.213C100.675,125.327,99.762,125.028,99.368,125.815Z"/><path class="cls-8" d="M99.467,126.257h0.447a0.685,0.685,0,0,0,.452-0.17l0.272-.239,0.3,0.249a0.685,0.685,0,0,0,.44.16h0.434a1.211,1.211,0,0,1-1.286,1.236C99.645,127.47,99.76,126.954,99.467,126.257Z"/><polygon class="cls-12" points="85.903 138.01 88.348 137.277 88.962 138.286 86.369 139.044 85.903 138.01"/><polygon class="cls-12" points="114.665 138.01 112.22 137.277 111.606 138.286 114.199 139.044 114.665 138.01"/><circle class="cls-146" cx="85.562" cy="120.593" r="2.307"/><polygon class="cls-12" points="86.192 120.593 84.933 121.32 84.933 119.866 86.192 120.593"/><g id="_Group_9" data-name="&lt;Group&gt;"><g id="_Group_10" data-name="&lt;Group&gt;"><g id="_Group_11" data-name="&lt;Group&gt;"><path id="_Rectangle_6" data-name="&lt;Rectangle&gt;" class="cls-5" d="M149.124,161.423H166a2.086,2.086,0,0,1,2.086,2.086v9.906a1.175,1.175,0,0,1-1.175,1.175H147.976a1.159,1.159,0,0,1-1.159-1.159v-9.7A2.307,2.307,0,0,1,149.124,161.423Z" transform="translate(314.903 336.012) rotate(180)"/></g></g><g id="_Group_12" data-name="&lt;Group&gt;"><g id="_Group_13" data-name="&lt;Group&gt;"><path id="_Path_12" data-name="&lt;Path&gt;" class="cls-5" d="M147.058,161.9l8.905-7.256a2.619,2.619,0,0,1,3.091,0l8.42,6.962Z"/></g></g><g id="_Group_14" data-name="&lt;Group&gt;"><g id="_Group_15" data-name="&lt;Group&gt;"><path id="_Path_13" data-name="&lt;Path&gt;" class="cls-12" d="M153.018,151.352l-3.116,3.026v16.612h14.757V152.6a1.25,1.25,0,0,0-1.25-1.25H153.018Z"/></g></g><g id="_Group_16" data-name="&lt;Group&gt;" class="cls-147"><g id="_Group_17" data-name="&lt;Group&gt;"><polygon id="_Path_14" data-name="&lt;Path&gt;" class="cls-5" points="152.833 154.064 149.902 157.415 149.902 154.378 152.833 154.064"/></g></g><g id="_Group_18" data-name="&lt;Group&gt;"><g id="_Group_19" data-name="&lt;Group&gt;"><path id="_Path_15" data-name="&lt;Path&gt;" class="cls-5" d="M153.018,151.352l-3.116,3.026h2.285a0.831,0.831,0,0,0,.831-0.831v-2.195Z"/></g></g><g id="_Group_20" data-name="&lt;Group&gt;"><g id="_Group_21" data-name="&lt;Group&gt;"><path id="_Path_16" data-name="&lt;Path&gt;" class="cls-3" d="M147.433,174.641s8.214-5.73,8.214-6.249l-8.589-6.493a4.9,4.9,0,0,0-.241,1.7v10.462A0.585,0.585,0,0,0,147.433,174.641Z"/></g></g><g id="_Group_22" data-name="&lt;Group&gt;"><g id="_Group_23" data-name="&lt;Group&gt;"><path id="_Path_17" data-name="&lt;Path&gt;" class="cls-3" d="M167.626,174.641s-8.034-5.852-8.034-6.371l8.339-6.127a2.309,2.309,0,0,1,.311,1.455v10.462A0.585,0.585,0,0,1,167.626,174.641Z"/></g></g><g id="_Group_24" data-name="&lt;Group&gt;"><g id="_Group_25" data-name="&lt;Group&gt;"><path id="_Path_18" data-name="&lt;Path&gt;" class="cls-5" d="M147.349,174.654l8.644-7.107a2.59,2.59,0,0,1,3.056,0l8.644,7.107H147.349Z"/></g></g><g id="_Group_26" data-name="&lt;Group&gt;"><g id="_Group_27" data-name="&lt;Group&gt;"><g id="_Group_28" data-name="&lt;Group&gt;"><path id="_Compound_Path_" data-name="&lt;Compound Path&gt;" class="cls-3" d="M159.274,162.069a4.048,4.048,0,0,1-1.976.444,3.305,3.305,0,0,1-3.365-3.465,4.062,4.062,0,0,1,4.053-4.264,3.084,3.084,0,0,1,3.231,3.21c0,1.666-.933,2.643-1.976,2.643a0.822,0.822,0,0,1-.822-0.977h-0.044a1.744,1.744,0,0,1-1.566.977,1.259,1.259,0,0,1-1.2-1.4,2.621,2.621,0,0,1,2.631-2.631,2.92,2.92,0,0,1,1.189.233l-0.378,2.009c-0.166.845-.033,1.233,0.333,1.244,0.567,0.011,1.2-.744,1.2-2.032A2.545,2.545,0,0,0,157.9,155.3a3.409,3.409,0,0,0-3.331,3.687,2.774,2.774,0,0,0,2.854,3,3.469,3.469,0,0,0,1.677-.389Zm-0.611-4.8a1.806,1.806,0,0,0-2.321,1.92,0.733,0.733,0,0,0,.733.844,1.772,1.772,0,0,0,1.355-1.511Z"/></g></g></g></g><path id="_Compound_Path_2" data-name="&lt;Compound Path&gt;" class="cls-11" d="M107.837,95.989h1.075a0.394,0.394,0,0,0,.394-0.394V94.224a0.394,0.394,0,0,0-.394-0.393h-0.841a0.331,0.331,0,0,1-.308-0.22q-0.045-.118-0.1-0.232A0.331,0.331,0,0,1,107.726,93l0.594-.595a0.394,0.394,0,0,0,0-.557l-0.97-.969a0.394,0.394,0,0,0-.557,0l-0.6.6a0.325,0.325,0,0,1-.359.069c-0.086-.037-0.178-0.074-0.258-0.1a0.324,0.324,0,0,1-.206-0.3V90.3a0.394,0.394,0,0,0-.394-0.394h-1.37a0.394,0.394,0,0,0-.394.394v0.841a0.331,0.331,0,0,1-.22.308q-0.123.046-.244,0.1a0.33,0.33,0,0,1-.374-0.06l-0.6-.593a0.394,0.394,0,0,0-.557,0l-0.966.972a0.394,0.394,0,0,0,0,.557l0.6,0.6a0.325,0.325,0,0,1,.07.359c-0.036.086-.073,0.178-0.1,0.258a0.324,0.324,0,0,1-.3.207l-0.85,0a0.394,0.394,0,0,0-.393.395l0,1.371a0.394,0.394,0,0,0,.395.393l0.841,0a0.332,0.332,0,0,1,.308.22q0.045,0.118.1,0.232a0.331,0.331,0,0,1-.061.374l-0.594.6a0.394,0.394,0,0,0,0,.557l0.971,0.967a0.394,0.394,0,0,0,.557,0l0.6-.6a0.325,0.325,0,0,1,.359-0.069c0.085,0.036.178,0.073,0.257,0.1a0.324,0.324,0,0,1,.207.3v0.85a0.394,0.394,0,0,0,.395.393l1.37,0a0.394,0.394,0,0,0,.393-0.394V98.688a0.331,0.331,0,0,1,.22-0.308q0.118-.044.232-0.1a0.331,0.331,0,0,1,.374.061l0.6,0.594a0.394,0.394,0,0,0,.557,0l0.968-.97a0.394,0.394,0,0,0,0-.557l-0.6-.6a0.326,0.326,0,0,1-.069-0.359C107.742,96.248,107.832,96,107.837,95.989Zm-5.454-1.426a1.942,1.942,0,1,1,1.209,2.16A1.942,1.942,0,0,1,102.383,94.563Z"/><rect class="cls-12" x="95.071" y="3.813" width="86.357" height="28.158" rx="4.055" ry="4.055"/><path class="cls-9" d="M177.373,3.813H99.126a4.055,4.055,0,0,0-4.055,4.055v2.6h86.357v-2.6A4.055,4.055,0,0,0,177.373,3.813Z"/><circle class="cls-4" cx="107.842" cy="21.568" r="6.596"/><rect class="cls-20" x="117.992" y="15.515" width="56.173" height="1.777"/><rect class="cls-20" x="117.992" y="20.688" width="56.173" height="1.777"/><rect class="cls-63" x="117.992" y="25.861" width="21.065" height="1.777"/><circle class="cls-12" cx="102.089" cy="7.142" r="0.844"/><circle class="cls-12" cx="105.754" cy="7.142" r="0.844"/><circle class="cls-12" cx="109.418" cy="7.142" r="0.844"/><rect class="cls-11" x="195.097" y="5.397" width="12.381" height="12.381" rx="2.612" ry="2.612"/><path class="cls-12" d="M198.044,11.956v0.018l1.677,0.55v0.933l-2.685-1.094V11.555l2.685-1.094v0.929Z"/><path class="cls-12" d="M201.015,13.989h-1.036l1.51-4.8h1.036Z"/><path class="cls-12" d="M204.53,11.968V11.95l-1.662-.553v-0.93l2.67,1.094v0.808l-2.67,1.094V12.533Z"/><g id="_Group_29" data-name="&lt;Group&gt;"><path id="_Path_19" data-name="&lt;Path&gt;" class="cls-11" d="M234.8,100.061l-1.255-.836a0.522,0.522,0,0,0-.579,0l-1.255.836a0.242,0.242,0,0,1-.333-0.224v-5.5h3.754v5.5A0.242,0.242,0,0,1,234.8,100.061Z"/><path id="_Path_20" data-name="&lt;Path&gt;" class="cls-19" d="M237.161,96.887l-3.771-1.921a0.251,0.251,0,0,0-.234,0l-3.72,2.018a0.251,0.251,0,0,1-.368-0.26l0.661-4.18a0.251,0.251,0,0,0-.075-0.221l-3.068-2.914a0.251,0.251,0,0,1,.133-0.43l4.18-.663a0.251,0.251,0,0,0,.187-0.14l1.823-3.819a0.251,0.251,0,0,1,.45-0.006l1.922,3.77a0.252,0.252,0,0,0,.191.135l4.2,0.554a0.251,0.251,0,0,1,.145.427l-2.992,2.993a0.251,0.251,0,0,0-.069.223l0.769,4.162A0.251,0.251,0,0,1,237.161,96.887Z"/></g><circle id="_Path_21" data-name="&lt;Path&gt;" class="cls-11" cx="80.277" cy="54.208" r="6.48"/><g id="_Group_30" data-name="&lt;Group&gt;"><polygon id="_Path_22" data-name="&lt;Path&gt;" class="cls-12" points="79.421 56.834 77.17 54.583 78.456 53.297 79.421 54.262 82.099 51.582 83.385 52.868 79.421 56.834"/></g><g id="_Group_31" data-name="&lt;Group&gt;"><polygon id="_Path_23" data-name="&lt;Path&gt;" class="cls-148" points="175.871 139.654 174.156 137.383 177.586 137.383 175.871 139.654"/><polygon id="_Path_24" data-name="&lt;Path&gt;" class="cls-148" points="172.46 139.654 170.745 137.383 174.174 137.383 172.46 139.654"/><polygon id="_Path_25" data-name="&lt;Path&gt;" class="cls-148" points="174.165 145.45 169.048 139.63 179.283 139.63 174.165 145.45"/><polygon id="_Path_26" data-name="&lt;Path&gt;" class="cls-149" points="174.165 145.45 172.46 139.63 175.889 139.63 174.165 145.45"/><polygon id="_Path_27" data-name="&lt;Path&gt;" class="cls-149" points="170.745 137.383 169.048 139.63 172.442 139.63 170.745 137.383"/><polygon id="_Path_28" data-name="&lt;Path&gt;" class="cls-149" points="174.156 137.383 172.46 139.63 175.853 139.63 174.156 137.383"/><polygon id="_Path_29" data-name="&lt;Path&gt;" class="cls-149" points="177.586 137.383 175.889 139.63 179.283 139.63 177.586 137.383"/></g></g></g></g></svg> \ No newline at end of file diff --git a/static/base/images/issues.jpg b/static/base/images/issues.jpg deleted file mode 100644 index ab0ee60a..00000000 Binary files a/static/base/images/issues.jpg and /dev/null differ diff --git a/static/base/images/pagetop.png b/static/base/images/pagetop.png deleted file mode 100644 index 71242a86..00000000 Binary files a/static/base/images/pagetop.png and /dev/null differ diff --git a/static/base/images/welcome.jpg b/static/base/images/welcome.jpg deleted file mode 100644 index 05d89e33..00000000 Binary files a/static/base/images/welcome.jpg and /dev/null differ diff --git a/static/base/js/menu.js b/static/base/js/menu.js deleted file mode 100644 index 0565f194..00000000 --- a/static/base/js/menu.js +++ /dev/null @@ -1,94 +0,0 @@ -function menu__showChildren(nav, children) { - let submenu = children[0].querySelector('.menu__subs'); - submenu.classList.add('active'); - submenu.style.animation = 'slideLeft 0.5s ease forwards'; - - let title = children[0].querySelector('i').parentNode.childNodes[0].textContent; - nav.querySelector('.menu__title').innerHTML = title; - nav.querySelector('.menu__header').classList.add('active'); -} - -function menu__hideChildren(nav, children) { - let submenu = children[0].querySelector('.menu__subs'); - submenu.style.animation = 'slideRight 0.5s ease forwards'; - setTimeout(() => { - submenu.classList.remove('active'); - submenu.style.removeProperty('animation'); - }, 300); - - children.shift(); - if (children.length > 0) { - let title = children[0].querySelector('i').parentNode.childNodes[0].textContent; - nav.querySelector('.menu__title').innerHTML = title; - } else { - nav.querySelector('.menu__header').classList.remove('active'); - nav.querySelector('.menu__title').innerHTML = ''; - } -} - -function menu__toggle(nav, overlay) { - nav.classList.toggle('active'); - overlay.classList.toggle('active'); -} - -function menu__reset(menu, nav, overlay) { - menu__toggle(nav, overlay); - setTimeout(() => { - nav.querySelector('.menu__header').classList.remove('active'); - nav.querySelector('.menu__title').innerHTML = ''; - menu.querySelectorAll('.menu__subs').forEach(submenu => { - submenu.classList.remove('active'); - submenu.style.removeProperty('animation'); - }); - }, 300); - return []; -} - -document.querySelectorAll('.menu__container').forEach(menu => { - - let menuChildren = []; - const menuNav = menu.querySelector('.menu__nav'); - const menuOverlay = menu.querySelector('.menu__overlay'); - - menu.querySelector('.menu__section').addEventListener('click', (e) => { - if (menuNav.classList.contains('active')) { - let target = e.target.closest('.menu__children'); - if (target && target != menuChildren[0]) { - menuChildren.unshift(target); - menu__showChildren(menuNav, menuChildren); - } - } - }); - - menu.querySelector('.menu__arrow').addEventListener('click', () => { - menu__hideChildren(menuNav, menuChildren); - }); - - menu.querySelector('.menu__close').addEventListener('click', () => { - menuChildren = menu__reset(menu, menuNav, menuOverlay); - }); - - menu.querySelectorAll('.menu__link > a[target="_blank"]').forEach(link => { - link.addEventListener('click', (e) => { - menuChildren = menu__reset(menu, menuNav, menuOverlay); - e.target.blur(); - }); - }); - - menu.querySelector('.menu__trigger').addEventListener('click', () => { - menu__toggle(menuNav, menuOverlay); - }); - - menuOverlay.addEventListener('click', () => { - menu__toggle(menuNav, menuOverlay); - }); - - window.onresize = function () { - if (menuNav.classList.contains('active')) { - var fontSizeRoot = parseFloat(getComputedStyle(document.documentElement).fontSize); - if (this.innerWidth >= 62 * fontSizeRoot) { - menuChildren = menu__reset(menu, menuNav, menuOverlay); - } - } - }; -}); diff --git a/static/base/pagetop-logo.svg b/static/base/pagetop-logo.svg deleted file mode 100644 index 3666bf3a..00000000 --- a/static/base/pagetop-logo.svg +++ /dev/null @@ -1,14 +0,0 @@ -<svg width="16.14mm" height="16.14mm" viewBox="0 0 1614 1614" xmlns="http://www.w3.org/2000/svg" aria-label="PageTop Logo" role="img"> -<path fill="rgb(255,184,75)" d="M 633,61 L 633,61 C 579,61 527,75 480,102 433,129 395,167 368,214 341,261 327,313 327,367 L 327,1244 327,1245 C 327,1299 341,1351 368,1398 395,1445 433,1483 480,1510 527,1537 579,1551 633,1551 L 982,1550 982,1551 C 1036,1551 1088,1537 1135,1510 1182,1483 1220,1445 1247,1398 1274,1351 1288,1299 1288,1245 L 1288,367 1288,367 1288,367 C 1288,313 1274,261 1247,214 1220,167 1182,129 1135,102 1088,75 1036,61 982,61 L 633,61 Z" /> -<path fill="rgb(158,96,0)" d="M 1389,573 L 1328,573 1328,460 1449,460 1449,573 1389,573 Z M 1491,627 L 1430,627 1430,404 1551,404 1551,627 1491,627 Z M 222,573 L 161,573 161,460 282,460 282,573 222,573 Z M 120,627 L 59,627 59,404 180,404 180,627 120,627 Z" /> -<path fill="rgb(150,0,184)" d="M 678,1040 L 678,1040 C 645,1040 612,1049 583,1065 554,1082 530,1106 513,1135 497,1164 488,1197 488,1230 L 488,1230 488,1230 C 488,1263 497,1296 513,1325 530,1354 554,1378 583,1395 612,1411 645,1420 678,1420 L 940,1420 940,1420 C 973,1420 1006,1411 1035,1395 1064,1378 1088,1354 1105,1325 1121,1296 1130,1263 1130,1230 L 1130,1230 1130,1230 1130,1230 C 1130,1197 1121,1164 1105,1135 1088,1106 1064,1082 1035,1065 1006,1049 973,1040 940,1040 L 678,1040 Z M 488,1040 L 488,1040 488,1040 488,1040 488,1040 488,1040 488,1238 488,1238 488,1238 488,1238 488,1238 1130,1238 1130,1238 1130,1238 1130,1238 1130,1238 1130,1238 1130,1040 1130,1040 1130,1040 1130,1040 1130,1040 488,1040 Z" /> -<path fill="rgb(255,255,255)" d="M 518,1128 L 488,1128 488,1066 547,1066 547,1128 518,1128 Z M 966,1128 L 908,1128 908,1066 1024,1066 1024,1128 966,1128 Z" /> -<path fill="rgb(221,255,149)" d="M 898,71 C 940,48 987,36 1035,36 1086,36 1137,50 1181,77 1226,104 1263,142 1289,189 1314,236 1328,288 1328,342 1328,396 1314,448 1289,495 1281,509 1272,522 1262,535 L 898,71 Z M 1337,429 C 1307,460 1272,480 1233,488 1192,496 1148,490 1107,470 1066,451 1029,418 999,375 969,332 948,281 938,227 927,173 928,117 940,66 943,51 948,36 953,22 L 1337,429 Z" /> -<path fill="rgb(146,128,99)" d="M 703,99 C 717,121 722,149 719,178 715,208 702,238 682,267 661,295 634,320 602,340 571,360 536,373 501,379 467,385 434,383 405,373 377,363 355,346 341,323 327,301 322,273 325,244 329,214 342,184 362,155 383,127 410,102 442,82 473,62 508,49 543,43 577,37 610,39 639,49 667,59 689,76 703,99 L 703,99 Z" /> -<path fill="rgb(146,128,99)" d="M 672,550 C 683,568 685,590 678,615 671,640 655,668 632,694 609,720 580,745 547,765 514,785 479,801 446,810 412,819 381,821 355,816 329,811 310,799 299,782 288,765 286,742 293,717 301,692 316,665 339,638 362,612 391,588 424,567 457,547 492,531 526,523 559,514 591,511 616,516 642,521 661,533 672,550 L 672,550 Z" /> -<path fill="rgb(146,128,99)" d="M 455,160 L 456,160 C 430,160 404,167 381,180 359,193 340,212 327,234 314,257 307,283 307,309 L 307,580 307,580 C 307,606 314,632 327,655 340,677 359,696 381,709 404,722 430,729 456,729 L 529,729 529,729 C 555,729 581,722 604,709 626,696 645,677 658,655 671,632 678,606 678,580 L 677,308 678,309 678,309 C 678,283 671,257 658,234 645,212 626,193 604,180 581,167 555,160 529,160 L 455,160 Z" /> -<path fill="rgb(240,0,0)" d="M 698,1332 L 699,1332 C 696,1332 694,1333 691,1334 689,1335 687,1337 686,1339 685,1342 684,1344 684,1347 L 684,1405 684,1405 C 684,1408 685,1410 686,1413 687,1415 689,1417 691,1418 694,1419 696,1420 699,1420 L 914,1419 914,1420 C 917,1420 919,1419 922,1418 924,1417 926,1415 927,1413 928,1410 929,1408 929,1405 L 929,1346 929,1347 929,1347 C 929,1344 928,1342 927,1339 926,1337 924,1335 922,1334 919,1333 917,1332 914,1332 L 698,1332 Z M 643,780 C 643,797 638,814 630,830 621,845 608,858 593,867 577,875 560,880 543,880 525,880 508,875 492,867 477,858 464,845 455,830 447,814 442,797 442,780 442,762 447,745 455,729 464,714 477,701 492,692 508,684 525,679 542,679 560,679 577,684 593,692 608,701 621,714 630,729 638,745 643,762 643,779 L 643,780 Z M 1171,780 C 1171,797 1166,814 1158,830 1149,845 1136,858 1121,867 1105,875 1088,880 1071,880 1053,880 1036,875 1020,867 1005,858 992,845 983,830 975,814 970,797 970,780 970,762 975,745 983,729 992,714 1005,701 1020,692 1036,684 1053,679 1071,679 1088,679 1105,684 1121,692 1136,701 1149,714 1158,729 1166,745 1171,762 1171,779 L 1171,780 Z" /> -<path fill="rgb(10,11,9)" d="M 1573,357 L 1415,357 C 1400,357 1388,369 1388,383 L 1388,410 1335,410 1335,357 C 1335,167 1181,13 992,13 L 621,13 C 432,13 278,167 278,357 L 278,410 225,410 225,383 C 225,369 213,357 198,357 L 40,357 C 25,357 13,369 13,383 L 13,648 C 13,662 25,674 40,674 L 198,674 C 213,674 225,662 225,648 L 225,621 278,621 278,1256 C 278,1446 432,1600 621,1600 L 992,1600 C 1181,1600 1335,1446 1335,1256 L 1335,621 1388,621 1388,648 C 1388,662 1400,674 1415,674 L 1573,674 C 1588,674 1600,662 1600,648 L 1600,383 C 1600,369 1588,357 1573,357 L 1573,357 1573,357 Z M 66,410 L 172,410 172,621 66,621 66,410 66,410 Z M 1282,357 L 1282,488 C 1247,485 1213,477 1181,464 L 1196,437 C 1203,425 1199,409 1186,401 1174,394 1158,398 1150,411 L 1133,440 C 1105,423 1079,401 1056,376 L 1075,361 C 1087,352 1089,335 1079,324 1070,313 1054,311 1042,320 L 1023,335 C 1000,301 981,263 967,221 L 1011,196 C 1023,189 1028,172 1021,160 1013,147 997,143 984,150 L 953,168 C 945,136 941,102 940,66 L 992,66 C 1152,66 1282,197 1282,357 L 1282,357 1282,357 Z M 621,66 L 674,66 674,225 648,225 C 633,225 621,237 621,251 621,266 633,278 648,278 L 674,278 674,357 648,357 C 633,357 621,369 621,383 621,398 633,410 648,410 L 674,410 674,489 648,489 C 633,489 621,501 621,516 621,530 633,542 648,542 L 664,542 C 651,582 626,623 600,662 583,653 563,648 542,648 469,648 410,707 410,780 410,787 411,794 412,801 388,805 361,806 331,806 L 331,357 C 331,197 461,66 621,66 L 621,66 621,66 Z M 621,780 C 621,824 586,859 542,859 498,859 463,824 463,780 463,736 498,701 542,701 586,701 621,736 621,780 L 621,780 621,780 Z M 225,463 L 278,463 278,569 225,569 225,463 225,463 Z M 992,1547 L 621,1547 C 461,1547 331,1416 331,1256 L 331,859 C 367,859 400,858 431,851 454,888 495,912 542,912 615,912 674,853 674,780 674,747 662,718 642,695 675,645 706,594 720,542 L 780,542 C 795,542 807,530 807,516 807,501 795,489 780,489 L 727,489 727,410 780,410 C 795,410 807,398 807,383 807,369 795,357 780,357 L 727,357 727,278 780,278 C 795,278 807,266 807,251 807,237 795,225 780,225 L 727,225 727,66 887,66 C 889,111 895,155 905,196 L 869,217 C 856,224 852,240 859,253 864,261 873,266 882,266 887,266 891,265 895,263 L 921,248 C 937,291 958,331 983,367 L 938,403 C 926,412 925,429 934,440 939,447 947,450 954,450 960,450 966,448 971,444 L 1016,408 C 1043,438 1074,465 1108,485 L 1084,527 C 1076,539 1081,555 1093,563 1098,565 1102,566 1107,566 1116,566 1125,561 1129,553 L 1155,509 C 1194,527 1237,538 1282,541 L 1282,1256 C 1282,1416 1152,1547 992,1547 L 992,1547 992,1547 Z M 1335,463 L 1388,463 1388,569 1335,569 1335,463 1335,463 Z M 1441,410 L 1547,410 1547,621 1441,621 1441,410 1441,410 Z" /> -<path fill="rgb(10,11,9)" d="M 1150,1018 L 463,1018 C 448,1018 436,1030 436,1044 L 436,1177 C 436,1348 545,1468 701,1468 L 912,1468 C 1068,1468 1177,1348 1177,1177 L 1177,1044 C 1177,1030 1165,1018 1150,1018 L 1150,1018 1150,1018 Z M 912,1071 L 1018,1071 1018,1124 912,1124 912,1071 912,1071 Z M 489,1071 L 542,1071 542,1124 489,1124 489,1071 489,1071 Z M 701,1415 L 700,1415 C 701,1385 704,1352 718,1343 731,1335 759,1341 795,1359 802,1363 811,1363 818,1359 854,1341 882,1335 895,1343 909,1352 912,1385 913,1415 L 912,1415 701,1415 701,1415 701,1415 Z M 1124,1177 C 1124,1296 1061,1384 966,1408 964,1365 958,1320 922,1298 894,1281 856,1283 807,1306 757,1283 719,1281 691,1298 655,1320 649,1365 647,1408 552,1384 489,1296 489,1177 L 569,1177 C 583,1177 595,1165 595,1150 L 595,1071 859,1071 859,1150 C 859,1165 871,1177 886,1177 L 1044,1177 C 1059,1177 1071,1165 1071,1150 L 1071,1071 1124,1071 1124,1177 1124,1177 1124,1177 Z" /> -<path fill="rgb(10,11,9)" d="M 1071,648 C 998,648 939,707 939,780 939,853 998,912 1071,912 1144,912 1203,853 1203,780 1203,707 1144,648 1071,648 L 1071,648 1071,648 Z M 1071,859 C 1027,859 992,824 992,780 992,736 1027,701 1071,701 1115,701 1150,736 1150,780 1150,824 1115,859 1071,859 L 1071,859 1071,859 Z" /> -</svg>