commit a8c0bb1641970756933c9dbe94356cd1a95d8d9c Author: august kline Date: Wed Nov 13 21:41:12 2024 -0500 Initial commit diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..abd3415 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a35c129 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/index +.env diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..23b6efe --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3339 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[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", + "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 = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", +] + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "axum" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +dependencies = [ + "async-trait", + "axum-core", + "axum-macros", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa 1.0.11", + "matchit", + "memchr", + "mime", + "multer", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.1", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-extra" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c3220b188aea709cf1b6c5f9b01c3bd936bb08bd2b5184a12b35ac8131b1f9" +dependencies = [ + "axum", + "axum-core", + "bytes", + "cookie", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "multer", + "pin-project-lite", + "serde", + "serde_html_form", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[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 0.52.6", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "bitpacking" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c1d3e2bfd8d06048a179f7b17afc3188effa10385e7b00dc65af6aae732ea92" +dependencies = [ + "crunchy", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[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 = "blogdb" +version = "0.1.0" +source = "git+https://git.augustkline.com/august/blogdb#d7798783ba50735dbae5a68d97384918be2956eb" +dependencies = [ + "anyhow", + "argon2", + "infer", + "mime_guess", + "rand 0.8.5", + "rand_chacha 0.3.1", + "sqlx", + "tokio", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "cc" +version = "1.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "census" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[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 = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constcat" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4938185353434999ef52c81753c8cca8955ed38042fc29913db3751916f3b7ab" + +[[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.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "aes-gcm", + "base64", + "percent-encoding", + "rand 0.8.5", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[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-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +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 = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[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 0.6.4", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.79", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[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 2.0.79", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +dependencies = [ + "serde", +] + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +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 = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "evie" +version = "0.1.0" +dependencies = [ + "anyhow", + "argon2", + "axum", + "axum-extra", + "blogdb", + "constcat", + "dotenvy", + "futures", + "glob", + "http-body", + "lol_html", + "mime_guess", + "phf 0.11.2", + "phf_codegen 0.11.2", + "serde", + "serde_json", + "sqlx", + "tantivy", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "fastdivide" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afc2bd4d5a73106dd53d10d73d3401c2f32730ba2c0b93ddb888a8983680471" + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + +[[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 = "fs4" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e180ac76c23b45e767bd7ae9579bc0bb458618c4bc71835926e098e61d15f8" +dependencies = [ + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[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-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[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 = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[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 = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "htmlescape" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.11", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" + +[[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 = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa 1.0.11", + "pin-project-lite", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.0", +] + +[[package]] +name = "infer" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847" +dependencies = [ + "cfb", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[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 = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "levenshtein_automata" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[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 = "lol_html" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964b47c14635e111f7efddcd8f1f8794195f66225fef19822fa942b217a859cf" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cssparser", + "encoding_rs", + "hashbrown 0.13.2", + "lazy_static", + "lazycell", + "memchr", + "mime", + "selectors", + "thiserror", +] + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.0", +] + +[[package]] +name = "lz4_flex" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" + +[[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 = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "measure_time" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbefd235b0aadd181626f281e1d684e116972988c14c264e42069d5e8a5775cc" +dependencies = [ + "instant", + "log", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] + +[[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", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "memchr", + "mime", + "spin", + "version_check", +] + +[[package]] +name = "murmurhash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[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-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[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 = "oneshot" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e296cf87e61c9cfc1a61c3c63a0f7f286ed4554e0e22be84e8a38e1d264a2a29" + +[[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 = "ownedbytes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a059efb063b8f425b948e042e6b9bd85edfe60e913630ed727b23e2dfcc558" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[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 0.52.6", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[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 = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[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.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +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.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[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 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + +[[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.8", + "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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[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 = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rust-stemmers" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" +dependencies = [ + "serde", + "serde_derive", +] + +[[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.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[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.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "serde_html_form" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de514ef58196f1fc96dcaef80fe6170a1ce6215df9687a93fe8300e773fefc5" +dependencies = [ + "form_urlencoded", + "indexmap", + "itoa 1.0.11", + "ryu", + "serde", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa 1.0.11", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa 1.0.11", + "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 1.0.11", + "ryu", + "serde", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[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 = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" +dependencies = [ + "serde", +] + +[[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" +dependencies = [ + "serde", +] + +[[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 = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" +dependencies = [ + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e" +dependencies = [ + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.14.5", + "hashlink", + "hex", + "indexmap", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.79", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.79", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a" +dependencies = [ + "atoi", + "base64", + "bitflags 2.6.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa 1.0.11", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8" +dependencies = [ + "atoi", + "base64", + "bitflags 2.6.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa 1.0.11", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "tracing", + "url", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + +[[package]] +name = "tantivy" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8d0582f186c0a6d55655d24543f15e43607299425c5ad8352c242b914b31856" +dependencies = [ + "aho-corasick", + "arc-swap", + "base64", + "bitpacking", + "byteorder", + "census", + "crc32fast", + "crossbeam-channel", + "downcast-rs", + "fastdivide", + "fnv", + "fs4", + "htmlescape", + "itertools", + "levenshtein_automata", + "log", + "lru", + "lz4_flex", + "measure_time", + "memmap2", + "num_cpus", + "once_cell", + "oneshot", + "rayon", + "regex", + "rust-stemmers", + "rustc-hash", + "serde", + "serde_json", + "sketches-ddsketch", + "smallvec", + "tantivy-bitpacker", + "tantivy-columnar", + "tantivy-common", + "tantivy-fst", + "tantivy-query-grammar", + "tantivy-stacker", + "tantivy-tokenizer-api", + "tempfile", + "thiserror", + "time", + "uuid", + "winapi", +] + +[[package]] +name = "tantivy-bitpacker" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284899c2325d6832203ac6ff5891b297fc5239c3dc754c5bc1977855b23c10df" +dependencies = [ + "bitpacking", +] + +[[package]] +name = "tantivy-columnar" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12722224ffbe346c7fec3275c699e508fd0d4710e629e933d5736ec524a1f44e" +dependencies = [ + "downcast-rs", + "fastdivide", + "itertools", + "serde", + "tantivy-bitpacker", + "tantivy-common", + "tantivy-sstable", + "tantivy-stacker", +] + +[[package]] +name = "tantivy-common" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8019e3cabcfd20a1380b491e13ff42f57bb38bf97c3d5fa5c07e50816e0621f4" +dependencies = [ + "async-trait", + "byteorder", + "ownedbytes", + "serde", + "time", +] + +[[package]] +name = "tantivy-fst" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d60769b80ad7953d8a7b2c70cdfe722bbcdcac6bccc8ac934c40c034d866fc18" +dependencies = [ + "byteorder", + "regex-syntax 0.8.5", + "utf8-ranges", +] + +[[package]] +name = "tantivy-query-grammar" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "847434d4af57b32e309f4ab1b4f1707a6c566656264caa427ff4285c4d9d0b82" +dependencies = [ + "nom", +] + +[[package]] +name = "tantivy-sstable" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c69578242e8e9fc989119f522ba5b49a38ac20f576fc778035b96cc94f41f98e" +dependencies = [ + "tantivy-bitpacker", + "tantivy-common", + "tantivy-fst", + "zstd", +] + +[[package]] +name = "tantivy-stacker" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56d6ff5591fc332739b3ce7035b57995a3ce29a93ffd6012660e0949c956ea8" +dependencies = [ + "murmurhash32", + "rand_distr", + "tantivy-common", +] + +[[package]] +name = "tantivy-tokenizer-api" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0dcade25819a89cfe6f17d932c9cedff11989936bf6dd4f336d50392053b04" +dependencies = [ + "serde", +] + +[[package]] +name = "tempfile" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[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 1.0.11", + "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 = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[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 = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437150ab6bbc8c5f0f519e3d5ed4aa883a83dd4cdd3d1b21f9482936046cb97" +dependencies = [ + "bitflags 2.6.0", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[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-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[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-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", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" + +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom 0.2.15", + "serde", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.79", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whoami" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" +dependencies = [ + "redox_syscall", + "wasite", +] + +[[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-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.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[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 2.0.79", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[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 new file mode 100644 index 0000000..55ad9d2 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "evie" +version = "0.1.0" +edition = "2021" + +[dependencies] +blogdb = { git = "https://git.augustkline.com/august/blogdb" } +anyhow = "1.0.89" +argon2 = "0.5.3" +axum = { version = "0.7.7", features = ["macros", "multipart"] } +axum-extra = { version = "0.9.4", features = [ + "cookie", + "cookie-private", + "form", + "multipart", + "query", +] } +serde = { version = "1.0.210", features = ["derive"] } +sqlx = { version = "0.8.2", features = ["sqlite", "runtime-tokio", "macros"] } +tokio = { version = "1.40.0", features = ["full"] } +tower-http = { version = "0.6.1", features = [ + "cors", + "fs", + "limit", + "normalize-path", + "trace", +] } +tracing = "0.1.40" +futures = "0.3.31" +tower = "0.5.1" +http-body = "1.0.1" +lol_html = "2.0.0" +tokio-util = { version = "0.7.12", features = ["io"] } +glob = "0.3.1" +mime_guess = "2.0.5" +constcat = "0.5.1" +serde_json = "1.0.132" +tantivy = "0.22.0" +tracing-subscriber = { version = "0.3.18", features = [ + "env-filter", + "serde", + "serde_json", + "std", +] } +phf = "0.11.2" + +[build-dependencies] +dotenvy = "0.15.7" +glob = "0.3.1" +phf = "0.11.2" +phf_codegen = "0.11.2" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..ba5f286 --- /dev/null +++ b/build.rs @@ -0,0 +1,56 @@ +use std::{ + env, + fs::File, + io::Write, + io::{BufWriter, Read}, + path::Path, +}; + +use dotenvy::{dotenv, dotenv_iter}; +use glob::glob; +use phf_codegen::Map; + +fn main() { + println!("cargo:rerun-if-changed={}", dotenv().unwrap().display()); + for item in dotenv_iter().unwrap() { + let (key, value) = item.unwrap(); + println!("cargo:rustc-env={key}={value}"); + } + let path = Path::new(&env::var("OUT_DIR").unwrap()).join("codegen.rs"); + let mut file = BufWriter::new(File::create(&path).unwrap()); + let template_dir = [&env::var("CARGO_MANIFEST_DIR").unwrap(), "/src/templates"].concat(); + println!("cargo:rerun-if-changed={}", template_dir); + let pattern = [&template_dir, "/**/*.html"].concat(); + let mut map: Map = phf_codegen::Map::new(); + + let paths = glob(&pattern).unwrap(); + for path in paths { + match path { + Ok(path) => { + let slug_path = path.clone(); + let slug: String = slug_path + .strip_prefix(&template_dir) + .unwrap() + .as_os_str() + .to_str() + .unwrap() + .strip_suffix(".html") + .unwrap() + .into(); // eek + let mut file = File::open(path.clone()).unwrap(); + let mut content = "r####\"".to_string(); + file.read_to_string(&mut content).unwrap(); + content.push_str("\"####"); + println!("cargo:warning={}\n{}", &slug, &content); + map.entry(slug, &content); + } + Err(_) => todo!(), + } + } + writeln!( + &mut file, + "static TEMPLATES: phf::Map<&'static str, &'static str> = {};", + map.build() + ) + .unwrap(); +} diff --git a/src/client/assets/css/admin.css b/src/client/assets/css/admin.css new file mode 100644 index 0000000..b34c53b --- /dev/null +++ b/src/client/assets/css/admin.css @@ -0,0 +1,256 @@ +main { + --page-margin: calc(0.333 * 100vi / 2); + --page-content-size: calc(100% - (var(--page-margin) * 2)); + display: flex; + flex-direction: column; + gap: var(--default-padding); + margin-block-end: 40svb; + padding: 0; +} + +@media screen and (min-width: 60rem) { + main { + block-size: calc(100svb - 8rem + /*the most magic number of all...*/ + ); + margin-block-end: unset; + max-inline-size: var(--page-content-size); + } + + .blog-admin { + flex-wrap: nowrap !important; + } + + .admin-widget-user { + flex-direction: row !important; + justify-content: space-between; + } + + .admin-widget ul { + display: flex; + flex-direction: column; + justify-content: start; + flex: 1; + min-block-size: 0; + block-size: 100%; + overflow: auto; + max-block-size: 100%; + margin-block: 0; + gap: var(--default-padding); + + li { + @media screen and (min-width: 60rem) { + min-block-size: 6rem; + flex: 0 1 6rem; + } + } + } +} + +.admin-widget-user { + padding: var(--default-padding); + flex-direction: column; + gap: var(--default-padding); + + &>* { + align-self: flex-start; + } + + #user-info { + display: flex; + position: absolute; + z-index: -1; + transition: opacity 0.3s ease; + transform: translate(calc(var(--default-padding) * -1), calc(var(--default-padding) * -1)); + box-sizing: border-box; + opacity: 0; + text-wrap: nowrap; + inline-size: 100%; + block-size: 100%; + background: var(--color-bg); + + .close { + aspect-ratio: 1; + border: none; + box-shadow: none; + } + + &:target { + z-index: 100; + opacity: 1; + } + + form { + align-items: stretch; + justify-content: stretch; + } + + .user-info-form { + display: contents; + + &>* { + padding-block: 0; + min-inline-size: 0; + } + } + } + + + &>*:not(#user-info) { + transition: all 0.3s ease; + } + + &:has(#user-info:target) { + &>*:not(#user-info) { + opacity: 0; + } + } +} + +.admin-widget:not(.admin-widget-user) { + min-block-size: 0; + box-sizing: border-box; + flex: 1; + flex-direction: column; +} + +.blog-admin { + box-sizing: border-box; + display: flex; + gap: var(--default-padding); + flex-wrap: wrap; + box-sizing: border-box; + min-block-size: 0; + flex: 1; + justify-content: stretch; + + ul { + padding-inline: 0; + } + + form { + flex-direction: column; + gap: var(--default-padding); + box-sizing: border-box; + min-block-size: 0; + flex: 0 1 100%; + + + .empty-message { + @media screen and (min-width: 60rem) { + margin-block-start: 50%; + transform: translateY(-50%); + } + + align-self: center; + } + + .form-action { + transition: all 0.3s ease; + visibility: hidden; + opacity: 0; + min-block-size: 0; + } + + .form-actions { + border-block-start: var(--border); + transition: all 0.3s ease; + display: flex; + gap: var(--default-padding); + box-sizing: content-box; + justify-content: end; + max-block-size: 0; + padding: 0 var(--default-padding); + min-block-size: 0; + } + + &:has(:checked) { + .form-actions { + border-block: var(--border); + transition: all 0.3s ease; + max-block-size: calc(var(--default-padding) * 2); + padding-block: var(--default-padding); + + @media screen and (max-width: 500px) { + & { + max-block-size: 4rem; + } + } + + } + + .form-action { + transition: all 0.3s ease; + visibility: visible; + opacity: 1; + } + } + + input[type="checkbox"] { + min-inline-size: 2rem; + } + } + +} + +.admin-widget { + position: relative; + min-block-size: 0; + border: var(--border); + display: flex; + + &>*:not(form, a) { + padding-inline: var(--default-padding); + } + + .widget-header { + display: flex; + min-block-size: 0; + align-items: center; + justify-content: space-between; + } + + li { + flex: 1; + display: flex; + justify-content: space-between; + align-items: center; + padding: calc(2 * var(--default-padding)) var(--default-padding); + border-inline-start: 0px solid black; + } + + .widget-entry { + transition: all 0.2s ease; + + &:has(.entry-content:hover), + &:has(.entry-content:focus) { + border-inline-start-width: 3px; + transition: all 0.2s ease; + } + } + + + .entry-content { + &>* { + margin: 0; + } + } + + a.entry-content { + color: inherit; + text-decoration: inherit; + inline-size: 90%; + + transition: all 0.3s ease; + + &:hover, + &:focus { + transform: translateX(1ch); + } + + &:focus { + outline: none; + } + + } +} diff --git a/src/client/assets/css/blog.css b/src/client/assets/css/blog.css new file mode 100644 index 0000000..bf8f63b --- /dev/null +++ b/src/client/assets/css/blog.css @@ -0,0 +1,44 @@ +main { + display: block; +} + +h1 { + margin-block: 0; +} + +.blog-roll-entry { + margin-block: 1rem; + + a { + border: var(--border); + background: var(--color-bg-accent); + display: flex; + flex-direction: column; + align-items: start; + outline: none; + + --content-padding: 1rem; + + .entry-content { + padding: var(--content-padding); + transition: padding-inline-start 0.3s ease, box-shadow 0.3s ease; + + * { + margin-block: 0; + } + } + + &:hover, + &:focus-visible { + .entry-content { + padding-inline-start: calc(var(--content-padding) * 2); + box-shadow: inset 3px 0px 0px var(--color-text); + } + } + } + + img { + border-inline: none; + border-block-start: none; + } +} diff --git a/src/client/assets/css/editor.css b/src/client/assets/css/editor.css new file mode 100644 index 0000000..a5af579 --- /dev/null +++ b/src/client/assets/css/editor.css @@ -0,0 +1,200 @@ +main { + @media screen and (min-width: 60rem) { + min-block-size: calc(100svb - 8rem + /*the most magic number of all...*/ + ) !important; + } + + margin-block-end: 0; + + border: solid 1px var(--color-text); + padding: 2rem; + min-block-size: 80%; + display: flex; + flex-direction: column; + align-items: stretch; + + h1 { + font-size: calc(var(--font-size) * 3.33); + } + + h2 { + font-size: calc(var(--font-size) * 2.66); + } + + h3 { + font-size: calc(var(--font-size) * 2); + } + + :is(h4, h5, h6) { + font-size: calc(var(--font-size) * 1.33); + } + + :is(h1, + h2, + h3, + h4, + h5, + h6) { + margin-block: 2rem 0.5rem; + } +} + +.ce-block:not(:first-child) { + + *:is(h1, + h2, + h3, + h4, + h5, + h6) { + margin-block: 0rem 0.5rem !important; + } +} + +.ce-header { + + &::before, + &::after { + font-family: var(--font-family-display) !important; + } +} + +.ce-delimiter { + width: 100%; + margin-block: 1rem; + text-align: left !important; +} + +.cdx-input { + border-radius: 0 !important; + border: var(--border) !important; + background-color: var(--color-bg) !important; +} + +.ce-delimiter::before { + display: block; + content: "" !important; + height: 1px !important; + inline-size: 100%; + position: absolute; + background: var(--color-text); + color: green +} + +.image-tool__image_preloader::after { + display: none !important; + visibility: hidden !important; + height: 0 !important; + width: 0 !important; +} + +@media all and (max-width: 650px) { + .ce-toolbar__actions { + + &>*:nth-child(1), + &>*:nth-child(2) { + border-radius: 0; + background: var(--color-bg); + color: var(--color-text); + border: 1px solid var(--color-text); + } + } +} + +.cdx-warning { + &::before { + display: none !important; + inline-size: 0 !important; + } + + .cdx-warning__message { + display: none; + } + + .cdx-warning__title { + margin-bottom: 0; + padding: 0; + } + + .cdx-input[data-placeholder]::before { + display: none !important; + } + + .cdx-input { + box-shadow: none; + -webkit-box-shadow: none; + border: none; + } + + font-size: calc(var(--font-size) * 1.3); + border: 1px solid var(--color-text); + border-inline-start: 4px solid var(--color-text); + padding: 1rem 2rem !important; + max-inline-size: 100%; + margin-inline: 0; +} + +.codex-editor__redactor { + display: flex; + flex-direction: column; + gap: var(--default-padding); +} + +.ce-block__content { + word-wrap: break-word; + display: contents; +} + +.ce-block { + margin-block: 0; + padding-block: 0; +} + +.cdx-block { + margin-block: 0; + padding-block: 0; +} + +.codex-editor--narrow { + /* margin-inline-end: -50px !important; */ +} + +.codex-editor { + &>*:first-child { + + & h1, + h2, + h3, + h4 { + padding-block-start: 0; + } + } +} + +.ce-popover--opened>.ce-popover__container { + border: solid 1px var(--color-text) !important; + border-radius: 0; + background: var(--color-bg); + color: var(--color-text); +} + +.ce-paragraph { + font-size: calc(var(--font-size) * 1.3); + /* margin-block: calc(var(--font-size) * 2.6); */ + line-height: calc(var(--font-size) * 2); +} + +.cdx-block { + &>span { + background-color: var(--color-selection) !important; + } +} + +.ce-block--selected .ce-block__content { + background-color: var(--color-selection) !important; +} + +.embed-tool__caption { + display: none; +} diff --git a/src/client/assets/css/login.css b/src/client/assets/css/login.css new file mode 100644 index 0000000..92fb503 --- /dev/null +++ b/src/client/assets/css/login.css @@ -0,0 +1,73 @@ +body { + display: flex; + flex-wrap: wrap; + justify-content: stretch; + align-items: stretch; +} + +@media screen and (max-width: 50rem) { + body { + flex-direction: column; + flex-wrap: nowrap; + } +} + +body>div { + display: block; + object-fit: cover; + all: unset; + max-block-size: 100%; + min-block-size: 25%; + min-inline-size: 50%; + max-inline-size: 100%; + background: url("/assets/images/login.jpg"); + filter: invert(); + background-size: cover; + mask-size: 100%; + mask-image: linear-gradient(rgb(0 0 0 / 100%), transparent); + + @media screen and (min-width: 50rem) { + mask-image: linear-gradient(90deg, rgb(0 0 0 / 100%), transparent); + } + + image-rendering: pixelated; +} + + +main { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + /* block-size: 100%; */ + max-block-size: 100%; + + &>:first-child { + display: flex; + flex-direction: column; + border: var(--border); + padding: 1rem; + align-items: center; + + h1 { + align-self: center; + } + } +} + +label:has(input:not([type="checkbox"])) { + display: flex; + flex-direction: column; +} + + +button { + padding: 0.5ch; +} + +form { + display: flex; + flex-direction: column; + max-inline-size: 40ch; + gap: 1rem; +} diff --git a/src/client/assets/css/style.css b/src/client/assets/css/style.css new file mode 100644 index 0000000..b66ece6 --- /dev/null +++ b/src/client/assets/css/style.css @@ -0,0 +1,432 @@ +@font-face { + src: url("/assets/fonts/Redaction-Regular.woff2"); + font-family: Redaction; +} + +@font-face { + src: url("/assets/fonts/Atkinson-Hyperlegible-Regular.woff2"); + font-family: Atkinson-Hyperlegible; +} + +:root { + --color-bg: #faf9f6; + --color-bg-accent: #fffefb; + --color-text: #000000; + --color-accent: oklch(70.92% 0.1619 310); + --color-selection: color-mix(in srgb, var(--color-bg) 85%, var(--color-accent) 15%); + --font-family-display: Redaction; + --font-family-text: Atkinson-Hyperlegible; + --border: 1px solid var(--color-text); + + --default-padding: 1rem; + + --transition-timing: 0.3s ease; + + --header-size: 6rem; + + --font-size: 1rem; + font-size: var(--font-size); + line-height: 1.15; + /* 1. Correct the line height in all browsers. */ + -webkit-text-size-adjust: 100%; + /* 2. Prevent adjustments of font size after orientation changes in iOS. */ + tab-size: 4; + /* 3. Use a more readable tab size (opinionated). */ + color: var(--color-text); + + scroll-behavior: smooth; + + *::selection { + background-color: var(--color-selection); + } +} + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; +} + +html, +body { + inline-size: 100%; + block-size: 100%; + margin: 0; + background: var(--color-bg); +} + +*, +::before, +::after { + box-sizing: border-box; + font-family: var(--font-family-text); +} + +p, +li, +button, +.button, +input, +label, +a, +blockquote, +aside, +ol, +ul { + font-size: calc(var(--font-size) * 1.33); +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: var(--font-family-display); +} + +aside, +blockquote { + border: var(--border); +} + +blockquote, +aside { + padding: var(--default-padding) calc(var(--default-padding) * 2); + max-inline-size: 100%; + margin-inline: 0; +} + +blockquote { + &::before { + content: '“'; + font-weight: 600; + } + + &::after { + content: '”'; + font-weight: 600; + } +} + +ul { + appearance: none; + list-style: none; + padding-inline: unset; +} + +a { + color: unset; + text-decoration: unset; +} + +form { + display: flex; +} + +input { + appearance: none; + -webkit-appearance: none; + background: var(--color-bg-accent); + outline: none; + border: var(--border); + transition: box-shadow var(--transition-timing); + margin: 0; +} + +input:is([type="text"], [type="password"], [type="search"]) { + padding: 0.5ch 1ch; + + &:focus, + &:hover { + box-shadow: inset 3px 0px 0px var(--color-text); + } +} + +input[type="checkbox"] { + min-inline-size: 1ch; + align-content: center; + justify-content: center; + display: inline-block; + cursor: pointer; + + &:focus-visible { + outline: none; + border: 0px solid var(--color-bg); + outline: 0px solid var(--color-text); + + &:not(:checked)::before { + outline: 3px solid var(--color-text); + } + + &:checked::before { + outline: 3px solid var(--color-text); + border: 3px solid var(--color-bg); + } + } + + &::before { + content: ""; + display: block; + aspect-ratio: 1; + background: var(--color-bg); + outline: 1px solid var(--color-text); + box-shadow: inset 0px 0px 0px var(--color-text), inset 0px 0px 0px var(--color-text); + } + + &, + &::before { + transition: box-shadow var(--transition-timing), background var(--transition-timing), outline var(--transition-timing); + } + + &:hover::before { + box-shadow: inset 1px 1px 0px var(--color-text), inset -1px -1px 0px var(--color-text); + } + + &:checked::before { + background: var(--color-text); + } +} + +button, +.button { + appearance: unset; + background: var(--color-bg); + color: var(--color-text); + border: var(--border); + transition: box-shadow var(--transition-timing); + cursor: pointer; + display: inline-block; + outline: none; + + &:hover, + &:focus-visible { + box-shadow: 0px 2px 0px var(--color-text); + } + + &:active { + box-shadow: + 0px 1px 0px var(--color-text); + } +} + +.button { + padding: 1px 4px; +} + + +.animated-link-underline { + background-size: 100% 1px; +} + +.animated-link, +.animated-link-underline { + text-decoration: unset; + background-size: 100% 0%; + background-position: left bottom; + background-repeat: no-repeat; + + transition: background-size var(--transition-timing), background-image var(--transition-timing), color var(--transition-timing); + background-image: linear-gradient(var(--color-text), var(--color-text)); + + color: var(--color-text); + + * { + transition: color var(--transition-timing); + color: var(--color-text); + } + + &:hover, + &:focus, + &:focus-visible { + outline: none; + + color: var(--color-bg); + + * { + color: var(--color-bg); + } + + background-size: 100% 100%; + } +} + +header { + box-sizing: content-box; + flex-direction: column; + border-block-end: var(--border); + max-inline-size: 100%; + display: flex; + justify-content: center; + align-items: center; + padding: var(--default-padding); + position: sticky; + z-index: 100; + top: 0; + background: var(--color-bg); + + &>:first-child { + margin: unset; + } + + h1 { + margin-block: 0.25ch; + text-align: center; + } + + nav { + flex-wrap: wrap; + max-inline-size: 100%; + display: flex; + align-items: center; + justify-content: center; + + a { + all: unset; + cursor: pointer; + font-family: var(--font-family-display); + } + + &:first-child { + margin-inline-start: 0; + } + + &:last-child { + margin-inline-end: 0; + } + + gap: var(--default-padding); + + font-size: calc(var(--font-size) * 1.8); + } + + + form { + min-inline-size: min(100%, 10ch); + flex: 0; + align-items: center; + border: var(--border); + background: var(--color-bg-accent); + + + button { + display: flex; + pointer-events: none; + + padding-inline-end: 0.25rem; + } + + input { + min-inline-size: 0; + flex: 1; + } + + transition: flex var(--transition-timing), + padding-inline var(--transition-timing); + + input[type="search"]::-webkit-search-decoration, + input[type="search"]::-webkit-search-cancel-button, + input[type="search"]::-webkit-search-results-button, + input[type="search"]::-webkit-search-results-decoration { + display: none; + } + + &>* { + box-sizing: content-box; + background: transparent; + margin-inline: 0; + margin-block: 0; + padding-block: 0; + block-size: 100%; + border: none; + } + } + +} + +main { + margin-block: var(--default-padding) 40svb; + margin-inline: auto; + max-inline-size: min(60ch, 80%); + padding-block: var(--default-padding); + gap: var(--default-padding); + display: flex; + flex-direction: column; + + &>:first-child { + margin-block-start: 0; + + &:is(a) { + &+* { + margin-block-start: 0rem !important; + } + } + } + + &>* { + margin-block: 0; + } + + &>* { + + &:is(h1) { + font-size: calc(var(--font-size) * 3.33); + } + + &:is(h2) { + font-size: calc(var(--font-size) * 2.66); + } + + &:is(h3) { + font-size: calc(var(--font-size) * 2); + } + + &:is(h4, h5, h6) { + font-size: calc(var(--font-size) * 1.33); + } + + &:is(h1, + h2, + h3, + h4, + h5, + h6) { + margin-block: 2rem 0.5rem; + } + } + + img { + min-inline-size: 100%; + max-inline-size: 100%; + object-fit: cover; + object-position: top; + border: var(--border); + + } +} + + +/* anything wider than mobile */ +@media all and (min-width: 60rem) { + header { + box-sizing: border-box; + flex-direction: row; + justify-content: space-between; + + nav { + justify-content: flex-end; + box-sizing: border-box; + } + } + + main { + margin-block: var(--default-padding); + } +} + +/* tablet */ +@media all and (min-width: 60rem) and (max-width: 80rem) {} + +/* desktop */ +@media all and (min-width: 80rem) {} diff --git a/src/client/assets/fonts/Atkinson-Hyperlegible-Regular.woff2 b/src/client/assets/fonts/Atkinson-Hyperlegible-Regular.woff2 new file mode 100644 index 0000000..99b3c6f Binary files /dev/null and b/src/client/assets/fonts/Atkinson-Hyperlegible-Regular.woff2 differ diff --git a/src/client/assets/fonts/Redaction-Bold.woff2 b/src/client/assets/fonts/Redaction-Bold.woff2 new file mode 100644 index 0000000..392d60d Binary files /dev/null and b/src/client/assets/fonts/Redaction-Bold.woff2 differ diff --git a/src/client/assets/fonts/Redaction-Italic.woff2 b/src/client/assets/fonts/Redaction-Italic.woff2 new file mode 100644 index 0000000..1bd3c5c Binary files /dev/null and b/src/client/assets/fonts/Redaction-Italic.woff2 differ diff --git a/src/client/assets/fonts/Redaction-Regular.woff2 b/src/client/assets/fonts/Redaction-Regular.woff2 new file mode 100644 index 0000000..d187654 Binary files /dev/null and b/src/client/assets/fonts/Redaction-Regular.woff2 differ diff --git a/src/client/assets/images/login.jpg b/src/client/assets/images/login.jpg new file mode 100644 index 0000000..1330c43 Binary files /dev/null and b/src/client/assets/images/login.jpg differ diff --git a/src/client/assets/js/editor.js b/src/client/assets/js/editor.js new file mode 100644 index 0000000..1f2d759 --- /dev/null +++ b/src/client/assets/js/editor.js @@ -0,0 +1,13695 @@ +(function () { + "use strict"; + try { + if (typeof document < "u") { + var e = document.createElement("style"); + e.appendChild( + document.createTextNode( + ".ce-header{padding:.6em 0 3px;margin:0;line-height:1.25em;outline:none}.ce-header p,.ce-header div{padding:0!important;margin:0!important}", + ), + ), + document.head.appendChild(e); + } + } catch (n) { + console.error("vite-plugin-css-injected-by-js", n); + } +})(); +(function (n, s) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = s()) + : typeof define == "function" && define.amd + ? define(s) + : ((n = typeof globalThis < "u" ? globalThis : n || self), + (n.Header = s())); +})(this, function () { + "use strict"; + const n = "", + s = + '', + a = + '', + h = + '', + d = + '', + u = + '', + g = + '', + c = + ''; + /** + * Header block for the Editor.js. + * + * @author CodeX (team@ifmo.su) + * @copyright CodeX 2018 + * @license MIT + * @version 2.0.0 + */ class v { + constructor({ data: e, config: t, api: i, readOnly: r }) { + (this.api = i), + (this.readOnly = r), + (this._settings = t), + (this._data = this.normalizeData(e)), + (this._element = this.getTag()); + } + get _CSS() { + return { block: this.api.styles.block, wrapper: "ce-header" }; + } + isHeaderData(e) { + return e.text !== void 0; + } + normalizeData(e) { + const t = { text: "", level: this.defaultLevel.number }; + return ( + this.isHeaderData(e) && + ((t.text = e.text || ""), + e.level !== void 0 && + !isNaN(parseInt(e.level.toString())) && + (t.level = parseInt(e.level.toString()))), + t + ); + } + render() { + return this._element; + } + renderSettings() { + return this.levels.map((e) => ({ + icon: e.svg, + label: this.api.i18n.t(`Heading ${e.number}`), + onActivate: () => this.setLevel(e.number), + closeOnActivate: !0, + isActive: this.currentLevel.number === e.number, + render: () => document.createElement("div"), + })); + } + setLevel(e) { + this.data = { level: e, text: this.data.text }; + } + merge(e) { + this._element.insertAdjacentHTML("beforeend", e.text); + } + validate(e) { + return e.text.trim() !== ""; + } + save(e) { + return { text: e.innerHTML, level: this.currentLevel.number }; + } + static get conversionConfig() { + return { export: "text", import: "text" }; + } + static get sanitize() { + return { level: !1, text: {} }; + } + static get isReadOnlySupported() { + return !0; + } + get data() { + return ( + (this._data.text = this._element.innerHTML), + (this._data.level = this.currentLevel.number), + this._data + ); + } + set data(e) { + if ( + ((this._data = this.normalizeData(e)), + e.level !== void 0 && this._element.parentNode) + ) { + const t = this.getTag(); + (t.innerHTML = this._element.innerHTML), + this._element.parentNode.replaceChild(t, this._element), + (this._element = t); + } + e.text !== void 0 && (this._element.innerHTML = this._data.text || ""); + } + getTag() { + const e = document.createElement(this.currentLevel.tag); + return ( + (e.innerHTML = this._data.text || ""), + e.classList.add(this._CSS.wrapper), + (e.contentEditable = this.readOnly ? "false" : "true"), + (e.dataset.placeholder = this.api.i18n.t( + this._settings.placeholder || "", + )), + e + ); + } + get currentLevel() { + let e = this.levels.find((t) => t.number === this._data.level); + return e || (e = this.defaultLevel), e; + } + get defaultLevel() { + return this.levels[0]; + } + get levels() { + const e = [ + { number: 1, tag: "H1", svg: s }, + { number: 2, tag: "H2", svg: a }, + { number: 3, tag: "H3", svg: h }, + { number: 4, tag: "H4", svg: d }, + { number: 5, tag: "H5", svg: u }, + { number: 6, tag: "H6", svg: g }, + ]; + return this._settings.levels + ? e.filter((t) => this._settings.levels.includes(t.number)) + : e; + } + onPaste(e) { + const t = e.detail; + if ("data" in t) { + const i = t.data; + let r = this.defaultLevel.number; + switch (i.tagName) { + case "H1": + r = 1; + break; + case "H2": + r = 2; + break; + case "H3": + r = 3; + break; + case "H4": + r = 4; + break; + case "H5": + r = 5; + break; + case "H6": + r = 6; + break; + } + this._settings.levels && + (r = this._settings.levels.reduce((o, l) => + Math.abs(l - r) < Math.abs(o - r) ? l : o, + )), + (this.data = { level: r, text: i.innerHTML }); + } + } + static get pasteConfig() { + return { tags: ["H1", "H2", "H3", "H4", "H5", "H6"] }; + } + static get toolbox() { + return { icon: c, title: "Heading" }; + } + } + return v; +}); +(function () { + "use strict"; + try { + if (typeof document < "u") { + var o = document.createElement("style"); + o.appendChild( + document.createTextNode( + '.image-tool{--bg-color: #cdd1e0;--front-color: #388ae5;--border-color: #e8e8eb}.image-tool__image{overflow:hidden;}.image-tool__image-picture{max-width:100%;vertical-align:bottom;display:block}.image-tool__image-preloader{display:none !important}.image-tool__image-preloader:after{display:none !important}.image-tool__caption{display:none}.image-tool__caption[contentEditable=true][data-placeholder]:before{position:absolute!important;content:attr(data-placeholder);color:#707684;font-weight:400;display:none}.image-tool__caption[contentEditable=true][data-placeholder]:empty:before{display:block}.image-tool__caption[contentEditable=true][data-placeholder]:empty:focus:before{display:none}.image-tool--empty .image-tool__image,.image-tool--empty .image-tool__caption,.image-tool--loading .image-tool__caption{display:none}.image-tool .cdx-button{display:flex;align-items:center;justify-content:center}.image-tool .cdx-button svg{height:auto;margin:0 6px 0 0}.image-tool--filled .cdx-button,.image-tool--filled .image-tool__image-preloader{display:none}.image-tool--loading .image-tool__image{min-height:200px;display:flex;border:1px solid var(--border-color);background-color:#fff}.image-tool--loading .image-tool__image-picture,.image-tool--loading .cdx-button{display:none}.image-tool--withBorder .image-tool__image{border:1px solid var(--border-color)}.image-tool--withBackground .image-tool__image{padding:15px;background:var(--bg-color)}.image-tool--withBackground .image-tool__image-picture{max-width:60%;margin:0 auto}.image-tool--stretched .image-tool__image-picture{width:100%}.image-tool--caption .image-tool__caption{display:block}@keyframes image-preloader-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}', + ), + ), + document.head.appendChild(o); + } + } catch (e) { + console.error("vite-plugin-css-injected-by-js", e); + } +})(); +(function (S, F) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = F()) + : typeof define == "function" && define.amd + ? define(F) + : ((S = typeof globalThis < "u" ? globalThis : S || self), + (S.ImageTool = F())); +})(this, function () { + "use strict"; + const S = + '', + F = + '', + R = + '', + x = + '', + B = + ''; + function M(C, i = null, a = {}) { + const s = document.createElement(C); + Array.isArray(i) ? s.classList.add(...i) : i !== null && s.classList.add(i); + for (const r in a) a.hasOwnProperty(r) && (s[r] = a[r]); + return s; + } + var O = ((C) => ( + (C.Empty = "empty"), (C.Uploading = "uploading"), (C.Filled = "filled"), C + ))(O || {}); + class U { + constructor({ api: i, config: a, onSelectFile: s, readOnly: r }) { + (this.api = i), + (this.config = a), + (this.onSelectFile = s), + (this.readOnly = r), + (this.nodes = { + wrapper: M("div", [this.CSS.baseClass, this.CSS.wrapper]), + imageContainer: M("div", [this.CSS.imageContainer]), + fileButton: this.createFileButton(), + imageEl: void 0, + imagePreloader: M("div", this.CSS.imagePreloader), + caption: M("div", [this.CSS.input, this.CSS.caption], { + contentEditable: !this.readOnly, + }), + }), + (this.nodes.caption.dataset.placeholder = + this.config.captionPlaceholder), + this.nodes.imageContainer.appendChild(this.nodes.imagePreloader), + this.nodes.wrapper.appendChild(this.nodes.imageContainer), + this.nodes.wrapper.appendChild(this.nodes.caption), + this.nodes.wrapper.appendChild(this.nodes.fileButton); + } + applyTune(i, a) { + this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${i}`, a); + } + render(i) { + return ( + i.file === void 0 || Object.keys(i.file).length === 0 + ? this.toggleStatus("empty") + : this.toggleStatus("uploading"), + this.nodes.wrapper + ); + } + showPreloader(i) { + (this.nodes.imagePreloader.style.backgroundImage = `url(${i})`), + this.toggleStatus("uploading"); + } + hidePreloader() { + (this.nodes.imagePreloader.style.backgroundImage = ""), + this.toggleStatus("empty"); + } + fillImage(i) { + const a = /\.mp4$/.test(i) ? "VIDEO" : "IMG", + s = { src: i }; + let r = "load"; + a === "VIDEO" && + ((s.autoplay = !0), + (s.loop = !0), + (s.muted = !0), + (s.playsinline = !0), + (r = "loadeddata")), + (this.nodes.imageEl = M(a, this.CSS.imageEl, s)), + this.nodes.imageEl.addEventListener(r, () => { + this.toggleStatus("filled"), + this.nodes.imagePreloader !== void 0 && + (this.nodes.imagePreloader.style.backgroundImage = ""); + }), + this.nodes.imageContainer.appendChild(this.nodes.imageEl); + } + fillCaption(i) { + this.nodes.caption !== void 0 && (this.nodes.caption.innerHTML = i); + } + get CSS() { + return { + baseClass: this.api.styles.block, + loading: this.api.styles.loader, + input: this.api.styles.input, + button: this.api.styles.button, + wrapper: "image-tool", + imageContainer: "image-tool__image", + imagePreloader: "image-tool__image-preloader", + imageEl: "image-tool__image-picture", + caption: "image-tool__caption", + }; + } + createFileButton() { + const i = M("div", [this.CSS.button]); + return ( + (i.innerHTML = + this.config.buttonContent ?? + `${R} ${this.api.i18n.t("Select an Image")}`), + i.addEventListener("click", () => { + this.onSelectFile(); + }), + i + ); + } + toggleStatus(i) { + for (const a in O) + Object.prototype.hasOwnProperty.call(O, a) && + this.nodes.wrapper.classList.toggle( + `${this.CSS.wrapper}--${O[a]}`, + i === O[a], + ); + } + } + function D(C) { + return C && + C.__esModule && + Object.prototype.hasOwnProperty.call(C, "default") + ? C.default + : C; + } + var I = { exports: {} }; + (function (C, i) { + (function (a, s) { + C.exports = s(); + })(window, function () { + return (function (a) { + var s = {}; + function r(e) { + if (s[e]) return s[e].exports; + var o = (s[e] = { i: e, l: !1, exports: {} }); + return a[e].call(o.exports, o, o.exports, r), (o.l = !0), o.exports; + } + return ( + (r.m = a), + (r.c = s), + (r.d = function (e, o, d) { + r.o(e, o) || + Object.defineProperty(e, o, { enumerable: !0, get: d }); + }), + (r.r = function (e) { + typeof Symbol < "u" && + Symbol.toStringTag && + Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), + Object.defineProperty(e, "__esModule", { value: !0 }); + }), + (r.t = function (e, o) { + if ( + (1 & o && (e = r(e)), + 8 & o || (4 & o && typeof e == "object" && e && e.__esModule)) + ) + return e; + var d = Object.create(null); + if ( + (r.r(d), + Object.defineProperty(d, "default", { enumerable: !0, value: e }), + 2 & o && typeof e != "string") + ) + for (var v in e) + r.d( + d, + v, + function (l) { + return e[l]; + }.bind(null, v), + ); + return d; + }), + (r.n = function (e) { + var o = + e && e.__esModule + ? function () { + return e.default; + } + : function () { + return e; + }; + return r.d(o, "a", o), o; + }), + (r.o = function (e, o) { + return Object.prototype.hasOwnProperty.call(e, o); + }), + (r.p = ""), + r((r.s = 3)) + ); + })([ + function (a, s) { + var r; + r = (function () { + return this; + })(); + try { + r = r || new Function("return this")(); + } catch { + typeof window == "object" && (r = window); + } + a.exports = r; + }, + function (a, s, r) { + (function (e) { + var o = r(2), + d = setTimeout; + function v() {} + function l(n) { + if (!(this instanceof l)) + throw new TypeError("Promises must be constructed via new"); + if (typeof n != "function") throw new TypeError("not a function"); + (this._state = 0), + (this._handled = !1), + (this._value = void 0), + (this._deferreds = []), + t(n, this); + } + function f(n, c) { + for (; n._state === 3; ) n = n._value; + n._state !== 0 + ? ((n._handled = !0), + l._immediateFn(function () { + var u = n._state === 1 ? c.onFulfilled : c.onRejected; + if (u !== null) { + var g; + try { + g = u(n._value); + } catch (m) { + return void y(c.promise, m); + } + p(c.promise, g); + } else (n._state === 1 ? p : y)(c.promise, n._value); + })) + : n._deferreds.push(c); + } + function p(n, c) { + try { + if (c === n) + throw new TypeError( + "A promise cannot be resolved with itself.", + ); + if (c && (typeof c == "object" || typeof c == "function")) { + var u = c.then; + if (c instanceof l) + return (n._state = 3), (n._value = c), void w(n); + if (typeof u == "function") + return void t( + ((g = u), + (m = c), + function () { + g.apply(m, arguments); + }), + n, + ); + } + (n._state = 1), (n._value = c), w(n); + } catch (h) { + y(n, h); + } + var g, m; + } + function y(n, c) { + (n._state = 2), (n._value = c), w(n); + } + function w(n) { + n._state === 2 && + n._deferreds.length === 0 && + l._immediateFn(function () { + n._handled || l._unhandledRejectionFn(n._value); + }); + for (var c = 0, u = n._deferreds.length; c < u; c++) + f(n, n._deferreds[c]); + n._deferreds = null; + } + function b(n, c, u) { + (this.onFulfilled = typeof n == "function" ? n : null), + (this.onRejected = typeof c == "function" ? c : null), + (this.promise = u); + } + function t(n, c) { + var u = !1; + try { + n( + function (g) { + u || ((u = !0), p(c, g)); + }, + function (g) { + u || ((u = !0), y(c, g)); + }, + ); + } catch (g) { + if (u) return; + (u = !0), y(c, g); + } + } + (l.prototype.catch = function (n) { + return this.then(null, n); + }), + (l.prototype.then = function (n, c) { + var u = new this.constructor(v); + return f(this, new b(n, c, u)), u; + }), + (l.prototype.finally = o.a), + (l.all = function (n) { + return new l(function (c, u) { + if (!n || n.length === void 0) + throw new TypeError("Promise.all accepts an array"); + var g = Array.prototype.slice.call(n); + if (g.length === 0) return c([]); + var m = g.length; + function h(E, T) { + try { + if ( + T && + (typeof T == "object" || typeof T == "function") + ) { + var j = T.then; + if (typeof j == "function") + return void j.call( + T, + function (H) { + h(E, H); + }, + u, + ); + } + (g[E] = T), --m == 0 && c(g); + } catch (H) { + u(H); + } + } + for (var k = 0; k < g.length; k++) h(k, g[k]); + }); + }), + (l.resolve = function (n) { + return n && typeof n == "object" && n.constructor === l + ? n + : new l(function (c) { + c(n); + }); + }), + (l.reject = function (n) { + return new l(function (c, u) { + u(n); + }); + }), + (l.race = function (n) { + return new l(function (c, u) { + for (var g = 0, m = n.length; g < m; g++) n[g].then(c, u); + }); + }), + (l._immediateFn = + (typeof e == "function" && + function (n) { + e(n); + }) || + function (n) { + d(n, 0); + }), + (l._unhandledRejectionFn = function (n) { + typeof console < "u" && + console && + console.warn("Possible Unhandled Promise Rejection:", n); + }), + (s.a = l); + }).call(this, r(5).setImmediate); + }, + function (a, s, r) { + s.a = function (e) { + var o = this.constructor; + return this.then( + function (d) { + return o.resolve(e()).then(function () { + return d; + }); + }, + function (d) { + return o.resolve(e()).then(function () { + return o.reject(d); + }); + }, + ); + }; + }, + function (a, s, r) { + function e(t) { + return (e = + typeof Symbol == "function" && typeof Symbol.iterator == "symbol" + ? function (n) { + return typeof n; + } + : function (n) { + return n && + typeof Symbol == "function" && + n.constructor === Symbol && + n !== Symbol.prototype + ? "symbol" + : typeof n; + })(t); + } + r(4); + var o, + d, + v, + l, + f, + p, + y, + w = r(8), + b = + ((d = function (t) { + return new Promise(function (n, c) { + (t = l(t)), (t = f(t)).beforeSend && t.beforeSend(); + var u = window.XMLHttpRequest + ? new window.XMLHttpRequest() + : new window.ActiveXObject("Microsoft.XMLHTTP"); + u.open(t.method, t.url), + u.setRequestHeader("X-Requested-With", "XMLHttpRequest"), + Object.keys(t.headers).forEach(function (m) { + var h = t.headers[m]; + u.setRequestHeader(m, h); + }); + var g = t.ratio; + u.upload.addEventListener( + "progress", + function (m) { + var h = Math.round((m.loaded / m.total) * 100), + k = Math.ceil((h * g) / 100); + t.progress(Math.min(k, 100)); + }, + !1, + ), + u.addEventListener( + "progress", + function (m) { + var h = Math.round((m.loaded / m.total) * 100), + k = Math.ceil((h * (100 - g)) / 100) + g; + t.progress(Math.min(k, 100)); + }, + !1, + ), + (u.onreadystatechange = function () { + if (u.readyState === 4) { + var m = u.response; + try { + m = JSON.parse(m); + } catch {} + var h = w.parseHeaders(u.getAllResponseHeaders()), + k = { body: m, code: u.status, headers: h }; + y(u.status) ? n(k) : c(k); + } + }), + u.send(t.data); + }); + }), + (v = function (t) { + return (t.method = "POST"), d(t); + }), + (l = function () { + var t = + arguments.length > 0 && arguments[0] !== void 0 + ? arguments[0] + : {}; + if (t.url && typeof t.url != "string") + throw new Error("Url must be a string"); + if ( + ((t.url = t.url || ""), + t.method && typeof t.method != "string") + ) + throw new Error("`method` must be a string or null"); + if ( + ((t.method = t.method ? t.method.toUpperCase() : "GET"), + t.headers && e(t.headers) !== "object") + ) + throw new Error("`headers` must be an object or null"); + if ( + ((t.headers = t.headers || {}), + t.type && + (typeof t.type != "string" || + !Object.values(o).includes(t.type))) + ) + throw new Error( + "`type` must be taken from module's «contentType» library", + ); + if (t.progress && typeof t.progress != "function") + throw new Error("`progress` must be a function or null"); + if ( + ((t.progress = t.progress || function (n) {}), + (t.beforeSend = t.beforeSend || function (n) {}), + t.ratio && typeof t.ratio != "number") + ) + throw new Error("`ratio` must be a number"); + if (t.ratio < 0 || t.ratio > 100) + throw new Error("`ratio` must be in a 0-100 interval"); + if ( + ((t.ratio = t.ratio || 90), + t.accept && typeof t.accept != "string") + ) + throw new Error( + "`accept` must be a string with a list of allowed mime-types", + ); + if ( + ((t.accept = t.accept || "*/*"), + t.multiple && typeof t.multiple != "boolean") + ) + throw new Error("`multiple` must be a true or false"); + if ( + ((t.multiple = t.multiple || !1), + t.fieldName && typeof t.fieldName != "string") + ) + throw new Error("`fieldName` must be a string"); + return (t.fieldName = t.fieldName || "files"), t; + }), + (f = function (t) { + switch (t.method) { + case "GET": + var n = p(t.data, o.URLENCODED); + delete t.data, + (t.url = /\?/.test(t.url) + ? t.url + "&" + n + : t.url + "?" + n); + break; + case "POST": + case "PUT": + case "DELETE": + case "UPDATE": + var c = (function () { + return ( + (arguments.length > 0 && arguments[0] !== void 0 + ? arguments[0] + : {} + ).type || o.JSON + ); + })(t); + (w.isFormData(t.data) || w.isFormElement(t.data)) && + (c = o.FORM), + (t.data = p(t.data, c)), + c !== b.contentType.FORM && + (t.headers["content-type"] = c); + } + return t; + }), + (p = function () { + var t = + arguments.length > 0 && arguments[0] !== void 0 + ? arguments[0] + : {}; + switch (arguments.length > 1 ? arguments[1] : void 0) { + case o.URLENCODED: + return w.urlEncode(t); + case o.JSON: + return w.jsonEncode(t); + case o.FORM: + return w.formEncode(t); + default: + return t; + } + }), + (y = function (t) { + return t >= 200 && t < 300; + }), + { + contentType: (o = { + URLENCODED: + "application/x-www-form-urlencoded; charset=utf-8", + FORM: "multipart/form-data", + JSON: "application/json; charset=utf-8", + }), + request: d, + get: function (t) { + return (t.method = "GET"), d(t); + }, + post: v, + transport: function (t) { + return ( + (t = l(t)), + w.selectFiles(t).then(function (n) { + for (var c = new FormData(), u = 0; u < n.length; u++) + c.append(t.fieldName, n[u], n[u].name); + w.isObject(t.data) && + Object.keys(t.data).forEach(function (m) { + var h = t.data[m]; + c.append(m, h); + }); + var g = t.beforeSend; + return ( + (t.beforeSend = function () { + return g(n); + }), + (t.data = c), + v(t) + ); + }) + ); + }, + selectFiles: function (t) { + return delete (t = l(t)).beforeSend, w.selectFiles(t); + }, + }); + a.exports = b; + }, + function (a, s, r) { + r.r(s); + var e = r(1); + window.Promise = window.Promise || e.a; + }, + function (a, s, r) { + (function (e) { + var o = + (e !== void 0 && e) || (typeof self < "u" && self) || window, + d = Function.prototype.apply; + function v(l, f) { + (this._id = l), (this._clearFn = f); + } + (s.setTimeout = function () { + return new v(d.call(setTimeout, o, arguments), clearTimeout); + }), + (s.setInterval = function () { + return new v(d.call(setInterval, o, arguments), clearInterval); + }), + (s.clearTimeout = s.clearInterval = + function (l) { + l && l.close(); + }), + (v.prototype.unref = v.prototype.ref = function () {}), + (v.prototype.close = function () { + this._clearFn.call(o, this._id); + }), + (s.enroll = function (l, f) { + clearTimeout(l._idleTimeoutId), (l._idleTimeout = f); + }), + (s.unenroll = function (l) { + clearTimeout(l._idleTimeoutId), (l._idleTimeout = -1); + }), + (s._unrefActive = s.active = + function (l) { + clearTimeout(l._idleTimeoutId); + var f = l._idleTimeout; + f >= 0 && + (l._idleTimeoutId = setTimeout(function () { + l._onTimeout && l._onTimeout(); + }, f)); + }), + r(6), + (s.setImmediate = + (typeof self < "u" && self.setImmediate) || + (e !== void 0 && e.setImmediate) || + (this && this.setImmediate)), + (s.clearImmediate = + (typeof self < "u" && self.clearImmediate) || + (e !== void 0 && e.clearImmediate) || + (this && this.clearImmediate)); + }).call(this, r(0)); + }, + function (a, s, r) { + (function (e, o) { + (function (d, v) { + if (!d.setImmediate) { + var l, + f, + p, + y, + w, + b = 1, + t = {}, + n = !1, + c = d.document, + u = Object.getPrototypeOf && Object.getPrototypeOf(d); + (u = u && u.setTimeout ? u : d), + {}.toString.call(d.process) === "[object process]" + ? (l = function (h) { + o.nextTick(function () { + m(h); + }); + }) + : (function () { + if (d.postMessage && !d.importScripts) { + var h = !0, + k = d.onmessage; + return ( + (d.onmessage = function () { + h = !1; + }), + d.postMessage("", "*"), + (d.onmessage = k), + h + ); + } + })() + ? ((y = "setImmediate$" + Math.random() + "$"), + (w = function (h) { + h.source === d && + typeof h.data == "string" && + h.data.indexOf(y) === 0 && + m(+h.data.slice(y.length)); + }), + d.addEventListener + ? d.addEventListener("message", w, !1) + : d.attachEvent("onmessage", w), + (l = function (h) { + d.postMessage(y + h, "*"); + })) + : d.MessageChannel + ? (((p = new MessageChannel()).port1.onmessage = + function (h) { + m(h.data); + }), + (l = function (h) { + p.port2.postMessage(h); + })) + : c && "onreadystatechange" in c.createElement("script") + ? ((f = c.documentElement), + (l = function (h) { + var k = c.createElement("script"); + (k.onreadystatechange = function () { + m(h), + (k.onreadystatechange = null), + f.removeChild(k), + (k = null); + }), + f.appendChild(k); + })) + : (l = function (h) { + setTimeout(m, 0, h); + }), + (u.setImmediate = function (h) { + typeof h != "function" && (h = new Function("" + h)); + for ( + var k = new Array(arguments.length - 1), E = 0; + E < k.length; + E++ + ) + k[E] = arguments[E + 1]; + var T = { callback: h, args: k }; + return (t[b] = T), l(b), b++; + }), + (u.clearImmediate = g); + } + function g(h) { + delete t[h]; + } + function m(h) { + if (n) setTimeout(m, 0, h); + else { + var k = t[h]; + if (k) { + n = !0; + try { + (function (E) { + var T = E.callback, + j = E.args; + switch (j.length) { + case 0: + T(); + break; + case 1: + T(j[0]); + break; + case 2: + T(j[0], j[1]); + break; + case 3: + T(j[0], j[1], j[2]); + break; + default: + T.apply(v, j); + } + })(k); + } finally { + g(h), (n = !1); + } + } + } + } + })(typeof self > "u" ? (e === void 0 ? this : e) : self); + }).call(this, r(0), r(7)); + }, + function (a, s) { + var r, + e, + o = (a.exports = {}); + function d() { + throw new Error("setTimeout has not been defined"); + } + function v() { + throw new Error("clearTimeout has not been defined"); + } + function l(u) { + if (r === setTimeout) return setTimeout(u, 0); + if ((r === d || !r) && setTimeout) + return (r = setTimeout), setTimeout(u, 0); + try { + return r(u, 0); + } catch { + try { + return r.call(null, u, 0); + } catch { + return r.call(this, u, 0); + } + } + } + (function () { + try { + r = typeof setTimeout == "function" ? setTimeout : d; + } catch { + r = d; + } + try { + e = typeof clearTimeout == "function" ? clearTimeout : v; + } catch { + e = v; + } + })(); + var f, + p = [], + y = !1, + w = -1; + function b() { + y && + f && + ((y = !1), + f.length ? (p = f.concat(p)) : (w = -1), + p.length && t()); + } + function t() { + if (!y) { + var u = l(b); + y = !0; + for (var g = p.length; g; ) { + for (f = p, p = []; ++w < g; ) f && f[w].run(); + (w = -1), (g = p.length); + } + (f = null), + (y = !1), + (function (m) { + if (e === clearTimeout) return clearTimeout(m); + if ((e === v || !e) && clearTimeout) + return (e = clearTimeout), clearTimeout(m); + try { + e(m); + } catch { + try { + return e.call(null, m); + } catch { + return e.call(this, m); + } + } + })(u); + } + } + function n(u, g) { + (this.fun = u), (this.array = g); + } + function c() {} + (o.nextTick = function (u) { + var g = new Array(arguments.length - 1); + if (arguments.length > 1) + for (var m = 1; m < arguments.length; m++) + g[m - 1] = arguments[m]; + p.push(new n(u, g)), p.length !== 1 || y || l(t); + }), + (n.prototype.run = function () { + this.fun.apply(null, this.array); + }), + (o.title = "browser"), + (o.browser = !0), + (o.env = {}), + (o.argv = []), + (o.version = ""), + (o.versions = {}), + (o.on = c), + (o.addListener = c), + (o.once = c), + (o.off = c), + (o.removeListener = c), + (o.removeAllListeners = c), + (o.emit = c), + (o.prependListener = c), + (o.prependOnceListener = c), + (o.listeners = function (u) { + return []; + }), + (o.binding = function (u) { + throw new Error("process.binding is not supported"); + }), + (o.cwd = function () { + return "/"; + }), + (o.chdir = function (u) { + throw new Error("process.chdir is not supported"); + }), + (o.umask = function () { + return 0; + }); + }, + function (a, s, r) { + function e(d, v) { + for (var l = 0; l < v.length; l++) { + var f = v[l]; + (f.enumerable = f.enumerable || !1), + (f.configurable = !0), + "value" in f && (f.writable = !0), + Object.defineProperty(d, f.key, f); + } + } + var o = r(9); + a.exports = (function () { + function d() { + (function (p, y) { + if (!(p instanceof y)) + throw new TypeError("Cannot call a class as a function"); + })(this, d); + } + var v, l, f; + return ( + (v = d), + (f = [ + { + key: "urlEncode", + value: function (p) { + return o(p); + }, + }, + { + key: "jsonEncode", + value: function (p) { + return JSON.stringify(p); + }, + }, + { + key: "formEncode", + value: function (p) { + if (this.isFormData(p)) return p; + if (this.isFormElement(p)) return new FormData(p); + if (this.isObject(p)) { + var y = new FormData(); + return ( + Object.keys(p).forEach(function (w) { + var b = p[w]; + y.append(w, b); + }), + y + ); + } + throw new Error( + "`data` must be an instance of Object, FormData or
HTMLElement", + ); + }, + }, + { + key: "isObject", + value: function (p) { + return ( + Object.prototype.toString.call(p) === "[object Object]" + ); + }, + }, + { + key: "isFormData", + value: function (p) { + return p instanceof FormData; + }, + }, + { + key: "isFormElement", + value: function (p) { + return p instanceof HTMLFormElement; + }, + }, + { + key: "selectFiles", + value: function () { + var p = + arguments.length > 0 && arguments[0] !== void 0 + ? arguments[0] + : {}; + return new Promise(function (y, w) { + var b = document.createElement("INPUT"); + (b.type = "file"), + p.multiple && b.setAttribute("multiple", "multiple"), + p.accept && b.setAttribute("accept", p.accept), + (b.style.display = "none"), + document.body.appendChild(b), + b.addEventListener( + "change", + function (t) { + var n = t.target.files; + y(n), document.body.removeChild(b); + }, + !1, + ), + b.click(); + }); + }, + }, + { + key: "parseHeaders", + value: function (p) { + var y = p.trim().split(/[\r\n]+/), + w = {}; + return ( + y.forEach(function (b) { + var t = b.split(": "), + n = t.shift(), + c = t.join(": "); + n && (w[n] = c); + }), + w + ); + }, + }, + ]), + (l = null) && e(v.prototype, l), + f && e(v, f), + d + ); + })(); + }, + function (a, s) { + var r = function (o) { + return encodeURIComponent(o) + .replace(/[!'()*]/g, escape) + .replace(/%20/g, "+"); + }, + e = function (o, d, v, l) { + return ( + (d = d || null), + (v = v || "&"), + (l = l || null), + o + ? (function (f) { + for (var p = new Array(), y = 0; y < f.length; y++) + f[y] && p.push(f[y]); + return p; + })( + Object.keys(o).map(function (f) { + var p, + y, + w = f; + if ( + (l && (w = l + "[" + w + "]"), + typeof o[f] == "object" && o[f] !== null) + ) + p = e(o[f], null, v, w); + else { + d && + ((y = w), + (w = + !isNaN(parseFloat(y)) && isFinite(y) + ? d + Number(w) + : w)); + var b = o[f]; + (b = + (b = + (b = + (b = b === !0 ? "1" : b) === !1 ? "0" : b) === 0 + ? "0" + : b) || ""), + (p = r(w) + "=" + r(b)); + } + return p; + }), + ) + .join(v) + .replace(/[!'()*]/g, "") + : "" + ); + }; + a.exports = e; + }, + ]); + }); + })(I); + var q = I.exports; + const _ = D(q); + function L(C) { + return C !== void 0 && typeof C.then == "function"; + } + class A { + constructor({ config: i, onUpload: a, onError: s }) { + (this.config = i), (this.onUpload = a), (this.onError = s); + } + uploadSelectedFile({ onPreview: i }) { + const a = function (r) { + const e = new FileReader(); + e.readAsDataURL(r), + (e.onload = (o) => { + i(o.target.result); + }); + }; + let s; + if ( + this.config.uploader && + typeof this.config.uploader.uploadByFile == "function" + ) { + const r = this.config.uploader.uploadByFile; + s = _.selectFiles({ accept: this.config.types ?? "image/*" }).then( + (e) => { + a(e[0]); + const o = r(e[0]); + return ( + L(o) || + console.warn( + "Custom uploader method uploadByFile should return a Promise", + ), + o + ); + }, + ); + } else + s = _.transport({ + url: this.config.endpoints.byFile, + data: this.config.additionalRequestData, + accept: this.config.types ?? "image/*", + headers: this.config.additionalRequestHeaders, + beforeSend: (r) => { + a(r[0]); + }, + fieldName: this.config.field ?? "image", + }).then((r) => r.body); + s.then((r) => { + this.onUpload(r); + }).catch((r) => { + this.onError(r); + }); + } + uploadByUrl(i) { + let a; + this.config.uploader && + typeof this.config.uploader.uploadByUrl == "function" + ? ((a = this.config.uploader.uploadByUrl(i)), + L(a) || + console.warn( + "Custom uploader method uploadByUrl should return a Promise", + )) + : (a = _.post({ + url: this.config.endpoints.byUrl, + data: Object.assign({ url: i }, this.config.additionalRequestData), + type: _.contentType.JSON, + headers: this.config.additionalRequestHeaders, + }).then((s) => s.body)), + a + .then((s) => { + this.onUpload(s); + }) + .catch((s) => { + this.onError(s); + }); + } + uploadByFile(i, { onPreview: a }) { + const s = new FileReader(); + s.readAsDataURL(i), + (s.onload = (e) => { + a(e.target.result); + }); + let r; + if ( + this.config.uploader && + typeof this.config.uploader.uploadByFile == "function" + ) + (r = this.config.uploader.uploadByFile(i)), + L(r) || + console.warn( + "Custom uploader method uploadByFile should return a Promise", + ); + else { + const e = new FormData(); + e.append(this.config.field ?? "image", i), + this.config.additionalRequestData && + Object.keys(this.config.additionalRequestData).length && + Object.entries(this.config.additionalRequestData).forEach( + ([o, d]) => { + e.append(o, d); + }, + ), + (r = _.post({ + url: this.config.endpoints.byFile, + data: e, + type: _.contentType.JSON, + headers: this.config.additionalRequestHeaders, + }).then((o) => o.body)); + } + r.then((e) => { + this.onUpload(e); + }).catch((e) => { + this.onError(e); + }); + } + } + /** + * Image Tool for the Editor.js + * @author CodeX + * @license MIT + * @see {@link https://github.com/editor-js/image} + * + * To developers. + * To simplify Tool structure, we split it to 4 parts: + * 1) index.ts — main Tool's interface, public API and methods for working with data + * 2) uploader.ts — module that has methods for sending files via AJAX: from device, by URL or File pasting + * 3) ui.ts — module for UI manipulations: render, showing preloader, etc + * + * For debug purposes there is a testing server + * that can save uploaded files and return a Response {@link UploadResponseFormat} + * + * $ node dev/server.js + * + * It will expose 8008 port, so you can pass http://localhost:8008 with the Tools config: + * + * image: { + * class: ImageTool, + * config: { + * endpoints: { + * byFile: 'http://localhost:8008/uploadFile', + * byUrl: 'http://localhost:8008/fetchUrl', + * } + * }, + * }, + */ class P { + constructor({ data: i, config: a, api: s, readOnly: r, block: e }) { + (this.api = s), + (this.block = e), + (this.config = { + endpoints: a.endpoints, + additionalRequestData: a.additionalRequestData, + additionalRequestHeaders: a.additionalRequestHeaders, + field: a.field, + types: a.types, + captionPlaceholder: this.api.i18n.t( + a.captionPlaceholder ?? "Caption", + ), + buttonContent: a.buttonContent, + uploader: a.uploader, + actions: a.actions, + features: a.features || {}, + }), + (this.uploader = new A({ + config: this.config, + onUpload: (o) => this.onUpload(o), + onError: (o) => this.uploadingFailed(o), + })), + (this.ui = new U({ + api: s, + config: this.config, + onSelectFile: () => { + this.uploader.uploadSelectedFile({ + onPreview: (o) => { + this.ui.showPreloader(o); + }, + }); + }, + readOnly: r, + })), + (this._data = { + caption: "", + withBorder: !1, + withBackground: !1, + stretched: !1, + file: { url: "" }, + }), + (this.data = i); + } + static get isReadOnlySupported() { + return !0; + } + static get toolbox() { + return { icon: R, title: "Image" }; + } + static get tunes() { + return [ + { name: "withBorder", icon: F, title: "With border", toggle: !0 }, + { name: "stretched", icon: x, title: "Stretch image", toggle: !0 }, + { + name: "withBackground", + icon: S, + title: "With background", + toggle: !0, + }, + ]; + } + render() { + var i, a, s; + return ( + (((i = this.config.features) == null ? void 0 : i.caption) === !0 || + ((a = this.config.features) == null ? void 0 : a.caption) === + void 0 || + (((s = this.config.features) == null ? void 0 : s.caption) === + "optional" && + this.data.caption)) && + this.ui.applyTune("caption", !0), + this.ui.render(this.data) + ); + } + validate(i) { + return !!i.file.url; + } + save() { + const i = this.ui.nodes.caption; + return (this._data.caption = i.innerHTML), this.data; + } + renderSettings() { + var r; + const i = P.tunes.concat(this.config.actions || []), + a = { + border: "withBorder", + background: "withBackground", + stretch: "stretched", + caption: "caption", + }; + return ( + ((r = this.config.features) == null ? void 0 : r.caption) === + "optional" && + i.push({ + name: "caption", + icon: B, + title: "With caption", + toggle: !0, + }), + i + .filter((e) => { + var d, v; + const o = Object.keys(a).find((l) => a[l] === e.name); + return o === "caption" + ? ((d = this.config.features) == null ? void 0 : d.caption) !== !1 + : o == null || + ((v = this.config.features) == null ? void 0 : v[o]) !== !1; + }) + .map((e) => ({ + icon: e.icon, + label: this.api.i18n.t(e.title), + name: e.name, + toggle: e.toggle, + isActive: this.data[e.name], + onActivate: () => { + if (typeof e.action == "function") { + e.action(e.name); + return; + } + this.tuneToggled(e.name); + }, + })) + ); + } + appendCallback() { + this.ui.nodes.fileButton.click(); + } + static get pasteConfig() { + return { + tags: [{ img: { src: !0 } }], + patterns: { + image: + /https?:\/\/\S+\.(gif|jpe?g|tiff|png|svg|webp)(\?[a-z0-9=]*)?$/i, + }, + files: { mimeTypes: ["image/*"] }, + }; + } + async onPaste(i) { + switch (i.type) { + case "tag": { + const a = i.detail.data; + if (/^blob:/.test(a.src)) { + const r = await (await fetch(a.src)).blob(); + this.uploadFile(r); + break; + } + this.uploadUrl(a.src); + break; + } + case "pattern": { + const a = i.detail.data; + this.uploadUrl(a); + break; + } + case "file": { + const a = i.detail.file; + this.uploadFile(a); + break; + } + } + } + set data(i) { + (this.image = i.file), + (this._data.caption = i.caption || ""), + this.ui.fillCaption(this._data.caption), + P.tunes.forEach(({ name: a }) => { + const s = typeof i[a] < "u" ? i[a] === !0 || i[a] === "true" : !1; + this.setTune(a, s); + }); + } + get data() { + return this._data; + } + set image(i) { + (this._data.file = i || { url: "" }), + i && i.url && this.ui.fillImage(i.url); + } + onUpload(i) { + i.success && i.file + ? (this.image = i.file) + : this.uploadingFailed("incorrect response: " + JSON.stringify(i)); + } + uploadingFailed(i) { + console.log("Image Tool: uploading failed because of", i), + this.api.notifier.show({ + message: this.api.i18n.t( + "Couldn’t upload image. Please try another.", + ), + style: "error", + }), + this.ui.hidePreloader(); + } + tuneToggled(i) { + this.setTune(i, !this._data[i]), + i === "caption" && + !this._data[i] && + ((this._data.caption = ""), this.ui.fillCaption("")); + } + setTune(i, a) { + (this._data[i] = a), + this.ui.applyTune(i, a), + i === "stretched" && + Promise.resolve() + .then(() => { + this.block.stretched = a; + }) + .catch((s) => { + console.error(s); + }); + } + uploadFile(i) { + this.uploader.uploadByFile(i, { + onPreview: (a) => { + this.ui.showPreloader(a); + }, + }); + } + uploadUrl(i) { + this.ui.showPreloader(i), this.uploader.uploadByUrl(i); + } + } + return P; +}); +(function () { + "use strict"; + try { + if (typeof document < "u") { + var e = document.createElement("style"); + e.appendChild( + document.createTextNode( + '.ce-delimiter{line-height:1.6em;width:100%;text-align:center}.ce-delimiter:before{display:inline-block;content:"***";font-size:30px;line-height:65px;height:30px;letter-spacing:.2em}', + ), + ), + document.head.appendChild(e); + } + } catch (t) { + console.error("vite-plugin-css-injected-by-js", t); + } +})(); +(function (t, i) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = i()) + : typeof define == "function" && define.amd + ? define(i) + : ((t = typeof globalThis < "u" ? globalThis : t || self), + (t.Delimiter = i())); +})(this, function () { + "use strict"; + const t = + ''; + /** + * Delimiter Block for the Editor.js. + * + * @author CodeX (team@ifmo.su) + * @copyright CodeX 2018 + * @license The MIT License (MIT) + * @version 2.0.0 + */ class i { + static get isReadOnlySupported() { + return !0; + } + static get contentless() { + return !0; + } + constructor({ data: e, config: s, api: r }) { + (this.api = r), + (this._CSS = { block: this.api.styles.block, wrapper: "ce-delimiter" }), + (this._element = this.drawView()), + (this.data = e); + } + drawView() { + let e = document.createElement("div"); + return e.classList.add(this._CSS.wrapper, this._CSS.block), e; + } + render() { + return this._element; + } + save(e) { + return {}; + } + static get toolbox() { + return { icon: t, title: "Delimiter" }; + } + static get pasteConfig() { + return { tags: ["HR"] }; + } + onPaste(e) { + this.data = {}; + } + } + return i; +}); +(function () { + "use strict"; + try { + if (typeof document < "u") { + var e = document.createElement("style"); + e.appendChild( + document.createTextNode( + ".cdx-list{margin:0;padding-left:40px;outline:none}.cdx-list__item{padding:5.5px 0 5.5px 3px;line-height:1.6em}.cdx-list--unordered{list-style:disc}.cdx-list--ordered{list-style:decimal}.cdx-list-settings{display:flex}.cdx-list-settings .cdx-settings-button{width:50%}", + ), + ), + document.head.appendChild(e); + } + } catch (t) { + console.error("vite-plugin-css-injected-by-js", t); + } +})(); +(function (o, n) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = n()) + : typeof define == "function" && define.amd + ? define(n) + : ((o = typeof globalThis < "u" ? globalThis : o || self), + (o.List = n())); +})(this, function () { + "use strict"; + const o = "", + n = + '', + l = + ''; + class d { + static get isReadOnlySupported() { + return !0; + } + static get enableLineBreaks() { + return !0; + } + static get toolbox() { + return { icon: n, title: "List" }; + } + constructor({ data: e, config: t, api: r, readOnly: s }) { + (this._elements = { wrapper: null }), + (this.api = r), + (this.readOnly = s), + (this.settings = [ + { + name: "unordered", + label: this.api.i18n.t("Unordered"), + icon: n, + default: t.defaultStyle === "unordered" || !1, + }, + { + name: "ordered", + label: this.api.i18n.t("Ordered"), + icon: l, + default: t.defaultStyle === "ordered" || !0, + }, + ]), + (this._data = { + style: this.settings.find((i) => i.default === !0).name, + items: [], + }), + (this.data = e); + } + render() { + return ( + (this._elements.wrapper = this.makeMainTag(this._data.style)), + this._data.items.length + ? this._data.items.forEach((e) => { + this._elements.wrapper.appendChild( + this._make("li", this.CSS.item, { innerHTML: e }), + ); + }) + : this._elements.wrapper.appendChild(this._make("li", this.CSS.item)), + this.readOnly || + this._elements.wrapper.addEventListener( + "keydown", + (e) => { + const [t, r] = [13, 8]; + switch (e.keyCode) { + case t: + this.getOutofList(e); + break; + case r: + this.backspace(e); + break; + } + }, + !1, + ), + this._elements.wrapper + ); + } + save() { + return this.data; + } + static get conversionConfig() { + return { + export: (e) => e.items.join(". "), + import: (e) => ({ items: [e], style: "unordered" }), + }; + } + static get sanitize() { + return { style: {}, items: { br: !0 } }; + } + renderSettings() { + return this.settings.map((e) => ({ + ...e, + isActive: this._data.style === e.name, + closeOnActivate: !0, + onActivate: () => this.toggleTune(e.name), + })); + } + onPaste(e) { + const t = e.detail.data; + this.data = this.pasteHandler(t); + } + static get pasteConfig() { + return { tags: ["OL", "UL", "LI"] }; + } + makeMainTag(e) { + const t = + e === "ordered" ? this.CSS.wrapperOrdered : this.CSS.wrapperUnordered, + r = e === "ordered" ? "ol" : "ul"; + return this._make(r, [this.CSS.baseBlock, this.CSS.wrapper, t], { + contentEditable: !this.readOnly, + }); + } + toggleTune(e) { + const t = this.makeMainTag(e); + for (; this._elements.wrapper.hasChildNodes(); ) + t.appendChild(this._elements.wrapper.firstChild); + this._elements.wrapper.replaceWith(t), + (this._elements.wrapper = t), + (this._data.style = e); + } + get CSS() { + return { + baseBlock: this.api.styles.block, + wrapper: "cdx-list", + wrapperOrdered: "cdx-list--ordered", + wrapperUnordered: "cdx-list--unordered", + item: "cdx-list__item", + }; + } + set data(e) { + e || (e = {}), + (this._data.style = + e.style || this.settings.find((r) => r.default === !0).name), + (this._data.items = e.items || []); + const t = this._elements.wrapper; + t && t.parentNode.replaceChild(this.render(), t); + } + get data() { + this._data.items = []; + const e = this._elements.wrapper.querySelectorAll(`.${this.CSS.item}`); + for (let t = 0; t < e.length; t++) + e[t].innerHTML.replace("
", " ").trim() && + this._data.items.push(e[t].innerHTML); + return this._data; + } + _make(e, t = null, r = {}) { + const s = document.createElement(e); + Array.isArray(t) ? s.classList.add(...t) : t && s.classList.add(t); + for (const i in r) s[i] = r[i]; + return s; + } + get currentItem() { + let e = window.getSelection().anchorNode; + return ( + e.nodeType !== Node.ELEMENT_NODE && (e = e.parentNode), + e.closest(`.${this.CSS.item}`) + ); + } + getOutofList(e) { + const t = this._elements.wrapper.querySelectorAll("." + this.CSS.item); + if (t.length < 2) return; + const r = t[t.length - 1], + s = this.currentItem; + s === r && + !r.textContent.trim().length && + (s.parentElement.removeChild(s), + this.api.blocks.insert(), + this.api.caret.setToBlock(this.api.blocks.getCurrentBlockIndex()), + e.preventDefault(), + e.stopPropagation()); + } + backspace(e) { + const t = this._elements.wrapper.querySelectorAll("." + this.CSS.item), + r = t[0]; + r && + t.length < 2 && + !r.innerHTML.replace("
", " ").trim() && + e.preventDefault(); + } + selectItem(e) { + e.preventDefault(); + const t = window.getSelection(), + r = t.anchorNode.parentNode, + s = r.closest("." + this.CSS.item), + i = new Range(); + i.selectNodeContents(s), t.removeAllRanges(), t.addRange(i); + } + pasteHandler(e) { + const { tagName: t } = e; + let r; + switch (t) { + case "OL": + r = "ordered"; + break; + case "UL": + case "LI": + r = "unordered"; + } + const s = { style: r, items: [] }; + if (t === "LI") s.items = [e.innerHTML]; + else { + const i = Array.from(e.querySelectorAll("LI")); + s.items = i.map((a) => a.innerHTML).filter((a) => !!a.trim()); + } + return s; + } + } + return d; +}); +(function () { + "use strict"; + try { + if (typeof document < "u") { + var t = document.createElement("style"); + t.appendChild( + document.createTextNode( + ".cdx-quote-icon svg{transform:rotate(180deg)}.cdx-quote{margin:0}.cdx-quote__text{min-height:158px;margin-bottom:10px}.cdx-quote [contentEditable=true][data-placeholder]:before{position:absolute;content:attr(data-placeholder);color:#707684;font-weight:400;opacity:0}.cdx-quote [contentEditable=true][data-placeholder]:empty:before{opacity:1}.cdx-quote [contentEditable=true][data-placeholder]:empty:focus:before{opacity:0}.cdx-quote-settings{display:flex}.cdx-quote-settings .cdx-settings-button{width:50%}", + ), + ), + document.head.appendChild(t); + } + } catch (e) { + console.error("vite-plugin-css-injected-by-js", e); + } +})(); +(function (v, d) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = d()) + : typeof define == "function" && define.amd + ? define(d) + : ((v = typeof globalThis < "u" ? globalThis : v || self), + (v.Quote = d())); +})(this, function () { + "use strict"; + const v = "", + d = + '', + Te = + '', + je = + ''; + var m = + typeof globalThis < "u" + ? globalThis + : typeof window < "u" + ? window + : typeof global < "u" + ? global + : typeof self < "u" + ? self + : {}; + function Se(e) { + if (e.__esModule) return e; + var t = e.default; + if (typeof t == "function") { + var n = function r() { + return this instanceof r + ? Reflect.construct(t, arguments, this.constructor) + : t.apply(this, arguments); + }; + n.prototype = t.prototype; + } else n = {}; + return ( + Object.defineProperty(n, "__esModule", { value: !0 }), + Object.keys(e).forEach(function (r) { + var i = Object.getOwnPropertyDescriptor(e, r); + Object.defineProperty( + n, + r, + i.get + ? i + : { + enumerable: !0, + get: function () { + return e[r]; + }, + }, + ); + }), + n + ); + } + var b = {}, + T = {}, + j = {}; + Object.defineProperty(j, "__esModule", { value: !0 }), + (j.allInputsSelector = Ce); + function Ce() { + var e = ["text", "password", "email", "number", "search", "tel", "url"]; + return ( + "[contenteditable=true], textarea, input:not([type]), " + + e + .map(function (t) { + return 'input[type="'.concat(t, '"]'); + }) + .join(", ") + ); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.allInputsSelector = void 0); + var t = j; + Object.defineProperty(e, "allInputsSelector", { + enumerable: !0, + get: function () { + return t.allInputsSelector; + }, + }); + })(T); + var c = {}, + S = {}; + Object.defineProperty(S, "__esModule", { value: !0 }), (S.isNativeInput = Le); + function Le(e) { + var t = ["INPUT", "TEXTAREA"]; + return e && e.tagName ? t.includes(e.tagName) : !1; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isNativeInput = void 0); + var t = S; + Object.defineProperty(e, "isNativeInput", { + enumerable: !0, + get: function () { + return t.isNativeInput; + }, + }); + })(c); + var ae = {}, + C = {}; + Object.defineProperty(C, "__esModule", { value: !0 }), (C.append = Me); + function Me(e, t) { + Array.isArray(t) + ? t.forEach(function (n) { + e.appendChild(n); + }) + : e.appendChild(t); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), (e.append = void 0); + var t = C; + Object.defineProperty(e, "append", { + enumerable: !0, + get: function () { + return t.append; + }, + }); + })(ae); + var L = {}, + M = {}; + Object.defineProperty(M, "__esModule", { value: !0 }), (M.blockElements = ke); + function ke() { + return [ + "address", + "article", + "aside", + "blockquote", + "canvas", + "div", + "dl", + "dt", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "header", + "hgroup", + "hr", + "li", + "main", + "nav", + "noscript", + "ol", + "output", + "p", + "pre", + "ruby", + "section", + "table", + "tbody", + "thead", + "tr", + "tfoot", + "ul", + "video", + ]; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.blockElements = void 0); + var t = M; + Object.defineProperty(e, "blockElements", { + enumerable: !0, + get: function () { + return t.blockElements; + }, + }); + })(L); + var le = {}, + k = {}; + Object.defineProperty(k, "__esModule", { value: !0 }), + (k.calculateBaseline = we); + function we(e) { + var t = window.getComputedStyle(e), + n = parseFloat(t.fontSize), + r = parseFloat(t.lineHeight) || n * 1.2, + i = parseFloat(t.paddingTop), + a = parseFloat(t.borderTopWidth), + l = parseFloat(t.marginTop), + u = n * 0.8, + p = (r - n) / 2, + s = l + a + i + p + u; + return s; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.calculateBaseline = void 0); + var t = k; + Object.defineProperty(e, "calculateBaseline", { + enumerable: !0, + get: function () { + return t.calculateBaseline; + }, + }); + })(le); + var ue = {}, + w = {}, + N = {}, + I = {}; + Object.defineProperty(I, "__esModule", { value: !0 }), + (I.isContentEditable = Ne); + function Ne(e) { + return e.contentEditable === "true"; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isContentEditable = void 0); + var t = I; + Object.defineProperty(e, "isContentEditable", { + enumerable: !0, + get: function () { + return t.isContentEditable; + }, + }); + })(N), + Object.defineProperty(w, "__esModule", { value: !0 }), + (w.canSetCaret = $e); + var Ie = c, + Ae = N; + function $e(e) { + var t = !0; + if ((0, Ie.isNativeInput)(e)) + switch (e.type) { + case "file": + case "checkbox": + case "radio": + case "hidden": + case "submit": + case "button": + case "image": + case "reset": + t = !1; + break; + } + else t = (0, Ae.isContentEditable)(e); + return t; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.canSetCaret = void 0); + var t = w; + Object.defineProperty(e, "canSetCaret", { + enumerable: !0, + get: function () { + return t.canSetCaret; + }, + }); + })(ue); + var _ = {}, + A = {}; + function Be(e, t, n) { + const r = n.value !== void 0 ? "value" : "get", + i = n[r], + a = `#${t}Cache`; + if ( + ((n[r] = function (...l) { + return this[a] === void 0 && (this[a] = i.apply(this, l)), this[a]; + }), + r === "get" && n.set) + ) { + const l = n.set; + n.set = function (u) { + delete e[a], l.apply(this, u); + }; + } + return n; + } + function oe() { + const e = { win: !1, mac: !1, x11: !1, linux: !1 }, + t = Object.keys(e).find( + (n) => window.navigator.appVersion.toLowerCase().indexOf(n) !== -1, + ); + return t !== void 0 && (e[t] = !0), e; + } + function $(e) { + return ( + e != null && + e !== "" && + (typeof e != "object" || Object.keys(e).length > 0) + ); + } + function De(e) { + return !$(e); + } + const He = () => + typeof window < "u" && + window.navigator !== null && + $(window.navigator.platform) && + (/iP(ad|hone|od)/.test(window.navigator.platform) || + (window.navigator.platform === "MacIntel" && + window.navigator.maxTouchPoints > 1)); + function Re(e) { + const t = oe(); + return ( + (e = e + .replace(/shift/gi, "⇧") + .replace(/backspace/gi, "⌫") + .replace(/enter/gi, "⏎") + .replace(/up/gi, "↑") + .replace(/left/gi, "→") + .replace(/down/gi, "↓") + .replace(/right/gi, "←") + .replace(/escape/gi, "⎋") + .replace(/insert/gi, "Ins") + .replace(/delete/gi, "␡") + .replace(/\+/gi, "+")), + t.mac + ? (e = e.replace(/ctrl|cmd/gi, "⌘").replace(/alt/gi, "⌥")) + : (e = e.replace(/cmd/gi, "Ctrl").replace(/windows/gi, "WIN")), + e + ); + } + function Fe(e) { + return e[0].toUpperCase() + e.slice(1); + } + function We(e) { + const t = document.createElement("div"); + (t.style.position = "absolute"), + (t.style.left = "-999px"), + (t.style.bottom = "-999px"), + (t.innerHTML = e), + document.body.appendChild(t); + const n = window.getSelection(), + r = document.createRange(); + if ((r.selectNode(t), n === null)) + throw new Error("Cannot copy text to clipboard"); + n.removeAllRanges(), + n.addRange(r), + document.execCommand("copy"), + document.body.removeChild(t); + } + function Ue(e, t, n) { + let r; + return (...i) => { + const a = this, + l = () => { + (r = void 0), n !== !0 && e.apply(a, i); + }, + u = n === !0 && r !== void 0; + window.clearTimeout(r), (r = window.setTimeout(l, t)), u && e.apply(a, i); + }; + } + function o(e) { + return Object.prototype.toString + .call(e) + .match(/\s([a-zA-Z]+)/)[1] + .toLowerCase(); + } + function qe(e) { + return o(e) === "boolean"; + } + function ce(e) { + return o(e) === "function" || o(e) === "asyncfunction"; + } + function ze(e) { + return ce(e) && /^\s*class\s+/.test(e.toString()); + } + function Ge(e) { + return o(e) === "number"; + } + function y(e) { + return o(e) === "object"; + } + function Ke(e) { + return Promise.resolve(e) === e; + } + function Qe(e) { + return o(e) === "string"; + } + function Xe(e) { + return o(e) === "undefined"; + } + function B(e, ...t) { + if (!t.length) return e; + const n = t.shift(); + if (y(e) && y(n)) + for (const r in n) + y(n[r]) + ? (e[r] === void 0 && Object.assign(e, { [r]: {} }), B(e[r], n[r])) + : Object.assign(e, { [r]: n[r] }); + return B(e, ...t); + } + function Ye(e, t, n) { + const r = `«${t}» is deprecated and will be removed in the next major release. Please use the «${n}» instead.`; + e && console.warn(r); + } + function Ve(e) { + try { + return new URL(e).href; + } catch {} + return e.substring(0, 2) === "//" + ? window.location.protocol + e + : window.location.origin + e; + } + function Ze(e) { + return ( + (e > 47 && e < 58) || + e === 32 || + e === 13 || + e === 229 || + (e > 64 && e < 91) || + (e > 95 && e < 112) || + (e > 185 && e < 193) || + (e > 218 && e < 223) + ); + } + const Je = { + BACKSPACE: 8, + TAB: 9, + ENTER: 13, + SHIFT: 16, + CTRL: 17, + ALT: 18, + ESC: 27, + SPACE: 32, + LEFT: 37, + UP: 38, + DOWN: 40, + RIGHT: 39, + DELETE: 46, + META: 91, + SLASH: 191, + }, + xe = { LEFT: 0, WHEEL: 1, RIGHT: 2, BACKWARD: 3, FORWARD: 4 }; + class et { + constructor() { + this.completed = Promise.resolve(); + } + add(t) { + return new Promise((n, r) => { + this.completed = this.completed.then(t).then(n).catch(r); + }); + } + } + function tt(e, t, n = void 0) { + let r, + i, + a, + l = null, + u = 0; + n || (n = {}); + const p = function () { + (u = n.leading === !1 ? 0 : Date.now()), + (l = null), + (a = e.apply(r, i)), + l === null && (r = i = null); + }; + return function () { + const s = Date.now(); + !u && n.leading === !1 && (u = s); + const g = t - (s - u); + return ( + (r = this), + (i = arguments), + g <= 0 || g > t + ? (l && (clearTimeout(l), (l = null)), + (u = s), + (a = e.apply(r, i)), + l === null && (r = i = null)) + : !l && n.trailing !== !1 && (l = setTimeout(p, g)), + a + ); + }; + } + const D = Se( + Object.freeze( + Object.defineProperty( + { + __proto__: null, + PromiseQueue: et, + beautifyShortcut: Re, + cacheable: Be, + capitalize: Fe, + copyTextToClipboard: We, + debounce: Ue, + deepMerge: B, + deprecationAssert: Ye, + getUserOS: oe, + getValidUrl: Ve, + isBoolean: qe, + isClass: ze, + isEmpty: De, + isFunction: ce, + isIosDevice: He, + isNumber: Ge, + isObject: y, + isPrintableKey: Ze, + isPromise: Ke, + isString: Qe, + isUndefined: Xe, + keyCodes: Je, + mouseButtons: xe, + notEmpty: $, + throttle: tt, + typeOf: o, + }, + Symbol.toStringTag, + { value: "Module" }, + ), + ), + ); + Object.defineProperty(A, "__esModule", { value: !0 }), + (A.containsOnlyInlineElements = it); + var nt = D, + rt = L; + function it(e) { + var t; + (0, nt.isString)(e) + ? ((t = document.createElement("div")), (t.innerHTML = e)) + : (t = e); + var n = function (r) { + return ( + !(0, rt.blockElements)().includes(r.tagName.toLowerCase()) && + Array.from(r.children).every(n) + ); + }; + return Array.from(t.children).every(n); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.containsOnlyInlineElements = void 0); + var t = A; + Object.defineProperty(e, "containsOnlyInlineElements", { + enumerable: !0, + get: function () { + return t.containsOnlyInlineElements; + }, + }); + })(_); + var se = {}, + H = {}, + h = {}, + R = {}; + Object.defineProperty(R, "__esModule", { value: !0 }), (R.make = at); + function at(e, t, n) { + var r; + t === void 0 && (t = null), n === void 0 && (n = {}); + var i = document.createElement(e); + if (Array.isArray(t)) { + var a = t.filter(function (u) { + return u !== void 0; + }); + (r = i.classList).add.apply(r, a); + } else t !== null && i.classList.add(t); + for (var l in n) + Object.prototype.hasOwnProperty.call(n, l) && (i[l] = n[l]); + return i; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), (e.make = void 0); + var t = R; + Object.defineProperty(e, "make", { + enumerable: !0, + get: function () { + return t.make; + }, + }); + })(h), + Object.defineProperty(H, "__esModule", { value: !0 }), + (H.fragmentToString = ut); + var lt = h; + function ut(e) { + var t = (0, lt.make)("div"); + return t.appendChild(e), t.innerHTML; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.fragmentToString = void 0); + var t = H; + Object.defineProperty(e, "fragmentToString", { + enumerable: !0, + get: function () { + return t.fragmentToString; + }, + }); + })(se); + var de = {}, + F = {}; + Object.defineProperty(F, "__esModule", { value: !0 }), + (F.getContentLength = ct); + var ot = c; + function ct(e) { + var t, n; + return (0, ot.isNativeInput)(e) + ? e.value.length + : e.nodeType === Node.TEXT_NODE + ? e.length + : (n = + (t = e.textContent) === null || t === void 0 + ? void 0 + : t.length) !== null && n !== void 0 + ? n + : 0; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.getContentLength = void 0); + var t = F; + Object.defineProperty(e, "getContentLength", { + enumerable: !0, + get: function () { + return t.getContentLength; + }, + }); + })(de); + var W = {}, + U = {}, + fe = + (m && m.__spreadArray) || + function (e, t, n) { + if (n || arguments.length === 2) + for (var r = 0, i = t.length, a; r < i; r++) + (a || !(r in t)) && + (a || (a = Array.prototype.slice.call(t, 0, r)), (a[r] = t[r])); + return e.concat(a || Array.prototype.slice.call(t)); + }; + Object.defineProperty(U, "__esModule", { value: !0 }), + (U.getDeepestBlockElements = pe); + var st = _; + function pe(e) { + return (0, st.containsOnlyInlineElements)(e) + ? [e] + : Array.from(e.children).reduce(function (t, n) { + return fe(fe([], t, !0), pe(n), !0); + }, []); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.getDeepestBlockElements = void 0); + var t = U; + Object.defineProperty(e, "getDeepestBlockElements", { + enumerable: !0, + get: function () { + return t.getDeepestBlockElements; + }, + }); + })(W); + var ge = {}, + q = {}, + E = {}, + z = {}; + Object.defineProperty(z, "__esModule", { value: !0 }), + (z.isLineBreakTag = dt); + function dt(e) { + return ["BR", "WBR"].includes(e.tagName); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isLineBreakTag = void 0); + var t = z; + Object.defineProperty(e, "isLineBreakTag", { + enumerable: !0, + get: function () { + return t.isLineBreakTag; + }, + }); + })(E); + var O = {}, + G = {}; + Object.defineProperty(G, "__esModule", { value: !0 }), (G.isSingleTag = ft); + function ft(e) { + return [ + "AREA", + "BASE", + "BR", + "COL", + "COMMAND", + "EMBED", + "HR", + "IMG", + "INPUT", + "KEYGEN", + "LINK", + "META", + "PARAM", + "SOURCE", + "TRACK", + "WBR", + ].includes(e.tagName); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isSingleTag = void 0); + var t = G; + Object.defineProperty(e, "isSingleTag", { + enumerable: !0, + get: function () { + return t.isSingleTag; + }, + }); + })(O), + Object.defineProperty(q, "__esModule", { value: !0 }), + (q.getDeepestNode = ve); + var pt = c, + gt = E, + vt = O; + function ve(e, t) { + t === void 0 && (t = !1); + var n = t ? "lastChild" : "firstChild", + r = t ? "previousSibling" : "nextSibling"; + if (e.nodeType === Node.ELEMENT_NODE && e[n]) { + var i = e[n]; + if ( + (0, vt.isSingleTag)(i) && + !(0, pt.isNativeInput)(i) && + !(0, gt.isLineBreakTag)(i) + ) + if (i[r]) i = i[r]; + else if (i.parentNode !== null && i.parentNode[r]) i = i.parentNode[r]; + else return i.parentNode; + return ve(i, t); + } + return e; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.getDeepestNode = void 0); + var t = q; + Object.defineProperty(e, "getDeepestNode", { + enumerable: !0, + get: function () { + return t.getDeepestNode; + }, + }); + })(ge); + var me = {}, + K = {}, + P = + (m && m.__spreadArray) || + function (e, t, n) { + if (n || arguments.length === 2) + for (var r = 0, i = t.length, a; r < i; r++) + (a || !(r in t)) && + (a || (a = Array.prototype.slice.call(t, 0, r)), (a[r] = t[r])); + return e.concat(a || Array.prototype.slice.call(t)); + }; + Object.defineProperty(K, "__esModule", { value: !0 }), (K.findAllInputs = ht); + var mt = _, + bt = W, + _t = T, + yt = c; + function ht(e) { + return Array.from(e.querySelectorAll((0, _t.allInputsSelector)())).reduce( + function (t, n) { + return (0, yt.isNativeInput)(n) || (0, mt.containsOnlyInlineElements)(n) + ? P(P([], t, !0), [n], !1) + : P(P([], t, !0), (0, bt.getDeepestBlockElements)(n), !0); + }, + [], + ); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.findAllInputs = void 0); + var t = K; + Object.defineProperty(e, "findAllInputs", { + enumerable: !0, + get: function () { + return t.findAllInputs; + }, + }); + })(me); + var be = {}, + Q = {}; + Object.defineProperty(Q, "__esModule", { value: !0 }), + (Q.isCollapsedWhitespaces = Et); + function Et(e) { + return !/[^\t\n\r ]/.test(e); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isCollapsedWhitespaces = void 0); + var t = Q; + Object.defineProperty(e, "isCollapsedWhitespaces", { + enumerable: !0, + get: function () { + return t.isCollapsedWhitespaces; + }, + }); + })(be); + var X = {}, + Y = {}; + Object.defineProperty(Y, "__esModule", { value: !0 }), (Y.isElement = Pt); + var Ot = D; + function Pt(e) { + return (0, Ot.isNumber)(e) + ? !1 + : !!e && !!e.nodeType && e.nodeType === Node.ELEMENT_NODE; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isElement = void 0); + var t = Y; + Object.defineProperty(e, "isElement", { + enumerable: !0, + get: function () { + return t.isElement; + }, + }); + })(X); + var _e = {}, + V = {}, + Z = {}, + J = {}; + Object.defineProperty(J, "__esModule", { value: !0 }), (J.isLeaf = Tt); + function Tt(e) { + return e === null ? !1 : e.childNodes.length === 0; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), (e.isLeaf = void 0); + var t = J; + Object.defineProperty(e, "isLeaf", { + enumerable: !0, + get: function () { + return t.isLeaf; + }, + }); + })(Z); + var x = {}, + ee = {}; + Object.defineProperty(ee, "__esModule", { value: !0 }), (ee.isNodeEmpty = Mt); + var jt = E, + St = X, + Ct = c, + Lt = O; + function Mt(e, t) { + var n = ""; + return (0, Lt.isSingleTag)(e) && !(0, jt.isLineBreakTag)(e) + ? !1 + : ((0, St.isElement)(e) && (0, Ct.isNativeInput)(e) + ? (n = e.value) + : e.textContent !== null && (n = e.textContent.replace("​", "")), + t !== void 0 && (n = n.replace(new RegExp(t, "g"), "")), + n.trim().length === 0); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isNodeEmpty = void 0); + var t = ee; + Object.defineProperty(e, "isNodeEmpty", { + enumerable: !0, + get: function () { + return t.isNodeEmpty; + }, + }); + })(x), + Object.defineProperty(V, "__esModule", { value: !0 }), + (V.isEmpty = Nt); + var kt = Z, + wt = x; + function Nt(e, t) { + e.normalize(); + for (var n = [e]; n.length > 0; ) { + var r = n.shift(); + if (r) { + if (((e = r), (0, kt.isLeaf)(e) && !(0, wt.isNodeEmpty)(e, t))) + return !1; + n.push.apply(n, Array.from(e.childNodes)); + } + } + return !0; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), (e.isEmpty = void 0); + var t = V; + Object.defineProperty(e, "isEmpty", { + enumerable: !0, + get: function () { + return t.isEmpty; + }, + }); + })(_e); + var ye = {}, + te = {}; + Object.defineProperty(te, "__esModule", { value: !0 }), (te.isFragment = At); + var It = D; + function At(e) { + return (0, It.isNumber)(e) + ? !1 + : !!e && !!e.nodeType && e.nodeType === Node.DOCUMENT_FRAGMENT_NODE; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isFragment = void 0); + var t = te; + Object.defineProperty(e, "isFragment", { + enumerable: !0, + get: function () { + return t.isFragment; + }, + }); + })(ye); + var he = {}, + ne = {}; + Object.defineProperty(ne, "__esModule", { value: !0 }), + (ne.isHTMLString = Bt); + var $t = h; + function Bt(e) { + var t = (0, $t.make)("div"); + return (t.innerHTML = e), t.childElementCount > 0; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.isHTMLString = void 0); + var t = ne; + Object.defineProperty(e, "isHTMLString", { + enumerable: !0, + get: function () { + return t.isHTMLString; + }, + }); + })(he); + var Ee = {}, + re = {}; + Object.defineProperty(re, "__esModule", { value: !0 }), (re.offset = Dt); + function Dt(e) { + var t = e.getBoundingClientRect(), + n = window.pageXOffset || document.documentElement.scrollLeft, + r = window.pageYOffset || document.documentElement.scrollTop, + i = t.top + r, + a = t.left + n; + return { top: i, left: a, bottom: i + t.height, right: a + t.width }; + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), (e.offset = void 0); + var t = re; + Object.defineProperty(e, "offset", { + enumerable: !0, + get: function () { + return t.offset; + }, + }); + })(Ee); + var Oe = {}, + ie = {}; + Object.defineProperty(ie, "__esModule", { value: !0 }), (ie.prepend = Ht); + function Ht(e, t) { + Array.isArray(t) + ? ((t = t.reverse()), + t.forEach(function (n) { + return e.prepend(n); + })) + : e.prepend(t); + } + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), (e.prepend = void 0); + var t = ie; + Object.defineProperty(e, "prepend", { + enumerable: !0, + get: function () { + return t.prepend; + }, + }); + })(Oe), + (function (e) { + Object.defineProperty(e, "__esModule", { value: !0 }), + (e.prepend = + e.offset = + e.make = + e.isLineBreakTag = + e.isSingleTag = + e.isNodeEmpty = + e.isLeaf = + e.isHTMLString = + e.isFragment = + e.isEmpty = + e.isElement = + e.isContentEditable = + e.isCollapsedWhitespaces = + e.findAllInputs = + e.isNativeInput = + e.allInputsSelector = + e.getDeepestNode = + e.getDeepestBlockElements = + e.getContentLength = + e.fragmentToString = + e.containsOnlyInlineElements = + e.canSetCaret = + e.calculateBaseline = + e.blockElements = + e.append = + void 0); + var t = T; + Object.defineProperty(e, "allInputsSelector", { + enumerable: !0, + get: function () { + return t.allInputsSelector; + }, + }); + var n = c; + Object.defineProperty(e, "isNativeInput", { + enumerable: !0, + get: function () { + return n.isNativeInput; + }, + }); + var r = ae; + Object.defineProperty(e, "append", { + enumerable: !0, + get: function () { + return r.append; + }, + }); + var i = L; + Object.defineProperty(e, "blockElements", { + enumerable: !0, + get: function () { + return i.blockElements; + }, + }); + var a = le; + Object.defineProperty(e, "calculateBaseline", { + enumerable: !0, + get: function () { + return a.calculateBaseline; + }, + }); + var l = ue; + Object.defineProperty(e, "canSetCaret", { + enumerable: !0, + get: function () { + return l.canSetCaret; + }, + }); + var u = _; + Object.defineProperty(e, "containsOnlyInlineElements", { + enumerable: !0, + get: function () { + return u.containsOnlyInlineElements; + }, + }); + var p = se; + Object.defineProperty(e, "fragmentToString", { + enumerable: !0, + get: function () { + return p.fragmentToString; + }, + }); + var s = de; + Object.defineProperty(e, "getContentLength", { + enumerable: !0, + get: function () { + return s.getContentLength; + }, + }); + var g = W; + Object.defineProperty(e, "getDeepestBlockElements", { + enumerable: !0, + get: function () { + return g.getDeepestBlockElements; + }, + }); + var Rt = ge; + Object.defineProperty(e, "getDeepestNode", { + enumerable: !0, + get: function () { + return Rt.getDeepestNode; + }, + }); + var Ft = me; + Object.defineProperty(e, "findAllInputs", { + enumerable: !0, + get: function () { + return Ft.findAllInputs; + }, + }); + var Wt = be; + Object.defineProperty(e, "isCollapsedWhitespaces", { + enumerable: !0, + get: function () { + return Wt.isCollapsedWhitespaces; + }, + }); + var Ut = N; + Object.defineProperty(e, "isContentEditable", { + enumerable: !0, + get: function () { + return Ut.isContentEditable; + }, + }); + var qt = X; + Object.defineProperty(e, "isElement", { + enumerable: !0, + get: function () { + return qt.isElement; + }, + }); + var zt = _e; + Object.defineProperty(e, "isEmpty", { + enumerable: !0, + get: function () { + return zt.isEmpty; + }, + }); + var Gt = ye; + Object.defineProperty(e, "isFragment", { + enumerable: !0, + get: function () { + return Gt.isFragment; + }, + }); + var Kt = he; + Object.defineProperty(e, "isHTMLString", { + enumerable: !0, + get: function () { + return Kt.isHTMLString; + }, + }); + var Qt = Z; + Object.defineProperty(e, "isLeaf", { + enumerable: !0, + get: function () { + return Qt.isLeaf; + }, + }); + var Xt = x; + Object.defineProperty(e, "isNodeEmpty", { + enumerable: !0, + get: function () { + return Xt.isNodeEmpty; + }, + }); + var Yt = E; + Object.defineProperty(e, "isLineBreakTag", { + enumerable: !0, + get: function () { + return Yt.isLineBreakTag; + }, + }); + var Vt = O; + Object.defineProperty(e, "isSingleTag", { + enumerable: !0, + get: function () { + return Vt.isSingleTag; + }, + }); + var Zt = h; + Object.defineProperty(e, "make", { + enumerable: !0, + get: function () { + return Zt.make; + }, + }); + var Jt = Ee; + Object.defineProperty(e, "offset", { + enumerable: !0, + get: function () { + return Jt.offset; + }, + }); + var xt = Oe; + Object.defineProperty(e, "prepend", { + enumerable: !0, + get: function () { + return xt.prepend; + }, + }); + })(b); + var Pe = ((e) => ((e.Left = "left"), (e.Center = "center"), e))(Pe || {}); + class f { + constructor({ data: t, config: n, api: r, readOnly: i, block: a }) { + const { DEFAULT_ALIGNMENT: l } = f; + (this.api = r), + (this.readOnly = i), + (this._quotePlaceholder = + n.quotePlaceholder || f.DEFAULT_QUOTE_PLACEHOLDER), + (this._captionPlaceholder = + n.captionPlaceholder || f.DEFAULT_CAPTION_PLACEHOLDER), + (this._data = { + text: t.text || "", + caption: t.caption || "", + alignment: + (Object.values(Pe).includes(t.alignment) && t.alignment) || + n.defaultAlignment || + l, + }), + (this._CSS = { + baseClass: this.api.styles.block, + wrapper: "cdx-quote", + text: "cdx-quote__text", + input: this.api.styles.input, + caption: "cdx-quote__caption", + }), + (this._block = a); + } + static get isReadOnlySupported() { + return !0; + } + static get toolbox() { + return { icon: je, title: "Quote" }; + } + static get contentless() { + return !0; + } + static get enableLineBreaks() { + return !0; + } + static get DEFAULT_QUOTE_PLACEHOLDER() { + return "Enter a quote"; + } + static get DEFAULT_CAPTION_PLACEHOLDER() { + return "Enter a caption"; + } + static get DEFAULT_ALIGNMENT() { + return "left"; + } + static get conversionConfig() { + return { + import: "text", + export: function (t) { + return t.caption ? `${t.text} — ${t.caption}` : t.text; + }, + }; + } + get CSS() { + return { + baseClass: this.api.styles.block, + wrapper: "cdx-quote", + text: "cdx-quote__text", + input: this.api.styles.input, + caption: "cdx-quote__caption", + }; + } + get settings() { + return [ + { name: "left", icon: Te }, + { name: "center", icon: d }, + ]; + } + render() { + const t = b.make("blockquote", [this._CSS.baseClass, this._CSS.wrapper]), + n = b.make("div", [this._CSS.input, this._CSS.text], { + contentEditable: !this.readOnly, + innerHTML: this._data.text, + }), + r = b.make("div", [this._CSS.input, this._CSS.caption], { + contentEditable: !this.readOnly, + innerHTML: this._data.caption, + }); + return ( + (n.dataset.placeholder = this._quotePlaceholder), + (r.dataset.placeholder = this._captionPlaceholder), + t.appendChild(n), + t.appendChild(r), + t + ); + } + save(t) { + const n = t.querySelector(`.${this._CSS.text}`), + r = t.querySelector(`.${this._CSS.caption}`); + return Object.assign(this._data, { + text: (n == null ? void 0 : n.innerHTML) ?? "", + caption: (r == null ? void 0 : r.innerHTML) ?? "", + }); + } + static get sanitize() { + return { text: { br: !0 }, caption: { br: !0 }, alignment: {} }; + } + renderSettings() { + const t = (n) => n && n[0].toUpperCase() + n.slice(1); + return this.settings.map((n) => ({ + icon: n.icon, + label: this.api.i18n.t(`Align ${t(n.name)}`), + onActivate: () => this._toggleTune(n.name), + isActive: this._data.alignment === n.name, + closeOnActivate: !0, + })); + } + _toggleTune(t) { + (this._data.alignment = t), this._block.dispatchChange(); + } + } + return f; +}); +(function () { + "use strict"; + try { + if (typeof document < "u") { + var e = document.createElement("style"); + e.appendChild( + document.createTextNode( + '.embed-tool--loading .embed-tool__caption{display:none}.embed-tool--loading .embed-tool__preloader{display:block}.embed-tool--loading .embed-tool__content{display:none}.embed-tool__preloader{display:none;position:relative;height:200px;box-sizing:border-box;border-radius:5px;border:1px solid #e6e9eb}.embed-tool__preloader:before{content:"";position:absolute;z-index:3;left:50%;top:50%;width:30px;height:30px;margin-top:-25px;margin-left:-15px;border-radius:50%;border:2px solid #cdd1e0;border-top-color:#388ae5;box-sizing:border-box;animation:embed-preloader-spin 2s infinite linear}.embed-tool__url{position:absolute;bottom:20px;left:50%;transform:translate(-50%);max-width:250px;color:#7b7e89;font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.embed-tool__content{width:100%}.embed-tool__caption{margin-top:7px}.embed-tool__caption[contentEditable=true][data-placeholder]:before{position:absolute;content:attr(data-placeholder);color:#707684;font-weight:400;opacity:0}.embed-tool__caption[contentEditable=true][data-placeholder]:empty:before{opacity:1}.embed-tool__caption[contentEditable=true][data-placeholder]:empty:focus:before{opacity:0}@keyframes embed-preloader-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}', + ), + ), + document.head.appendChild(e); + } + } catch (o) { + console.error("vite-plugin-css-injected-by-js", o); + } +})(); +(function (c, u) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = u()) + : typeof define == "function" && define.amd + ? define(u) + : ((c = typeof globalThis < "u" ? globalThis : c || self), + (c.Embed = u())); +})(this, function () { + "use strict"; + const c = { + vimeo: { + regex: + /(?:http[s]?:\/\/)?(?:www.)?(?:player.)?vimeo\.co(?:.+\/([^\/]\d+)(?:#t=[\d]+)?s?$)/, + embedUrl: + "https://player.vimeo.com/video/<%= remote_id %>?title=0&byline=0", + html: '', + height: 320, + width: 580, + }, + youtube: { + regex: + /(?:https?:\/\/)?(?:www\.)?(?:(?:youtu\.be\/)|(?:youtube\.com)\/(?:v\/|u\/\w\/|embed\/|watch))(?:(?:\?v=)?([^#&?=]*))?((?:[?&]\w*=\w*)*)/, + embedUrl: "https://www.youtube.com/embed/<%= remote_id %>", + html: '', + height: 320, + width: 580, + id: ([n, i]) => { + if (!i && n) return n; + const r = { + start: "start", + end: "end", + t: "start", + time_continue: "start", + list: "list", + }; + let e = i + .slice(1) + .split("&") + .map((o) => { + const [l, t] = o.split("="); + return !n && l === "v" + ? ((n = t), null) + : !r[l] || + t === "LL" || + t.startsWith("RDMM") || + t.startsWith("FL") + ? null + : `${r[l]}=${t}`; + }) + .filter((o) => !!o); + return n + "?" + e.join("&"); + }, + }, + coub: { + regex: /https?:\/\/coub\.com\/view\/([^\/\?\&]+)/, + embedUrl: "https://coub.com/embed/<%= remote_id %>", + html: '', + height: 320, + width: 580, + }, + vine: { + regex: /https?:\/\/vine\.co\/v\/([^\/\?\&]+)/, + embedUrl: "https://vine.co/v/<%= remote_id %>/embed/simple/", + html: '', + height: 320, + width: 580, + }, + imgur: { + regex: /https?:\/\/(?:i\.)?imgur\.com.*\/([a-zA-Z0-9]+)(?:\.gifv)?/, + embedUrl: "http://imgur.com/<%= remote_id %>/embed", + html: '', + height: 500, + width: 540, + }, + gfycat: { + regex: /https?:\/\/gfycat\.com(?:\/detail)?\/([a-zA-Z]+)/, + embedUrl: "https://gfycat.com/ifr/<%= remote_id %>", + html: ``, + height: 436, + width: 580, + }, + "twitch-channel": { + regex: /https?:\/\/www\.twitch\.tv\/([^\/\?\&]*)\/?$/, + embedUrl: "https://player.twitch.tv/?channel=<%= remote_id %>", + html: '', + height: 366, + width: 600, + }, + "twitch-video": { + regex: /https?:\/\/www\.twitch\.tv\/(?:[^\/\?\&]*\/v|videos)\/([0-9]*)/, + embedUrl: "https://player.twitch.tv/?video=v<%= remote_id %>", + html: '', + height: 366, + width: 600, + }, + "yandex-music-album": { + regex: /https?:\/\/music\.yandex\.ru\/album\/([0-9]*)\/?$/, + embedUrl: "https://music.yandex.ru/iframe/#album/<%= remote_id %>/", + html: '', + height: 400, + width: 540, + }, + "yandex-music-track": { + regex: /https?:\/\/music\.yandex\.ru\/album\/([0-9]*)\/track\/([0-9]*)/, + embedUrl: "https://music.yandex.ru/iframe/#track/<%= remote_id %>/", + html: '', + height: 100, + width: 540, + id: (n) => n.join("/"), + }, + "yandex-music-playlist": { + regex: + /https?:\/\/music\.yandex\.ru\/users\/([^\/\?\&]*)\/playlists\/([0-9]*)/, + embedUrl: + "https://music.yandex.ru/iframe/#playlist/<%= remote_id %>/show/cover/description/", + html: '', + height: 400, + width: 540, + id: (n) => n.join("/"), + }, + codepen: { + regex: /https?:\/\/codepen\.io\/([^\/\?\&]*)\/pen\/([^\/\?\&]*)/, + embedUrl: + "https://codepen.io/<%= remote_id %>?height=300&theme-id=0&default-tab=css,result&embed-version=2", + html: "", + height: 300, + width: 600, + id: (n) => n.join("/embed/"), + }, + instagram: { + regex: /^https:\/\/(?:www\.)?instagram\.com\/(?:reel|p)\/(.*)/, + embedUrl: "https://www.instagram.com/p/<%= remote_id %>/embed", + html: '', + height: 505, + width: 400, + id: (n) => { + var i; + return (i = n == null ? void 0 : n[0]) == null + ? void 0 + : i.split("/")[0]; + }, + }, + twitter: { + regex: /^https?:\/\/(www\.)?(?:twitter\.com|x\.com)\/.+\/status\/(\d+)/, + embedUrl: + "https://platform.twitter.com/embed/Tweet.html?id=<%= remote_id %>", + html: '', + height: 300, + width: 600, + id: (n) => n[1], + }, + pinterest: { + regex: /https?:\/\/([^\/\?\&]*).pinterest.com\/pin\/([^\/\?\&]*)\/?$/, + embedUrl: + "https://assets.pinterest.com/ext/embed.html?id=<%= remote_id %>", + html: "", + id: (n) => n[1], + }, + facebook: { + regex: /https?:\/\/www.facebook.com\/([^\/\?\&]*)\/(.*)/, + embedUrl: + "https://www.facebook.com/plugins/post.php?href=https://www.facebook.com/<%= remote_id %>&width=500", + html: "", + id: (n) => n.join("/"), + }, + aparat: { + regex: /(?:http[s]?:\/\/)?(?:www.)?aparat\.com\/v\/([^\/\?\&]+)\/?/, + embedUrl: + "https://www.aparat.com/video/video/embed/videohash/<%= remote_id %>/vt/frame", + html: '', + height: 300, + width: 600, + }, + miro: { + regex: /https:\/\/miro.com\/\S+(\S{12})\/(\S+)?/, + embedUrl: "https://miro.com/app/live-embed/<%= remote_id %>", + html: '', + }, + github: { + regex: /https?:\/\/gist.github.com\/([^\/\?\&]*)\/([^\/\?\&]*)/, + embedUrl: + 'data:text/html;charset=utf-8,', + html: '', + height: 300, + width: 600, + id: (n) => `${n.join("/")}.js`, + }, + }, + u = ""; + function f(n, i, r) { + var e, o, l, t, a; + i == null && (i = 100); + function s() { + var d = Date.now() - t; + d < i && d >= 0 + ? (e = setTimeout(s, i - d)) + : ((e = null), r || ((a = n.apply(l, o)), (l = o = null))); + } + var h = function () { + (l = this), (o = arguments), (t = Date.now()); + var d = r && !e; + return ( + e || (e = setTimeout(s, i)), + d && ((a = n.apply(l, o)), (l = o = null)), + a + ); + }; + return ( + (h.clear = function () { + e && (clearTimeout(e), (e = null)); + }), + (h.flush = function () { + e && ((a = n.apply(l, o)), (l = o = null), clearTimeout(e), (e = null)); + }), + h + ); + } + f.debounce = f; + var g = f; + class m { + constructor({ data: i, api: r, readOnly: e }) { + (this.api = r), + (this._data = {}), + (this.element = null), + (this.readOnly = e), + (this.data = i); + } + set data(i) { + var h; + if (!(i instanceof Object)) + throw Error("Embed Tool data should be object"); + const { + service: r, + source: e, + embed: o, + width: l, + height: t, + caption: a = "", + } = i; + this._data = { + service: r || this.data.service, + source: e || this.data.source, + embed: o || this.data.embed, + width: l || this.data.width, + height: t || this.data.height, + caption: a || this.data.caption || "", + }; + const s = this.element; + s && ((h = s.parentNode) == null || h.replaceChild(this.render(), s)); + } + get data() { + if (this.element) { + const i = this.element.querySelector(`.${this.api.styles.input}`); + this._data.caption = i ? i.innerHTML : ""; + } + return this._data; + } + get CSS() { + return { + baseClass: this.api.styles.block, + input: this.api.styles.input, + container: "embed-tool", + containerLoading: "embed-tool--loading", + preloader: "embed-tool__preloader", + caption: "embed-tool__caption", + url: "embed-tool__url", + content: "embed-tool__content", + }; + } + render() { + if (!this.data.service) { + const a = document.createElement("div"); + return (this.element = a), a; + } + const { html: i } = m.services[this.data.service], + r = document.createElement("div"), + e = document.createElement("div"), + o = document.createElement("template"), + l = this.createPreloader(); + r.classList.add( + this.CSS.baseClass, + this.CSS.container, + this.CSS.containerLoading, + ), + e.classList.add(this.CSS.input, this.CSS.caption), + r.appendChild(l), + (e.contentEditable = (!this.readOnly).toString()), + (e.dataset.placeholder = this.api.i18n.t("Enter a caption")), + (e.innerHTML = this.data.caption || ""), + (o.innerHTML = i), + o.content.firstChild.setAttribute("src", this.data.embed), + o.content.firstChild.classList.add(this.CSS.content); + const t = this.embedIsReady(r); + return ( + o.content.firstChild && r.appendChild(o.content.firstChild), + r.appendChild(e), + t.then(() => { + r.classList.remove(this.CSS.containerLoading); + }), + (this.element = r), + r + ); + } + createPreloader() { + const i = document.createElement("preloader"), + r = document.createElement("div"); + return ( + (r.textContent = this.data.source), + i.classList.add(this.CSS.preloader), + r.classList.add(this.CSS.url), + i.appendChild(r), + i + ); + } + save() { + return this.data; + } + onPaste(i) { + var p; + const { key: r, data: e } = i.detail, + { + regex: o, + embedUrl: l, + width: t, + height: a, + id: s = (b) => b.shift() || "", + } = m.services[r], + h = (p = o.exec(e)) == null ? void 0 : p.slice(1), + d = h ? l.replace(/<%= remote_id %>/g, s(h)) : ""; + this.data = { service: r, source: e, embed: d, width: t, height: a }; + } + static prepare({ config: i = {} }) { + const { services: r = {} } = i; + let e = Object.entries(c); + const o = Object.entries(r) + .filter(([t, a]) => typeof a == "boolean" && a === !0) + .map(([t]) => t), + l = Object.entries(r) + .filter(([t, a]) => typeof a == "object") + .filter(([t, a]) => m.checkServiceConfig(a)) + .map(([t, a]) => { + const { + regex: s, + embedUrl: h, + html: d, + height: p, + width: b, + id: w, + } = a; + return [ + t, + { regex: s, embedUrl: h, html: d, height: p, width: b, id: w }, + ]; + }); + o.length && (e = e.filter(([t]) => o.includes(t))), + (e = e.concat(l)), + (m.services = e.reduce( + (t, [a, s]) => + a in t ? ((t[a] = Object.assign({}, t[a], s)), t) : ((t[a] = s), t), + {}, + )), + (m.patterns = e.reduce( + (t, [a, s]) => (s && typeof s != "boolean" && (t[a] = s.regex), t), + {}, + )); + } + static checkServiceConfig(i) { + const { regex: r, embedUrl: e, html: o, height: l, width: t, id: a } = i; + let s = + !!(r && r instanceof RegExp) && + !!(e && typeof e == "string") && + !!(o && typeof o == "string"); + return ( + (s = s && (a !== void 0 ? a instanceof Function : !0)), + (s = s && (l !== void 0 ? Number.isFinite(l) : !0)), + (s = s && (t !== void 0 ? Number.isFinite(t) : !0)), + s + ); + } + static get pasteConfig() { + return { patterns: m.patterns }; + } + static get isReadOnlySupported() { + return !0; + } + embedIsReady(i) { + let e; + return new Promise((o, l) => { + (e = new MutationObserver(g.debounce(o, 450))), + e.observe(i, { childList: !0, subtree: !0 }); + }).then(() => { + e.disconnect(); + }); + } + } + return m; +}); +(function () { + var r; + ("use strict"); + try { + if (typeof document < "u") { + var o = document.createElement("style"); + (o.nonce = + (r = document.head.querySelector("meta[property=csp-nonce]")) == null + ? void 0 + : r.content), + o.appendChild( + document.createTextNode( + '.tc-wrap{--color-background:#f9f9fb;--color-text-secondary:#7b7e89;--color-border:#e8e8eb;--cell-size:34px;--toolbox-icon-size:18px;--toolbox-padding:6px;--toolbox-aiming-field-size:calc(var(--toolbox-icon-size) + var(--toolbox-padding)*2);border-left:0;position:relative;height:100%;width:100%;margin-top:var(--toolbox-icon-size);box-sizing:border-box;display:grid;grid-template-columns:calc(100% - var(--cell-size)) var(--cell-size)}.tc-wrap--readonly{grid-template-columns:100% var(--cell-size)}.tc-wrap svg{vertical-align:top}@media print{.tc-wrap{border-left-color:var(--color-border);border-left-style:solid;border-left-width:1px;grid-template-columns:100% var(--cell-size)}}@media print{.tc-wrap .tc-row:after{display:none}}.tc-table{position:relative;width:100%;height:100%;display:grid;font-size:14px;border-top:1px solid var(--color-border);line-height:1.4}.tc-table:after{width:calc(var(--cell-size));height:100%;left:calc(var(--cell-size)*-1);top:0}.tc-table:after,.tc-table:before{position:absolute;content:""}.tc-table:before{width:100%;height:var(--toolbox-aiming-field-size);top:calc(var(--toolbox-aiming-field-size)*-1);left:0}.tc-table--heading .tc-row:first-child{font-weight:600;border-bottom:2px solid var(--color-border)}.tc-table--heading .tc-row:first-child [contenteditable]:empty:before{content:attr(heading);color:var(--color-text-secondary)}.tc-table--heading .tc-row:first-child:after{bottom:-2px;border-bottom:2px solid var(--color-border)}.tc-add-column,.tc-add-row{display:flex;color:var(--color-text-secondary)}@media print{.tc-add{display:none}}.tc-add-column{padding:4px 0;justify-content:center;border-top:1px solid var(--color-border)}.tc-add-column--disabled{visibility:hidden}@media print{.tc-add-column{display:none}}.tc-add-row{height:var(--cell-size);align-items:center;padding-left:4px;position:relative}.tc-add-row--disabled{display:none}.tc-add-row:before{content:"";position:absolute;right:calc(var(--cell-size)*-1);width:var(--cell-size);height:100%}@media print{.tc-add-row{display:none}}.tc-add-column,.tc-add-row{transition:0s;cursor:pointer;will-change:background-color}.tc-add-column:hover,.tc-add-row:hover{transition:background-color .1s ease;background-color:var(--color-background)}.tc-add-row{margin-top:1px}.tc-add-row:hover:before{transition:.1s;background-color:var(--color-background)}.tc-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(10px,1fr));position:relative;border-bottom:1px solid var(--color-border)}.tc-row:after{content:"";pointer-events:none;position:absolute;width:var(--cell-size);height:100%;bottom:-1px;right:calc(var(--cell-size)*-1);border-bottom:1px solid var(--color-border)}.tc-row--selected{background:var(--color-background)}.tc-row--selected:after{background:var(--color-background)}.tc-cell{border-right:1px solid var(--color-border);padding:6px 12px;overflow:hidden;outline:none;line-break:normal}.tc-cell--selected{background:var(--color-background)}.tc-wrap--readonly .tc-row:after{display:none}.tc-toolbox{--toolbox-padding:6px;--popover-margin:30px;--toggler-click-zone-size:30px;--toggler-dots-color:#7b7e89;--toggler-dots-color-hovered:#1d202b;position:absolute;cursor:pointer;z-index:1;opacity:0;transition:opacity .1s;will-change:left,opacity}.tc-toolbox--column{top:calc(var(--toggler-click-zone-size)*-1);transform:translate(calc(var(--toggler-click-zone-size)*-1/2));will-change:left,opacity}.tc-toolbox--row{left:calc(var(--popover-margin)*-1);transform:translateY(calc(var(--toggler-click-zone-size)*-1/2));margin-top:-1px;will-change:top,opacity}.tc-toolbox--showed{opacity:1}.tc-toolbox .tc-popover{position:absolute;top:0;left:var(--popover-margin)}.tc-toolbox__toggler{display:flex;align-items:center;justify-content:center;width:var(--toggler-click-zone-size);height:var(--toggler-click-zone-size);color:var(--toggler-dots-color);opacity:0;transition:opacity .15s ease;will-change:opacity}.tc-toolbox__toggler:hover{color:var(--toggler-dots-color-hovered)}.tc-toolbox__toggler svg{fill:currentColor}.tc-wrap:hover .tc-toolbox__toggler{opacity:1}.tc-settings .cdx-settings-button{width:50%;margin:0}.tc-popover{--color-border:#eaeaea;--color-background:#fff;--color-background-hover:rgba(232,232,235,.49);--color-background-confirm:#e24a4a;--color-background-confirm-hover:#d54040;--color-text-confirm:#fff;background:var(--color-background);border:1px solid var(--color-border);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;padding:6px;display:none;will-change:opacity,transform}.tc-popover--opened{display:block;animation:menuShowing .1s cubic-bezier(.215,.61,.355,1) forwards}.tc-popover__item{display:flex;align-items:center;padding:2px 14px 2px 2px;border-radius:5px;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none}.tc-popover__item:hover{background:var(--color-background-hover)}.tc-popover__item:not(:last-of-type){margin-bottom:2px}.tc-popover__item-icon{display:inline-flex;width:26px;height:26px;align-items:center;justify-content:center;background:var(--color-background);border-radius:5px;border:1px solid var(--color-border);margin-right:8px}.tc-popover__item-label{line-height:22px;font-size:14px;font-weight:500}.tc-popover__item--confirm{background:var(--color-background-confirm);color:var(--color-text-confirm)}.tc-popover__item--confirm:hover{background-color:var(--color-background-confirm-hover)}.tc-popover__item--confirm .tc-popover__item-icon{background:var(--color-background-confirm);border-color:#0000001a}.tc-popover__item--confirm .tc-popover__item-icon svg{transition:transform .2s ease-in;transform:rotate(90deg) scale(1.2)}.tc-popover__item--hidden{display:none}@keyframes menuShowing{0%{opacity:0;transform:translateY(-8px) scale(.9)}70%{opacity:1;transform:translateY(2px)}to{transform:translateY(0)}}', + ), + ), + document.head.appendChild(o); + } + } catch (e) { + console.error("vite-plugin-css-injected-by-js", e); + } +})(); +(function (d, p) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = p()) + : typeof define == "function" && define.amd + ? define(p) + : ((d = typeof globalThis < "u" ? globalThis : d || self), + (d.Table = p())); +})(this, function () { + "use strict"; + function d(a, t, e = {}) { + const o = document.createElement(a); + Array.isArray(t) ? o.classList.add(...t) : t && o.classList.add(t); + for (const i in e) + Object.prototype.hasOwnProperty.call(e, i) && (o[i] = e[i]); + return o; + } + function p(a) { + const t = a.getBoundingClientRect(); + return { + y1: Math.floor(t.top + window.pageYOffset), + x1: Math.floor(t.left + window.pageXOffset), + x2: Math.floor(t.right + window.pageXOffset), + y2: Math.floor(t.bottom + window.pageYOffset), + }; + } + function g(a, t) { + const e = p(a), + o = p(t); + return { + fromTopBorder: o.y1 - e.y1, + fromLeftBorder: o.x1 - e.x1, + fromRightBorder: e.x2 - o.x2, + fromBottomBorder: e.y2 - o.y2, + }; + } + function k(a, t) { + const e = a.getBoundingClientRect(), + { width: o, height: i, x: n, y: r } = e, + { clientX: h, clientY: l } = t; + return { width: o, height: i, x: h - n, y: l - r }; + } + function m(a, t) { + return t.parentNode.insertBefore(a, t); + } + function C(a, t = !0) { + const e = document.createRange(), + o = window.getSelection(); + e.selectNodeContents(a), e.collapse(t), o.removeAllRanges(), o.addRange(e); + } + class c { + constructor({ items: t }) { + (this.items = t), (this.wrapper = void 0), (this.itemEls = []); + } + static get CSS() { + return { + popover: "tc-popover", + popoverOpened: "tc-popover--opened", + item: "tc-popover__item", + itemHidden: "tc-popover__item--hidden", + itemConfirmState: "tc-popover__item--confirm", + itemIcon: "tc-popover__item-icon", + itemLabel: "tc-popover__item-label", + }; + } + render() { + return ( + (this.wrapper = d("div", c.CSS.popover)), + this.items.forEach((t, e) => { + const o = d("div", c.CSS.item), + i = d("div", c.CSS.itemIcon, { innerHTML: t.icon }), + n = d("div", c.CSS.itemLabel, { textContent: t.label }); + (o.dataset.index = e), + o.appendChild(i), + o.appendChild(n), + this.wrapper.appendChild(o), + this.itemEls.push(o); + }), + this.wrapper.addEventListener("click", (t) => { + this.popoverClicked(t); + }), + this.wrapper + ); + } + popoverClicked(t) { + const e = t.target.closest(`.${c.CSS.item}`); + if (!e) return; + const o = e.dataset.index, + i = this.items[o]; + if (i.confirmationRequired && !this.hasConfirmationState(e)) { + this.setConfirmationState(e); + return; + } + i.onClick(); + } + setConfirmationState(t) { + t.classList.add(c.CSS.itemConfirmState); + } + clearConfirmationState(t) { + t.classList.remove(c.CSS.itemConfirmState); + } + hasConfirmationState(t) { + return t.classList.contains(c.CSS.itemConfirmState); + } + get opened() { + return this.wrapper.classList.contains(c.CSS.popoverOpened); + } + open() { + this.items.forEach((t, e) => { + typeof t.hideIf == "function" && + this.itemEls[e].classList.toggle(c.CSS.itemHidden, t.hideIf()); + }), + this.wrapper.classList.add(c.CSS.popoverOpened); + } + close() { + this.wrapper.classList.remove(c.CSS.popoverOpened), + this.itemEls.forEach((t) => { + this.clearConfirmationState(t); + }); + } + } + const R = + '', + b = + '', + x = + '', + S = + '', + y = + '', + L = + '', + M = + '', + v = + '', + O = + '', + T = + '', + H = + '', + A = + ''; + class w { + constructor({ + api: t, + items: e, + onOpen: o, + onClose: i, + cssModifier: n = "", + }) { + (this.api = t), + (this.items = e), + (this.onOpen = o), + (this.onClose = i), + (this.cssModifier = n), + (this.popover = null), + (this.wrapper = this.createToolbox()); + } + static get CSS() { + return { + toolbox: "tc-toolbox", + toolboxShowed: "tc-toolbox--showed", + toggler: "tc-toolbox__toggler", + }; + } + get element() { + return this.wrapper; + } + createToolbox() { + const t = d("div", [ + w.CSS.toolbox, + this.cssModifier ? `${w.CSS.toolbox}--${this.cssModifier}` : "", + ]); + t.dataset.mutationFree = "true"; + const e = this.createPopover(), + o = this.createToggler(); + return t.appendChild(o), t.appendChild(e), t; + } + createToggler() { + const t = d("div", w.CSS.toggler, { innerHTML: M }); + return ( + t.addEventListener("click", () => { + this.togglerClicked(); + }), + t + ); + } + createPopover() { + return ( + (this.popover = new c({ items: this.items })), this.popover.render() + ); + } + togglerClicked() { + this.popover.opened + ? (this.popover.close(), this.onClose()) + : (this.popover.open(), this.onOpen()); + } + show(t) { + const e = t(); + Object.entries(e).forEach(([o, i]) => { + this.wrapper.style[o] = i; + }), + this.wrapper.classList.add(w.CSS.toolboxShowed); + } + hide() { + this.popover.close(), this.wrapper.classList.remove(w.CSS.toolboxShowed); + } + } + function B(a, t) { + let e = 0; + return function (...o) { + const i = new Date().getTime(); + if (!(i - e < a)) return (e = i), t(...o); + }; + } + const s = { + wrapper: "tc-wrap", + wrapperReadOnly: "tc-wrap--readonly", + table: "tc-table", + row: "tc-row", + withHeadings: "tc-table--heading", + rowSelected: "tc-row--selected", + cell: "tc-cell", + cellSelected: "tc-cell--selected", + addRow: "tc-add-row", + addRowDisabled: "tc-add-row--disabled", + addColumn: "tc-add-column", + addColumnDisabled: "tc-add-column--disabled", + }; + class E { + constructor(t, e, o, i) { + (this.readOnly = t), + (this.api = e), + (this.data = o), + (this.config = i), + (this.wrapper = null), + (this.table = null), + (this.toolboxColumn = this.createColumnToolbox()), + (this.toolboxRow = this.createRowToolbox()), + this.createTableWrapper(), + (this.hoveredRow = 0), + (this.hoveredColumn = 0), + (this.selectedRow = 0), + (this.selectedColumn = 0), + (this.tunes = { withHeadings: !1 }), + this.resize(), + this.fill(), + (this.focusedCell = { row: 0, column: 0 }), + (this.documentClicked = (n) => { + const r = n.target.closest(`.${s.table}`) !== null, + h = n.target.closest(`.${s.wrapper}`) === null; + (r || h) && this.hideToolboxes(); + const u = n.target.closest(`.${s.addRow}`), + f = n.target.closest(`.${s.addColumn}`); + u && u.parentNode === this.wrapper + ? (this.addRow(void 0, !0), this.hideToolboxes()) + : f && + f.parentNode === this.wrapper && + (this.addColumn(void 0, !0), this.hideToolboxes()); + }), + this.readOnly || this.bindEvents(); + } + getWrapper() { + return this.wrapper; + } + bindEvents() { + document.addEventListener("click", this.documentClicked), + this.table.addEventListener( + "mousemove", + B(150, (t) => this.onMouseMoveInTable(t)), + { passive: !0 }, + ), + (this.table.onkeypress = (t) => this.onKeyPressListener(t)), + this.table.addEventListener("keydown", (t) => + this.onKeyDownListener(t), + ), + this.table.addEventListener("focusin", (t) => + this.focusInTableListener(t), + ); + } + createColumnToolbox() { + return new w({ + api: this.api, + cssModifier: "column", + items: [ + { + label: this.api.i18n.t("Add column to left"), + icon: S, + hideIf: () => this.numberOfColumns === this.config.maxcols, + onClick: () => { + this.addColumn(this.selectedColumn, !0), this.hideToolboxes(); + }, + }, + { + label: this.api.i18n.t("Add column to right"), + icon: y, + hideIf: () => this.numberOfColumns === this.config.maxcols, + onClick: () => { + this.addColumn(this.selectedColumn + 1, !0), this.hideToolboxes(); + }, + }, + { + label: this.api.i18n.t("Delete column"), + icon: b, + hideIf: () => this.numberOfColumns === 1, + confirmationRequired: !0, + onClick: () => { + this.deleteColumn(this.selectedColumn), this.hideToolboxes(); + }, + }, + ], + onOpen: () => { + this.selectColumn(this.hoveredColumn), this.hideRowToolbox(); + }, + onClose: () => { + this.unselectColumn(); + }, + }); + } + createRowToolbox() { + return new w({ + api: this.api, + cssModifier: "row", + items: [ + { + label: this.api.i18n.t("Add row above"), + icon: L, + hideIf: () => this.numberOfRows === this.config.maxrows, + onClick: () => { + this.addRow(this.selectedRow, !0), this.hideToolboxes(); + }, + }, + { + label: this.api.i18n.t("Add row below"), + icon: x, + hideIf: () => this.numberOfRows === this.config.maxrows, + onClick: () => { + this.addRow(this.selectedRow + 1, !0), this.hideToolboxes(); + }, + }, + { + label: this.api.i18n.t("Delete row"), + icon: b, + hideIf: () => this.numberOfRows === 1, + confirmationRequired: !0, + onClick: () => { + this.deleteRow(this.selectedRow), this.hideToolboxes(); + }, + }, + ], + onOpen: () => { + this.selectRow(this.hoveredRow), this.hideColumnToolbox(); + }, + onClose: () => { + this.unselectRow(); + }, + }); + } + moveCursorToNextRow() { + this.focusedCell.row !== this.numberOfRows + ? ((this.focusedCell.row += 1), this.focusCell(this.focusedCell)) + : (this.addRow(), + (this.focusedCell.row += 1), + this.focusCell(this.focusedCell), + this.updateToolboxesPosition(0, 0)); + } + getCell(t, e) { + return this.table.querySelectorAll( + `.${s.row}:nth-child(${t}) .${s.cell}`, + )[e - 1]; + } + getRow(t) { + return this.table.querySelector(`.${s.row}:nth-child(${t})`); + } + getRowByCell(t) { + return t.parentElement; + } + getRowFirstCell(t) { + return t.querySelector(`.${s.cell}:first-child`); + } + setCellContent(t, e, o) { + const i = this.getCell(t, e); + i.innerHTML = o; + } + addColumn(t = -1, e = !1) { + var n; + let o = this.numberOfColumns; + if ( + this.config && + this.config.maxcols && + this.numberOfColumns >= this.config.maxcols + ) + return; + for (let r = 1; r <= this.numberOfRows; r++) { + let h; + const l = this.createCell(); + if ( + (t > 0 && t <= o + ? ((h = this.getCell(r, t)), m(l, h)) + : (h = this.getRow(r).appendChild(l)), + r === 1) + ) { + const u = this.getCell(r, t > 0 ? t : o + 1); + u && e && C(u); + } + } + const i = this.wrapper.querySelector(`.${s.addColumn}`); + (n = this.config) != null && + n.maxcols && + this.numberOfColumns > this.config.maxcols - 1 && + i && + i.classList.add(s.addColumnDisabled), + this.addHeadingAttrToFirstRow(); + } + addRow(t = -1, e = !1) { + let o, + i = d("div", s.row); + this.tunes.withHeadings && this.removeHeadingAttrFromFirstRow(); + let n = this.numberOfColumns; + if ( + this.config && + this.config.maxrows && + this.numberOfRows >= this.config.maxrows && + h + ) + return; + if (t > 0 && t <= this.numberOfRows) { + let l = this.getRow(t); + o = m(i, l); + } else o = this.table.appendChild(i); + this.fillRow(o, n), + this.tunes.withHeadings && this.addHeadingAttrToFirstRow(); + const r = this.getRowFirstCell(o); + r && e && C(r); + const h = this.wrapper.querySelector(`.${s.addRow}`); + return ( + this.config && + this.config.maxrows && + this.numberOfRows >= this.config.maxrows && + h && + h.classList.add(s.addRowDisabled), + o + ); + } + deleteColumn(t) { + for (let o = 1; o <= this.numberOfRows; o++) { + const i = this.getCell(o, t); + if (!i) return; + i.remove(); + } + const e = this.wrapper.querySelector(`.${s.addColumn}`); + e && e.classList.remove(s.addColumnDisabled); + } + deleteRow(t) { + this.getRow(t).remove(); + const e = this.wrapper.querySelector(`.${s.addRow}`); + e && e.classList.remove(s.addRowDisabled), + this.addHeadingAttrToFirstRow(); + } + createTableWrapper() { + if ( + ((this.wrapper = d("div", s.wrapper)), + (this.table = d("div", s.table)), + this.readOnly && this.wrapper.classList.add(s.wrapperReadOnly), + this.wrapper.appendChild(this.toolboxRow.element), + this.wrapper.appendChild(this.toolboxColumn.element), + this.wrapper.appendChild(this.table), + !this.readOnly) + ) { + const t = d("div", s.addColumn, { innerHTML: v }), + e = d("div", s.addRow, { innerHTML: v }); + this.wrapper.appendChild(t), this.wrapper.appendChild(e); + } + } + computeInitialSize() { + const t = this.data && this.data.content, + e = Array.isArray(t), + o = e ? t.length : !1, + i = e ? t.length : void 0, + n = o ? t[0].length : void 0, + r = Number.parseInt(this.config && this.config.rows), + h = Number.parseInt(this.config && this.config.cols), + l = !isNaN(r) && r > 0 ? r : void 0, + u = !isNaN(h) && h > 0 ? h : void 0; + return { rows: i || l || 2, cols: n || u || 2 }; + } + resize() { + const { rows: t, cols: e } = this.computeInitialSize(); + for (let o = 0; o < t; o++) this.addRow(); + for (let o = 0; o < e; o++) this.addColumn(); + } + fill() { + const t = this.data; + if (t && t.content) + for (let e = 0; e < t.content.length; e++) + for (let o = 0; o < t.content[e].length; o++) + this.setCellContent(e + 1, o + 1, t.content[e][o]); + } + fillRow(t, e) { + for (let o = 1; o <= e; o++) { + const i = this.createCell(); + t.appendChild(i); + } + } + createCell() { + return d("div", s.cell, { contentEditable: !this.readOnly }); + } + get numberOfRows() { + return this.table.childElementCount; + } + get numberOfColumns() { + return this.numberOfRows + ? this.table.querySelectorAll(`.${s.row}:first-child .${s.cell}`).length + : 0; + } + get isColumnMenuShowing() { + return this.selectedColumn !== 0; + } + get isRowMenuShowing() { + return this.selectedRow !== 0; + } + onMouseMoveInTable(t) { + const { row: e, column: o } = this.getHoveredCell(t); + (this.hoveredColumn = o), + (this.hoveredRow = e), + this.updateToolboxesPosition(); + } + onKeyPressListener(t) { + if (t.key === "Enter") { + if (t.shiftKey) return !0; + this.moveCursorToNextRow(); + } + return t.key !== "Enter"; + } + onKeyDownListener(t) { + t.key === "Tab" && t.stopPropagation(); + } + focusInTableListener(t) { + const e = t.target, + o = this.getRowByCell(e); + this.focusedCell = { + row: + Array.from(this.table.querySelectorAll(`.${s.row}`)).indexOf(o) + 1, + column: Array.from(o.querySelectorAll(`.${s.cell}`)).indexOf(e) + 1, + }; + } + hideToolboxes() { + this.hideRowToolbox(), + this.hideColumnToolbox(), + this.updateToolboxesPosition(); + } + hideRowToolbox() { + this.unselectRow(), this.toolboxRow.hide(); + } + hideColumnToolbox() { + this.unselectColumn(), this.toolboxColumn.hide(); + } + focusCell() { + this.focusedCellElem.focus(); + } + get focusedCellElem() { + const { row: t, column: e } = this.focusedCell; + return this.getCell(t, e); + } + updateToolboxesPosition(t = this.hoveredRow, e = this.hoveredColumn) { + this.isColumnMenuShowing || + (e > 0 && + e <= this.numberOfColumns && + this.toolboxColumn.show(() => ({ + left: `calc((100% - var(--cell-size)) / (${this.numberOfColumns} * 2) * (1 + (${e} - 1) * 2))`, + }))), + this.isRowMenuShowing || + (t > 0 && + t <= this.numberOfRows && + this.toolboxRow.show(() => { + const o = this.getRow(t), + { fromTopBorder: i } = g(this.table, o), + { height: n } = o.getBoundingClientRect(); + return { top: `${Math.ceil(i + n / 2)}px` }; + })); + } + setHeadingsSetting(t) { + (this.tunes.withHeadings = t), + t + ? (this.table.classList.add(s.withHeadings), + this.addHeadingAttrToFirstRow()) + : (this.table.classList.remove(s.withHeadings), + this.removeHeadingAttrFromFirstRow()); + } + addHeadingAttrToFirstRow() { + for (let t = 1; t <= this.numberOfColumns; t++) { + let e = this.getCell(1, t); + e && e.setAttribute("heading", this.api.i18n.t("Heading")); + } + } + removeHeadingAttrFromFirstRow() { + for (let t = 1; t <= this.numberOfColumns; t++) { + let e = this.getCell(1, t); + e && e.removeAttribute("heading"); + } + } + selectRow(t) { + const e = this.getRow(t); + e && ((this.selectedRow = t), e.classList.add(s.rowSelected)); + } + unselectRow() { + if (this.selectedRow <= 0) return; + const t = this.table.querySelector(`.${s.rowSelected}`); + t && t.classList.remove(s.rowSelected), (this.selectedRow = 0); + } + selectColumn(t) { + for (let e = 1; e <= this.numberOfRows; e++) { + const o = this.getCell(e, t); + o && o.classList.add(s.cellSelected); + } + this.selectedColumn = t; + } + unselectColumn() { + if (this.selectedColumn <= 0) return; + let t = this.table.querySelectorAll(`.${s.cellSelected}`); + Array.from(t).forEach((e) => { + e.classList.remove(s.cellSelected); + }), + (this.selectedColumn = 0); + } + getHoveredCell(t) { + let e = this.hoveredRow, + o = this.hoveredColumn; + const { width: i, height: n, x: r, y: h } = k(this.table, t); + return ( + r >= 0 && + (o = this.binSearch( + this.numberOfColumns, + (l) => this.getCell(1, l), + ({ fromLeftBorder: l }) => r < l, + ({ fromRightBorder: l }) => r > i - l, + )), + h >= 0 && + (e = this.binSearch( + this.numberOfRows, + (l) => this.getCell(l, 1), + ({ fromTopBorder: l }) => h < l, + ({ fromBottomBorder: l }) => h > n - l, + )), + { row: e || this.hoveredRow, column: o || this.hoveredColumn } + ); + } + binSearch(t, e, o, i) { + let n = 0, + r = t + 1, + h = 0, + l; + for (; n < r - 1 && h < 10; ) { + l = Math.ceil((n + r) / 2); + const u = e(l), + f = g(this.table, u); + if (o(f)) r = l; + else if (i(f)) n = l; + else break; + h++; + } + return l; + } + getData() { + const t = []; + for (let e = 1; e <= this.numberOfRows; e++) { + const o = this.table.querySelector(`.${s.row}:nth-child(${e})`), + i = Array.from(o.querySelectorAll(`.${s.cell}`)); + i.every((r) => !r.textContent.trim()) || + t.push(i.map((r) => r.innerHTML)); + } + return t; + } + destroy() { + document.removeEventListener("click", this.documentClicked); + } + } + class $ { + static get isReadOnlySupported() { + return !0; + } + static get enableLineBreaks() { + return !0; + } + constructor({ data: t, config: e, api: o, readOnly: i, block: n }) { + (this.api = o), + (this.readOnly = i), + (this.config = e), + (this.data = { + withHeadings: this.getConfig("withHeadings", !1, t), + stretched: this.getConfig("stretched", !1, t), + content: t && t.content ? t.content : [], + }), + (this.table = null), + (this.block = n); + } + static get toolbox() { + return { icon: A, title: "Table" }; + } + render() { + return ( + (this.table = new E(this.readOnly, this.api, this.data, this.config)), + (this.container = d("div", this.api.styles.block)), + this.container.appendChild(this.table.getWrapper()), + this.table.setHeadingsSetting(this.data.withHeadings), + this.container + ); + } + renderSettings() { + return [ + { + label: this.api.i18n.t("With headings"), + icon: T, + isActive: this.data.withHeadings, + closeOnActivate: !0, + toggle: !0, + onActivate: () => { + (this.data.withHeadings = !0), + this.table.setHeadingsSetting(this.data.withHeadings); + }, + }, + { + label: this.api.i18n.t("Without headings"), + icon: H, + isActive: !this.data.withHeadings, + closeOnActivate: !0, + toggle: !0, + onActivate: () => { + (this.data.withHeadings = !1), + this.table.setHeadingsSetting(this.data.withHeadings); + }, + }, + { + label: this.data.stretched + ? this.api.i18n.t("Collapse") + : this.api.i18n.t("Stretch"), + icon: this.data.stretched ? R : O, + closeOnActivate: !0, + toggle: !0, + onActivate: () => { + (this.data.stretched = !this.data.stretched), + (this.block.stretched = this.data.stretched); + }, + }, + ]; + } + save() { + const t = this.table.getData(); + return { + withHeadings: this.data.withHeadings, + stretched: this.data.stretched, + content: t, + }; + } + destroy() { + this.table.destroy(); + } + getConfig(t, e = void 0, o = void 0) { + const i = this.data || o; + return i + ? i[t] + ? i[t] + : e + : this.config && this.config[t] + ? this.config[t] + : e; + } + static get pasteConfig() { + return { tags: ["TABLE", "TR", "TH", "TD"] }; + } + onPaste(t) { + const e = t.detail.data, + o = e.querySelector(":scope > thead, tr:first-of-type th"), + n = Array.from(e.querySelectorAll("tr")).map((r) => + Array.from(r.querySelectorAll("th, td")).map((l) => l.innerHTML), + ); + (this.data = { withHeadings: o !== null, content: n }), + this.table.wrapper && this.table.wrapper.replaceWith(this.render()); + } + } + const I = ""; + return $; +}); +(function () { + "use strict"; + try { + if (typeof document < "u") { + var e = document.createElement("style"); + e.appendChild( + document.createTextNode( + `.cdx-warning{position:relative}@media all and (min-width: 736px){.cdx-warning{padding-left:36px}}.cdx-warning [contentEditable=true][data-placeholder]:before{position:absolute;content:attr(data-placeholder);color:#707684;font-weight:400;opacity:0}.cdx-warning [contentEditable=true][data-placeholder]:empty:before{opacity:1}.cdx-warning [contentEditable=true][data-placeholder]:empty:focus:before{opacity:0}.cdx-warning:before{content:"";background-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='5' y='5' width='14' height='14' rx='4' stroke='black' stroke-width='2'/%3E%3Cline x1='12' y1='9' x2='12' y2='12' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3Cpath d='M12 15.02V15.01' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");width:24px;height:24px;background-size:24px 24px;position:absolute;margin-top:8px;left:0}@media all and (max-width: 735px){.cdx-warning:before{display:none}}.cdx-warning__message{min-height:85px}.cdx-warning__title{margin-bottom:6px}`, + ), + ), + document.head.appendChild(e); + } + } catch (t) { + console.error("vite-plugin-css-injected-by-js", t); + } +})(); +(function (r, n) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = n()) + : typeof define == "function" && define.amd + ? define(n) + : ((r = typeof globalThis < "u" ? globalThis : r || self), + (r.Warning = n())); +})(this, function () { + "use strict"; + const r = + '', + n = ""; + class a { + static get isReadOnlySupported() { + return !0; + } + static get toolbox() { + return { icon: r, title: "Warning" }; + } + static get enableLineBreaks() { + return !0; + } + static get DEFAULT_TITLE_PLACEHOLDER() { + return "Title"; + } + static get DEFAULT_MESSAGE_PLACEHOLDER() { + return "Message"; + } + get CSS() { + return { + baseClass: this.api.styles.block, + wrapper: "cdx-warning", + title: "cdx-warning__title", + input: this.api.styles.input, + message: "cdx-warning__message", + }; + } + constructor({ data: t, config: e, api: s, readOnly: i }) { + (this.api = s), + (this.readOnly = i), + (this.titlePlaceholder = + e.titlePlaceholder || a.DEFAULT_TITLE_PLACEHOLDER), + (this.messagePlaceholder = + e.messagePlaceholder || a.DEFAULT_MESSAGE_PLACEHOLDER), + (this.data = { title: t.title || "", message: t.message || "" }); + } + render() { + const t = this._make("div", [this.CSS.baseClass, this.CSS.wrapper]), + e = this._make("div", [this.CSS.input, this.CSS.title], { + contentEditable: !this.readOnly, + innerHTML: this.data.title, + }), + s = this._make("div", [this.CSS.input, this.CSS.message], { + contentEditable: !this.readOnly, + innerHTML: this.data.message, + }); + return ( + (e.dataset.placeholder = this.titlePlaceholder), + (s.dataset.placeholder = this.messagePlaceholder), + t.appendChild(e), + t.appendChild(s), + t + ); + } + save(t) { + const e = t.querySelector(`.${this.CSS.title}`), + s = t.querySelector(`.${this.CSS.message}`); + return Object.assign(this.data, { + title: e.innerHTML, + message: s.innerHTML, + }); + } + _make(t, e = null, s = {}) { + const i = document.createElement(t); + Array.isArray(e) ? i.classList.add(...e) : e && i.classList.add(e); + for (const l in s) i[l] = s[l]; + return i; + } + static get sanitize() { + return { title: {}, message: {} }; + } + } + return a; +}); +(function () { + "use strict"; + try { + if (typeof document < "u") { + var e = document.createElement("style"); + e.appendChild( + document.createTextNode( + ".inline-code{background:rgba(250,239,240,.78);color:#b44437;padding:3px 4px;border-radius:5px;margin:0 1px;font-family:inherit;font-size:.86em;font-weight:500;letter-spacing:.3px}", + ), + ), + document.head.appendChild(e); + } + } catch (n) { + console.error("vite-plugin-css-injected-by-js", n); + } +})(); +(function (i, s) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = s()) + : typeof define == "function" && define.amd + ? define(s) + : ((i = typeof globalThis < "u" ? globalThis : i || self), + (i.InlineCode = s())); +})(this, function () { + "use strict"; + const i = "", + s = + ''; + class n { + constructor({ api: t }) { + (this.tag = "CODE"), + (this.api = t), + (this.button = null), + (this.iconClasses = { + base: this.api.styles.inlineToolButton, + active: this.api.styles.inlineToolButtonActive, + }); + } + static get CSS() { + return "inline-code"; + } + static get isInline() { + return !0; + } + render() { + return ( + (this.button = document.createElement("button")), + (this.button.type = "button"), + this.button.classList.add(this.iconClasses.base), + (this.button.innerHTML = this.toolboxIcon), + this.button + ); + } + surround(t) { + if (!t) return; + let e = this.api.selection.findParentTag(this.tag, n.CSS); + e ? this.unwrap(e) : this.wrap(t); + } + wrap(t) { + let e = document.createElement(this.tag); + e.classList.add(n.CSS), + e.appendChild(t.extractContents()), + t.insertNode(e), + this.api.selection.expandToTag(e); + } + unwrap(t) { + var r; + this.api.selection.expandToTag(t); + const e = window.getSelection(); + if (!e) return; + const o = e.getRangeAt(0), + a = o.extractContents(); + (r = t.parentNode) == null || r.removeChild(t), + o.insertNode(a), + e.removeAllRanges(), + e.addRange(o); + } + checkState() { + const t = this.api.selection.findParentTag(this.tag, n.CSS); + return ( + this.button && + this.button.classList.toggle(this.iconClasses.active, !!t), + !!t + ); + } + get toolboxIcon() { + return s; + } + static get sanitize() { + return { code: { class: n.CSS } }; + } + } + return n; +}); +(function () { + "use strict"; + try { + if (typeof document < "u") { + var e = document.createElement("style"); + e.appendChild( + document.createTextNode( + ".ce-hint--align-start{text-align:left}.ce-hint--align-center{text-align:center}.ce-hint__description{opacity:.6;margin-top:3px}", + ), + ), + document.head.appendChild(e); + } + } catch (t) { + console.error("vite-plugin-css-injected-by-js", t); + } +})(); +(function (ge, ee) { + typeof exports == "object" && typeof module < "u" + ? (module.exports = ee()) + : typeof define == "function" && define.amd + ? define(ee) + : ((ge = typeof globalThis < "u" ? globalThis : ge || self), + (ge.EditorJS = ee())); +})(this, function () { + "use strict"; + var ge = + typeof globalThis < "u" + ? globalThis + : typeof window < "u" + ? window + : typeof global < "u" + ? global + : typeof self < "u" + ? self + : {}; + function ee(n) { + return n && + n.__esModule && + Object.prototype.hasOwnProperty.call(n, "default") + ? n.default + : n; + } + function ze() {} + Object.assign(ze, { + default: ze, + register: ze, + revert: function () {}, + __esModule: !0, + }), + Element.prototype.matches || + (Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function (n) { + const e = (this.document || this.ownerDocument).querySelectorAll(n); + let t = e.length; + for (; --t >= 0 && e.item(t) !== this; ); + return t > -1; + }), + Element.prototype.closest || + (Element.prototype.closest = function (n) { + let e = this; + if (!document.documentElement.contains(e)) return null; + do { + if (e.matches(n)) return e; + e = e.parentElement || e.parentNode; + } while (e !== null); + return null; + }), + Element.prototype.prepend || + (Element.prototype.prepend = function (e) { + const t = document.createDocumentFragment(); + Array.isArray(e) || (e = [e]), + e.forEach((o) => { + const i = o instanceof Node; + t.appendChild(i ? o : document.createTextNode(o)); + }), + this.insertBefore(t, this.firstChild); + }), + Element.prototype.scrollIntoViewIfNeeded || + (Element.prototype.scrollIntoViewIfNeeded = function (n) { + n = arguments.length === 0 ? !0 : !!n; + const e = this.parentNode, + t = window.getComputedStyle(e, null), + o = parseInt(t.getPropertyValue("border-top-width")), + i = parseInt(t.getPropertyValue("border-left-width")), + s = this.offsetTop - e.offsetTop < e.scrollTop, + r = + this.offsetTop - e.offsetTop + this.clientHeight - o > + e.scrollTop + e.clientHeight, + l = this.offsetLeft - e.offsetLeft < e.scrollLeft, + a = + this.offsetLeft - e.offsetLeft + this.clientWidth - i > + e.scrollLeft + e.clientWidth, + c = s && !r; + (s || r) && + n && + (e.scrollTop = + this.offsetTop - + e.offsetTop - + e.clientHeight / 2 - + o + + this.clientHeight / 2), + (l || a) && + n && + (e.scrollLeft = + this.offsetLeft - + e.offsetLeft - + e.clientWidth / 2 - + i + + this.clientWidth / 2), + (s || r || l || a) && !n && this.scrollIntoView(c); + }), + (window.requestIdleCallback = + window.requestIdleCallback || + function (n) { + const e = Date.now(); + return setTimeout(function () { + n({ + didTimeout: !1, + timeRemaining: function () { + return Math.max(0, 50 - (Date.now() - e)); + }, + }); + }, 1); + }), + (window.cancelIdleCallback = + window.cancelIdleCallback || + function (n) { + clearTimeout(n); + }); + let bo = (n = 21) => + crypto + .getRandomValues(new Uint8Array(n)) + .reduce( + (e, t) => ( + (t &= 63), + t < 36 + ? (e += t.toString(36)) + : t < 62 + ? (e += (t - 26).toString(36).toUpperCase()) + : t > 62 + ? (e += "-") + : (e += "_"), + e + ), + "", + ); + var bt = ((n) => ( + (n.VERBOSE = "VERBOSE"), + (n.INFO = "INFO"), + (n.WARN = "WARN"), + (n.ERROR = "ERROR"), + n + ))(bt || {}); + const w = { + BACKSPACE: 8, + TAB: 9, + ENTER: 13, + SHIFT: 16, + CTRL: 17, + ALT: 18, + ESC: 27, + SPACE: 32, + LEFT: 37, + UP: 38, + DOWN: 40, + RIGHT: 39, + DELETE: 46, + META: 91, + SLASH: 191, + }, + ko = { LEFT: 0, WHEEL: 1, RIGHT: 2, BACKWARD: 3, FORWARD: 4 }; + function me(n, e, t = "log", o, i = "color: inherit") { + if (!("console" in window) || !window.console[t]) return; + const s = ["info", "log", "warn", "error"].includes(t), + r = []; + switch (me.logLevel) { + case "ERROR": + if (t !== "error") return; + break; + case "WARN": + if (!["error", "warn"].includes(t)) return; + break; + case "INFO": + if (!s || n) return; + break; + } + o && r.push(o); + const l = "Editor.js 2.30.6", + a = `line-height: 1em; + color: #006FEA; + display: inline-block; + font-size: 11px; + line-height: 1em; + background-color: #fff; + padding: 4px 9px; + border-radius: 30px; + border: 1px solid rgba(56, 138, 229, 0.16); + margin: 4px 5px 4px 0;`; + n && (s ? (r.unshift(a, i), (e = `%c${l}%c ${e}`)) : (e = `( ${l} )${e}`)); + try { + s + ? o + ? console[t](`${e} %o`, ...r) + : console[t](e, ...r) + : console[t](e); + } catch {} + } + me.logLevel = "VERBOSE"; + function vo(n) { + me.logLevel = n; + } + const C = me.bind(window, !1), + X = me.bind(window, !0); + function ie(n) { + return Object.prototype.toString + .call(n) + .match(/\s([a-zA-Z]+)/)[1] + .toLowerCase(); + } + function O(n) { + return ie(n) === "function" || ie(n) === "asyncfunction"; + } + function P(n) { + return ie(n) === "object"; + } + function G(n) { + return ie(n) === "string"; + } + function wo(n) { + return ie(n) === "boolean"; + } + function kt(n) { + return ie(n) === "number"; + } + function vt(n) { + return ie(n) === "undefined"; + } + function V(n) { + return n ? Object.keys(n).length === 0 && n.constructor === Object : !0; + } + function wt(n) { + return ( + (n > 47 && n < 58) || + n === 32 || + n === 13 || + n === 229 || + (n > 64 && n < 91) || + (n > 95 && n < 112) || + (n > 185 && n < 193) || + (n > 218 && n < 223) + ); + } + async function xo(n, e = () => {}, t = () => {}) { + async function o(i, s, r) { + try { + await i.function(i.data), await s(vt(i.data) ? {} : i.data); + } catch { + r(vt(i.data) ? {} : i.data); + } + } + return n.reduce(async (i, s) => (await i, o(s, e, t)), Promise.resolve()); + } + function xt(n) { + return Array.prototype.slice.call(n); + } + function Me(n, e) { + return function () { + const t = this, + o = arguments; + window.setTimeout(() => n.apply(t, o), e); + }; + } + function yo(n) { + return n.name.split(".").pop(); + } + function Eo(n) { + return /^[-\w]+\/([-+\w]+|\*)$/.test(n); + } + function yt(n, e, t) { + let o; + return (...i) => { + const s = this, + r = () => { + (o = null), t || n.apply(s, i); + }, + l = t && !o; + window.clearTimeout(o), (o = window.setTimeout(r, e)), l && n.apply(s, i); + }; + } + function Ue(n, e, t = void 0) { + let o, + i, + s, + r = null, + l = 0; + t || (t = {}); + const a = function () { + (l = t.leading === !1 ? 0 : Date.now()), + (r = null), + (s = n.apply(o, i)), + r || (o = i = null); + }; + return function () { + const c = Date.now(); + !l && t.leading === !1 && (l = c); + const u = e - (c - l); + return ( + (o = this), + (i = arguments), + u <= 0 || u > e + ? (r && (clearTimeout(r), (r = null)), + (l = c), + (s = n.apply(o, i)), + r || (o = i = null)) + : !r && t.trailing !== !1 && (r = setTimeout(a, u)), + s + ); + }; + } + function Bo() { + const n = { win: !1, mac: !1, x11: !1, linux: !1 }, + e = Object.keys(n).find( + (t) => window.navigator.appVersion.toLowerCase().indexOf(t) !== -1, + ); + return e && (n[e] = !0), n; + } + function Ae(n) { + return n[0].toUpperCase() + n.slice(1); + } + function je(n, ...e) { + if (!e.length) return n; + const t = e.shift(); + if (P(n) && P(t)) + for (const o in t) + P(t[o]) + ? (n[o] || Object.assign(n, { [o]: {} }), je(n[o], t[o])) + : Object.assign(n, { [o]: t[o] }); + return je(n, ...e); + } + function $e(n) { + const e = Bo(); + return ( + (n = n + .replace(/shift/gi, "⇧") + .replace(/backspace/gi, "⌫") + .replace(/enter/gi, "⏎") + .replace(/up/gi, "↑") + .replace(/left/gi, "→") + .replace(/down/gi, "↓") + .replace(/right/gi, "←") + .replace(/escape/gi, "⎋") + .replace(/insert/gi, "Ins") + .replace(/delete/gi, "␡") + .replace(/\+/gi, " + ")), + e.mac + ? (n = n.replace(/ctrl|cmd/gi, "⌘").replace(/alt/gi, "⌥")) + : (n = n.replace(/cmd/gi, "Ctrl").replace(/windows/gi, "WIN")), + n + ); + } + function To(n) { + try { + return new URL(n).href; + } catch {} + return n.substring(0, 2) === "//" + ? window.location.protocol + n + : window.location.origin + n; + } + function Co() { + return bo(10); + } + function So(n) { + window.open(n, "_blank"); + } + function Io(n = "") { + return `${n}${Math.floor(Math.random() * 1e8).toString(16)}`; + } + function Ye(n, e, t) { + const o = `«${e}» is deprecated and will be removed in the next major release. Please use the «${t}» instead.`; + n && X(o, "warn"); + } + function ce(n, e, t) { + const o = t.value ? "value" : "get", + i = t[o], + s = `#${e}Cache`; + if ( + ((t[o] = function (...r) { + return this[s] === void 0 && (this[s] = i.apply(this, ...r)), this[s]; + }), + o === "get" && t.set) + ) { + const r = t.set; + t.set = function (l) { + delete n[s], r.apply(this, l); + }; + } + return t; + } + const Et = 650; + function de() { + return window.matchMedia(`(max-width: ${Et}px)`).matches; + } + const We = + typeof window < "u" && + window.navigator && + window.navigator.platform && + (/iP(ad|hone|od)/.test(window.navigator.platform) || + (window.navigator.platform === "MacIntel" && + window.navigator.maxTouchPoints > 1)); + function Mo(n, e) { + const t = Array.isArray(n) || P(n), + o = Array.isArray(e) || P(e); + return t || o ? JSON.stringify(n) === JSON.stringify(e) : n === e; + } + class d { + static isSingleTag(e) { + return ( + e.tagName && + [ + "AREA", + "BASE", + "BR", + "COL", + "COMMAND", + "EMBED", + "HR", + "IMG", + "INPUT", + "KEYGEN", + "LINK", + "META", + "PARAM", + "SOURCE", + "TRACK", + "WBR", + ].includes(e.tagName) + ); + } + static isLineBreakTag(e) { + return e && e.tagName && ["BR", "WBR"].includes(e.tagName); + } + static make(e, t = null, o = {}) { + const i = document.createElement(e); + if (Array.isArray(t)) { + const s = t.filter((r) => r !== void 0); + i.classList.add(...s); + } else t && i.classList.add(t); + for (const s in o) + Object.prototype.hasOwnProperty.call(o, s) && (i[s] = o[s]); + return i; + } + static text(e) { + return document.createTextNode(e); + } + static append(e, t) { + Array.isArray(t) ? t.forEach((o) => e.appendChild(o)) : e.appendChild(t); + } + static prepend(e, t) { + Array.isArray(t) + ? ((t = t.reverse()), t.forEach((o) => e.prepend(o))) + : e.prepend(t); + } + static swap(e, t) { + const o = document.createElement("div"), + i = e.parentNode; + i.insertBefore(o, e), + i.insertBefore(e, t), + i.insertBefore(t, o), + i.removeChild(o); + } + static find(e = document, t) { + return e.querySelector(t); + } + static get(e) { + return document.getElementById(e); + } + static findAll(e = document, t) { + return e.querySelectorAll(t); + } + static get allInputsSelector() { + return ( + "[contenteditable=true], textarea, input:not([type]), " + + ["text", "password", "email", "number", "search", "tel", "url"] + .map((t) => `input[type="${t}"]`) + .join(", ") + ); + } + static findAllInputs(e) { + return xt(e.querySelectorAll(d.allInputsSelector)).reduce( + (t, o) => + d.isNativeInput(o) || d.containsOnlyInlineElements(o) + ? [...t, o] + : [...t, ...d.getDeepestBlockElements(o)], + [], + ); + } + static getDeepestNode(e, t = !1) { + const o = t ? "lastChild" : "firstChild", + i = t ? "previousSibling" : "nextSibling"; + if (e && e.nodeType === Node.ELEMENT_NODE && e[o]) { + let s = e[o]; + if (d.isSingleTag(s) && !d.isNativeInput(s) && !d.isLineBreakTag(s)) + if (s[i]) s = s[i]; + else if (s.parentNode[i]) s = s.parentNode[i]; + else return s.parentNode; + return this.getDeepestNode(s, t); + } + return e; + } + static isElement(e) { + return kt(e) ? !1 : e && e.nodeType && e.nodeType === Node.ELEMENT_NODE; + } + static isFragment(e) { + return kt(e) + ? !1 + : e && e.nodeType && e.nodeType === Node.DOCUMENT_FRAGMENT_NODE; + } + static isContentEditable(e) { + return e.contentEditable === "true"; + } + static isNativeInput(e) { + const t = ["INPUT", "TEXTAREA"]; + return e && e.tagName ? t.includes(e.tagName) : !1; + } + static canSetCaret(e) { + let t = !0; + if (d.isNativeInput(e)) + switch (e.type) { + case "file": + case "checkbox": + case "radio": + case "hidden": + case "submit": + case "button": + case "image": + case "reset": + t = !1; + break; + } + else t = d.isContentEditable(e); + return t; + } + static isNodeEmpty(e, t) { + let o; + return this.isSingleTag(e) && !this.isLineBreakTag(e) + ? !1 + : (this.isElement(e) && this.isNativeInput(e) + ? (o = e.value) + : (o = e.textContent.replace("​", "")), + t && (o = o.replace(new RegExp(t, "g"), "")), + o.trim().length === 0); + } + static isLeaf(e) { + return e ? e.childNodes.length === 0 : !1; + } + static isEmpty(e, t) { + e.normalize(); + const o = [e]; + for (; o.length > 0; ) + if (((e = o.shift()), !!e)) { + if (this.isLeaf(e) && !this.isNodeEmpty(e, t)) return !1; + e.childNodes && o.push(...Array.from(e.childNodes)); + } + return !0; + } + static isHTMLString(e) { + const t = d.make("div"); + return (t.innerHTML = e), t.childElementCount > 0; + } + static getContentLength(e) { + return d.isNativeInput(e) + ? e.value.length + : e.nodeType === Node.TEXT_NODE + ? e.length + : e.textContent.length; + } + static get blockElements() { + return [ + "address", + "article", + "aside", + "blockquote", + "canvas", + "div", + "dl", + "dt", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "header", + "hgroup", + "hr", + "li", + "main", + "nav", + "noscript", + "ol", + "output", + "p", + "pre", + "ruby", + "section", + "table", + "tbody", + "thead", + "tr", + "tfoot", + "ul", + "video", + ]; + } + static containsOnlyInlineElements(e) { + let t; + G(e) ? ((t = document.createElement("div")), (t.innerHTML = e)) : (t = e); + const o = (i) => + !d.blockElements.includes(i.tagName.toLowerCase()) && + Array.from(i.children).every(o); + return Array.from(t.children).every(o); + } + static getDeepestBlockElements(e) { + return d.containsOnlyInlineElements(e) + ? [e] + : Array.from(e.children).reduce( + (t, o) => [...t, ...d.getDeepestBlockElements(o)], + [], + ); + } + static getHolder(e) { + return G(e) ? document.getElementById(e) : e; + } + static isAnchor(e) { + return e.tagName.toLowerCase() === "a"; + } + static offset(e) { + const t = e.getBoundingClientRect(), + o = window.pageXOffset || document.documentElement.scrollLeft, + i = window.pageYOffset || document.documentElement.scrollTop, + s = t.top + i, + r = t.left + o; + return { top: s, left: r, bottom: s + t.height, right: r + t.width }; + } + } + function Ao(n) { + return !/[^\t\n\r ]/.test(n); + } + function Oo(n) { + const e = window.getComputedStyle(n), + t = parseFloat(e.fontSize), + o = parseFloat(e.lineHeight) || t * 1.2, + i = parseFloat(e.paddingTop), + s = parseFloat(e.borderTopWidth), + r = parseFloat(e.marginTop), + l = t * 0.8, + a = (o - t) / 2; + return r + s + i + a + l; + } + function Bt(n) { + n.dataset.empty = d.isEmpty(n) ? "true" : "false"; + } + const Tt = { + ui: { + blockTunes: { toggler: { "Click to tune": "", "or drag to move": "" } }, + inlineToolbar: { converter: { "Convert to": "" } }, + toolbar: { toolbox: { Add: "" } }, + popover: { Filter: "", "Nothing found": "", "Convert to": "" }, + }, + toolNames: { Text: "", Link: "", Bold: "", Italic: "" }, + tools: { + link: { "Add a link": "" }, + stub: { "The block can not be displayed correctly.": "" }, + }, + blockTunes: { + delete: { Delete: "", "Click to delete": "" }, + moveUp: { "Move up": "" }, + moveDown: { "Move down": "" }, + }, + }, + Ct = class fe { + static ui(e, t) { + return fe._t(e, t); + } + static t(e, t) { + return fe._t(e, t); + } + static setDictionary(e) { + fe.currentDictionary = e; + } + static _t(e, t) { + const o = fe.getNamespace(e); + return !o || !o[t] ? t : o[t]; + } + static getNamespace(e) { + return e + .split(".") + .reduce( + (o, i) => (!o || !Object.keys(o).length ? {} : o[i]), + fe.currentDictionary, + ); + } + }; + Ct.currentDictionary = Tt; + let H = Ct; + class St extends Error {} + class be { + constructor() { + this.subscribers = {}; + } + on(e, t) { + e in this.subscribers || (this.subscribers[e] = []), + this.subscribers[e].push(t); + } + once(e, t) { + e in this.subscribers || (this.subscribers[e] = []); + const o = (i) => { + const s = t(i), + r = this.subscribers[e].indexOf(o); + return r !== -1 && this.subscribers[e].splice(r, 1), s; + }; + this.subscribers[e].push(o); + } + emit(e, t) { + V(this.subscribers) || + !this.subscribers[e] || + this.subscribers[e].reduce((o, i) => { + const s = i(o); + return s !== void 0 ? s : o; + }, t); + } + off(e, t) { + if (this.subscribers[e] === void 0) { + console.warn( + `EventDispatcher .off(): there is no subscribers for event "${e.toString()}". Probably, .off() called before .on()`, + ); + return; + } + for (let o = 0; o < this.subscribers[e].length; o++) + if (this.subscribers[e][o] === t) { + delete this.subscribers[e][o]; + break; + } + } + destroy() { + this.subscribers = {}; + } + } + function J(n) { + Object.setPrototypeOf(this, { + get id() { + return n.id; + }, + get name() { + return n.name; + }, + get config() { + return n.config; + }, + get holder() { + return n.holder; + }, + get isEmpty() { + return n.isEmpty; + }, + get selected() { + return n.selected; + }, + set stretched(t) { + n.stretched = t; + }, + get stretched() { + return n.stretched; + }, + get focusable() { + return n.focusable; + }, + call(t, o) { + return n.call(t, o); + }, + save() { + return n.save(); + }, + validate(t) { + return n.validate(t); + }, + dispatchChange() { + n.dispatchChange(); + }, + getActiveToolboxEntry() { + return n.getActiveToolboxEntry(); + }, + }); + } + class ke { + constructor() { + this.allListeners = []; + } + on(e, t, o, i = !1) { + const s = Io("l"), + r = { id: s, element: e, eventType: t, handler: o, options: i }; + if (!this.findOne(e, t, o)) + return this.allListeners.push(r), e.addEventListener(t, o, i), s; + } + off(e, t, o, i) { + const s = this.findAll(e, t, o); + s.forEach((r, l) => { + const a = this.allListeners.indexOf(s[l]); + a > -1 && + (this.allListeners.splice(a, 1), + r.element.removeEventListener(r.eventType, r.handler, r.options)); + }); + } + offById(e) { + const t = this.findById(e); + t && t.element.removeEventListener(t.eventType, t.handler, t.options); + } + findOne(e, t, o) { + const i = this.findAll(e, t, o); + return i.length > 0 ? i[0] : null; + } + findAll(e, t, o) { + let i; + const s = e ? this.findByEventTarget(e) : []; + return ( + e && t && o + ? (i = s.filter((r) => r.eventType === t && r.handler === o)) + : e && t + ? (i = s.filter((r) => r.eventType === t)) + : (i = s), + i + ); + } + removeAll() { + this.allListeners.map((e) => { + e.element.removeEventListener(e.eventType, e.handler, e.options); + }), + (this.allListeners = []); + } + destroy() { + this.removeAll(); + } + findByEventTarget(e) { + return this.allListeners.filter((t) => { + if (t.element === e) return t; + }); + } + findByType(e) { + return this.allListeners.filter((t) => { + if (t.eventType === e) return t; + }); + } + findByHandler(e) { + return this.allListeners.filter((t) => { + if (t.handler === e) return t; + }); + } + findById(e) { + return this.allListeners.find((t) => t.id === e); + } + } + class y { + constructor({ config: e, eventsDispatcher: t }) { + if ( + ((this.nodes = {}), + (this.listeners = new ke()), + (this.readOnlyMutableListeners = { + on: (o, i, s, r = !1) => { + this.mutableListenerIds.push(this.listeners.on(o, i, s, r)); + }, + clearAll: () => { + for (const o of this.mutableListenerIds) this.listeners.offById(o); + this.mutableListenerIds = []; + }, + }), + (this.mutableListenerIds = []), + new.target === y) + ) + throw new TypeError( + "Constructors for abstract class Module are not allowed.", + ); + (this.config = e), (this.eventsDispatcher = t); + } + set state(e) { + this.Editor = e; + } + removeAllNodes() { + for (const e in this.nodes) { + const t = this.nodes[e]; + t instanceof HTMLElement && t.remove(); + } + } + get isRtl() { + return this.config.i18n.direction === "rtl"; + } + } + class m { + constructor() { + (this.instance = null), + (this.selection = null), + (this.savedSelectionRange = null), + (this.isFakeBackgroundEnabled = !1), + (this.commandBackground = "backColor"), + (this.commandRemoveFormat = "removeFormat"); + } + static get CSS() { + return { + editorWrapper: "codex-editor", + editorZone: "codex-editor__redactor", + }; + } + static get anchorNode() { + const e = window.getSelection(); + return e ? e.anchorNode : null; + } + static get anchorElement() { + const e = window.getSelection(); + if (!e) return null; + const t = e.anchorNode; + return t ? (d.isElement(t) ? t : t.parentElement) : null; + } + static get anchorOffset() { + const e = window.getSelection(); + return e ? e.anchorOffset : null; + } + static get isCollapsed() { + const e = window.getSelection(); + return e ? e.isCollapsed : null; + } + static get isAtEditor() { + return this.isSelectionAtEditor(m.get()); + } + static isSelectionAtEditor(e) { + if (!e) return !1; + let t = e.anchorNode || e.focusNode; + t && t.nodeType === Node.TEXT_NODE && (t = t.parentNode); + let o = null; + return ( + t && t instanceof Element && (o = t.closest(`.${m.CSS.editorZone}`)), + o ? o.nodeType === Node.ELEMENT_NODE : !1 + ); + } + static isRangeAtEditor(e) { + if (!e) return; + let t = e.startContainer; + t && t.nodeType === Node.TEXT_NODE && (t = t.parentNode); + let o = null; + return ( + t && t instanceof Element && (o = t.closest(`.${m.CSS.editorZone}`)), + o ? o.nodeType === Node.ELEMENT_NODE : !1 + ); + } + static get isSelectionExists() { + return !!m.get().anchorNode; + } + static get range() { + return this.getRangeFromSelection(this.get()); + } + static getRangeFromSelection(e) { + return e && e.rangeCount ? e.getRangeAt(0) : null; + } + static get rect() { + let e = document.selection, + t, + o = { x: 0, y: 0, width: 0, height: 0 }; + if (e && e.type !== "Control") + return ( + (e = e), + (t = e.createRange()), + (o.x = t.boundingLeft), + (o.y = t.boundingTop), + (o.width = t.boundingWidth), + (o.height = t.boundingHeight), + o + ); + if (!window.getSelection) + return C("Method window.getSelection is not supported", "warn"), o; + if ( + ((e = window.getSelection()), + e.rangeCount === null || isNaN(e.rangeCount)) + ) + return ( + C("Method SelectionUtils.rangeCount is not supported", "warn"), o + ); + if (e.rangeCount === 0) return o; + if ( + ((t = e.getRangeAt(0).cloneRange()), + t.getBoundingClientRect && (o = t.getBoundingClientRect()), + o.x === 0 && o.y === 0) + ) { + const i = document.createElement("span"); + if (i.getBoundingClientRect) { + i.appendChild(document.createTextNode("​")), + t.insertNode(i), + (o = i.getBoundingClientRect()); + const s = i.parentNode; + s.removeChild(i), s.normalize(); + } + } + return o; + } + static get text() { + return window.getSelection ? window.getSelection().toString() : ""; + } + static get() { + return window.getSelection(); + } + static setCursor(e, t = 0) { + const o = document.createRange(), + i = window.getSelection(); + return d.isNativeInput(e) + ? d.canSetCaret(e) + ? (e.focus(), + (e.selectionStart = e.selectionEnd = t), + e.getBoundingClientRect()) + : void 0 + : (o.setStart(e, t), + o.setEnd(e, t), + i.removeAllRanges(), + i.addRange(o), + o.getBoundingClientRect()); + } + static isRangeInsideContainer(e) { + const t = m.range; + return t === null ? !1 : e.contains(t.startContainer); + } + static addFakeCursor() { + const e = m.range; + if (e === null) return; + const t = d.make("span", "codex-editor__fake-cursor"); + (t.dataset.mutationFree = "true"), e.collapse(), e.insertNode(t); + } + static isFakeCursorInsideContainer(e) { + return d.find(e, ".codex-editor__fake-cursor") !== null; + } + static removeFakeCursor(e = document.body) { + const t = d.find(e, ".codex-editor__fake-cursor"); + t && t.remove(); + } + removeFakeBackground() { + this.isFakeBackgroundEnabled && + ((this.isFakeBackgroundEnabled = !1), + document.execCommand(this.commandRemoveFormat)); + } + setFakeBackground() { + document.execCommand(this.commandBackground, !1, "#a8d6ff"), + (this.isFakeBackgroundEnabled = !0); + } + save() { + this.savedSelectionRange = m.range; + } + restore() { + if (!this.savedSelectionRange) return; + const e = window.getSelection(); + e.removeAllRanges(), e.addRange(this.savedSelectionRange); + } + clearSaved() { + this.savedSelectionRange = null; + } + collapseToEnd() { + const e = window.getSelection(), + t = document.createRange(); + t.selectNodeContents(e.focusNode), + t.collapse(!1), + e.removeAllRanges(), + e.addRange(t); + } + findParentTag(e, t, o = 10) { + const i = window.getSelection(); + let s = null; + return !i || !i.anchorNode || !i.focusNode + ? null + : ([i.anchorNode, i.focusNode].forEach((l) => { + let a = o; + for ( + ; + a > 0 && + l.parentNode && + !( + l.tagName === e && + ((s = l), + t && l.classList && !l.classList.contains(t) && (s = null), + s) + ); + + ) + (l = l.parentNode), a--; + }), + s); + } + expandToTag(e) { + const t = window.getSelection(); + t.removeAllRanges(); + const o = document.createRange(); + o.selectNodeContents(e), t.addRange(o); + } + } + function Lo(n, e) { + const { type: t, target: o, addedNodes: i, removedNodes: s } = n; + return n.type === "attributes" && n.attributeName === "data-empty" + ? !1 + : !!( + e.contains(o) || + (t === "childList" && + (Array.from(i).some((a) => a === e) || + Array.from(s).some((a) => a === e))) + ); + } + const Ke = "redactor dom changed", + It = "block changed", + Mt = "fake cursor is about to be toggled", + At = "fake cursor have been set", + ve = "editor mobile layout toggled"; + function Xe(n, e) { + if (!n.conversionConfig) return !1; + const t = n.conversionConfig[e]; + return O(t) || G(t); + } + function Oe(n, e) { + return Xe(n.tool, e); + } + function Ot(n, e) { + return Object.entries(n).some(([t, o]) => e[t] && Mo(e[t], o)); + } + async function Lt(n, e) { + const o = (await n.save()).data, + i = e.find((s) => s.name === n.name); + return i !== void 0 && !Xe(i, "export") + ? [] + : e.reduce((s, r) => { + if (!Xe(r, "import") || r.toolbox === void 0) return s; + const l = r.toolbox.filter((a) => { + if (V(a) || a.icon === void 0) return !1; + if (a.data !== void 0) { + if (Ot(a.data, o)) return !1; + } else if (r.name === n.name) return !1; + return !0; + }); + return s.push({ ...r, toolbox: l }), s; + }, []); + } + function _t(n, e) { + return n.mergeable + ? n.name === e.name + ? !0 + : Oe(e, "export") && Oe(n, "import") + : !1; + } + function _o(n, e) { + const t = e == null ? void 0 : e.export; + return O(t) + ? t(n) + : G(t) + ? n[t] + : (t !== void 0 && + C( + "Conversion «export» property must be a string or function. String means key of saved data object to export. Function should export processed string to export.", + ), + ""); + } + function Nt(n, e) { + const t = e == null ? void 0 : e.import; + return O(t) + ? t(n) + : G(t) + ? { [t]: n } + : (t !== void 0 && + C( + "Conversion «import» property must be a string or function. String means key of tool data to import. Function accepts a imported string and return composed tool data.", + ), + {}); + } + var A = ((n) => ( + (n.Default = "default"), (n.Separator = "separator"), (n.Html = "html"), n + ))(A || {}), + Q = ((n) => ( + (n.APPEND_CALLBACK = "appendCallback"), + (n.RENDERED = "rendered"), + (n.MOVED = "moved"), + (n.UPDATED = "updated"), + (n.REMOVED = "removed"), + (n.ON_PASTE = "onPaste"), + n + ))(Q || {}); + class D extends be { + constructor( + { id: e = Co(), data: t, tool: o, readOnly: i, tunesData: s }, + r, + ) { + super(), + (this.cachedInputs = []), + (this.toolRenderedElement = null), + (this.tunesInstances = new Map()), + (this.defaultTunesInstances = new Map()), + (this.unavailableTunesData = {}), + (this.inputIndex = 0), + (this.editorEventBus = null), + (this.handleFocus = () => { + this.dropInputsCache(), this.updateCurrentInput(); + }), + (this.didMutated = (l = void 0) => { + const a = l === void 0, + c = l instanceof InputEvent; + !a && !c && this.detectToolRootChange(l); + let u; + a || c + ? (u = !0) + : (u = !( + l.length > 0 && + l.every((p) => { + const { addedNodes: g, removedNodes: f, target: k } = p; + return [...Array.from(g), ...Array.from(f), k].some( + (I) => ( + d.isElement(I) || (I = I.parentElement), + I && I.closest('[data-mutation-free="true"]') !== null + ), + ); + }) + )), + u && + (this.dropInputsCache(), + this.updateCurrentInput(), + this.toggleInputsEmptyMark(), + this.call("updated"), + this.emit("didMutated", this)); + }), + (this.name = o.name), + (this.id = e), + (this.settings = o.settings), + (this.config = o.settings.config || {}), + (this.editorEventBus = r || null), + (this.blockAPI = new J(this)), + (this.tool = o), + (this.toolInstance = o.create(t, this.blockAPI, i)), + (this.tunes = o.tunes), + this.composeTunes(s), + (this.holder = this.compose()), + window.requestIdleCallback(() => { + this.watchBlockMutations(), + this.addInputEvents(), + this.toggleInputsEmptyMark(); + }); + } + static get CSS() { + return { + wrapper: "ce-block", + wrapperStretched: "ce-block--stretched", + content: "ce-block__content", + selected: "ce-block--selected", + dropTarget: "ce-block--drop-target", + }; + } + get inputs() { + if (this.cachedInputs.length !== 0) return this.cachedInputs; + const e = d.findAllInputs(this.holder); + return ( + this.inputIndex > e.length - 1 && (this.inputIndex = e.length - 1), + (this.cachedInputs = e), + e + ); + } + get currentInput() { + return this.inputs[this.inputIndex]; + } + set currentInput(e) { + const t = this.inputs.findIndex((o) => o === e || o.contains(e)); + t !== -1 && (this.inputIndex = t); + } + get firstInput() { + return this.inputs[0]; + } + get lastInput() { + const e = this.inputs; + return e[e.length - 1]; + } + get nextInput() { + return this.inputs[this.inputIndex + 1]; + } + get previousInput() { + return this.inputs[this.inputIndex - 1]; + } + get data() { + return this.save().then((e) => (e && !V(e.data) ? e.data : {})); + } + get sanitize() { + return this.tool.sanitizeConfig; + } + get mergeable() { + return O(this.toolInstance.merge); + } + get focusable() { + return this.inputs.length !== 0; + } + get isEmpty() { + const e = d.isEmpty(this.pluginsContent, "/"), + t = !this.hasMedia; + return e && t; + } + get hasMedia() { + const e = [ + "img", + "iframe", + "video", + "audio", + "source", + "input", + "textarea", + "twitterwidget", + ]; + return !!this.holder.querySelector(e.join(",")); + } + set selected(e) { + var i, s; + this.holder.classList.toggle(D.CSS.selected, e); + const t = e === !0 && m.isRangeInsideContainer(this.holder), + o = e === !1 && m.isFakeCursorInsideContainer(this.holder); + (t || o) && + ((i = this.editorEventBus) == null || i.emit(Mt, { state: e }), + t ? m.addFakeCursor() : m.removeFakeCursor(this.holder), + (s = this.editorEventBus) == null || s.emit(At, { state: e })); + } + get selected() { + return this.holder.classList.contains(D.CSS.selected); + } + set stretched(e) { + this.holder.classList.toggle(D.CSS.wrapperStretched, e); + } + get stretched() { + return this.holder.classList.contains(D.CSS.wrapperStretched); + } + set dropTarget(e) { + this.holder.classList.toggle(D.CSS.dropTarget, e); + } + get pluginsContent() { + return this.toolRenderedElement; + } + call(e, t) { + if (O(this.toolInstance[e])) { + e === "appendCallback" && + C( + "`appendCallback` hook is deprecated and will be removed in the next major release. Use `rendered` hook instead", + "warn", + ); + try { + this.toolInstance[e].call(this.toolInstance, t); + } catch (o) { + C(`Error during '${e}' call: ${o.message}`, "error"); + } + } + } + async mergeWith(e) { + await this.toolInstance.merge(e); + } + async save() { + const e = await this.toolInstance.save(this.pluginsContent), + t = this.unavailableTunesData; + [ + ...this.tunesInstances.entries(), + ...this.defaultTunesInstances.entries(), + ].forEach(([s, r]) => { + if (O(r.save)) + try { + t[s] = r.save(); + } catch (l) { + C( + `Tune ${r.constructor.name} save method throws an Error %o`, + "warn", + l, + ); + } + }); + const o = window.performance.now(); + let i; + return Promise.resolve(e) + .then( + (s) => ( + (i = window.performance.now()), + { id: this.id, tool: this.name, data: s, tunes: t, time: i - o } + ), + ) + .catch((s) => { + C( + `Saving process for ${this.name} tool failed due to the ${s}`, + "log", + "red", + ); + }); + } + async validate(e) { + let t = !0; + return ( + this.toolInstance.validate instanceof Function && + (t = await this.toolInstance.validate(e)), + t + ); + } + getTunes() { + const e = [], + t = [], + o = + typeof this.toolInstance.renderSettings == "function" + ? this.toolInstance.renderSettings() + : []; + return ( + d.isElement(o) + ? e.push({ type: A.Html, element: o }) + : Array.isArray(o) + ? e.push(...o) + : e.push(o), + [ + ...this.tunesInstances.values(), + ...this.defaultTunesInstances.values(), + ] + .map((s) => s.render()) + .forEach((s) => { + d.isElement(s) + ? t.push({ type: A.Html, element: s }) + : Array.isArray(s) + ? t.push(...s) + : t.push(s); + }), + { toolTunes: e, commonTunes: t } + ); + } + updateCurrentInput() { + this.currentInput = + d.isNativeInput(document.activeElement) || !m.anchorNode + ? document.activeElement + : m.anchorNode; + } + dispatchChange() { + this.didMutated(); + } + destroy() { + this.unwatchBlockMutations(), + this.removeInputEvents(), + super.destroy(), + O(this.toolInstance.destroy) && this.toolInstance.destroy(); + } + async getActiveToolboxEntry() { + const e = this.tool.toolbox; + if (e.length === 1) return Promise.resolve(this.tool.toolbox[0]); + const t = await this.data, + o = e; + return o == null ? void 0 : o.find((i) => Ot(i.data, t)); + } + async exportDataAsString() { + const e = await this.data; + return _o(e, this.tool.conversionConfig); + } + compose() { + const e = d.make("div", D.CSS.wrapper), + t = d.make("div", D.CSS.content), + o = this.toolInstance.render(); + (e.dataset.id = this.id), + (this.toolRenderedElement = o), + t.appendChild(this.toolRenderedElement); + let i = t; + return ( + [ + ...this.tunesInstances.values(), + ...this.defaultTunesInstances.values(), + ].forEach((s) => { + if (O(s.wrap)) + try { + i = s.wrap(i); + } catch (r) { + C( + `Tune ${s.constructor.name} wrap method throws an Error %o`, + "warn", + r, + ); + } + }), + e.appendChild(i), + e + ); + } + composeTunes(e) { + Array.from(this.tunes.values()).forEach((t) => { + (t.isInternal ? this.defaultTunesInstances : this.tunesInstances).set( + t.name, + t.create(e[t.name], this.blockAPI), + ); + }), + Object.entries(e).forEach(([t, o]) => { + this.tunesInstances.has(t) || (this.unavailableTunesData[t] = o); + }); + } + addInputEvents() { + this.inputs.forEach((e) => { + e.addEventListener("focus", this.handleFocus), + d.isNativeInput(e) && e.addEventListener("input", this.didMutated); + }); + } + removeInputEvents() { + this.inputs.forEach((e) => { + e.removeEventListener("focus", this.handleFocus), + d.isNativeInput(e) && e.removeEventListener("input", this.didMutated); + }); + } + watchBlockMutations() { + var e; + (this.redactorDomChangedCallback = (t) => { + const { mutations: o } = t; + o.some((s) => Lo(s, this.toolRenderedElement)) && this.didMutated(o); + }), + (e = this.editorEventBus) == null || + e.on(Ke, this.redactorDomChangedCallback); + } + unwatchBlockMutations() { + var e; + (e = this.editorEventBus) == null || + e.off(Ke, this.redactorDomChangedCallback); + } + detectToolRootChange(e) { + e.forEach((t) => { + if (Array.from(t.removedNodes).includes(this.toolRenderedElement)) { + const i = t.addedNodes[t.addedNodes.length - 1]; + this.toolRenderedElement = i; + } + }); + } + dropInputsCache() { + this.cachedInputs = []; + } + toggleInputsEmptyMark() { + this.inputs.forEach(Bt); + } + } + class No extends y { + constructor() { + super(...arguments), + (this.insert = ( + e = this.config.defaultBlock, + t = {}, + o = {}, + i, + s, + r, + l, + ) => { + const a = this.Editor.BlockManager.insert({ + id: l, + tool: e, + data: t, + index: i, + needToFocus: s, + replace: r, + }); + return new J(a); + }), + (this.composeBlockData = async (e) => { + const t = this.Editor.Tools.blockTools.get(e); + return new D({ + tool: t, + api: this.Editor.API, + readOnly: !0, + data: {}, + tunesData: {}, + }).data; + }), + (this.update = async (e, t, o) => { + const { BlockManager: i } = this.Editor, + s = i.getBlockById(e); + if (s === void 0) throw new Error(`Block with id "${e}" not found`); + const r = await i.update(s, t, o); + return new J(r); + }), + (this.convert = async (e, t, o) => { + var h, p; + const { BlockManager: i, Tools: s } = this.Editor, + r = i.getBlockById(e); + if (!r) throw new Error(`Block with id "${e}" not found`); + const l = s.blockTools.get(r.name), + a = s.blockTools.get(t); + if (!a) throw new Error(`Block Tool with type "${t}" not found`); + const c = + ((h = l == null ? void 0 : l.conversionConfig) == null + ? void 0 + : h.export) !== void 0, + u = + ((p = a.conversionConfig) == null ? void 0 : p.import) !== void 0; + if (c && u) { + const g = await i.convert(r, t, o); + return new J(g); + } else { + const g = [c ? !1 : Ae(r.name), u ? !1 : Ae(t)] + .filter(Boolean) + .join(" and "); + throw new Error( + `Conversion from "${r.name}" to "${t}" is not possible. ${g} tool(s) should provide a "conversionConfig"`, + ); + } + }), + (this.insertMany = ( + e, + t = this.Editor.BlockManager.blocks.length - 1, + ) => { + this.validateIndex(t); + const o = e.map(({ id: i, type: s, data: r }) => + this.Editor.BlockManager.composeBlock({ + id: i, + tool: s || this.config.defaultBlock, + data: r, + }), + ); + return ( + this.Editor.BlockManager.insertMany(o, t), o.map((i) => new J(i)) + ); + }); + } + get methods() { + return { + clear: () => this.clear(), + render: (e) => this.render(e), + renderFromHTML: (e) => this.renderFromHTML(e), + delete: (e) => this.delete(e), + swap: (e, t) => this.swap(e, t), + move: (e, t) => this.move(e, t), + getBlockByIndex: (e) => this.getBlockByIndex(e), + getById: (e) => this.getById(e), + getCurrentBlockIndex: () => this.getCurrentBlockIndex(), + getBlockIndex: (e) => this.getBlockIndex(e), + getBlocksCount: () => this.getBlocksCount(), + getBlockByElement: (e) => this.getBlockByElement(e), + stretchBlock: (e, t = !0) => this.stretchBlock(e, t), + insertNewBlock: () => this.insertNewBlock(), + insert: this.insert, + insertMany: this.insertMany, + update: this.update, + composeBlockData: this.composeBlockData, + convert: this.convert, + }; + } + getBlocksCount() { + return this.Editor.BlockManager.blocks.length; + } + getCurrentBlockIndex() { + return this.Editor.BlockManager.currentBlockIndex; + } + getBlockIndex(e) { + const t = this.Editor.BlockManager.getBlockById(e); + if (!t) { + X("There is no block with id `" + e + "`", "warn"); + return; + } + return this.Editor.BlockManager.getBlockIndex(t); + } + getBlockByIndex(e) { + const t = this.Editor.BlockManager.getBlockByIndex(e); + if (t === void 0) { + X("There is no block at index `" + e + "`", "warn"); + return; + } + return new J(t); + } + getById(e) { + const t = this.Editor.BlockManager.getBlockById(e); + return t === void 0 + ? (X("There is no block with id `" + e + "`", "warn"), null) + : new J(t); + } + getBlockByElement(e) { + const t = this.Editor.BlockManager.getBlock(e); + if (t === void 0) { + X("There is no block corresponding to element `" + e + "`", "warn"); + return; + } + return new J(t); + } + swap(e, t) { + C( + "`blocks.swap()` method is deprecated and will be removed in the next major release. Use `block.move()` method instead", + "info", + ), + this.Editor.BlockManager.swap(e, t); + } + move(e, t) { + this.Editor.BlockManager.move(e, t); + } + delete(e = this.Editor.BlockManager.currentBlockIndex) { + try { + const t = this.Editor.BlockManager.getBlockByIndex(e); + this.Editor.BlockManager.removeBlock(t); + } catch (t) { + X(t, "warn"); + return; + } + this.Editor.BlockManager.blocks.length === 0 && + this.Editor.BlockManager.insert(), + this.Editor.BlockManager.currentBlock && + this.Editor.Caret.setToBlock( + this.Editor.BlockManager.currentBlock, + this.Editor.Caret.positions.END, + ), + this.Editor.Toolbar.close(); + } + async clear() { + await this.Editor.BlockManager.clear(!0), + this.Editor.InlineToolbar.close(); + } + async render(e) { + if (e === void 0 || e.blocks === void 0) + throw new Error("Incorrect data passed to the render() method"); + this.Editor.ModificationsObserver.disable(), + await this.Editor.BlockManager.clear(), + await this.Editor.Renderer.render(e.blocks), + this.Editor.ModificationsObserver.enable(); + } + renderFromHTML(e) { + return ( + this.Editor.BlockManager.clear(), this.Editor.Paste.processText(e, !0) + ); + } + stretchBlock(e, t = !0) { + Ye(!0, "blocks.stretchBlock()", "BlockAPI"); + const o = this.Editor.BlockManager.getBlockByIndex(e); + o && (o.stretched = t); + } + insertNewBlock() { + C( + "Method blocks.insertNewBlock() is deprecated and it will be removed in the next major release. Use blocks.insert() instead.", + "warn", + ), + this.insert(); + } + validateIndex(e) { + if (typeof e != "number") throw new Error("Index should be a number"); + if (e < 0) throw new Error("Index should be greater than or equal to 0"); + if (e === null) + throw new Error("Index should be greater than or equal to 0"); + } + } + function Po(n, e) { + return typeof n == "number" + ? e.BlockManager.getBlockByIndex(n) + : typeof n == "string" + ? e.BlockManager.getBlockById(n) + : e.BlockManager.getBlockById(n.id); + } + class Do extends y { + constructor() { + super(...arguments), + (this.setToFirstBlock = ( + e = this.Editor.Caret.positions.DEFAULT, + t = 0, + ) => + this.Editor.BlockManager.firstBlock + ? (this.Editor.Caret.setToBlock( + this.Editor.BlockManager.firstBlock, + e, + t, + ), + !0) + : !1), + (this.setToLastBlock = ( + e = this.Editor.Caret.positions.DEFAULT, + t = 0, + ) => + this.Editor.BlockManager.lastBlock + ? (this.Editor.Caret.setToBlock( + this.Editor.BlockManager.lastBlock, + e, + t, + ), + !0) + : !1), + (this.setToPreviousBlock = ( + e = this.Editor.Caret.positions.DEFAULT, + t = 0, + ) => + this.Editor.BlockManager.previousBlock + ? (this.Editor.Caret.setToBlock( + this.Editor.BlockManager.previousBlock, + e, + t, + ), + !0) + : !1), + (this.setToNextBlock = ( + e = this.Editor.Caret.positions.DEFAULT, + t = 0, + ) => + this.Editor.BlockManager.nextBlock + ? (this.Editor.Caret.setToBlock( + this.Editor.BlockManager.nextBlock, + e, + t, + ), + !0) + : !1), + (this.setToBlock = ( + e, + t = this.Editor.Caret.positions.DEFAULT, + o = 0, + ) => { + const i = Po(e, this.Editor); + return i === void 0 + ? !1 + : (this.Editor.Caret.setToBlock(i, t, o), !0); + }), + (this.focus = (e = !1) => + e + ? this.setToLastBlock(this.Editor.Caret.positions.END) + : this.setToFirstBlock(this.Editor.Caret.positions.START)); + } + get methods() { + return { + setToFirstBlock: this.setToFirstBlock, + setToLastBlock: this.setToLastBlock, + setToPreviousBlock: this.setToPreviousBlock, + setToNextBlock: this.setToNextBlock, + setToBlock: this.setToBlock, + focus: this.focus, + }; + } + } + class Ro extends y { + get methods() { + return { + emit: (e, t) => this.emit(e, t), + off: (e, t) => this.off(e, t), + on: (e, t) => this.on(e, t), + }; + } + on(e, t) { + this.eventsDispatcher.on(e, t); + } + emit(e, t) { + this.eventsDispatcher.emit(e, t); + } + off(e, t) { + this.eventsDispatcher.off(e, t); + } + } + class Ve extends y { + static getNamespace(e, t) { + return t ? `blockTunes.${e}` : `tools.${e}`; + } + get methods() { + return { + t: () => { + X("I18n.t() method can be accessed only from Tools", "warn"); + }, + }; + } + getMethodsForTool(e, t) { + return Object.assign(this.methods, { + t: (o) => H.t(Ve.getNamespace(e, t), o), + }); + } + } + class Fo extends y { + get methods() { + return { + blocks: this.Editor.BlocksAPI.methods, + caret: this.Editor.CaretAPI.methods, + tools: this.Editor.ToolsAPI.methods, + events: this.Editor.EventsAPI.methods, + listeners: this.Editor.ListenersAPI.methods, + notifier: this.Editor.NotifierAPI.methods, + sanitizer: this.Editor.SanitizerAPI.methods, + saver: this.Editor.SaverAPI.methods, + selection: this.Editor.SelectionAPI.methods, + styles: this.Editor.StylesAPI.classes, + toolbar: this.Editor.ToolbarAPI.methods, + inlineToolbar: this.Editor.InlineToolbarAPI.methods, + tooltip: this.Editor.TooltipAPI.methods, + i18n: this.Editor.I18nAPI.methods, + readOnly: this.Editor.ReadOnlyAPI.methods, + ui: this.Editor.UiAPI.methods, + }; + } + getMethodsForTool(e, t) { + return Object.assign(this.methods, { + i18n: this.Editor.I18nAPI.getMethodsForTool(e, t), + }); + } + } + class Ho extends y { + get methods() { + return { close: () => this.close(), open: () => this.open() }; + } + open() { + this.Editor.InlineToolbar.tryToShow(); + } + close() { + this.Editor.InlineToolbar.close(); + } + } + class zo extends y { + get methods() { + return { + on: (e, t, o, i) => this.on(e, t, o, i), + off: (e, t, o, i) => this.off(e, t, o, i), + offById: (e) => this.offById(e), + }; + } + on(e, t, o, i) { + return this.listeners.on(e, t, o, i); + } + off(e, t, o, i) { + this.listeners.off(e, t, o, i); + } + offById(e) { + this.listeners.offById(e); + } + } + var Pt = { exports: {} }; + (function (n, e) { + (function (t, o) { + n.exports = o(); + })(window, function () { + return (function (t) { + var o = {}; + function i(s) { + if (o[s]) return o[s].exports; + var r = (o[s] = { i: s, l: !1, exports: {} }); + return t[s].call(r.exports, r, r.exports, i), (r.l = !0), r.exports; + } + return ( + (i.m = t), + (i.c = o), + (i.d = function (s, r, l) { + i.o(s, r) || + Object.defineProperty(s, r, { enumerable: !0, get: l }); + }), + (i.r = function (s) { + typeof Symbol < "u" && + Symbol.toStringTag && + Object.defineProperty(s, Symbol.toStringTag, { value: "Module" }), + Object.defineProperty(s, "__esModule", { value: !0 }); + }), + (i.t = function (s, r) { + if ( + (1 & r && (s = i(s)), + 8 & r || (4 & r && typeof s == "object" && s && s.__esModule)) + ) + return s; + var l = Object.create(null); + if ( + (i.r(l), + Object.defineProperty(l, "default", { enumerable: !0, value: s }), + 2 & r && typeof s != "string") + ) + for (var a in s) + i.d( + l, + a, + function (c) { + return s[c]; + }.bind(null, a), + ); + return l; + }), + (i.n = function (s) { + var r = + s && s.__esModule + ? function () { + return s.default; + } + : function () { + return s; + }; + return i.d(r, "a", r), r; + }), + (i.o = function (s, r) { + return Object.prototype.hasOwnProperty.call(s, r); + }), + (i.p = "/"), + i((i.s = 0)) + ); + })([ + function (t, o, i) { + i(1), + (t.exports = (function () { + var s = i(6), + r = "cdx-notify--bounce-in", + l = null; + return { + show: function (a) { + if (a.message) { + (function () { + if (l) return !0; + (l = s.getWrapper()), document.body.appendChild(l); + })(); + var c = null, + u = a.time || 8e3; + switch (a.type) { + case "confirm": + c = s.confirm(a); + break; + case "prompt": + c = s.prompt(a); + break; + default: + (c = s.alert(a)), + window.setTimeout(function () { + c.remove(); + }, u); + } + l.appendChild(c), c.classList.add(r); + } + }, + }; + })()); + }, + function (t, o, i) { + var s = i(2); + typeof s == "string" && (s = [[t.i, s, ""]]); + var r = { hmr: !0, transform: void 0, insertInto: void 0 }; + i(4)(s, r), s.locals && (t.exports = s.locals); + }, + function (t, o, i) { + (t.exports = i(3)(!1)).push([ + t.i, + `.cdx-notify--error{background:#fffbfb!important}.cdx-notify--error::before{background:#fb5d5d!important}.cdx-notify__input{max-width:130px;padding:5px 10px;background:#f7f7f7;border:0;border-radius:3px;font-size:13px;color:#656b7c;outline:0}.cdx-notify__input:-ms-input-placeholder{color:#656b7c}.cdx-notify__input::placeholder{color:#656b7c}.cdx-notify__input:focus:-ms-input-placeholder{color:rgba(101,107,124,.3)}.cdx-notify__input:focus::placeholder{color:rgba(101,107,124,.3)}.cdx-notify__button{border:none;border-radius:3px;font-size:13px;padding:5px 10px;cursor:pointer}.cdx-notify__button:last-child{margin-left:10px}.cdx-notify__button--cancel{background:#f2f5f7;box-shadow:0 2px 1px 0 rgba(16,19,29,0);color:#656b7c}.cdx-notify__button--cancel:hover{background:#eee}.cdx-notify__button--confirm{background:#34c992;box-shadow:0 1px 1px 0 rgba(18,49,35,.05);color:#fff}.cdx-notify__button--confirm:hover{background:#33b082}.cdx-notify__btns-wrapper{display:-ms-flexbox;display:flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;margin-top:5px}.cdx-notify__cross{position:absolute;top:5px;right:5px;width:10px;height:10px;padding:5px;opacity:.54;cursor:pointer}.cdx-notify__cross::after,.cdx-notify__cross::before{content:'';position:absolute;left:9px;top:5px;height:12px;width:2px;background:#575d67}.cdx-notify__cross::before{transform:rotate(-45deg)}.cdx-notify__cross::after{transform:rotate(45deg)}.cdx-notify__cross:hover{opacity:1}.cdx-notifies{position:fixed;z-index:2;bottom:20px;left:20px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",sans-serif}.cdx-notify{position:relative;width:220px;margin-top:15px;padding:13px 16px;background:#fff;box-shadow:0 11px 17px 0 rgba(23,32,61,.13);border-radius:5px;font-size:14px;line-height:1.4em;word-wrap:break-word}.cdx-notify::before{content:'';position:absolute;display:block;top:0;left:0;width:3px;height:calc(100% - 6px);margin:3px;border-radius:5px;background:0 0}@keyframes bounceIn{0%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.05)}70%{transform:scale(.9)}100%{transform:scale(1)}}.cdx-notify--bounce-in{animation-name:bounceIn;animation-duration:.6s;animation-iteration-count:1}.cdx-notify--success{background:#fafffe!important}.cdx-notify--success::before{background:#41ffb1!important}`, + "", + ]); + }, + function (t, o) { + t.exports = function (i) { + var s = []; + return ( + (s.toString = function () { + return this.map(function (r) { + var l = (function (a, c) { + var u = a[1] || "", + h = a[3]; + if (!h) return u; + if (c && typeof btoa == "function") { + var p = + ((f = h), + "/*# sourceMappingURL=data:application/json;charset=utf-8;base64," + + btoa( + unescape(encodeURIComponent(JSON.stringify(f))), + ) + + " */"), + g = h.sources.map(function (k) { + return "/*# sourceURL=" + h.sourceRoot + k + " */"; + }); + return [u].concat(g).concat([p]).join(` +`); + } + var f; + return [u].join(` +`); + })(r, i); + return r[2] ? "@media " + r[2] + "{" + l + "}" : l; + }).join(""); + }), + (s.i = function (r, l) { + typeof r == "string" && (r = [[null, r, ""]]); + for (var a = {}, c = 0; c < this.length; c++) { + var u = this[c][0]; + typeof u == "number" && (a[u] = !0); + } + for (c = 0; c < r.length; c++) { + var h = r[c]; + (typeof h[0] == "number" && a[h[0]]) || + (l && !h[2] + ? (h[2] = l) + : l && (h[2] = "(" + h[2] + ") and (" + l + ")"), + s.push(h)); + } + }), + s + ); + }; + }, + function (t, o, i) { + var s, + r, + l = {}, + a = + ((s = function () { + return window && document && document.all && !window.atob; + }), + function () { + return r === void 0 && (r = s.apply(this, arguments)), r; + }), + c = (function (v) { + var b = {}; + return function (x) { + if (typeof x == "function") return x(); + if (b[x] === void 0) { + var E = function (M) { + return document.querySelector(M); + }.call(this, x); + if ( + window.HTMLIFrameElement && + E instanceof window.HTMLIFrameElement + ) + try { + E = E.contentDocument.head; + } catch { + E = null; + } + b[x] = E; + } + return b[x]; + }; + })(), + u = null, + h = 0, + p = [], + g = i(5); + function f(v, b) { + for (var x = 0; x < v.length; x++) { + var E = v[x], + M = l[E.id]; + if (M) { + M.refs++; + for (var T = 0; T < M.parts.length; T++) M.parts[T](E.parts[T]); + for (; T < E.parts.length; T++) M.parts.push(j(E.parts[T], b)); + } else { + var R = []; + for (T = 0; T < E.parts.length; T++) R.push(j(E.parts[T], b)); + l[E.id] = { id: E.id, refs: 1, parts: R }; + } + } + } + function k(v, b) { + for (var x = [], E = {}, M = 0; M < v.length; M++) { + var T = v[M], + R = b.base ? T[0] + b.base : T[0], + B = { css: T[1], media: T[2], sourceMap: T[3] }; + E[R] + ? E[R].parts.push(B) + : x.push((E[R] = { id: R, parts: [B] })); + } + return x; + } + function S(v, b) { + var x = c(v.insertInto); + if (!x) + throw new Error( + "Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.", + ); + var E = p[p.length - 1]; + if (v.insertAt === "top") + E + ? E.nextSibling + ? x.insertBefore(b, E.nextSibling) + : x.appendChild(b) + : x.insertBefore(b, x.firstChild), + p.push(b); + else if (v.insertAt === "bottom") x.appendChild(b); + else { + if (typeof v.insertAt != "object" || !v.insertAt.before) + throw new Error(`[Style Loader] + + Invalid value for parameter 'insertAt' ('options.insertAt') found. + Must be 'top', 'bottom', or Object. + (https://github.com/webpack-contrib/style-loader#insertat) +`); + var M = c(v.insertInto + " " + v.insertAt.before); + x.insertBefore(b, M); + } + } + function I(v) { + if (v.parentNode === null) return !1; + v.parentNode.removeChild(v); + var b = p.indexOf(v); + b >= 0 && p.splice(b, 1); + } + function N(v) { + var b = document.createElement("style"); + return ( + v.attrs.type === void 0 && (v.attrs.type = "text/css"), + oe(b, v.attrs), + S(v, b), + b + ); + } + function oe(v, b) { + Object.keys(b).forEach(function (x) { + v.setAttribute(x, b[x]); + }); + } + function j(v, b) { + var x, E, M, T; + if (b.transform && v.css) { + if (!(T = b.transform(v.css))) return function () {}; + v.css = T; + } + if (b.singleton) { + var R = h++; + (x = u || (u = N(b))), + (E = Te.bind(null, x, R, !1)), + (M = Te.bind(null, x, R, !0)); + } else + v.sourceMap && + typeof URL == "function" && + typeof URL.createObjectURL == "function" && + typeof URL.revokeObjectURL == "function" && + typeof Blob == "function" && + typeof btoa == "function" + ? ((x = (function (B) { + var K = document.createElement("link"); + return ( + B.attrs.type === void 0 && (B.attrs.type = "text/css"), + (B.attrs.rel = "stylesheet"), + oe(K, B.attrs), + S(B, K), + K + ); + })(b)), + (E = function (B, K, Ce) { + var ae = Ce.css, + mt = Ce.sourceMap, + ws = K.convertToAbsoluteUrls === void 0 && mt; + (K.convertToAbsoluteUrls || ws) && (ae = g(ae)), + mt && + (ae += + ` +/*# sourceMappingURL=data:application/json;base64,` + + btoa( + unescape(encodeURIComponent(JSON.stringify(mt))), + ) + + " */"); + var xs = new Blob([ae], { type: "text/css" }), + po = B.href; + (B.href = URL.createObjectURL(xs)), + po && URL.revokeObjectURL(po); + }.bind(null, x, b)), + (M = function () { + I(x), x.href && URL.revokeObjectURL(x.href); + })) + : ((x = N(b)), + (E = function (B, K) { + var Ce = K.css, + ae = K.media; + if ((ae && B.setAttribute("media", ae), B.styleSheet)) + B.styleSheet.cssText = Ce; + else { + for (; B.firstChild; ) B.removeChild(B.firstChild); + B.appendChild(document.createTextNode(Ce)); + } + }.bind(null, x)), + (M = function () { + I(x); + })); + return ( + E(v), + function (B) { + if (B) { + if ( + B.css === v.css && + B.media === v.media && + B.sourceMap === v.sourceMap + ) + return; + E((v = B)); + } else M(); + } + ); + } + t.exports = function (v, b) { + if (typeof DEBUG < "u" && DEBUG && typeof document != "object") + throw new Error( + "The style-loader cannot be used in a non-browser environment", + ); + ((b = b || {}).attrs = typeof b.attrs == "object" ? b.attrs : {}), + b.singleton || + typeof b.singleton == "boolean" || + (b.singleton = a()), + b.insertInto || (b.insertInto = "head"), + b.insertAt || (b.insertAt = "bottom"); + var x = k(v, b); + return ( + f(x, b), + function (E) { + for (var M = [], T = 0; T < x.length; T++) { + var R = x[T]; + (B = l[R.id]).refs--, M.push(B); + } + for (E && f(k(E, b), b), T = 0; T < M.length; T++) { + var B; + if ((B = M[T]).refs === 0) { + for (var K = 0; K < B.parts.length; K++) B.parts[K](); + delete l[B.id]; + } + } + } + ); + }; + var W, + le = + ((W = []), + function (v, b) { + return ( + (W[v] = b), + W.filter(Boolean).join(` +`) + ); + }); + function Te(v, b, x, E) { + var M = x ? "" : E.css; + if (v.styleSheet) v.styleSheet.cssText = le(b, M); + else { + var T = document.createTextNode(M), + R = v.childNodes; + R[b] && v.removeChild(R[b]), + R.length ? v.insertBefore(T, R[b]) : v.appendChild(T); + } + } + }, + function (t, o) { + t.exports = function (i) { + var s = typeof window < "u" && window.location; + if (!s) throw new Error("fixUrls requires window.location"); + if (!i || typeof i != "string") return i; + var r = s.protocol + "//" + s.host, + l = r + s.pathname.replace(/\/[^\/]*$/, "/"); + return i.replace( + /url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, + function (a, c) { + var u, + h = c + .trim() + .replace(/^"(.*)"$/, function (p, g) { + return g; + }) + .replace(/^'(.*)'$/, function (p, g) { + return g; + }); + return /^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test( + h, + ) + ? a + : ((u = + h.indexOf("//") === 0 + ? h + : h.indexOf("/") === 0 + ? r + h + : l + h.replace(/^\.\//, "")), + "url(" + JSON.stringify(u) + ")"); + }, + ); + }; + }, + function (t, o, i) { + var s, r, l, a, c, u, h, p, g; + t.exports = + ((s = "cdx-notifies"), + (r = "cdx-notify"), + (l = "cdx-notify__cross"), + (a = "cdx-notify__button--confirm"), + (c = "cdx-notify__button--cancel"), + (u = "cdx-notify__input"), + (h = "cdx-notify__button"), + (p = "cdx-notify__btns-wrapper"), + { + alert: (g = function (f) { + var k = document.createElement("DIV"), + S = document.createElement("DIV"), + I = f.message, + N = f.style; + return ( + k.classList.add(r), + N && k.classList.add(r + "--" + N), + (k.innerHTML = I), + S.classList.add(l), + S.addEventListener("click", k.remove.bind(k)), + k.appendChild(S), + k + ); + }), + confirm: function (f) { + var k = g(f), + S = document.createElement("div"), + I = document.createElement("button"), + N = document.createElement("button"), + oe = k.querySelector("." + l), + j = f.cancelHandler, + W = f.okHandler; + return ( + S.classList.add(p), + (I.innerHTML = f.okText || "Confirm"), + (N.innerHTML = f.cancelText || "Cancel"), + I.classList.add(h), + N.classList.add(h), + I.classList.add(a), + N.classList.add(c), + j && + typeof j == "function" && + (N.addEventListener("click", j), + oe.addEventListener("click", j)), + W && typeof W == "function" && I.addEventListener("click", W), + I.addEventListener("click", k.remove.bind(k)), + N.addEventListener("click", k.remove.bind(k)), + S.appendChild(I), + S.appendChild(N), + k.appendChild(S), + k + ); + }, + prompt: function (f) { + var k = g(f), + S = document.createElement("div"), + I = document.createElement("button"), + N = document.createElement("input"), + oe = k.querySelector("." + l), + j = f.cancelHandler, + W = f.okHandler; + return ( + S.classList.add(p), + (I.innerHTML = f.okText || "Ok"), + I.classList.add(h), + I.classList.add(a), + N.classList.add(u), + f.placeholder && N.setAttribute("placeholder", f.placeholder), + f.default && (N.value = f.default), + f.inputType && (N.type = f.inputType), + j && + typeof j == "function" && + oe.addEventListener("click", j), + W && + typeof W == "function" && + I.addEventListener("click", function () { + W(N.value); + }), + I.addEventListener("click", k.remove.bind(k)), + S.appendChild(N), + S.appendChild(I), + k.appendChild(S), + k + ); + }, + getWrapper: function () { + var f = document.createElement("DIV"); + return f.classList.add(s), f; + }, + }); + }, + ]); + }); + })(Pt); + var Uo = Pt.exports; + const jo = ee(Uo); + class $o { + show(e) { + jo.show(e); + } + } + class Yo extends y { + constructor({ config: e, eventsDispatcher: t }) { + super({ config: e, eventsDispatcher: t }), (this.notifier = new $o()); + } + get methods() { + return { show: (e) => this.show(e) }; + } + show(e) { + return this.notifier.show(e); + } + } + class Wo extends y { + get methods() { + const e = () => this.isEnabled; + return { + toggle: (t) => this.toggle(t), + get isEnabled() { + return e(); + }, + }; + } + toggle(e) { + return this.Editor.ReadOnly.toggle(e); + } + get isEnabled() { + return this.Editor.ReadOnly.isEnabled; + } + } + var Dt = { exports: {} }; + (function (n, e) { + (function (t, o) { + n.exports = o(); + })(ge, function () { + function t(h) { + var p = h.tags, + g = Object.keys(p), + f = g + .map(function (k) { + return typeof p[k]; + }) + .every(function (k) { + return k === "object" || k === "boolean" || k === "function"; + }); + if (!f) throw new Error("The configuration was invalid"); + this.config = h; + } + var o = [ + "P", + "LI", + "TD", + "TH", + "DIV", + "H1", + "H2", + "H3", + "H4", + "H5", + "H6", + "PRE", + ]; + function i(h) { + return o.indexOf(h.nodeName) !== -1; + } + var s = ["A", "B", "STRONG", "I", "EM", "SUB", "SUP", "U", "STRIKE"]; + function r(h) { + return s.indexOf(h.nodeName) !== -1; + } + (t.prototype.clean = function (h) { + const p = document.implementation.createHTMLDocument(), + g = p.createElement("div"); + return (g.innerHTML = h), this._sanitize(p, g), g.innerHTML; + }), + (t.prototype._sanitize = function (h, p) { + var g = l(h, p), + f = g.firstChild(); + if (f) + do { + if (f.nodeType === Node.TEXT_NODE) + if ( + f.data.trim() === "" && + ((f.previousElementSibling && i(f.previousElementSibling)) || + (f.nextElementSibling && i(f.nextElementSibling))) + ) { + p.removeChild(f), this._sanitize(h, p); + break; + } else continue; + if (f.nodeType === Node.COMMENT_NODE) { + p.removeChild(f), this._sanitize(h, p); + break; + } + var k = r(f), + S; + k && (S = Array.prototype.some.call(f.childNodes, i)); + var I = !!p.parentNode, + N = i(p) && i(f) && I, + oe = f.nodeName.toLowerCase(), + j = a(this.config, oe, f), + W = k && S; + if (W || c(f, j) || (!this.config.keepNestedBlockElements && N)) { + if (!(f.nodeName === "SCRIPT" || f.nodeName === "STYLE")) + for (; f.childNodes.length > 0; ) + p.insertBefore(f.childNodes[0], f); + p.removeChild(f), this._sanitize(h, p); + break; + } + for (var le = 0; le < f.attributes.length; le += 1) { + var Te = f.attributes[le]; + u(Te, j, f) && (f.removeAttribute(Te.name), (le = le - 1)); + } + this._sanitize(h, f); + } while ((f = g.nextSibling())); + }); + function l(h, p) { + return h.createTreeWalker( + p, + NodeFilter.SHOW_TEXT | + NodeFilter.SHOW_ELEMENT | + NodeFilter.SHOW_COMMENT, + null, + !1, + ); + } + function a(h, p, g) { + return typeof h.tags[p] == "function" ? h.tags[p](g) : h.tags[p]; + } + function c(h, p) { + return typeof p > "u" ? !0 : typeof p == "boolean" ? !p : !1; + } + function u(h, p, g) { + var f = h.name.toLowerCase(); + return p === !0 + ? !1 + : typeof p[f] == "function" + ? !p[f](h.value, g) + : typeof p[f] > "u" || p[f] === !1 + ? !0 + : typeof p[f] == "string" + ? p[f] !== h.value + : !1; + } + return t; + }); + })(Dt); + var Ko = Dt.exports; + const Xo = ee(Ko); + function qe(n, e) { + return n.map((t) => { + const o = O(e) ? e(t.tool) : e; + return V(o) || (t.data = Ze(t.data, o)), t; + }); + } + function q(n, e = {}) { + const t = { tags: e }; + return new Xo(t).clean(n); + } + function Ze(n, e) { + return Array.isArray(n) ? Vo(n, e) : P(n) ? qo(n, e) : G(n) ? Zo(n, e) : n; + } + function Vo(n, e) { + return n.map((t) => Ze(t, e)); + } + function qo(n, e) { + const t = {}; + for (const o in n) { + if (!Object.prototype.hasOwnProperty.call(n, o)) continue; + const i = n[o], + s = Go(e[o]) ? e[o] : e; + t[o] = Ze(i, s); + } + return t; + } + function Zo(n, e) { + return P(e) ? q(n, e) : e === !1 ? q(n, {}) : n; + } + function Go(n) { + return P(n) || wo(n) || O(n); + } + class Jo extends y { + get methods() { + return { clean: (e, t) => this.clean(e, t) }; + } + clean(e, t) { + return q(e, t); + } + } + class Qo extends y { + get methods() { + return { save: () => this.save() }; + } + save() { + const e = "Editor's content can not be saved in read-only mode"; + return this.Editor.ReadOnly.isEnabled + ? (X(e, "warn"), Promise.reject(new Error(e))) + : this.Editor.Saver.save(); + } + } + class ei extends y { + constructor() { + super(...arguments), (this.selectionUtils = new m()); + } + get methods() { + return { + findParentTag: (e, t) => this.findParentTag(e, t), + expandToTag: (e) => this.expandToTag(e), + save: () => this.selectionUtils.save(), + restore: () => this.selectionUtils.restore(), + setFakeBackground: () => this.selectionUtils.setFakeBackground(), + removeFakeBackground: () => this.selectionUtils.removeFakeBackground(), + }; + } + findParentTag(e, t) { + return this.selectionUtils.findParentTag(e, t); + } + expandToTag(e) { + this.selectionUtils.expandToTag(e); + } + } + class ti extends y { + get methods() { + return { + getBlockTools: () => Array.from(this.Editor.Tools.blockTools.values()), + }; + } + } + class oi extends y { + get classes() { + return { + block: "cdx-block", + inlineToolButton: "ce-inline-tool", + inlineToolButtonActive: "ce-inline-tool--active", + input: "cdx-input", + loader: "cdx-loader", + button: "cdx-button", + settingsButton: "cdx-settings-button", + settingsButtonActive: "cdx-settings-button--active", + }; + } + } + class ii extends y { + get methods() { + return { + close: () => this.close(), + open: () => this.open(), + toggleBlockSettings: (e) => this.toggleBlockSettings(e), + toggleToolbox: (e) => this.toggleToolbox(e), + }; + } + open() { + this.Editor.Toolbar.moveAndOpen(); + } + close() { + this.Editor.Toolbar.close(); + } + toggleBlockSettings(e) { + if (this.Editor.BlockManager.currentBlockIndex === -1) { + X( + "Could't toggle the Toolbar because there is no block selected ", + "warn", + ); + return; + } + e ?? !this.Editor.BlockSettings.opened + ? (this.Editor.Toolbar.moveAndOpen(), this.Editor.BlockSettings.open()) + : this.Editor.BlockSettings.close(); + } + toggleToolbox(e) { + if (this.Editor.BlockManager.currentBlockIndex === -1) { + X( + "Could't toggle the Toolbox because there is no block selected ", + "warn", + ); + return; + } + e ?? !this.Editor.Toolbar.toolbox.opened + ? (this.Editor.Toolbar.moveAndOpen(), + this.Editor.Toolbar.toolbox.open()) + : this.Editor.Toolbar.toolbox.close(); + } + } + var Rt = { exports: {} }; + /*! + * CodeX.Tooltips + * + * @version 1.0.5 + * + * @licence MIT + * @author CodeX + * + * + */ (function (n, e) { + (function (t, o) { + n.exports = o(); + })(window, function () { + return (function (t) { + var o = {}; + function i(s) { + if (o[s]) return o[s].exports; + var r = (o[s] = { i: s, l: !1, exports: {} }); + return t[s].call(r.exports, r, r.exports, i), (r.l = !0), r.exports; + } + return ( + (i.m = t), + (i.c = o), + (i.d = function (s, r, l) { + i.o(s, r) || + Object.defineProperty(s, r, { enumerable: !0, get: l }); + }), + (i.r = function (s) { + typeof Symbol < "u" && + Symbol.toStringTag && + Object.defineProperty(s, Symbol.toStringTag, { value: "Module" }), + Object.defineProperty(s, "__esModule", { value: !0 }); + }), + (i.t = function (s, r) { + if ( + (1 & r && (s = i(s)), + 8 & r || (4 & r && typeof s == "object" && s && s.__esModule)) + ) + return s; + var l = Object.create(null); + if ( + (i.r(l), + Object.defineProperty(l, "default", { enumerable: !0, value: s }), + 2 & r && typeof s != "string") + ) + for (var a in s) + i.d( + l, + a, + function (c) { + return s[c]; + }.bind(null, a), + ); + return l; + }), + (i.n = function (s) { + var r = + s && s.__esModule + ? function () { + return s.default; + } + : function () { + return s; + }; + return i.d(r, "a", r), r; + }), + (i.o = function (s, r) { + return Object.prototype.hasOwnProperty.call(s, r); + }), + (i.p = ""), + i((i.s = 0)) + ); + })([ + function (t, o, i) { + t.exports = i(1); + }, + function (t, o, i) { + i.r(o), + i.d(o, "default", function () { + return s; + }); + class s { + constructor() { + (this.nodes = { wrapper: null, content: null }), + (this.showed = !1), + (this.offsetTop = 10), + (this.offsetLeft = 10), + (this.offsetRight = 10), + (this.hidingDelay = 0), + (this.handleWindowScroll = () => { + this.showed && this.hide(!0); + }), + this.loadStyles(), + this.prepare(), + window.addEventListener("scroll", this.handleWindowScroll, { + passive: !0, + }); + } + get CSS() { + return { + tooltip: "ct", + tooltipContent: "ct__content", + tooltipShown: "ct--shown", + placement: { + left: "ct--left", + bottom: "ct--bottom", + right: "ct--right", + top: "ct--top", + }, + }; + } + show(l, a, c) { + this.nodes.wrapper || this.prepare(), + this.hidingTimeout && clearTimeout(this.hidingTimeout); + const u = Object.assign( + { + placement: "bottom", + marginTop: 0, + marginLeft: 0, + marginRight: 0, + marginBottom: 0, + delay: 70, + hidingDelay: 0, + }, + c, + ); + if ( + (u.hidingDelay && (this.hidingDelay = u.hidingDelay), + (this.nodes.content.innerHTML = ""), + typeof a == "string") + ) + this.nodes.content.appendChild(document.createTextNode(a)); + else { + if (!(a instanceof Node)) + throw Error( + "[CodeX Tooltip] Wrong type of «content» passed. It should be an instance of Node or String. But " + + typeof a + + " given.", + ); + this.nodes.content.appendChild(a); + } + switch ( + (this.nodes.wrapper.classList.remove( + ...Object.values(this.CSS.placement), + ), + u.placement) + ) { + case "top": + this.placeTop(l, u); + break; + case "left": + this.placeLeft(l, u); + break; + case "right": + this.placeRight(l, u); + break; + case "bottom": + default: + this.placeBottom(l, u); + } + u && u.delay + ? (this.showingTimeout = setTimeout(() => { + this.nodes.wrapper.classList.add(this.CSS.tooltipShown), + (this.showed = !0); + }, u.delay)) + : (this.nodes.wrapper.classList.add(this.CSS.tooltipShown), + (this.showed = !0)); + } + hide(l = !1) { + if (this.hidingDelay && !l) + return ( + this.hidingTimeout && clearTimeout(this.hidingTimeout), + void (this.hidingTimeout = setTimeout(() => { + this.hide(!0); + }, this.hidingDelay)) + ); + this.nodes.wrapper.classList.remove(this.CSS.tooltipShown), + (this.showed = !1), + this.showingTimeout && clearTimeout(this.showingTimeout); + } + onHover(l, a, c) { + l.addEventListener("mouseenter", () => { + this.show(l, a, c); + }), + l.addEventListener("mouseleave", () => { + this.hide(); + }); + } + destroy() { + this.nodes.wrapper.remove(), + window.removeEventListener("scroll", this.handleWindowScroll); + } + prepare() { + (this.nodes.wrapper = this.make("div", this.CSS.tooltip)), + (this.nodes.content = this.make( + "div", + this.CSS.tooltipContent, + )), + this.append(this.nodes.wrapper, this.nodes.content), + this.append(document.body, this.nodes.wrapper); + } + loadStyles() { + const l = "codex-tooltips-style"; + if (document.getElementById(l)) return; + const a = i(2), + c = this.make("style", null, { + textContent: a.toString(), + id: l, + }); + this.prepend(document.head, c); + } + placeBottom(l, a) { + const c = l.getBoundingClientRect(), + u = + c.left + + l.clientWidth / 2 - + this.nodes.wrapper.offsetWidth / 2, + h = + c.bottom + window.pageYOffset + this.offsetTop + a.marginTop; + this.applyPlacement("bottom", u, h); + } + placeTop(l, a) { + const c = l.getBoundingClientRect(), + u = + c.left + + l.clientWidth / 2 - + this.nodes.wrapper.offsetWidth / 2, + h = + c.top + + window.pageYOffset - + this.nodes.wrapper.clientHeight - + this.offsetTop; + this.applyPlacement("top", u, h); + } + placeLeft(l, a) { + const c = l.getBoundingClientRect(), + u = + c.left - + this.nodes.wrapper.offsetWidth - + this.offsetLeft - + a.marginLeft, + h = + c.top + + window.pageYOffset + + l.clientHeight / 2 - + this.nodes.wrapper.offsetHeight / 2; + this.applyPlacement("left", u, h); + } + placeRight(l, a) { + const c = l.getBoundingClientRect(), + u = c.right + this.offsetRight + a.marginRight, + h = + c.top + + window.pageYOffset + + l.clientHeight / 2 - + this.nodes.wrapper.offsetHeight / 2; + this.applyPlacement("right", u, h); + } + applyPlacement(l, a, c) { + this.nodes.wrapper.classList.add(this.CSS.placement[l]), + (this.nodes.wrapper.style.left = a + "px"), + (this.nodes.wrapper.style.top = c + "px"); + } + make(l, a = null, c = {}) { + const u = document.createElement(l); + Array.isArray(a) + ? u.classList.add(...a) + : a && u.classList.add(a); + for (const h in c) c.hasOwnProperty(h) && (u[h] = c[h]); + return u; + } + append(l, a) { + Array.isArray(a) + ? a.forEach((c) => l.appendChild(c)) + : l.appendChild(a); + } + prepend(l, a) { + Array.isArray(a) + ? (a = a.reverse()).forEach((c) => l.prepend(c)) + : l.prepend(a); + } + } + }, + function (t, o) { + t.exports = `.ct{z-index:999;opacity:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;-webkit-transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1),-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);will-change:opacity,top,left;-webkit-box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);border-radius:9px}.ct,.ct:before{position:absolute;top:0;left:0}.ct:before{content:"";bottom:0;right:0;background-color:#1d202b;z-index:-1;border-radius:4px}@supports(-webkit-mask-box-image:url("")){.ct:before{border-radius:0;-webkit-mask-box-image:url('data:image/svg+xml;charset=utf-8,') 48% 41% 37.9% 53.3%}}@media (--mobile){.ct{display:none}}.ct__content{padding:6px 10px;color:#cdd1e0;font-size:12px;text-align:center;letter-spacing:.02em;line-height:1em}.ct:after{content:"";width:8px;height:8px;position:absolute;background-color:#1d202b;z-index:-1}.ct--bottom{-webkit-transform:translateY(5px);transform:translateY(5px)}.ct--bottom:after{top:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--top{-webkit-transform:translateY(-5px);transform:translateY(-5px)}.ct--top:after{top:auto;bottom:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--left{-webkit-transform:translateX(-5px);transform:translateX(-5px)}.ct--left:after{top:50%;left:auto;right:0;-webkit-transform:translate(41.6%,-50%) rotate(-45deg);transform:translate(41.6%,-50%) rotate(-45deg)}.ct--right{-webkit-transform:translateX(5px);transform:translateX(5px)}.ct--right:after{top:50%;left:0;-webkit-transform:translate(-41.6%,-50%) rotate(-45deg);transform:translate(-41.6%,-50%) rotate(-45deg)}.ct--shown{opacity:1;-webkit-transform:none;transform:none}`; + }, + ]).default; + }); + })(Rt); + var si = Rt.exports; + const ni = ee(si); + let z = null; + function Ge() { + z || (z = new ni()); + } + function ri(n, e, t) { + Ge(), z == null || z.show(n, e, t); + } + function Le(n = !1) { + Ge(), z == null || z.hide(n); + } + function _e(n, e, t) { + Ge(), z == null || z.onHover(n, e, t); + } + function li() { + z == null || z.destroy(), (z = null); + } + class ai extends y { + constructor({ config: e, eventsDispatcher: t }) { + super({ config: e, eventsDispatcher: t }); + } + get methods() { + return { + show: (e, t, o) => this.show(e, t, o), + hide: () => this.hide(), + onHover: (e, t, o) => this.onHover(e, t, o), + }; + } + show(e, t, o) { + ri(e, t, o); + } + hide() { + Le(); + } + onHover(e, t, o) { + _e(e, t, o); + } + } + class ci extends y { + get methods() { + return { nodes: this.editorNodes }; + } + get editorNodes() { + return { + wrapper: this.Editor.UI.nodes.wrapper, + redactor: this.Editor.UI.nodes.redactor, + }; + } + } + function Ft(n, e) { + const t = {}; + return ( + Object.entries(n).forEach(([o, i]) => { + if (P(i)) { + const s = e ? `${e}.${o}` : o; + Object.values(i).every((l) => G(l)) ? (t[o] = s) : (t[o] = Ft(i, s)); + return; + } + t[o] = i; + }), + t + ); + } + const $ = Ft(Tt); + function di(n, e) { + const t = {}; + return ( + Object.keys(n).forEach((o) => { + const i = e[o]; + i !== void 0 ? (t[i] = n[o]) : (t[o] = n[o]); + }), + t + ); + } + const Ht = class Se { + constructor(e, t) { + (this.cursor = -1), + (this.items = []), + (this.items = e || []), + (this.focusedCssClass = t); + } + get currentItem() { + return this.cursor === -1 ? null : this.items[this.cursor]; + } + setCursor(e) { + e < this.items.length && + e >= -1 && + (this.dropCursor(), + (this.cursor = e), + this.items[this.cursor].classList.add(this.focusedCssClass)); + } + setItems(e) { + this.items = e; + } + next() { + this.cursor = this.leafNodesAndReturnIndex(Se.directions.RIGHT); + } + previous() { + this.cursor = this.leafNodesAndReturnIndex(Se.directions.LEFT); + } + dropCursor() { + this.cursor !== -1 && + (this.items[this.cursor].classList.remove(this.focusedCssClass), + (this.cursor = -1)); + } + leafNodesAndReturnIndex(e) { + if (this.items.length === 0) return this.cursor; + let t = this.cursor; + return ( + t === -1 + ? (t = e === Se.directions.RIGHT ? -1 : 0) + : this.items[t].classList.remove(this.focusedCssClass), + e === Se.directions.RIGHT + ? (t = (t + 1) % this.items.length) + : (t = (this.items.length + t - 1) % this.items.length), + d.canSetCaret(this.items[t]) && + Me(() => m.setCursor(this.items[t]), 50)(), + this.items[t].classList.add(this.focusedCssClass), + t + ); + } + }; + Ht.directions = { RIGHT: "right", LEFT: "left" }; + let we = Ht; + class se { + constructor(e) { + (this.iterator = null), + (this.activated = !1), + (this.flipCallbacks = []), + (this.onKeyDown = (t) => { + if (this.isEventReadyForHandling(t)) + switch ( + (se.usedKeys.includes(t.keyCode) && t.preventDefault(), t.keyCode) + ) { + case w.TAB: + this.handleTabPress(t); + break; + case w.LEFT: + case w.UP: + this.flipLeft(); + break; + case w.RIGHT: + case w.DOWN: + this.flipRight(); + break; + case w.ENTER: + this.handleEnterPress(t); + break; + } + }), + (this.iterator = new we(e.items, e.focusedItemClass)), + (this.activateCallback = e.activateCallback), + (this.allowedKeys = e.allowedKeys || se.usedKeys); + } + get isActivated() { + return this.activated; + } + static get usedKeys() { + return [w.TAB, w.LEFT, w.RIGHT, w.ENTER, w.UP, w.DOWN]; + } + activate(e, t) { + (this.activated = !0), + e && this.iterator.setItems(e), + t !== void 0 && this.iterator.setCursor(t), + document.addEventListener("keydown", this.onKeyDown, !0); + } + deactivate() { + (this.activated = !1), + this.dropCursor(), + document.removeEventListener("keydown", this.onKeyDown); + } + focusFirst() { + this.dropCursor(), this.flipRight(); + } + flipLeft() { + this.iterator.previous(), this.flipCallback(); + } + flipRight() { + this.iterator.next(), this.flipCallback(); + } + hasFocus() { + return !!this.iterator.currentItem; + } + onFlip(e) { + this.flipCallbacks.push(e); + } + removeOnFlip(e) { + this.flipCallbacks = this.flipCallbacks.filter((t) => t !== e); + } + dropCursor() { + this.iterator.dropCursor(); + } + isEventReadyForHandling(e) { + return this.activated && this.allowedKeys.includes(e.keyCode); + } + handleTabPress(e) { + switch (e.shiftKey ? we.directions.LEFT : we.directions.RIGHT) { + case we.directions.RIGHT: + this.flipRight(); + break; + case we.directions.LEFT: + this.flipLeft(); + break; + } + } + handleEnterPress(e) { + this.activated && + (this.iterator.currentItem && + (e.stopPropagation(), + e.preventDefault(), + this.iterator.currentItem.click()), + O(this.activateCallback) && + this.activateCallback(this.iterator.currentItem)); + } + flipCallback() { + this.iterator.currentItem && + this.iterator.currentItem.scrollIntoViewIfNeeded(), + this.flipCallbacks.forEach((e) => e()); + } + } + const hi = + '', + ui = + '', + pi = + '', + fi = + '', + gi = + '', + mi = + '', + bi = + '', + ki = + '', + zt = + '', + vi = + '', + wi = + '', + Ut = + '', + xi = + '', + yi = + '', + Ei = + '', + Bi = "__", + Ti = "--"; + function te(n) { + return (e, t) => + [[n, e].filter((i) => !!i).join(Bi), t].filter((i) => !!i).join(Ti); + } + const xe = te("ce-hint"), + ye = { + root: xe(), + alignedStart: xe(null, "align-left"), + alignedCenter: xe(null, "align-center"), + title: xe("title"), + description: xe("description"), + }, + Cs = ""; + class Ci { + constructor(e) { + (this.nodes = { + root: d.make("div", [ + ye.root, + e.alignment === "center" ? ye.alignedCenter : ye.alignedStart, + ]), + title: d.make("div", ye.title, { textContent: e.title }), + }), + this.nodes.root.appendChild(this.nodes.title), + e.description !== void 0 && + ((this.nodes.description = d.make("div", ye.description, { + textContent: e.description, + })), + this.nodes.root.appendChild(this.nodes.description)); + } + getElement() { + return this.nodes.root; + } + } + class Je { + constructor(e) { + this.params = e; + } + get name() { + if (this.params !== void 0 && "name" in this.params) + return this.params.name; + } + destroy() { + Le(); + } + onChildrenOpen() { + var e; + this.params !== void 0 && + "children" in this.params && + typeof ((e = this.params.children) == null ? void 0 : e.onOpen) == + "function" && + this.params.children.onOpen(); + } + onChildrenClose() { + var e; + this.params !== void 0 && + "children" in this.params && + typeof ((e = this.params.children) == null ? void 0 : e.onClose) == + "function" && + this.params.children.onClose(); + } + handleClick() { + var e, t; + this.params !== void 0 && + "onActivate" in this.params && + ((t = (e = this.params).onActivate) == null || t.call(e, this.params)); + } + addHint(e, t) { + const o = new Ci(t); + _e(e, o.getElement(), { placement: t.position, hidingDelay: 100 }); + } + get children() { + var e; + return this.params !== void 0 && + "children" in this.params && + ((e = this.params.children) == null ? void 0 : e.items) !== void 0 + ? this.params.children.items + : []; + } + get hasChildren() { + return this.children.length > 0; + } + get isChildrenOpen() { + var e; + return ( + this.params !== void 0 && + "children" in this.params && + ((e = this.params.children) == null ? void 0 : e.isOpen) === !0 + ); + } + get isChildrenFlippable() { + var e; + return !( + this.params === void 0 || + !("children" in this.params) || + ((e = this.params.children) == null ? void 0 : e.isFlippable) === !1 + ); + } + get isChildrenSearchable() { + var e; + return ( + this.params !== void 0 && + "children" in this.params && + ((e = this.params.children) == null ? void 0 : e.searchable) === !0 + ); + } + get closeOnActivate() { + return ( + this.params !== void 0 && + "closeOnActivate" in this.params && + this.params.closeOnActivate + ); + } + get isActive() { + return this.params === void 0 || !("isActive" in this.params) + ? !1 + : typeof this.params.isActive == "function" + ? this.params.isActive() + : this.params.isActive === !0; + } + } + const Y = te("ce-popover-item"), + L = { + container: Y(), + active: Y(null, "active"), + disabled: Y(null, "disabled"), + focused: Y(null, "focused"), + hidden: Y(null, "hidden"), + confirmationState: Y(null, "confirmation"), + noHover: Y(null, "no-hover"), + noFocus: Y(null, "no-focus"), + title: Y("title"), + secondaryTitle: Y("secondary-title"), + icon: Y("icon"), + iconTool: Y("icon", "tool"), + iconChevronRight: Y("icon", "chevron-right"), + wobbleAnimation: te("wobble")(), + }; + class ne extends Je { + constructor(e, t) { + super(e), + (this.params = e), + (this.nodes = { root: null, icon: null }), + (this.confirmationState = null), + (this.removeSpecialFocusBehavior = () => { + var o; + (o = this.nodes.root) == null || o.classList.remove(L.noFocus); + }), + (this.removeSpecialHoverBehavior = () => { + var o; + (o = this.nodes.root) == null || o.classList.remove(L.noHover); + }), + (this.onErrorAnimationEnd = () => { + var o, i; + (o = this.nodes.icon) == null || + o.classList.remove(L.wobbleAnimation), + (i = this.nodes.icon) == null || + i.removeEventListener("animationend", this.onErrorAnimationEnd); + }), + (this.nodes.root = this.make(e, t)); + } + get isDisabled() { + return this.params.isDisabled === !0; + } + get toggle() { + return this.params.toggle; + } + get title() { + return this.params.title; + } + get isConfirmationStateEnabled() { + return this.confirmationState !== null; + } + get isFocused() { + return this.nodes.root === null + ? !1 + : this.nodes.root.classList.contains(L.focused); + } + getElement() { + return this.nodes.root; + } + handleClick() { + if (this.isConfirmationStateEnabled && this.confirmationState !== null) { + this.activateOrEnableConfirmationMode(this.confirmationState); + return; + } + this.activateOrEnableConfirmationMode(this.params); + } + toggleActive(e) { + var t; + (t = this.nodes.root) == null || t.classList.toggle(L.active, e); + } + toggleHidden(e) { + var t; + (t = this.nodes.root) == null || t.classList.toggle(L.hidden, e); + } + reset() { + this.isConfirmationStateEnabled && this.disableConfirmationMode(); + } + onFocus() { + this.disableSpecialHoverAndFocusBehavior(); + } + make(e, t) { + var s, r; + const o = (t == null ? void 0 : t.wrapperTag) || "div", + i = d.make(o, L.container, { + type: o === "button" ? "button" : void 0, + }); + return ( + e.name && (i.dataset.itemName = e.name), + (this.nodes.icon = d.make("div", [L.icon, L.iconTool], { + innerHTML: e.icon || bi, + })), + i.appendChild(this.nodes.icon), + e.title !== void 0 && + i.appendChild(d.make("div", L.title, { innerHTML: e.title || "" })), + e.secondaryLabel && + i.appendChild( + d.make("div", L.secondaryTitle, { textContent: e.secondaryLabel }), + ), + this.hasChildren && + i.appendChild( + d.make("div", [L.icon, L.iconChevronRight], { innerHTML: fi }), + ), + this.isActive && i.classList.add(L.active), + e.isDisabled && i.classList.add(L.disabled), + e.hint !== void 0 && + ((s = t == null ? void 0 : t.hint) == null ? void 0 : s.enabled) !== + !1 && + this.addHint(i, { + ...e.hint, + position: + ((r = t == null ? void 0 : t.hint) == null + ? void 0 + : r.position) || "right", + }), + i + ); + } + enableConfirmationMode(e) { + if (this.nodes.root === null) return; + const t = { + ...this.params, + ...e, + confirmation: "confirmation" in e ? e.confirmation : void 0, + }, + o = this.make(t); + (this.nodes.root.innerHTML = o.innerHTML), + this.nodes.root.classList.add(L.confirmationState), + (this.confirmationState = e), + this.enableSpecialHoverAndFocusBehavior(); + } + disableConfirmationMode() { + if (this.nodes.root === null) return; + const e = this.make(this.params); + (this.nodes.root.innerHTML = e.innerHTML), + this.nodes.root.classList.remove(L.confirmationState), + (this.confirmationState = null), + this.disableSpecialHoverAndFocusBehavior(); + } + enableSpecialHoverAndFocusBehavior() { + var e, t, o; + (e = this.nodes.root) == null || e.classList.add(L.noHover), + (t = this.nodes.root) == null || t.classList.add(L.noFocus), + (o = this.nodes.root) == null || + o.addEventListener("mouseleave", this.removeSpecialHoverBehavior, { + once: !0, + }); + } + disableSpecialHoverAndFocusBehavior() { + var e; + this.removeSpecialFocusBehavior(), + this.removeSpecialHoverBehavior(), + (e = this.nodes.root) == null || + e.removeEventListener("mouseleave", this.removeSpecialHoverBehavior); + } + activateOrEnableConfirmationMode(e) { + var t; + if (!("confirmation" in e) || e.confirmation === void 0) + try { + (t = e.onActivate) == null || t.call(e, e), + this.disableConfirmationMode(); + } catch { + this.animateError(); + } + else this.enableConfirmationMode(e.confirmation); + } + animateError() { + var e, t, o; + ((e = this.nodes.icon) != null && + e.classList.contains(L.wobbleAnimation)) || + ((t = this.nodes.icon) == null || t.classList.add(L.wobbleAnimation), + (o = this.nodes.icon) == null || + o.addEventListener("animationend", this.onErrorAnimationEnd)); + } + } + const Qe = te("ce-popover-item-separator"), + et = { container: Qe(), line: Qe("line"), hidden: Qe(null, "hidden") }; + class jt extends Je { + constructor() { + super(), + (this.nodes = { + root: d.make("div", et.container), + line: d.make("div", et.line), + }), + this.nodes.root.appendChild(this.nodes.line); + } + getElement() { + return this.nodes.root; + } + toggleHidden(e) { + var t; + (t = this.nodes.root) == null || t.classList.toggle(et.hidden, e); + } + } + var Z = ((n) => ( + (n.Closed = "closed"), (n.ClosedOnActivate = "closed-on-activate"), n + ))(Z || {}); + const U = te("ce-popover"), + _ = { + popover: U(), + popoverContainer: U("container"), + popoverOpenTop: U(null, "open-top"), + popoverOpenLeft: U(null, "open-left"), + popoverOpened: U(null, "opened"), + search: U("search"), + nothingFoundMessage: U("nothing-found-message"), + nothingFoundMessageDisplayed: U("nothing-found-message", "displayed"), + items: U("items"), + overlay: U("overlay"), + overlayHidden: U("overlay", "hidden"), + popoverNested: U(null, "nested"), + getPopoverNestedClass: (n) => U(null, `nested-level-${n.toString()}`), + popoverInline: U(null, "inline"), + popoverHeader: U("header"), + }; + var he = ((n) => ( + (n.NestingLevel = "--nesting-level"), + (n.PopoverHeight = "--popover-height"), + (n.InlinePopoverWidth = "--inline-popover-width"), + (n.TriggerItemLeft = "--trigger-item-left"), + (n.TriggerItemTop = "--trigger-item-top"), + n + ))(he || {}); + const $t = te("ce-popover-item-html"), + Yt = { root: $t(), hidden: $t(null, "hidden") }; + class Ee extends Je { + constructor(e, t) { + var o, i; + super(e), + (this.nodes = { root: d.make("div", Yt.root) }), + this.nodes.root.appendChild(e.element), + e.name && (this.nodes.root.dataset.itemName = e.name), + e.hint !== void 0 && + ((o = t == null ? void 0 : t.hint) == null ? void 0 : o.enabled) !== + !1 && + this.addHint(this.nodes.root, { + ...e.hint, + position: + ((i = t == null ? void 0 : t.hint) == null + ? void 0 + : i.position) || "right", + }); + } + getElement() { + return this.nodes.root; + } + toggleHidden(e) { + var t; + (t = this.nodes.root) == null || t.classList.toggle(Yt.hidden, e); + } + getControls() { + const e = this.nodes.root.querySelectorAll( + `button, ${d.allInputsSelector}`, + ); + return Array.from(e); + } + } + class Wt extends be { + constructor(e, t = {}) { + super(), + (this.params = e), + (this.itemsRenderParams = t), + (this.listeners = new ke()), + (this.messages = { nothingFound: "Nothing found", search: "Search" }), + (this.items = this.buildItems(e.items)), + e.messages && (this.messages = { ...this.messages, ...e.messages }), + (this.nodes = {}), + (this.nodes.popoverContainer = d.make("div", [_.popoverContainer])), + (this.nodes.nothingFoundMessage = d.make( + "div", + [_.nothingFoundMessage], + { textContent: this.messages.nothingFound }, + )), + this.nodes.popoverContainer.appendChild(this.nodes.nothingFoundMessage), + (this.nodes.items = d.make("div", [_.items])), + this.items.forEach((o) => { + const i = o.getElement(); + i !== null && this.nodes.items.appendChild(i); + }), + this.nodes.popoverContainer.appendChild(this.nodes.items), + this.listeners.on(this.nodes.popoverContainer, "click", (o) => + this.handleClick(o), + ), + (this.nodes.popover = d.make("div", [_.popover, this.params.class])), + this.nodes.popover.appendChild(this.nodes.popoverContainer); + } + get itemsDefault() { + return this.items.filter((e) => e instanceof ne); + } + getElement() { + return this.nodes.popover; + } + show() { + this.nodes.popover.classList.add(_.popoverOpened), + this.search !== void 0 && this.search.focus(); + } + hide() { + this.nodes.popover.classList.remove(_.popoverOpened), + this.nodes.popover.classList.remove(_.popoverOpenTop), + this.itemsDefault.forEach((e) => e.reset()), + this.search !== void 0 && this.search.clear(), + this.emit(Z.Closed); + } + destroy() { + var e; + this.items.forEach((t) => t.destroy()), + this.nodes.popover.remove(), + this.listeners.removeAll(), + (e = this.search) == null || e.destroy(); + } + activateItemByName(e) { + const t = this.items.find((o) => o.name === e); + this.handleItemClick(t); + } + buildItems(e) { + return e.map((t) => { + switch (t.type) { + case A.Separator: + return new jt(); + case A.Html: + return new Ee(t, this.itemsRenderParams[A.Html]); + default: + return new ne(t, this.itemsRenderParams[A.Default]); + } + }); + } + getTargetItem(e) { + return this.items + .filter((t) => t instanceof ne || t instanceof Ee) + .find((t) => { + const o = t.getElement(); + return o === null ? !1 : e.composedPath().includes(o); + }); + } + handleItemClick(e) { + if (!("isDisabled" in e && e.isDisabled)) { + if (e.hasChildren) { + this.showNestedItems(e), + "handleClick" in e && + typeof e.handleClick == "function" && + e.handleClick(); + return; + } + this.itemsDefault.filter((t) => t !== e).forEach((t) => t.reset()), + "handleClick" in e && + typeof e.handleClick == "function" && + e.handleClick(), + this.toggleItemActivenessIfNeeded(e), + e.closeOnActivate && (this.hide(), this.emit(Z.ClosedOnActivate)); + } + } + handleClick(e) { + const t = this.getTargetItem(e); + t !== void 0 && this.handleItemClick(t); + } + toggleItemActivenessIfNeeded(e) { + if ( + e instanceof ne && + (e.toggle === !0 && e.toggleActive(), typeof e.toggle == "string") + ) { + const t = this.itemsDefault.filter((o) => o.toggle === e.toggle); + if (t.length === 1) { + e.toggleActive(); + return; + } + t.forEach((o) => { + o.toggleActive(o === e); + }); + } + } + } + var Ne = ((n) => ((n.Search = "search"), n))(Ne || {}); + const tt = te("cdx-search-field"), + ot = { wrapper: tt(), icon: tt("icon"), input: tt("input") }; + class Si extends be { + constructor({ items: e, placeholder: t }) { + super(), + (this.listeners = new ke()), + (this.items = e), + (this.wrapper = d.make("div", ot.wrapper)); + const o = d.make("div", ot.icon, { innerHTML: xi }); + (this.input = d.make("input", ot.input, { + placeholder: t, + tabIndex: -1, + })), + this.wrapper.appendChild(o), + this.wrapper.appendChild(this.input), + this.listeners.on(this.input, "input", () => { + (this.searchQuery = this.input.value), + this.emit(Ne.Search, { + query: this.searchQuery, + items: this.foundItems, + }); + }); + } + getElement() { + return this.wrapper; + } + focus() { + this.input.focus(); + } + clear() { + (this.input.value = ""), + (this.searchQuery = ""), + this.emit(Ne.Search, { query: "", items: this.foundItems }); + } + destroy() { + this.listeners.removeAll(); + } + get foundItems() { + return this.items.filter((e) => this.checkItem(e)); + } + checkItem(e) { + var i, s; + const t = ((i = e.title) == null ? void 0 : i.toLowerCase()) || "", + o = (s = this.searchQuery) == null ? void 0 : s.toLowerCase(); + return o !== void 0 ? t.includes(o) : !1; + } + } + var Ii = Object.defineProperty, + Mi = Object.getOwnPropertyDescriptor, + Ai = (n, e, t, o) => { + for ( + var i = o > 1 ? void 0 : o ? Mi(e, t) : e, s = n.length - 1, r; + s >= 0; + s-- + ) + (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i); + return o && i && Ii(e, t, i), i; + }; + const Kt = class fo extends Wt { + constructor(e, t) { + super(e, t), + (this.nestingLevel = 0), + (this.nestedPopoverTriggerItem = null), + (this.previouslyHoveredItem = null), + (this.scopeElement = document.body), + (this.hide = () => { + var o; + super.hide(), + this.destroyNestedPopoverIfExists(), + (o = this.flipper) == null || o.deactivate(), + (this.previouslyHoveredItem = null); + }), + (this.onFlip = () => { + const o = this.itemsDefault.find((i) => i.isFocused); + o == null || o.onFocus(); + }), + (this.onSearch = (o) => { + var l; + const i = o.query === "", + s = o.items.length === 0; + this.items.forEach((a) => { + let c = !1; + a instanceof ne + ? (c = !o.items.includes(a)) + : (a instanceof jt || a instanceof Ee) && (c = s || !i), + a.toggleHidden(c); + }), + this.toggleNothingFoundMessage(s); + const r = + o.query === "" + ? this.flippableElements + : o.items.map((a) => a.getElement()); + (l = this.flipper) != null && + l.isActivated && + (this.flipper.deactivate(), this.flipper.activate(r)); + }), + e.nestingLevel !== void 0 && (this.nestingLevel = e.nestingLevel), + this.nestingLevel > 0 && + this.nodes.popover.classList.add(_.popoverNested), + e.scopeElement !== void 0 && (this.scopeElement = e.scopeElement), + this.nodes.popoverContainer !== null && + this.listeners.on(this.nodes.popoverContainer, "mouseover", (o) => + this.handleHover(o), + ), + e.searchable && this.addSearch(), + e.flippable !== !1 && + ((this.flipper = new se({ + items: this.flippableElements, + focusedItemClass: L.focused, + allowedKeys: [w.TAB, w.UP, w.DOWN, w.ENTER], + })), + this.flipper.onFlip(this.onFlip)); + } + hasFocus() { + return this.flipper === void 0 ? !1 : this.flipper.hasFocus(); + } + get scrollTop() { + return this.nodes.items === null ? 0 : this.nodes.items.scrollTop; + } + get offsetTop() { + return this.nodes.popoverContainer === null + ? 0 + : this.nodes.popoverContainer.offsetTop; + } + show() { + var e; + this.nodes.popover.style.setProperty( + he.PopoverHeight, + this.size.height + "px", + ), + this.shouldOpenBottom || + this.nodes.popover.classList.add(_.popoverOpenTop), + this.shouldOpenRight || + this.nodes.popover.classList.add(_.popoverOpenLeft), + super.show(), + (e = this.flipper) == null || e.activate(this.flippableElements); + } + destroy() { + this.hide(), super.destroy(); + } + showNestedItems(e) { + (this.nestedPopover !== null && this.nestedPopover !== void 0) || + ((this.nestedPopoverTriggerItem = e), this.showNestedPopoverForItem(e)); + } + handleHover(e) { + const t = this.getTargetItem(e); + t !== void 0 && + this.previouslyHoveredItem !== t && + (this.destroyNestedPopoverIfExists(), + (this.previouslyHoveredItem = t), + t.hasChildren && this.showNestedPopoverForItem(t)); + } + setTriggerItemPosition(e, t) { + const o = t.getElement(), + i = (o ? o.offsetTop : 0) - this.scrollTop, + s = this.offsetTop + i; + e.style.setProperty(he.TriggerItemTop, s + "px"); + } + destroyNestedPopoverIfExists() { + var e, t; + this.nestedPopover === void 0 || + this.nestedPopover === null || + (this.nestedPopover.off(Z.ClosedOnActivate, this.hide), + this.nestedPopover.hide(), + this.nestedPopover.destroy(), + this.nestedPopover.getElement().remove(), + (this.nestedPopover = null), + (e = this.flipper) == null || e.activate(this.flippableElements), + (t = this.nestedPopoverTriggerItem) == null || t.onChildrenClose()); + } + showNestedPopoverForItem(e) { + var o; + (this.nestedPopover = new fo({ + searchable: e.isChildrenSearchable, + items: e.children, + nestingLevel: this.nestingLevel + 1, + flippable: e.isChildrenFlippable, + messages: this.messages, + })), + e.onChildrenOpen(), + this.nestedPopover.on(Z.ClosedOnActivate, this.hide); + const t = this.nestedPopover.getElement(); + return ( + this.nodes.popover.appendChild(t), + this.setTriggerItemPosition(t, e), + t.style.setProperty( + he.NestingLevel, + this.nestedPopover.nestingLevel.toString(), + ), + this.nestedPopover.show(), + (o = this.flipper) == null || o.deactivate(), + this.nestedPopover + ); + } + get shouldOpenBottom() { + if (this.nodes.popover === void 0 || this.nodes.popover === null) + return !1; + const e = this.nodes.popoverContainer.getBoundingClientRect(), + t = this.scopeElement.getBoundingClientRect(), + o = this.size.height, + i = e.top + o, + s = e.top - o, + r = Math.min(window.innerHeight, t.bottom); + return s < t.top || i <= r; + } + get shouldOpenRight() { + if (this.nodes.popover === void 0 || this.nodes.popover === null) + return !1; + const e = this.nodes.popover.getBoundingClientRect(), + t = this.scopeElement.getBoundingClientRect(), + o = this.size.width, + i = e.right + o, + s = e.left - o, + r = Math.min(window.innerWidth, t.right); + return s < t.left || i <= r; + } + get size() { + var i; + const e = { height: 0, width: 0 }; + if (this.nodes.popover === null) return e; + const t = this.nodes.popover.cloneNode(!0); + (t.style.visibility = "hidden"), + (t.style.position = "absolute"), + (t.style.top = "-1000px"), + t.classList.add(_.popoverOpened), + (i = t.querySelector("." + _.popoverNested)) == null || i.remove(), + document.body.appendChild(t); + const o = t.querySelector("." + _.popoverContainer); + return ( + (e.height = o.offsetHeight), (e.width = o.offsetWidth), t.remove(), e + ); + } + get flippableElements() { + return this.items + .map((t) => { + if (t instanceof ne) return t.getElement(); + if (t instanceof Ee) return t.getControls(); + }) + .flat() + .filter((t) => t != null); + } + addSearch() { + (this.search = new Si({ + items: this.itemsDefault, + placeholder: this.messages.search, + })), + this.search.on(Ne.Search, this.onSearch); + const e = this.search.getElement(); + e.classList.add(_.search), + this.nodes.popoverContainer.insertBefore( + e, + this.nodes.popoverContainer.firstChild, + ); + } + toggleNothingFoundMessage(e) { + this.nodes.nothingFoundMessage.classList.toggle( + _.nothingFoundMessageDisplayed, + e, + ); + } + }; + Ai([ce], Kt.prototype, "size", 1); + let it = Kt; + class Oi extends it { + constructor(e) { + const t = !de(); + super( + { ...e, class: _.popoverInline }, + { + [A.Default]: { + wrapperTag: "button", + hint: { position: "top", alignment: "center", enabled: t }, + }, + [A.Html]: { + hint: { position: "top", alignment: "center", enabled: t }, + }, + }, + ), + this.items.forEach((o) => { + (!(o instanceof ne) && !(o instanceof Ee)) || + (o.hasChildren && o.isChildrenOpen && this.showNestedItems(o)); + }); + } + get offsetLeft() { + return this.nodes.popoverContainer === null + ? 0 + : this.nodes.popoverContainer.offsetLeft; + } + show() { + this.nestingLevel === 0 && + this.nodes.popover.style.setProperty( + he.InlinePopoverWidth, + this.size.width + "px", + ), + super.show(); + } + handleHover() {} + setTriggerItemPosition(e, t) { + const o = t.getElement(), + i = o ? o.offsetLeft : 0, + s = this.offsetLeft + i; + e.style.setProperty(he.TriggerItemLeft, s + "px"); + } + showNestedItems(e) { + if (this.nestedPopoverTriggerItem === e) { + this.destroyNestedPopoverIfExists(), + (this.nestedPopoverTriggerItem = null); + return; + } + super.showNestedItems(e); + } + showNestedPopoverForItem(e) { + const t = super.showNestedPopoverForItem(e); + return ( + t.getElement().classList.add(_.getPopoverNestedClass(t.nestingLevel)), t + ); + } + handleItemClick(e) { + var t; + e !== this.nestedPopoverTriggerItem && + ((t = this.nestedPopoverTriggerItem) == null || t.handleClick(), + super.destroyNestedPopoverIfExists()), + super.handleItemClick(e); + } + } + const Xt = class Ie { + constructor() { + this.scrollPosition = null; + } + lock() { + We ? this.lockHard() : document.body.classList.add(Ie.CSS.scrollLocked); + } + unlock() { + We + ? this.unlockHard() + : document.body.classList.remove(Ie.CSS.scrollLocked); + } + lockHard() { + (this.scrollPosition = window.pageYOffset), + document.documentElement.style.setProperty( + "--window-scroll-offset", + `${this.scrollPosition}px`, + ), + document.body.classList.add(Ie.CSS.scrollLockedHard); + } + unlockHard() { + document.body.classList.remove(Ie.CSS.scrollLockedHard), + this.scrollPosition !== null && window.scrollTo(0, this.scrollPosition), + (this.scrollPosition = null); + } + }; + Xt.CSS = { + scrollLocked: "ce-scroll-locked", + scrollLockedHard: "ce-scroll-locked--hard", + }; + let Li = Xt; + const st = te("ce-popover-header"), + nt = { root: st(), text: st("text"), backButton: st("back-button") }; + class _i { + constructor({ text: e, onBackButtonClick: t }) { + (this.listeners = new ke()), + (this.text = e), + (this.onBackButtonClick = t), + (this.nodes = { + root: d.make("div", [nt.root]), + backButton: d.make("button", [nt.backButton]), + text: d.make("div", [nt.text]), + }), + (this.nodes.backButton.innerHTML = pi), + this.nodes.root.appendChild(this.nodes.backButton), + this.listeners.on( + this.nodes.backButton, + "click", + this.onBackButtonClick, + ), + (this.nodes.text.innerText = this.text), + this.nodes.root.appendChild(this.nodes.text); + } + getElement() { + return this.nodes.root; + } + destroy() { + this.nodes.root.remove(), this.listeners.destroy(); + } + } + class Ni { + constructor() { + this.history = []; + } + push(e) { + this.history.push(e); + } + pop() { + return this.history.pop(); + } + get currentTitle() { + return this.history.length === 0 + ? "" + : this.history[this.history.length - 1].title; + } + get currentItems() { + return this.history.length === 0 + ? [] + : this.history[this.history.length - 1].items; + } + reset() { + for (; this.history.length > 1; ) this.pop(); + } + } + class Vt extends Wt { + constructor(e) { + super(e, { + [A.Default]: { hint: { enabled: !1 } }, + [A.Html]: { hint: { enabled: !1 } }, + }), + (this.scrollLocker = new Li()), + (this.history = new Ni()), + (this.isHidden = !0), + (this.nodes.overlay = d.make("div", [_.overlay, _.overlayHidden])), + this.nodes.popover.insertBefore( + this.nodes.overlay, + this.nodes.popover.firstChild, + ), + this.listeners.on(this.nodes.overlay, "click", () => { + this.hide(); + }), + this.history.push({ items: e.items }); + } + show() { + this.nodes.overlay.classList.remove(_.overlayHidden), + super.show(), + this.scrollLocker.lock(), + (this.isHidden = !1); + } + hide() { + this.isHidden || + (super.hide(), + this.nodes.overlay.classList.add(_.overlayHidden), + this.scrollLocker.unlock(), + this.history.reset(), + (this.isHidden = !0)); + } + destroy() { + super.destroy(), this.scrollLocker.unlock(); + } + showNestedItems(e) { + this.updateItemsAndHeader(e.children, e.title), + this.history.push({ title: e.title, items: e.children }); + } + updateItemsAndHeader(e, t) { + if ( + (this.header !== null && + this.header !== void 0 && + (this.header.destroy(), (this.header = null)), + t !== void 0) + ) { + this.header = new _i({ + text: t, + onBackButtonClick: () => { + this.history.pop(), + this.updateItemsAndHeader( + this.history.currentItems, + this.history.currentTitle, + ); + }, + }); + const o = this.header.getElement(); + o !== null && + this.nodes.popoverContainer.insertBefore( + o, + this.nodes.popoverContainer.firstChild, + ); + } + this.items.forEach((o) => { + var i; + return (i = o.getElement()) == null ? void 0 : i.remove(); + }), + (this.items = this.buildItems(e)), + this.items.forEach((o) => { + var s; + const i = o.getElement(); + i !== null && ((s = this.nodes.items) == null || s.appendChild(i)); + }); + } + } + class Pi extends y { + constructor() { + super(...arguments), + (this.opened = !1), + (this.selection = new m()), + (this.popover = null), + (this.close = () => { + this.opened && + ((this.opened = !1), + m.isAtEditor || this.selection.restore(), + this.selection.clearSaved(), + !this.Editor.CrossBlockSelection.isCrossBlockSelectionStarted && + this.Editor.BlockManager.currentBlock && + this.Editor.BlockSelection.unselectBlock( + this.Editor.BlockManager.currentBlock, + ), + this.eventsDispatcher.emit(this.events.closed), + this.popover && + (this.popover.off(Z.Closed, this.onPopoverClose), + this.popover.destroy(), + this.popover.getElement().remove(), + (this.popover = null))); + }), + (this.onPopoverClose = () => { + this.close(); + }); + } + get events() { + return { + opened: "block-settings-opened", + closed: "block-settings-closed", + }; + } + get CSS() { + return { settings: "ce-settings" }; + } + get flipper() { + var e; + if (this.popover !== null) + return "flipper" in this.popover + ? (e = this.popover) == null + ? void 0 + : e.flipper + : void 0; + } + make() { + (this.nodes.wrapper = d.make("div", [this.CSS.settings])), + this.eventsDispatcher.on(ve, this.close); + } + destroy() { + this.removeAllNodes(), + this.listeners.destroy(), + this.eventsDispatcher.off(ve, this.close); + } + async open(e = this.Editor.BlockManager.currentBlock) { + var s; + (this.opened = !0), + this.selection.save(), + this.Editor.BlockSelection.selectBlock(e), + this.Editor.BlockSelection.clearCache(); + const { toolTunes: t, commonTunes: o } = e.getTunes(); + this.eventsDispatcher.emit(this.events.opened); + const i = de() ? Vt : it; + (this.popover = new i({ + searchable: !0, + items: await this.getTunesItems(e, o, t), + scopeElement: this.Editor.API.methods.ui.nodes.redactor, + messages: { + nothingFound: H.ui($.ui.popover, "Nothing found"), + search: H.ui($.ui.popover, "Filter"), + }, + })), + this.popover.on(Z.Closed, this.onPopoverClose), + (s = this.nodes.wrapper) == null || s.append(this.popover.getElement()), + this.popover.show(); + } + getElement() { + return this.nodes.wrapper; + } + async getTunesItems(e, t, o) { + const i = []; + o !== void 0 && + o.length > 0 && + (i.push(...o), i.push({ type: A.Separator })); + const s = Array.from(this.Editor.Tools.blockTools.values()), + l = (await Lt(e, s)).reduce( + (a, c) => ( + c.toolbox.forEach((u) => { + a.push({ + icon: u.icon, + title: H.t($.toolNames, u.title), + name: c.name, + closeOnActivate: !0, + onActivate: async () => { + const { BlockManager: h, Caret: p, Toolbar: g } = this.Editor, + f = await h.convert(e, c.name, u.data); + g.close(), p.setToBlock(f, p.positions.END); + }, + }); + }), + a + ), + [], + ); + return ( + l.length > 0 && + (i.push({ + icon: Ut, + name: "convert-to", + title: H.ui($.ui.popover, "Convert to"), + children: { searchable: !0, items: l }, + }), + i.push({ type: A.Separator })), + i.push(...t), + i.map((a) => this.resolveTuneAliases(a)) + ); + } + resolveTuneAliases(e) { + if (e.type === A.Separator || e.type === A.Html) return e; + const t = di(e, { label: "title" }); + return ( + e.confirmation && + (t.confirmation = this.resolveTuneAliases(e.confirmation)), + t + ); + } + } + var qt = { exports: {} }; + /*! + * Library for handling keyboard shortcuts + * @copyright CodeX (https://codex.so) + * @license MIT + * @author CodeX (https://codex.so) + * @version 1.2.0 + */ (function (n, e) { + (function (t, o) { + n.exports = o(); + })(window, function () { + return (function (t) { + var o = {}; + function i(s) { + if (o[s]) return o[s].exports; + var r = (o[s] = { i: s, l: !1, exports: {} }); + return t[s].call(r.exports, r, r.exports, i), (r.l = !0), r.exports; + } + return ( + (i.m = t), + (i.c = o), + (i.d = function (s, r, l) { + i.o(s, r) || + Object.defineProperty(s, r, { enumerable: !0, get: l }); + }), + (i.r = function (s) { + typeof Symbol < "u" && + Symbol.toStringTag && + Object.defineProperty(s, Symbol.toStringTag, { value: "Module" }), + Object.defineProperty(s, "__esModule", { value: !0 }); + }), + (i.t = function (s, r) { + if ( + (1 & r && (s = i(s)), + 8 & r || (4 & r && typeof s == "object" && s && s.__esModule)) + ) + return s; + var l = Object.create(null); + if ( + (i.r(l), + Object.defineProperty(l, "default", { enumerable: !0, value: s }), + 2 & r && typeof s != "string") + ) + for (var a in s) + i.d( + l, + a, + function (c) { + return s[c]; + }.bind(null, a), + ); + return l; + }), + (i.n = function (s) { + var r = + s && s.__esModule + ? function () { + return s.default; + } + : function () { + return s; + }; + return i.d(r, "a", r), r; + }), + (i.o = function (s, r) { + return Object.prototype.hasOwnProperty.call(s, r); + }), + (i.p = ""), + i((i.s = 0)) + ); + })([ + function (t, o, i) { + function s(a, c) { + for (var u = 0; u < c.length; u++) { + var h = c[u]; + (h.enumerable = h.enumerable || !1), + (h.configurable = !0), + "value" in h && (h.writable = !0), + Object.defineProperty(a, h.key, h); + } + } + function r(a, c, u) { + return c && s(a.prototype, c), u && s(a, u), a; + } + i.r(o); + var l = (function () { + function a(c) { + var u = this; + (function (h, p) { + if (!(h instanceof p)) + throw new TypeError("Cannot call a class as a function"); + })(this, a), + (this.commands = {}), + (this.keys = {}), + (this.name = c.name), + this.parseShortcutName(c.name), + (this.element = c.on), + (this.callback = c.callback), + (this.executeShortcut = function (h) { + u.execute(h); + }), + this.element.addEventListener( + "keydown", + this.executeShortcut, + !1, + ); + } + return ( + r(a, null, [ + { + key: "supportedCommands", + get: function () { + return { + SHIFT: ["SHIFT"], + CMD: ["CMD", "CONTROL", "COMMAND", "WINDOWS", "CTRL"], + ALT: ["ALT", "OPTION"], + }; + }, + }, + { + key: "keyCodes", + get: function () { + return { + 0: 48, + 1: 49, + 2: 50, + 3: 51, + 4: 52, + 5: 53, + 6: 54, + 7: 55, + 8: 56, + 9: 57, + A: 65, + B: 66, + C: 67, + D: 68, + E: 69, + F: 70, + G: 71, + H: 72, + I: 73, + J: 74, + K: 75, + L: 76, + M: 77, + N: 78, + O: 79, + P: 80, + Q: 81, + R: 82, + S: 83, + T: 84, + U: 85, + V: 86, + W: 87, + X: 88, + Y: 89, + Z: 90, + BACKSPACE: 8, + ENTER: 13, + ESCAPE: 27, + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40, + INSERT: 45, + DELETE: 46, + ".": 190, + }; + }, + }, + ]), + r(a, [ + { + key: "parseShortcutName", + value: function (c) { + c = c.split("+"); + for (var u = 0; u < c.length; u++) { + c[u] = c[u].toUpperCase(); + var h = !1; + for (var p in a.supportedCommands) + if (a.supportedCommands[p].includes(c[u])) { + h = this.commands[p] = !0; + break; + } + h || (this.keys[c[u]] = !0); + } + for (var g in a.supportedCommands) + this.commands[g] || (this.commands[g] = !1); + }, + }, + { + key: "execute", + value: function (c) { + var u, + h = { + CMD: c.ctrlKey || c.metaKey, + SHIFT: c.shiftKey, + ALT: c.altKey, + }, + p = !0; + for (u in this.commands) + this.commands[u] !== h[u] && (p = !1); + var g, + f = !0; + for (g in this.keys) f = f && c.keyCode === a.keyCodes[g]; + p && f && this.callback(c); + }, + }, + { + key: "remove", + value: function () { + this.element.removeEventListener( + "keydown", + this.executeShortcut, + ); + }, + }, + ]), + a + ); + })(); + o.default = l; + }, + ]).default; + }); + })(qt); + var Di = qt.exports; + const Ri = ee(Di); + class Fi { + constructor() { + this.registeredShortcuts = new Map(); + } + add(e) { + if (this.findShortcut(e.on, e.name)) + throw Error( + `Shortcut ${e.name} is already registered for ${e.on}. Please remove it before add a new handler.`, + ); + const o = new Ri({ name: e.name, on: e.on, callback: e.handler }), + i = this.registeredShortcuts.get(e.on) || []; + this.registeredShortcuts.set(e.on, [...i, o]); + } + remove(e, t) { + const o = this.findShortcut(e, t); + if (!o) return; + o.remove(); + const i = this.registeredShortcuts.get(e); + this.registeredShortcuts.set( + e, + i.filter((s) => s !== o), + ); + } + findShortcut(e, t) { + return (this.registeredShortcuts.get(e) || []).find( + ({ name: i }) => i === t, + ); + } + } + const ue = new Fi(); + var Hi = Object.defineProperty, + zi = Object.getOwnPropertyDescriptor, + Zt = (n, e, t, o) => { + for ( + var i = o > 1 ? void 0 : o ? zi(e, t) : e, s = n.length - 1, r; + s >= 0; + s-- + ) + (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i); + return o && i && Hi(e, t, i), i; + }, + Pe = ((n) => ( + (n.Opened = "toolbox-opened"), + (n.Closed = "toolbox-closed"), + (n.BlockAdded = "toolbox-block-added"), + n + ))(Pe || {}); + const rt = class go extends be { + constructor({ api: e, tools: t, i18nLabels: o }) { + super(), + (this.opened = !1), + (this.listeners = new ke()), + (this.popover = null), + (this.handleMobileLayoutToggle = () => { + this.destroyPopover(), this.initPopover(); + }), + (this.onPopoverClose = () => { + (this.opened = !1), this.emit("toolbox-closed"); + }), + (this.api = e), + (this.tools = t), + (this.i18nLabels = o), + this.enableShortcuts(), + (this.nodes = { toolbox: d.make("div", go.CSS.toolbox) }), + this.initPopover(), + this.api.events.on(ve, this.handleMobileLayoutToggle); + } + get isEmpty() { + return this.toolsToBeDisplayed.length === 0; + } + static get CSS() { + return { toolbox: "ce-toolbox" }; + } + getElement() { + return this.nodes.toolbox; + } + hasFocus() { + if (this.popover !== null) + return "hasFocus" in this.popover ? this.popover.hasFocus() : void 0; + } + destroy() { + var e; + super.destroy(), + this.nodes && this.nodes.toolbox && this.nodes.toolbox.remove(), + this.removeAllShortcuts(), + (e = this.popover) == null || e.off(Z.Closed, this.onPopoverClose), + this.listeners.destroy(), + this.api.events.off(ve, this.handleMobileLayoutToggle); + } + toolButtonActivated(e, t) { + this.insertNewBlock(e, t); + } + open() { + var e; + this.isEmpty || + ((e = this.popover) == null || e.show(), + (this.opened = !0), + this.emit("toolbox-opened")); + } + close() { + var e; + (e = this.popover) == null || e.hide(), + (this.opened = !1), + this.emit("toolbox-closed"); + } + toggle() { + this.opened ? this.close() : this.open(); + } + initPopover() { + var t; + const e = de() ? Vt : it; + (this.popover = new e({ + scopeElement: this.api.ui.nodes.redactor, + searchable: !0, + messages: { + nothingFound: this.i18nLabels.nothingFound, + search: this.i18nLabels.filter, + }, + items: this.toolboxItemsToBeDisplayed, + })), + this.popover.on(Z.Closed, this.onPopoverClose), + (t = this.nodes.toolbox) == null || t.append(this.popover.getElement()); + } + destroyPopover() { + this.popover !== null && + (this.popover.hide(), + this.popover.off(Z.Closed, this.onPopoverClose), + this.popover.destroy(), + (this.popover = null)), + this.nodes.toolbox !== null && (this.nodes.toolbox.innerHTML = ""); + } + get toolsToBeDisplayed() { + const e = []; + return ( + this.tools.forEach((t) => { + t.toolbox && e.push(t); + }), + e + ); + } + get toolboxItemsToBeDisplayed() { + const e = (t, o) => ({ + icon: t.icon, + title: H.t($.toolNames, t.title || Ae(o.name)), + name: o.name, + onActivate: () => { + this.toolButtonActivated(o.name, t.data); + }, + secondaryLabel: o.shortcut ? $e(o.shortcut) : "", + }); + return this.toolsToBeDisplayed.reduce( + (t, o) => ( + Array.isArray(o.toolbox) + ? o.toolbox.forEach((i) => { + t.push(e(i, o)); + }) + : o.toolbox !== void 0 && t.push(e(o.toolbox, o)), + t + ), + [], + ); + } + enableShortcuts() { + this.toolsToBeDisplayed.forEach((e) => { + const t = e.shortcut; + t && this.enableShortcutForTool(e.name, t); + }); + } + enableShortcutForTool(e, t) { + ue.add({ + name: t, + on: this.api.ui.nodes.redactor, + handler: async (o) => { + o.preventDefault(); + const i = this.api.blocks.getCurrentBlockIndex(), + s = this.api.blocks.getBlockByIndex(i); + if (s) + try { + const r = await this.api.blocks.convert(s.id, e); + this.api.caret.setToBlock(r, "end"); + return; + } catch {} + this.insertNewBlock(e); + }, + }); + } + removeAllShortcuts() { + this.toolsToBeDisplayed.forEach((e) => { + const t = e.shortcut; + t && ue.remove(this.api.ui.nodes.redactor, t); + }); + } + async insertNewBlock(e, t) { + const o = this.api.blocks.getCurrentBlockIndex(), + i = this.api.blocks.getBlockByIndex(o); + if (!i) return; + const s = i.isEmpty ? o : o + 1; + let r; + if (t) { + const a = await this.api.blocks.composeBlockData(e); + r = Object.assign(a, t); + } + const l = this.api.blocks.insert(e, r, void 0, s, void 0, i.isEmpty); + l.call(Q.APPEND_CALLBACK), + this.api.caret.setToBlock(s), + this.emit("toolbox-block-added", { block: l }), + this.api.toolbar.close(); + } + }; + Zt([ce], rt.prototype, "toolsToBeDisplayed", 1), + Zt([ce], rt.prototype, "toolboxItemsToBeDisplayed", 1); + let Ui = rt; + const Gt = "block hovered"; + async function ji(n, e) { + const t = navigator.keyboard; + if (!t) return e; + try { + return (await t.getLayoutMap()).get(n) || e; + } catch (o) { + return console.error(o), e; + } + } + class $i extends y { + constructor({ config: e, eventsDispatcher: t }) { + super({ config: e, eventsDispatcher: t }), (this.toolboxInstance = null); + } + get CSS() { + return { + toolbar: "ce-toolbar", + content: "ce-toolbar__content", + actions: "ce-toolbar__actions", + actionsOpened: "ce-toolbar__actions--opened", + toolbarOpened: "ce-toolbar--opened", + openedToolboxHolderModifier: "codex-editor--toolbox-opened", + plusButton: "ce-toolbar__plus", + plusButtonShortcut: "ce-toolbar__plus-shortcut", + settingsToggler: "ce-toolbar__settings-btn", + settingsTogglerHidden: "ce-toolbar__settings-btn--hidden", + }; + } + get opened() { + return this.nodes.wrapper.classList.contains(this.CSS.toolbarOpened); + } + get toolbox() { + var e; + return { + opened: (e = this.toolboxInstance) == null ? void 0 : e.opened, + close: () => { + var t; + (t = this.toolboxInstance) == null || t.close(); + }, + open: () => { + if (this.toolboxInstance === null) { + C( + "toolbox.open() called before initialization is finished", + "warn", + ); + return; + } + (this.Editor.BlockManager.currentBlock = this.hoveredBlock), + this.toolboxInstance.open(); + }, + toggle: () => { + if (this.toolboxInstance === null) { + C( + "toolbox.toggle() called before initialization is finished", + "warn", + ); + return; + } + this.toolboxInstance.toggle(); + }, + hasFocus: () => { + var t; + return (t = this.toolboxInstance) == null ? void 0 : t.hasFocus(); + }, + }; + } + get blockActions() { + return { + hide: () => { + this.nodes.actions.classList.remove(this.CSS.actionsOpened); + }, + show: () => { + this.nodes.actions.classList.add(this.CSS.actionsOpened); + }, + }; + } + get blockTunesToggler() { + return { + hide: () => + this.nodes.settingsToggler.classList.add( + this.CSS.settingsTogglerHidden, + ), + show: () => + this.nodes.settingsToggler.classList.remove( + this.CSS.settingsTogglerHidden, + ), + }; + } + toggleReadOnly(e) { + e + ? (this.destroy(), + this.Editor.BlockSettings.destroy(), + this.disableModuleBindings()) + : window.requestIdleCallback( + () => { + this.drawUI(), this.enableModuleBindings(); + }, + { timeout: 2e3 }, + ); + } + moveAndOpen(e = this.Editor.BlockManager.currentBlock) { + if (this.toolboxInstance === null) { + C( + "Can't open Toolbar since Editor initialization is not finished yet", + "warn", + ); + return; + } + if ( + (this.toolboxInstance.opened && this.toolboxInstance.close(), + this.Editor.BlockSettings.opened && this.Editor.BlockSettings.close(), + !e) + ) + return; + this.hoveredBlock = e; + const t = e.holder, + { isMobile: o } = this.Editor.UI; + let i; + const s = 20, + r = e.firstInput, + l = t.getBoundingClientRect(), + a = r !== void 0 ? r.getBoundingClientRect() : null, + c = a !== null ? a.top - l.top : null, + u = c !== null ? c > s : void 0; + if (o) i = t.offsetTop + t.offsetHeight; + else if (r === void 0 || u) { + const h = parseInt( + window.getComputedStyle(e.pluginsContent).paddingTop, + ); + i = t.offsetTop + h; + } else { + const h = Oo(r), + p = parseInt( + window.getComputedStyle(this.nodes.plusButton).height, + 10, + ), + g = 8; + i = t.offsetTop + h - p + g + c; + } + (this.nodes.wrapper.style.top = `${Math.floor(i)}px`), + this.Editor.BlockManager.blocks.length === 1 && e.isEmpty + ? this.blockTunesToggler.hide() + : this.blockTunesToggler.show(), + this.open(); + } + close() { + var e, t; + this.Editor.ReadOnly.isEnabled || + ((e = this.nodes.wrapper) == null || + e.classList.remove(this.CSS.toolbarOpened), + this.blockActions.hide(), + (t = this.toolboxInstance) == null || t.close(), + this.Editor.BlockSettings.close(), + this.reset()); + } + reset() { + this.nodes.wrapper.style.top = "unset"; + } + open(e = !0) { + this.nodes.wrapper.classList.add(this.CSS.toolbarOpened), + e ? this.blockActions.show() : this.blockActions.hide(); + } + async make() { + (this.nodes.wrapper = d.make("div", this.CSS.toolbar)), + ["content", "actions"].forEach((s) => { + this.nodes[s] = d.make("div", this.CSS[s]); + }), + d.append(this.nodes.wrapper, this.nodes.content), + d.append(this.nodes.content, this.nodes.actions), + (this.nodes.plusButton = d.make("div", this.CSS.plusButton, { + innerHTML: wi, + })), + d.append(this.nodes.actions, this.nodes.plusButton), + this.readOnlyMutableListeners.on( + this.nodes.plusButton, + "click", + () => { + Le(!0), this.plusButtonClicked(); + }, + !1, + ); + const e = d.make("div"); + e.appendChild(document.createTextNode(H.ui($.ui.toolbar.toolbox, "Add"))), + e.appendChild( + d.make("div", this.CSS.plusButtonShortcut, { textContent: "/" }), + ), + _e(this.nodes.plusButton, e, { hidingDelay: 400 }), + (this.nodes.settingsToggler = d.make("span", this.CSS.settingsToggler, { + innerHTML: vi, + })), + d.append(this.nodes.actions, this.nodes.settingsToggler); + const t = d.make("div"), + o = d.text(H.ui($.ui.blockTunes.toggler, "Click to tune")), + i = await ji("Slash", "/"); + t.appendChild(o), + t.appendChild( + d.make("div", this.CSS.plusButtonShortcut, { + textContent: $e(`CMD + ${i}`), + }), + ), + _e(this.nodes.settingsToggler, t, { hidingDelay: 400 }), + d.append(this.nodes.actions, this.makeToolbox()), + d.append(this.nodes.actions, this.Editor.BlockSettings.getElement()), + d.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper); + } + makeToolbox() { + return ( + (this.toolboxInstance = new Ui({ + api: this.Editor.API.methods, + tools: this.Editor.Tools.blockTools, + i18nLabels: { + filter: H.ui($.ui.popover, "Filter"), + nothingFound: H.ui($.ui.popover, "Nothing found"), + }, + })), + this.toolboxInstance.on(Pe.Opened, () => { + this.Editor.UI.nodes.wrapper.classList.add( + this.CSS.openedToolboxHolderModifier, + ); + }), + this.toolboxInstance.on(Pe.Closed, () => { + this.Editor.UI.nodes.wrapper.classList.remove( + this.CSS.openedToolboxHolderModifier, + ); + }), + this.toolboxInstance.on(Pe.BlockAdded, ({ block: e }) => { + const { BlockManager: t, Caret: o } = this.Editor, + i = t.getBlockById(e.id); + i.inputs.length === 0 && + (i === t.lastBlock + ? (t.insertAtEnd(), o.setToBlock(t.lastBlock)) + : o.setToBlock(t.nextBlock)); + }), + this.toolboxInstance.getElement() + ); + } + plusButtonClicked() { + var e; + (this.Editor.BlockManager.currentBlock = this.hoveredBlock), + (e = this.toolboxInstance) == null || e.toggle(); + } + enableModuleBindings() { + this.readOnlyMutableListeners.on( + this.nodes.settingsToggler, + "mousedown", + (e) => { + var t; + e.stopPropagation(), + this.settingsTogglerClicked(), + (t = this.toolboxInstance) != null && + t.opened && + this.toolboxInstance.close(), + Le(!0); + }, + !0, + ), + de() || + this.eventsDispatcher.on(Gt, (e) => { + var t; + this.Editor.BlockSettings.opened || + ((t = this.toolboxInstance) != null && t.opened) || + this.moveAndOpen(e.block); + }); + } + disableModuleBindings() { + this.readOnlyMutableListeners.clearAll(); + } + settingsTogglerClicked() { + (this.Editor.BlockManager.currentBlock = this.hoveredBlock), + this.Editor.BlockSettings.opened + ? this.Editor.BlockSettings.close() + : this.Editor.BlockSettings.open(this.hoveredBlock); + } + drawUI() { + this.Editor.BlockSettings.make(), this.make(); + } + destroy() { + this.removeAllNodes(), + this.toolboxInstance && this.toolboxInstance.destroy(); + } + } + var re = ((n) => ( + (n[(n.Block = 0)] = "Block"), + (n[(n.Inline = 1)] = "Inline"), + (n[(n.Tune = 2)] = "Tune"), + n + ))(re || {}), + De = ((n) => ( + (n.Shortcut = "shortcut"), + (n.Toolbox = "toolbox"), + (n.EnabledInlineTools = "inlineToolbar"), + (n.EnabledBlockTunes = "tunes"), + (n.Config = "config"), + n + ))(De || {}), + Jt = ((n) => ( + (n.Shortcut = "shortcut"), (n.SanitizeConfig = "sanitize"), n + ))(Jt || {}), + pe = ((n) => ( + (n.IsEnabledLineBreaks = "enableLineBreaks"), + (n.Toolbox = "toolbox"), + (n.ConversionConfig = "conversionConfig"), + (n.IsReadOnlySupported = "isReadOnlySupported"), + (n.PasteConfig = "pasteConfig"), + n + ))(pe || {}), + lt = ((n) => ((n.IsInline = "isInline"), (n.Title = "title"), n))(lt || {}), + at = ((n) => ((n.IsTune = "isTune"), n))(at || {}); + class ct { + constructor({ + name: e, + constructable: t, + config: o, + api: i, + isDefault: s, + isInternal: r = !1, + defaultPlaceholder: l, + }) { + (this.api = i), + (this.name = e), + (this.constructable = t), + (this.config = o), + (this.isDefault = s), + (this.isInternal = r), + (this.defaultPlaceholder = l); + } + get settings() { + const e = this.config.config || {}; + return ( + this.isDefault && + !("placeholder" in e) && + this.defaultPlaceholder && + (e.placeholder = this.defaultPlaceholder), + e + ); + } + reset() { + if (O(this.constructable.reset)) return this.constructable.reset(); + } + prepare() { + if (O(this.constructable.prepare)) + return this.constructable.prepare({ + toolName: this.name, + config: this.settings, + }); + } + get shortcut() { + const e = this.constructable.shortcut; + return this.config.shortcut || e; + } + get sanitizeConfig() { + return this.constructable.sanitize || {}; + } + isInline() { + return this.type === re.Inline; + } + isBlock() { + return this.type === re.Block; + } + isTune() { + return this.type === re.Tune; + } + } + class Yi extends y { + constructor({ config: e, eventsDispatcher: t }) { + super({ config: e, eventsDispatcher: t }), + (this.CSS = { inlineToolbar: "ce-inline-toolbar" }), + (this.opened = !1), + (this.popover = null), + (this.toolbarVerticalMargin = de() ? 20 : 6), + (this.toolsInstances = new Map()); + } + toggleReadOnly(e) { + e + ? this.destroy() + : window.requestIdleCallback( + () => { + this.make(); + }, + { timeout: 2e3 }, + ); + } + async tryToShow(e = !1) { + e && this.close(), + this.allowedToShow() && + (await this.open(), this.Editor.Toolbar.close()); + } + close() { + var e, t; + this.opened && + (this.Editor.ReadOnly.isEnabled || + (Array.from(this.toolsInstances.entries()).forEach(([o, i]) => { + const s = this.getToolShortcut(o); + s && ue.remove(this.Editor.UI.nodes.redactor, s), + O(i.clear) && i.clear(); + }), + (this.toolsInstances = null), + this.reset(), + (this.opened = !1), + (e = this.popover) == null || e.hide(), + (t = this.popover) == null || t.destroy(), + (this.popover = null))); + } + containsNode(e) { + return this.nodes.wrapper === void 0 + ? !1 + : this.nodes.wrapper.contains(e); + } + destroy() { + var e; + this.removeAllNodes(), + (e = this.popover) == null || e.destroy(), + (this.popover = null); + } + make() { + (this.nodes.wrapper = d.make("div", [ + this.CSS.inlineToolbar, + ...(this.isRtl ? [this.Editor.UI.CSS.editorRtlFix] : []), + ])), + d.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper); + } + async open() { + var t; + if (this.opened) return; + (this.opened = !0), this.popover !== null && this.popover.destroy(); + const e = await this.getInlineTools(); + (this.popover = new Oi({ + items: e, + scopeElement: this.Editor.API.methods.ui.nodes.redactor, + messages: { + nothingFound: H.ui($.ui.popover, "Nothing found"), + search: H.ui($.ui.popover, "Filter"), + }, + })), + this.move(this.popover.size.width), + (t = this.nodes.wrapper) == null || t.append(this.popover.getElement()), + this.popover.show(); + } + move(e) { + const t = m.rect, + o = this.Editor.UI.nodes.wrapper.getBoundingClientRect(), + i = { + x: t.x - o.x, + y: t.y + t.height - o.top + this.toolbarVerticalMargin, + }; + i.x + e + o.x > this.Editor.UI.contentRect.right && + (i.x = this.Editor.UI.contentRect.right - e - o.x), + (this.nodes.wrapper.style.left = Math.floor(i.x) + "px"), + (this.nodes.wrapper.style.top = Math.floor(i.y) + "px"); + } + reset() { + (this.nodes.wrapper.style.left = "0"), + (this.nodes.wrapper.style.top = "0"); + } + allowedToShow() { + const e = ["IMG", "INPUT"], + t = m.get(), + o = m.text; + if (!t || !t.anchorNode || t.isCollapsed || o.length < 1) return !1; + const i = d.isElement(t.anchorNode) + ? t.anchorNode + : t.anchorNode.parentElement; + if ( + i === null || + (t && e.includes(i.tagName)) || + i.closest('[contenteditable="true"]') === null + ) + return !1; + const r = this.Editor.BlockManager.getBlock(t.anchorNode); + return r ? r.tool.inlineTools.size !== 0 : !1; + } + async getInlineTools() { + const e = m.get(), + t = this.Editor.BlockManager.getBlock(e.anchorNode), + o = Array.from(t.tool.inlineTools.values()), + i = []; + this.toolsInstances === null && (this.toolsInstances = new Map()); + for (let s = 0; s < o.length; s++) { + const r = o[s], + l = r.create(), + a = await l.render(); + this.toolsInstances.set(r.name, l); + const c = this.getToolShortcut(r.name); + if (c) + try { + this.enableShortcuts(r.name, c); + } catch {} + const u = c !== void 0 ? $e(c) : void 0, + h = H.t($.toolNames, r.title || Ae(r.name)); + [a].flat().forEach((p) => { + var f, k; + const g = { + name: r.name, + onActivate: () => { + this.toolClicked(l); + }, + hint: { title: h, description: u }, + }; + if (d.isElement(p)) { + const S = { ...g, element: p, type: A.Html }; + if (O(l.renderActions)) { + const I = l.renderActions(); + S.children = { + isOpen: + (f = l.checkState) == null ? void 0 : f.call(l, m.get()), + isFlippable: !1, + items: [{ type: A.Html, element: I }], + }; + } else (k = l.checkState) == null || k.call(l, m.get()); + i.push(S); + } else if (p.type === A.Html) i.push({ ...g, ...p, type: A.Html }); + else if (p.type === A.Separator) i.push({ type: A.Separator }); + else { + const S = { ...g, ...p, type: A.Default }; + "children" in S && s !== 0 && i.push({ type: A.Separator }), + i.push(S), + "children" in S && + s < o.length - 1 && + i.push({ type: A.Separator }); + } + }); + } + return i; + } + getToolShortcut(e) { + const { Tools: t } = this.Editor, + o = t.inlineTools.get(e), + i = t.internal.inlineTools; + return Array.from(i.keys()).includes(e) + ? this.inlineTools[e][Jt.Shortcut] + : o == null + ? void 0 + : o.shortcut; + } + enableShortcuts(e, t) { + ue.add({ + name: t, + handler: (o) => { + var s; + const { currentBlock: i } = this.Editor.BlockManager; + i && + i.tool.enabledInlineTools && + (o.preventDefault(), + (s = this.popover) == null || s.activateItemByName(e)); + }, + on: this.Editor.UI.nodes.redactor, + }); + } + toolClicked(e) { + var o; + const t = m.range; + (o = e.surround) == null || o.call(e, t), this.checkToolsState(); + } + checkToolsState() { + var e; + (e = this.toolsInstances) == null || + e.forEach((t) => { + var o; + (o = t.checkState) == null || o.call(t, m.get()); + }); + } + get inlineTools() { + const e = {}; + return ( + Array.from(this.Editor.Tools.inlineTools.entries()).forEach( + ([t, o]) => { + e[t] = o.create(); + }, + ), + e + ); + } + } + function Qt() { + const n = window.getSelection(); + if (n === null) return [null, 0]; + let e = n.focusNode, + t = n.focusOffset; + return e === null + ? [null, 0] + : (e.nodeType !== Node.TEXT_NODE && + e.childNodes.length > 0 && + (e.childNodes[t] + ? ((e = e.childNodes[t]), (t = 0)) + : ((e = e.childNodes[t - 1]), (t = e.textContent.length))), + [e, t]); + } + function eo(n, e, t, o) { + const i = document.createRange(); + o === "left" + ? (i.setStart(n, 0), i.setEnd(e, t)) + : (i.setStart(e, t), i.setEnd(n, n.childNodes.length)); + const s = i.cloneContents(), + r = document.createElement("div"); + r.appendChild(s); + const l = r.textContent || ""; + return Ao(l); + } + function Re(n) { + const e = d.getDeepestNode(n); + if (e === null || d.isEmpty(n)) return !0; + if (d.isNativeInput(e)) return e.selectionEnd === 0; + if (d.isEmpty(n)) return !0; + const [t, o] = Qt(); + return t === null ? !1 : eo(n, t, o, "left"); + } + function Fe(n) { + const e = d.getDeepestNode(n, !0); + if (e === null) return !0; + if (d.isNativeInput(e)) return e.selectionEnd === e.value.length; + const [t, o] = Qt(); + return t === null ? !1 : eo(n, t, o, "right"); + } + class Wi extends y { + keydown(e) { + switch ((this.beforeKeydownProcessing(e), e.keyCode)) { + case w.BACKSPACE: + this.backspace(e); + break; + case w.DELETE: + this.delete(e); + break; + case w.ENTER: + this.enter(e); + break; + case w.DOWN: + case w.RIGHT: + this.arrowRightAndDown(e); + break; + case w.UP: + case w.LEFT: + this.arrowLeftAndUp(e); + break; + case w.TAB: + this.tabPressed(e); + break; + } + e.key === "/" && !e.ctrlKey && !e.metaKey && this.slashPressed(e), + e.code === "Slash" && + (e.ctrlKey || e.metaKey) && + (e.preventDefault(), this.commandSlashPressed()); + } + beforeKeydownProcessing(e) { + this.needToolbarClosing(e) && + wt(e.keyCode) && + (this.Editor.Toolbar.close(), + e.ctrlKey || + e.metaKey || + e.altKey || + e.shiftKey || + this.Editor.BlockSelection.clearSelection(e)); + } + keyup(e) { + e.shiftKey || this.Editor.UI.checkEmptiness(); + } + dragOver(e) { + const t = this.Editor.BlockManager.getBlockByChildNode(e.target); + t.dropTarget = !0; + } + dragLeave(e) { + const t = this.Editor.BlockManager.getBlockByChildNode(e.target); + t.dropTarget = !1; + } + handleCommandC(e) { + const { BlockSelection: t } = this.Editor; + t.anyBlockSelected && t.copySelectedBlocks(e); + } + handleCommandX(e) { + const { BlockSelection: t, BlockManager: o, Caret: i } = this.Editor; + t.anyBlockSelected && + t.copySelectedBlocks(e).then(() => { + const s = o.removeSelectedBlocks(), + r = o.insertDefaultBlockAtIndex(s, !0); + i.setToBlock(r, i.positions.START), t.clearSelection(e); + }); + } + tabPressed(e) { + const { InlineToolbar: t, Caret: o } = this.Editor; + if (t.opened) return; + (e.shiftKey ? o.navigatePrevious(!0) : o.navigateNext(!0)) && + e.preventDefault(); + } + commandSlashPressed() { + this.Editor.BlockSelection.selectedBlocks.length > 1 || + this.activateBlockSettings(); + } + slashPressed(e) { + this.Editor.BlockManager.currentBlock.isEmpty && + (e.preventDefault(), + this.Editor.Caret.insertContentAtCaretPosition("/"), + this.activateToolbox()); + } + enter(e) { + const { BlockManager: t, UI: o } = this.Editor, + i = t.currentBlock; + if ( + i === void 0 || + i.tool.isLineBreaksEnabled || + (o.someToolbarOpened && o.someFlipperButtonFocused) || + (e.shiftKey && !We) + ) + return; + let s = i; + i.currentInput !== void 0 && Re(i.currentInput) && !i.hasMedia + ? this.Editor.BlockManager.insertDefaultBlockAtIndex( + this.Editor.BlockManager.currentBlockIndex, + ) + : i.currentInput && Fe(i.currentInput) + ? (s = this.Editor.BlockManager.insertDefaultBlockAtIndex( + this.Editor.BlockManager.currentBlockIndex + 1, + )) + : (s = this.Editor.BlockManager.split()), + this.Editor.Caret.setToBlock(s), + this.Editor.Toolbar.moveAndOpen(s), + e.preventDefault(); + } + backspace(e) { + const { BlockManager: t, Caret: o } = this.Editor, + { currentBlock: i, previousBlock: s } = t; + if ( + i === void 0 || + !m.isCollapsed || + !i.currentInput || + !Re(i.currentInput) + ) + return; + if ( + (e.preventDefault(), + this.Editor.Toolbar.close(), + !(i.currentInput === i.firstInput)) + ) { + o.navigatePrevious(); + return; + } + if (s === null) return; + if (s.isEmpty) { + t.removeBlock(s); + return; + } + if (i.isEmpty) { + t.removeBlock(i); + const a = t.currentBlock; + o.setToBlock(a, o.positions.END); + return; + } + _t(s, i) ? this.mergeBlocks(s, i) : o.setToBlock(s, o.positions.END); + } + delete(e) { + const { BlockManager: t, Caret: o } = this.Editor, + { currentBlock: i, nextBlock: s } = t; + if (!m.isCollapsed || !Fe(i.currentInput)) return; + if ( + (e.preventDefault(), + this.Editor.Toolbar.close(), + !(i.currentInput === i.lastInput)) + ) { + o.navigateNext(); + return; + } + if (s === null) return; + if (s.isEmpty) { + t.removeBlock(s); + return; + } + if (i.isEmpty) { + t.removeBlock(i), o.setToBlock(s, o.positions.START); + return; + } + _t(i, s) ? this.mergeBlocks(i, s) : o.setToBlock(s, o.positions.START); + } + mergeBlocks(e, t) { + const { BlockManager: o, Caret: i, Toolbar: s } = this.Editor; + i.createShadow(e.lastInput), + o.mergeBlocks(e, t).then(() => { + i.restoreCaret(e.pluginsContent), s.close(); + }); + } + arrowRightAndDown(e) { + const t = + se.usedKeys.includes(e.keyCode) && (!e.shiftKey || e.keyCode === w.TAB); + if (this.Editor.UI.someToolbarOpened && t) return; + this.Editor.Toolbar.close(); + const { currentBlock: o } = this.Editor.BlockManager, + s = + ((o == null ? void 0 : o.currentInput) !== void 0 + ? Fe(o.currentInput) + : void 0) || this.Editor.BlockSelection.anyBlockSelected; + if (e.shiftKey && e.keyCode === w.DOWN && s) { + this.Editor.CrossBlockSelection.toggleBlockSelectedState(); + return; + } + if ( + e.keyCode === w.DOWN || (e.keyCode === w.RIGHT && !this.isRtl) + ? this.Editor.Caret.navigateNext() + : this.Editor.Caret.navigatePrevious() + ) { + e.preventDefault(); + return; + } + Me(() => { + this.Editor.BlockManager.currentBlock && + this.Editor.BlockManager.currentBlock.updateCurrentInput(); + }, 20)(), + this.Editor.BlockSelection.clearSelection(e); + } + arrowLeftAndUp(e) { + if (this.Editor.UI.someToolbarOpened) { + if ( + se.usedKeys.includes(e.keyCode) && + (!e.shiftKey || e.keyCode === w.TAB) + ) + return; + this.Editor.UI.closeAllToolbars(); + } + this.Editor.Toolbar.close(); + const { currentBlock: t } = this.Editor.BlockManager, + i = + ((t == null ? void 0 : t.currentInput) !== void 0 + ? Re(t.currentInput) + : void 0) || this.Editor.BlockSelection.anyBlockSelected; + if (e.shiftKey && e.keyCode === w.UP && i) { + this.Editor.CrossBlockSelection.toggleBlockSelectedState(!1); + return; + } + if ( + e.keyCode === w.UP || (e.keyCode === w.LEFT && !this.isRtl) + ? this.Editor.Caret.navigatePrevious() + : this.Editor.Caret.navigateNext() + ) { + e.preventDefault(); + return; + } + Me(() => { + this.Editor.BlockManager.currentBlock && + this.Editor.BlockManager.currentBlock.updateCurrentInput(); + }, 20)(), + this.Editor.BlockSelection.clearSelection(e); + } + needToolbarClosing(e) { + const t = e.keyCode === w.ENTER && this.Editor.Toolbar.toolbox.opened, + o = e.keyCode === w.ENTER && this.Editor.BlockSettings.opened, + i = e.keyCode === w.ENTER && this.Editor.InlineToolbar.opened, + s = e.keyCode === w.TAB; + return !(e.shiftKey || s || t || o || i); + } + activateToolbox() { + this.Editor.Toolbar.opened || this.Editor.Toolbar.moveAndOpen(), + this.Editor.Toolbar.toolbox.open(); + } + activateBlockSettings() { + this.Editor.Toolbar.opened || this.Editor.Toolbar.moveAndOpen(), + this.Editor.BlockSettings.opened || this.Editor.BlockSettings.open(); + } + } + class dt { + constructor(e) { + (this.blocks = []), (this.workingArea = e); + } + get length() { + return this.blocks.length; + } + get array() { + return this.blocks; + } + get nodes() { + return xt(this.workingArea.children); + } + static set(e, t, o) { + return isNaN(Number(t)) + ? (Reflect.set(e, t, o), !0) + : (e.insert(+t, o), !0); + } + static get(e, t) { + return isNaN(Number(t)) ? Reflect.get(e, t) : e.get(+t); + } + push(e) { + this.blocks.push(e), this.insertToDOM(e); + } + swap(e, t) { + const o = this.blocks[t]; + d.swap(this.blocks[e].holder, o.holder), + (this.blocks[t] = this.blocks[e]), + (this.blocks[e] = o); + } + move(e, t) { + const o = this.blocks.splice(t, 1)[0], + i = e - 1, + s = Math.max(0, i), + r = this.blocks[s]; + e > 0 + ? this.insertToDOM(o, "afterend", r) + : this.insertToDOM(o, "beforebegin", r), + this.blocks.splice(e, 0, o); + const l = this.composeBlockEvent("move", { fromIndex: t, toIndex: e }); + o.call(Q.MOVED, l); + } + insert(e, t, o = !1) { + if (!this.length) { + this.push(t); + return; + } + e > this.length && (e = this.length), + o && (this.blocks[e].holder.remove(), this.blocks[e].call(Q.REMOVED)); + const i = o ? 1 : 0; + if ((this.blocks.splice(e, i, t), e > 0)) { + const s = this.blocks[e - 1]; + this.insertToDOM(t, "afterend", s); + } else { + const s = this.blocks[e + 1]; + s ? this.insertToDOM(t, "beforebegin", s) : this.insertToDOM(t); + } + } + replace(e, t) { + if (this.blocks[e] === void 0) throw Error("Incorrect index"); + this.blocks[e].holder.replaceWith(t.holder), (this.blocks[e] = t); + } + insertMany(e, t) { + const o = new DocumentFragment(); + for (const i of e) o.appendChild(i.holder); + if (this.length > 0) { + if (t > 0) { + const i = Math.min(t - 1, this.length - 1); + this.blocks[i].holder.after(o); + } else t === 0 && this.workingArea.prepend(o); + this.blocks.splice(t, 0, ...e); + } else this.blocks.push(...e), this.workingArea.appendChild(o); + e.forEach((i) => i.call(Q.RENDERED)); + } + remove(e) { + isNaN(e) && (e = this.length - 1), + this.blocks[e].holder.remove(), + this.blocks[e].call(Q.REMOVED), + this.blocks.splice(e, 1); + } + removeAll() { + (this.workingArea.innerHTML = ""), + this.blocks.forEach((e) => e.call(Q.REMOVED)), + (this.blocks.length = 0); + } + insertAfter(e, t) { + const o = this.blocks.indexOf(e); + this.insert(o + 1, t); + } + get(e) { + return this.blocks[e]; + } + indexOf(e) { + return this.blocks.indexOf(e); + } + insertToDOM(e, t, o) { + t + ? o.holder.insertAdjacentElement(t, e.holder) + : this.workingArea.appendChild(e.holder), + e.call(Q.RENDERED); + } + composeBlockEvent(e, t) { + return new CustomEvent(e, { detail: t }); + } + } + const to = "block-removed", + oo = "block-added", + Ki = "block-moved", + io = "block-changed"; + class Xi { + constructor() { + this.completed = Promise.resolve(); + } + add(e) { + return new Promise((t, o) => { + this.completed = this.completed.then(e).then(t).catch(o); + }); + } + } + class Vi extends y { + constructor() { + super(...arguments), + (this._currentBlockIndex = -1), + (this._blocks = null); + } + get currentBlockIndex() { + return this._currentBlockIndex; + } + set currentBlockIndex(e) { + this._currentBlockIndex = e; + } + get firstBlock() { + return this._blocks[0]; + } + get lastBlock() { + return this._blocks[this._blocks.length - 1]; + } + get currentBlock() { + return this._blocks[this.currentBlockIndex]; + } + set currentBlock(e) { + this.currentBlockIndex = this.getBlockIndex(e); + } + get nextBlock() { + return this.currentBlockIndex === this._blocks.length - 1 + ? null + : this._blocks[this.currentBlockIndex + 1]; + } + get nextContentfulBlock() { + return this.blocks + .slice(this.currentBlockIndex + 1) + .find((t) => !!t.inputs.length); + } + get previousContentfulBlock() { + return this.blocks + .slice(0, this.currentBlockIndex) + .reverse() + .find((t) => !!t.inputs.length); + } + get previousBlock() { + return this.currentBlockIndex === 0 + ? null + : this._blocks[this.currentBlockIndex - 1]; + } + get blocks() { + return this._blocks.array; + } + get isEditorEmpty() { + return this.blocks.every((e) => e.isEmpty); + } + prepare() { + const e = new dt(this.Editor.UI.nodes.redactor); + (this._blocks = new Proxy(e, { set: dt.set, get: dt.get })), + this.listeners.on(document, "copy", (t) => + this.Editor.BlockEvents.handleCommandC(t), + ); + } + toggleReadOnly(e) { + e ? this.disableModuleBindings() : this.enableModuleBindings(); + } + composeBlock({ tool: e, data: t = {}, id: o = void 0, tunes: i = {} }) { + const s = this.Editor.ReadOnly.isEnabled, + r = this.Editor.Tools.blockTools.get(e), + l = new D( + { + id: o, + data: t, + tool: r, + api: this.Editor.API, + readOnly: s, + tunesData: i, + }, + this.eventsDispatcher, + ); + return ( + s || + window.requestIdleCallback( + () => { + this.bindBlockEvents(l); + }, + { timeout: 2e3 }, + ), + l + ); + } + insert({ + id: e = void 0, + tool: t = this.config.defaultBlock, + data: o = {}, + index: i, + needToFocus: s = !0, + replace: r = !1, + tunes: l = {}, + } = {}) { + let a = i; + a === void 0 && (a = this.currentBlockIndex + (r ? 0 : 1)); + const c = this.composeBlock({ id: e, tool: t, data: o, tunes: l }); + return ( + r && this.blockDidMutated(to, this.getBlockByIndex(a), { index: a }), + this._blocks.insert(a, c, r), + this.blockDidMutated(oo, c, { index: a }), + s + ? (this.currentBlockIndex = a) + : a <= this.currentBlockIndex && this.currentBlockIndex++, + c + ); + } + insertMany(e, t = 0) { + this._blocks.insertMany(e, t); + } + async update(e, t, o) { + if (!t && !o) return e; + const i = await e.data, + s = this.composeBlock({ + id: e.id, + tool: e.name, + data: Object.assign({}, i, t ?? {}), + tunes: o ?? e.tunes, + }), + r = this.getBlockIndex(e); + return ( + this._blocks.replace(r, s), this.blockDidMutated(io, s, { index: r }), s + ); + } + replace(e, t, o) { + const i = this.getBlockIndex(e); + return this.insert({ tool: t, data: o, index: i, replace: !0 }); + } + paste(e, t, o = !1) { + const i = this.insert({ tool: e, replace: o }); + try { + window.requestIdleCallback(() => { + i.call(Q.ON_PASTE, t); + }); + } catch (s) { + C(`${e}: onPaste callback call is failed`, "error", s); + } + return i; + } + insertDefaultBlockAtIndex(e, t = !1) { + const o = this.composeBlock({ tool: this.config.defaultBlock }); + return ( + (this._blocks[e] = o), + this.blockDidMutated(oo, o, { index: e }), + t + ? (this.currentBlockIndex = e) + : e <= this.currentBlockIndex && this.currentBlockIndex++, + o + ); + } + insertAtEnd() { + return (this.currentBlockIndex = this.blocks.length - 1), this.insert(); + } + async mergeBlocks(e, t) { + let o; + if (e.name === t.name && e.mergeable) { + const i = await t.data; + if (V(i)) { + console.error( + "Could not merge Block. Failed to extract original Block data.", + ); + return; + } + const [s] = qe([i], e.tool.sanitizeConfig); + o = s; + } else if (e.mergeable && Oe(t, "export") && Oe(e, "import")) { + const i = await t.exportDataAsString(), + s = q(i, e.tool.sanitizeConfig); + o = Nt(s, e.tool.conversionConfig); + } + o !== void 0 && + (await e.mergeWith(o), + this.removeBlock(t), + (this.currentBlockIndex = this._blocks.indexOf(e))); + } + removeBlock(e, t = !0) { + return new Promise((o) => { + const i = this._blocks.indexOf(e); + if (!this.validateIndex(i)) + throw new Error("Can't find a Block to remove"); + e.destroy(), + this._blocks.remove(i), + this.blockDidMutated(to, e, { index: i }), + this.currentBlockIndex >= i && this.currentBlockIndex--, + this.blocks.length + ? i === 0 && (this.currentBlockIndex = 0) + : (this.unsetCurrentBlock(), t && this.insert()), + o(); + }); + } + removeSelectedBlocks() { + let e; + for (let t = this.blocks.length - 1; t >= 0; t--) + this.blocks[t].selected && (this.removeBlock(this.blocks[t]), (e = t)); + return e; + } + removeAllBlocks() { + for (let e = this.blocks.length - 1; e >= 0; e--) this._blocks.remove(e); + this.unsetCurrentBlock(), + this.insert(), + this.currentBlock.firstInput.focus(); + } + split() { + const e = this.Editor.Caret.extractFragmentFromCaretPosition(), + t = d.make("div"); + t.appendChild(e); + const o = { text: d.isEmpty(t) ? "" : t.innerHTML }; + return this.insert({ data: o }); + } + getBlockByIndex(e) { + return e === -1 && (e = this._blocks.length - 1), this._blocks[e]; + } + getBlockIndex(e) { + return this._blocks.indexOf(e); + } + getBlockById(e) { + return this._blocks.array.find((t) => t.id === e); + } + getBlock(e) { + d.isElement(e) || (e = e.parentNode); + const t = this._blocks.nodes, + o = e.closest(`.${D.CSS.wrapper}`), + i = t.indexOf(o); + if (i >= 0) return this._blocks[i]; + } + setCurrentBlockByChildNode(e) { + d.isElement(e) || (e = e.parentNode); + const t = e.closest(`.${D.CSS.wrapper}`); + if (!t) return; + const o = t.closest(`.${this.Editor.UI.CSS.editorWrapper}`); + if (o != null && o.isEqualNode(this.Editor.UI.nodes.wrapper)) + return ( + (this.currentBlockIndex = this._blocks.nodes.indexOf(t)), + this.currentBlock.updateCurrentInput(), + this.currentBlock + ); + } + getBlockByChildNode(e) { + if (!e || !(e instanceof Node)) return; + d.isElement(e) || (e = e.parentNode); + const t = e.closest(`.${D.CSS.wrapper}`); + return this.blocks.find((o) => o.holder === t); + } + swap(e, t) { + this._blocks.swap(e, t), (this.currentBlockIndex = t); + } + move(e, t = this.currentBlockIndex) { + if (isNaN(e) || isNaN(t)) { + C("Warning during 'move' call: incorrect indices provided.", "warn"); + return; + } + if (!this.validateIndex(e) || !this.validateIndex(t)) { + C( + "Warning during 'move' call: indices cannot be lower than 0 or greater than the amount of blocks.", + "warn", + ); + return; + } + this._blocks.move(e, t), + (this.currentBlockIndex = e), + this.blockDidMutated(Ki, this.currentBlock, { + fromIndex: t, + toIndex: e, + }); + } + async convert(e, t, o) { + if (!(await e.save())) + throw new Error( + "Could not convert Block. Failed to extract original Block data.", + ); + const s = this.Editor.Tools.blockTools.get(t); + if (!s) + throw new Error(`Could not convert Block. Tool «${t}» not found.`); + const r = await e.exportDataAsString(), + l = q(r, s.sanitizeConfig); + let a = Nt(l, s.conversionConfig); + return o && (a = Object.assign(a, o)), this.replace(e, s.name, a); + } + unsetCurrentBlock() { + this.currentBlockIndex = -1; + } + async clear(e = !1) { + const t = new Xi(); + this.blocks.forEach((o) => { + t.add(async () => { + await this.removeBlock(o, !1); + }); + }), + await t.completed, + this.unsetCurrentBlock(), + e && this.insert(), + this.Editor.UI.checkEmptiness(); + } + async destroy() { + await Promise.all(this.blocks.map((e) => e.destroy())); + } + bindBlockEvents(e) { + const { BlockEvents: t } = this.Editor; + this.readOnlyMutableListeners.on(e.holder, "keydown", (o) => { + t.keydown(o); + }), + this.readOnlyMutableListeners.on(e.holder, "keyup", (o) => { + t.keyup(o); + }), + this.readOnlyMutableListeners.on(e.holder, "dragover", (o) => { + t.dragOver(o); + }), + this.readOnlyMutableListeners.on(e.holder, "dragleave", (o) => { + t.dragLeave(o); + }), + e.on("didMutated", (o) => + this.blockDidMutated(io, o, { index: this.getBlockIndex(o) }), + ); + } + disableModuleBindings() { + this.readOnlyMutableListeners.clearAll(); + } + enableModuleBindings() { + this.readOnlyMutableListeners.on(document, "cut", (e) => + this.Editor.BlockEvents.handleCommandX(e), + ), + this.blocks.forEach((e) => { + this.bindBlockEvents(e); + }); + } + validateIndex(e) { + return !(e < 0 || e >= this._blocks.length); + } + blockDidMutated(e, t, o) { + const i = new CustomEvent(e, { detail: { target: new J(t), ...o } }); + return this.eventsDispatcher.emit(It, { event: i }), t; + } + } + class qi extends y { + constructor() { + super(...arguments), + (this.anyBlockSelectedCache = null), + (this.needToSelectAll = !1), + (this.nativeInputSelected = !1), + (this.readyToBlockSelection = !1); + } + get sanitizerConfig() { + return { + p: {}, + h1: {}, + h2: {}, + h3: {}, + h4: {}, + h5: {}, + h6: {}, + ol: {}, + ul: {}, + li: {}, + br: !0, + img: { src: !0, width: !0, height: !0 }, + a: { href: !0 }, + b: {}, + i: {}, + u: {}, + }; + } + get allBlocksSelected() { + const { BlockManager: e } = this.Editor; + return e.blocks.every((t) => t.selected === !0); + } + set allBlocksSelected(e) { + const { BlockManager: t } = this.Editor; + t.blocks.forEach((o) => { + o.selected = e; + }), + this.clearCache(); + } + get anyBlockSelected() { + const { BlockManager: e } = this.Editor; + return ( + this.anyBlockSelectedCache === null && + (this.anyBlockSelectedCache = e.blocks.some( + (t) => t.selected === !0, + )), + this.anyBlockSelectedCache + ); + } + get selectedBlocks() { + return this.Editor.BlockManager.blocks.filter((e) => e.selected); + } + prepare() { + (this.selection = new m()), + ue.add({ + name: "CMD+A", + handler: (e) => { + const { BlockManager: t, ReadOnly: o } = this.Editor; + if (o.isEnabled) { + e.preventDefault(), this.selectAllBlocks(); + return; + } + t.currentBlock && this.handleCommandA(e); + }, + on: this.Editor.UI.nodes.redactor, + }); + } + toggleReadOnly() { + m.get().removeAllRanges(), (this.allBlocksSelected = !1); + } + unSelectBlockByIndex(e) { + const { BlockManager: t } = this.Editor; + let o; + isNaN(e) ? (o = t.currentBlock) : (o = t.getBlockByIndex(e)), + (o.selected = !1), + this.clearCache(); + } + clearSelection(e, t = !1) { + const { BlockManager: o, Caret: i, RectangleSelection: s } = this.Editor; + (this.needToSelectAll = !1), + (this.nativeInputSelected = !1), + (this.readyToBlockSelection = !1); + const r = e && e instanceof KeyboardEvent, + l = r && wt(e.keyCode); + if (this.anyBlockSelected && r && l && !m.isSelectionExists) { + const a = o.removeSelectedBlocks(); + o.insertDefaultBlockAtIndex(a, !0), + i.setToBlock(o.currentBlock), + Me(() => { + const c = e.key; + i.insertContentAtCaretPosition(c.length > 1 ? "" : c); + }, 20)(); + } + if ( + (this.Editor.CrossBlockSelection.clear(e), + !this.anyBlockSelected || s.isRectActivated()) + ) { + this.Editor.RectangleSelection.clearSelection(); + return; + } + t && this.selection.restore(), (this.allBlocksSelected = !1); + } + copySelectedBlocks(e) { + e.preventDefault(); + const t = d.make("div"); + this.selectedBlocks.forEach((s) => { + const r = q(s.holder.innerHTML, this.sanitizerConfig), + l = d.make("p"); + (l.innerHTML = r), t.appendChild(l); + }); + const o = Array.from(t.childNodes).map((s) => s.textContent).join(` + +`), + i = t.innerHTML; + return ( + e.clipboardData.setData("text/plain", o), + e.clipboardData.setData("text/html", i), + Promise.all(this.selectedBlocks.map((s) => s.save())).then((s) => { + try { + e.clipboardData.setData( + this.Editor.Paste.MIME_TYPE, + JSON.stringify(s), + ); + } catch {} + }) + ); + } + selectBlockByIndex(e) { + const { BlockManager: t } = this.Editor, + o = t.getBlockByIndex(e); + o !== void 0 && this.selectBlock(o); + } + selectBlock(e) { + this.selection.save(), + m.get().removeAllRanges(), + (e.selected = !0), + this.clearCache(), + this.Editor.InlineToolbar.close(); + } + unselectBlock(e) { + (e.selected = !1), this.clearCache(); + } + clearCache() { + this.anyBlockSelectedCache = null; + } + destroy() { + ue.remove(this.Editor.UI.nodes.redactor, "CMD+A"); + } + handleCommandA(e) { + if ( + (this.Editor.RectangleSelection.clearSelection(), + d.isNativeInput(e.target) && !this.readyToBlockSelection) + ) { + this.readyToBlockSelection = !0; + return; + } + const t = this.Editor.BlockManager.getBlock(e.target), + o = t.inputs; + if (o.length > 1 && !this.readyToBlockSelection) { + this.readyToBlockSelection = !0; + return; + } + if (o.length === 1 && !this.needToSelectAll) { + this.needToSelectAll = !0; + return; + } + this.needToSelectAll + ? (e.preventDefault(), + this.selectAllBlocks(), + (this.needToSelectAll = !1), + (this.readyToBlockSelection = !1)) + : this.readyToBlockSelection && + (e.preventDefault(), + this.selectBlock(t), + (this.needToSelectAll = !0)); + } + selectAllBlocks() { + this.selection.save(), + m.get().removeAllRanges(), + (this.allBlocksSelected = !0), + this.Editor.InlineToolbar.close(); + } + } + class He extends y { + get positions() { + return { START: "start", END: "end", DEFAULT: "default" }; + } + static get CSS() { + return { shadowCaret: "cdx-shadow-caret" }; + } + setToBlock(e, t = this.positions.DEFAULT, o = 0) { + var c; + const { BlockManager: i, BlockSelection: s } = this.Editor; + if ((s.clearSelection(), !e.focusable)) { + (c = window.getSelection()) == null || c.removeAllRanges(), + s.selectBlock(e), + (i.currentBlock = e); + return; + } + let r; + switch (t) { + case this.positions.START: + r = e.firstInput; + break; + case this.positions.END: + r = e.lastInput; + break; + default: + r = e.currentInput; + } + if (!r) return; + const l = d.getDeepestNode(r, t === this.positions.END), + a = d.getContentLength(l); + switch (!0) { + case t === this.positions.START: + o = 0; + break; + case t === this.positions.END: + case o > a: + o = a; + break; + } + this.set(l, o), + i.setCurrentBlockByChildNode(e.holder), + (i.currentBlock.currentInput = r); + } + setToInput(e, t = this.positions.DEFAULT, o = 0) { + const { currentBlock: i } = this.Editor.BlockManager, + s = d.getDeepestNode(e); + switch (t) { + case this.positions.START: + this.set(s, 0); + break; + case this.positions.END: + this.set(s, d.getContentLength(s)); + break; + default: + o && this.set(s, o); + } + i.currentInput = e; + } + set(e, t = 0) { + const { top: i, bottom: s } = m.setCursor(e, t), + { innerHeight: r } = window; + i < 0 + ? window.scrollBy(0, i - 30) + : s > r && window.scrollBy(0, s - r + 30); + } + setToTheLastBlock() { + const e = this.Editor.BlockManager.lastBlock; + if (e) + if (e.tool.isDefault && e.isEmpty) this.setToBlock(e); + else { + const t = this.Editor.BlockManager.insertAtEnd(); + this.setToBlock(t); + } + } + extractFragmentFromCaretPosition() { + const e = m.get(); + if (e.rangeCount) { + const t = e.getRangeAt(0), + o = this.Editor.BlockManager.currentBlock.currentInput; + if ((t.deleteContents(), o)) + if (d.isNativeInput(o)) { + const i = o, + s = document.createDocumentFragment(), + r = i.value.substring(0, i.selectionStart), + l = i.value.substring(i.selectionStart); + return (s.textContent = l), (i.value = r), s; + } else { + const i = t.cloneRange(); + return ( + i.selectNodeContents(o), + i.setStart(t.endContainer, t.endOffset), + i.extractContents() + ); + } + } + } + navigateNext(e = !1) { + const { BlockManager: t } = this.Editor, + { currentBlock: o, nextBlock: i } = t; + if (o === void 0) return !1; + const { nextInput: s, currentInput: r } = o, + l = r !== void 0 ? Fe(r) : void 0; + let a = i; + const c = e || l || !o.focusable; + if (s && c) return this.setToInput(s, this.positions.START), !0; + if (a === null) { + if (o.tool.isDefault || !c) return !1; + a = t.insertAtEnd(); + } + return c ? (this.setToBlock(a, this.positions.START), !0) : !1; + } + navigatePrevious(e = !1) { + const { currentBlock: t, previousBlock: o } = this.Editor.BlockManager; + if (!t) return !1; + const { previousInput: i, currentInput: s } = t, + r = s !== void 0 ? Re(s) : void 0, + l = e || r || !t.focusable; + return i && l + ? (this.setToInput(i, this.positions.END), !0) + : o !== null && l + ? (this.setToBlock(o, this.positions.END), !0) + : !1; + } + createShadow(e) { + const t = document.createElement("span"); + t.classList.add(He.CSS.shadowCaret), + e.insertAdjacentElement("beforeend", t); + } + restoreCaret(e) { + const t = e.querySelector(`.${He.CSS.shadowCaret}`); + if (!t) return; + new m().expandToTag(t); + const i = document.createRange(); + i.selectNode(t), i.extractContents(); + } + insertContentAtCaretPosition(e) { + const t = document.createDocumentFragment(), + o = document.createElement("div"), + i = m.get(), + s = m.range; + (o.innerHTML = e), + Array.from(o.childNodes).forEach((c) => t.appendChild(c)), + t.childNodes.length === 0 && t.appendChild(new Text()); + const r = t.lastChild; + s.deleteContents(), s.insertNode(t); + const l = document.createRange(), + a = r.nodeType === Node.TEXT_NODE ? r : r.firstChild; + a !== null && + a.textContent !== null && + l.setStart(a, a.textContent.length), + i.removeAllRanges(), + i.addRange(l); + } + } + class Zi extends y { + constructor() { + super(...arguments), + (this.onMouseUp = () => { + this.listeners.off(document, "mouseover", this.onMouseOver), + this.listeners.off(document, "mouseup", this.onMouseUp); + }), + (this.onMouseOver = (e) => { + const { BlockManager: t, BlockSelection: o } = this.Editor; + if (e.relatedTarget === null && e.target === null) return; + const i = + t.getBlockByChildNode(e.relatedTarget) || this.lastSelectedBlock, + s = t.getBlockByChildNode(e.target); + if (!(!i || !s) && s !== i) { + if (i === this.firstSelectedBlock) { + m.get().removeAllRanges(), + (i.selected = !0), + (s.selected = !0), + o.clearCache(); + return; + } + if (s === this.firstSelectedBlock) { + (i.selected = !1), (s.selected = !1), o.clearCache(); + return; + } + this.Editor.InlineToolbar.close(), + this.toggleBlocksSelectedState(i, s), + (this.lastSelectedBlock = s); + } + }); + } + async prepare() { + this.listeners.on(document, "mousedown", (e) => { + this.enableCrossBlockSelection(e); + }); + } + watchSelection(e) { + if (e.button !== ko.LEFT) return; + const { BlockManager: t } = this.Editor; + (this.firstSelectedBlock = t.getBlock(e.target)), + (this.lastSelectedBlock = this.firstSelectedBlock), + this.listeners.on(document, "mouseover", this.onMouseOver), + this.listeners.on(document, "mouseup", this.onMouseUp); + } + get isCrossBlockSelectionStarted() { + return ( + !!this.firstSelectedBlock && + !!this.lastSelectedBlock && + this.firstSelectedBlock !== this.lastSelectedBlock + ); + } + toggleBlockSelectedState(e = !0) { + const { BlockManager: t, BlockSelection: o } = this.Editor; + this.lastSelectedBlock || + (this.lastSelectedBlock = this.firstSelectedBlock = t.currentBlock), + this.firstSelectedBlock === this.lastSelectedBlock && + ((this.firstSelectedBlock.selected = !0), + o.clearCache(), + m.get().removeAllRanges()); + const i = t.blocks.indexOf(this.lastSelectedBlock) + (e ? 1 : -1), + s = t.blocks[i]; + s && + (this.lastSelectedBlock.selected !== s.selected + ? ((s.selected = !0), o.clearCache()) + : ((this.lastSelectedBlock.selected = !1), o.clearCache()), + (this.lastSelectedBlock = s), + this.Editor.InlineToolbar.close(), + s.holder.scrollIntoView({ block: "nearest" })); + } + clear(e) { + const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor, + s = t.blocks.indexOf(this.firstSelectedBlock), + r = t.blocks.indexOf(this.lastSelectedBlock); + if ( + o.anyBlockSelected && + s > -1 && + r > -1 && + e && + e instanceof KeyboardEvent + ) + switch (e.keyCode) { + case w.DOWN: + case w.RIGHT: + i.setToBlock(t.blocks[Math.max(s, r)], i.positions.END); + break; + case w.UP: + case w.LEFT: + i.setToBlock(t.blocks[Math.min(s, r)], i.positions.START); + break; + default: + i.setToBlock(t.blocks[Math.max(s, r)], i.positions.END); + } + this.firstSelectedBlock = this.lastSelectedBlock = null; + } + enableCrossBlockSelection(e) { + const { UI: t } = this.Editor; + m.isCollapsed || this.Editor.BlockSelection.clearSelection(e), + t.nodes.redactor.contains(e.target) + ? this.watchSelection(e) + : this.Editor.BlockSelection.clearSelection(e); + } + toggleBlocksSelectedState(e, t) { + const { BlockManager: o, BlockSelection: i } = this.Editor, + s = o.blocks.indexOf(e), + r = o.blocks.indexOf(t), + l = e.selected !== t.selected; + for (let a = Math.min(s, r); a <= Math.max(s, r); a++) { + const c = o.blocks[a]; + c !== this.firstSelectedBlock && + c !== (l ? e : t) && + ((o.blocks[a].selected = !o.blocks[a].selected), i.clearCache()); + } + } + } + class Gi extends y { + constructor() { + super(...arguments), (this.isStartedAtEditor = !1); + } + toggleReadOnly(e) { + e ? this.disableModuleBindings() : this.enableModuleBindings(); + } + enableModuleBindings() { + const { UI: e } = this.Editor; + this.readOnlyMutableListeners.on( + e.nodes.holder, + "drop", + async (t) => { + await this.processDrop(t); + }, + !0, + ), + this.readOnlyMutableListeners.on(e.nodes.holder, "dragstart", () => { + this.processDragStart(); + }), + this.readOnlyMutableListeners.on( + e.nodes.holder, + "dragover", + (t) => { + this.processDragOver(t); + }, + !0, + ); + } + disableModuleBindings() { + this.readOnlyMutableListeners.clearAll(); + } + async processDrop(e) { + const { BlockManager: t, Paste: o, Caret: i } = this.Editor; + e.preventDefault(), + t.blocks.forEach((r) => { + r.dropTarget = !1; + }), + m.isAtEditor && + !m.isCollapsed && + this.isStartedAtEditor && + document.execCommand("delete"), + (this.isStartedAtEditor = !1); + const s = t.setCurrentBlockByChildNode(e.target); + if (s) this.Editor.Caret.setToBlock(s, i.positions.END); + else { + const r = t.setCurrentBlockByChildNode(t.lastBlock.holder); + this.Editor.Caret.setToBlock(r, i.positions.END); + } + await o.processDataTransfer(e.dataTransfer, !0); + } + processDragStart() { + m.isAtEditor && !m.isCollapsed && (this.isStartedAtEditor = !0), + this.Editor.InlineToolbar.close(); + } + processDragOver(e) { + e.preventDefault(); + } + } + const Ji = 180, + Qi = 400; + class es extends y { + constructor({ config: e, eventsDispatcher: t }) { + super({ config: e, eventsDispatcher: t }), + (this.disabled = !1), + (this.batchingTimeout = null), + (this.batchingOnChangeQueue = new Map()), + (this.batchTime = Qi), + (this.mutationObserver = new MutationObserver((o) => { + this.redactorChanged(o); + })), + this.eventsDispatcher.on(It, (o) => { + this.particularBlockChanged(o.event); + }), + this.eventsDispatcher.on(Mt, () => { + this.disable(); + }), + this.eventsDispatcher.on(At, () => { + this.enable(); + }); + } + enable() { + this.mutationObserver.observe(this.Editor.UI.nodes.redactor, { + childList: !0, + subtree: !0, + characterData: !0, + attributes: !0, + }), + (this.disabled = !1); + } + disable() { + this.mutationObserver.disconnect(), (this.disabled = !0); + } + particularBlockChanged(e) { + this.disabled || + !O(this.config.onChange) || + (this.batchingOnChangeQueue.set( + `block:${e.detail.target.id}:event:${e.type}`, + e, + ), + this.batchingTimeout && clearTimeout(this.batchingTimeout), + (this.batchingTimeout = setTimeout(() => { + let t; + this.batchingOnChangeQueue.size === 1 + ? (t = this.batchingOnChangeQueue.values().next().value) + : (t = Array.from(this.batchingOnChangeQueue.values())), + this.config.onChange && + this.config.onChange(this.Editor.API.methods, t), + this.batchingOnChangeQueue.clear(); + }, this.batchTime))); + } + redactorChanged(e) { + this.eventsDispatcher.emit(Ke, { mutations: e }); + } + } + const so = class mo extends y { + constructor() { + super(...arguments), + (this.MIME_TYPE = "application/x-editor-js"), + (this.toolsTags = {}), + (this.tagsByTool = {}), + (this.toolsPatterns = []), + (this.toolsFiles = {}), + (this.exceptionList = []), + (this.processTool = (e) => { + try { + const t = e.create({}, {}, !1); + if (e.pasteConfig === !1) { + this.exceptionList.push(e.name); + return; + } + if (!O(t.onPaste)) return; + this.getTagsConfig(e), + this.getFilesConfig(e), + this.getPatternsConfig(e); + } catch (t) { + C( + `Paste handling for «${e.name}» Tool hasn't been set up because of the error`, + "warn", + t, + ); + } + }), + (this.handlePasteEvent = async (e) => { + const { BlockManager: t, Toolbar: o } = this.Editor, + i = t.setCurrentBlockByChildNode(e.target); + !i || + (this.isNativeBehaviour(e.target) && + !e.clipboardData.types.includes("Files")) || + (i && this.exceptionList.includes(i.name)) || + (e.preventDefault(), + this.processDataTransfer(e.clipboardData), + o.close()); + }); + } + async prepare() { + this.processTools(); + } + toggleReadOnly(e) { + e ? this.unsetCallback() : this.setCallback(); + } + async processDataTransfer(e, t = !1) { + const { Tools: o } = this.Editor, + i = e.types; + if ( + (i.includes ? i.includes("Files") : i.contains("Files")) && + !V(this.toolsFiles) + ) { + await this.processFiles(e.files); + return; + } + const r = e.getData(this.MIME_TYPE), + l = e.getData("text/plain"); + let a = e.getData("text/html"); + if (r) + try { + this.insertEditorJSData(JSON.parse(r)); + return; + } catch {} + t && l.trim() && a.trim() && (a = "

" + (a.trim() ? a : l) + "

"); + const c = Object.keys(this.toolsTags).reduce( + (p, g) => ( + (p[g.toLowerCase()] = this.toolsTags[g].sanitizationConfig ?? {}), p + ), + {}, + ), + u = Object.assign({}, c, o.getAllInlineToolsSanitizeConfig(), { + br: {}, + }), + h = q(a, u); + !h.trim() || h.trim() === l || !d.isHTMLString(h) + ? await this.processText(l) + : await this.processText(h, !0); + } + async processText(e, t = !1) { + const { Caret: o, BlockManager: i } = this.Editor, + s = t ? this.processHTML(e) : this.processPlain(e); + if (!s.length) return; + if (s.length === 1) { + s[0].isBlock + ? this.processSingleBlock(s.pop()) + : this.processInlinePaste(s.pop()); + return; + } + const l = + i.currentBlock && + i.currentBlock.tool.isDefault && + i.currentBlock.isEmpty; + s.map(async (a, c) => this.insertBlock(a, c === 0 && l)), + i.currentBlock && o.setToBlock(i.currentBlock, o.positions.END); + } + setCallback() { + this.listeners.on( + this.Editor.UI.nodes.holder, + "paste", + this.handlePasteEvent, + ); + } + unsetCallback() { + this.listeners.off( + this.Editor.UI.nodes.holder, + "paste", + this.handlePasteEvent, + ); + } + processTools() { + const e = this.Editor.Tools.blockTools; + Array.from(e.values()).forEach(this.processTool); + } + collectTagNames(e) { + return G(e) ? [e] : P(e) ? Object.keys(e) : []; + } + getTagsConfig(e) { + if (e.pasteConfig === !1) return; + const t = e.pasteConfig.tags || [], + o = []; + t.forEach((i) => { + const s = this.collectTagNames(i); + o.push(...s), + s.forEach((r) => { + if (Object.prototype.hasOwnProperty.call(this.toolsTags, r)) { + C( + `Paste handler for «${e.name}» Tool on «${r}» tag is skipped because it is already used by «${this.toolsTags[r].tool.name}» Tool.`, + "warn", + ); + return; + } + const l = P(i) ? i[r] : null; + this.toolsTags[r.toUpperCase()] = { + tool: e, + sanitizationConfig: l, + }; + }); + }), + (this.tagsByTool[e.name] = o.map((i) => i.toUpperCase())); + } + getFilesConfig(e) { + if (e.pasteConfig === !1) return; + const { files: t = {} } = e.pasteConfig; + let { extensions: o, mimeTypes: i } = t; + (!o && !i) || + (o && + !Array.isArray(o) && + (C( + `«extensions» property of the onDrop config for «${e.name}» Tool should be an array`, + ), + (o = [])), + i && + !Array.isArray(i) && + (C( + `«mimeTypes» property of the onDrop config for «${e.name}» Tool should be an array`, + ), + (i = [])), + i && + (i = i.filter((s) => + Eo(s) + ? !0 + : (C( + `MIME type value «${s}» for the «${e.name}» Tool is not a valid MIME type`, + "warn", + ), + !1), + )), + (this.toolsFiles[e.name] = { + extensions: o || [], + mimeTypes: i || [], + })); + } + getPatternsConfig(e) { + e.pasteConfig === !1 || + !e.pasteConfig.patterns || + V(e.pasteConfig.patterns) || + Object.entries(e.pasteConfig.patterns).forEach(([t, o]) => { + o instanceof RegExp || + C( + `Pattern ${o} for «${e.name}» Tool is skipped because it should be a Regexp instance.`, + "warn", + ), + this.toolsPatterns.push({ key: t, pattern: o, tool: e }); + }); + } + isNativeBehaviour(e) { + return d.isNativeInput(e); + } + async processFiles(e) { + const { BlockManager: t } = this.Editor; + let o; + (o = await Promise.all(Array.from(e).map((r) => this.processFile(r)))), + (o = o.filter((r) => !!r)); + const s = t.currentBlock.tool.isDefault && t.currentBlock.isEmpty; + o.forEach((r, l) => { + t.paste(r.type, r.event, l === 0 && s); + }); + } + async processFile(e) { + const t = yo(e), + o = Object.entries(this.toolsFiles).find( + ([r, { mimeTypes: l, extensions: a }]) => { + const [c, u] = e.type.split("/"), + h = a.find((g) => g.toLowerCase() === t.toLowerCase()), + p = l.find((g) => { + const [f, k] = g.split("/"); + return f === c && (k === u || k === "*"); + }); + return !!h || !!p; + }, + ); + if (!o) return; + const [i] = o; + return { event: this.composePasteEvent("file", { file: e }), type: i }; + } + processHTML(e) { + const { Tools: t } = this.Editor, + o = d.make("DIV"); + return ( + (o.innerHTML = e), + this.getNodes(o) + .map((s) => { + let r, + l = t.defaultTool, + a = !1; + switch (s.nodeType) { + case Node.DOCUMENT_FRAGMENT_NODE: + (r = d.make("div")), r.appendChild(s); + break; + case Node.ELEMENT_NODE: + (r = s), + (a = !0), + this.toolsTags[r.tagName] && + (l = this.toolsTags[r.tagName].tool); + break; + } + const { tags: c } = l.pasteConfig || { tags: [] }, + u = c.reduce( + (g, f) => ( + this.collectTagNames(f).forEach((S) => { + const I = P(f) ? f[S] : null; + g[S.toLowerCase()] = I || {}; + }), + g + ), + {}, + ), + h = Object.assign({}, u, l.baseSanitizeConfig); + if (r.tagName.toLowerCase() === "table") { + const g = q(r.outerHTML, h); + r = d.make("div", void 0, { innerHTML: g }).firstChild; + } else r.innerHTML = q(r.innerHTML, h); + const p = this.composePasteEvent("tag", { data: r }); + return { content: r, isBlock: a, tool: l.name, event: p }; + }) + .filter((s) => { + const r = d.isEmpty(s.content), + l = d.isSingleTag(s.content); + return !r || l; + }) + ); + } + processPlain(e) { + const { defaultBlock: t } = this.config; + if (!e) return []; + const o = t; + return e + .split(/\r?\n/) + .filter((i) => i.trim()) + .map((i) => { + const s = d.make("div"); + s.textContent = i; + const r = this.composePasteEvent("tag", { data: s }); + return { content: s, tool: o, isBlock: !1, event: r }; + }); + } + async processSingleBlock(e) { + const { Caret: t, BlockManager: o } = this.Editor, + { currentBlock: i } = o; + if ( + !i || + e.tool !== i.name || + !d.containsOnlyInlineElements(e.content.innerHTML) + ) { + this.insertBlock( + e, + (i == null ? void 0 : i.tool.isDefault) && i.isEmpty, + ); + return; + } + t.insertContentAtCaretPosition(e.content.innerHTML); + } + async processInlinePaste(e) { + const { BlockManager: t, Caret: o } = this.Editor, + { content: i } = e; + if ( + t.currentBlock && + t.currentBlock.tool.isDefault && + i.textContent.length < mo.PATTERN_PROCESSING_MAX_LENGTH + ) { + const r = await this.processPattern(i.textContent); + if (r) { + const l = + t.currentBlock && + t.currentBlock.tool.isDefault && + t.currentBlock.isEmpty, + a = t.paste(r.tool, r.event, l); + o.setToBlock(a, o.positions.END); + return; + } + } + if (t.currentBlock && t.currentBlock.currentInput) { + const r = t.currentBlock.tool.baseSanitizeConfig; + document.execCommand("insertHTML", !1, q(i.innerHTML, r)); + } else this.insertBlock(e); + } + async processPattern(e) { + const t = this.toolsPatterns.find((i) => { + const s = i.pattern.exec(e); + return s ? e === s.shift() : !1; + }); + return t + ? { + event: this.composePasteEvent("pattern", { key: t.key, data: e }), + tool: t.tool.name, + } + : void 0; + } + insertBlock(e, t = !1) { + const { BlockManager: o, Caret: i } = this.Editor, + { currentBlock: s } = o; + let r; + if (t && s && s.isEmpty) { + (r = o.paste(e.tool, e.event, !0)), i.setToBlock(r, i.positions.END); + return; + } + (r = o.paste(e.tool, e.event)), i.setToBlock(r, i.positions.END); + } + insertEditorJSData(e) { + const { BlockManager: t, Caret: o, Tools: i } = this.Editor; + qe(e, (r) => i.blockTools.get(r).sanitizeConfig).forEach( + ({ tool: r, data: l }, a) => { + let c = !1; + a === 0 && + (c = + t.currentBlock && + t.currentBlock.tool.isDefault && + t.currentBlock.isEmpty); + const u = t.insert({ tool: r, data: l, replace: c }); + o.setToBlock(u, o.positions.END); + }, + ); + } + processElementNode(e, t, o) { + const i = Object.keys(this.toolsTags), + s = e, + { tool: r } = this.toolsTags[s.tagName] || {}, + l = this.tagsByTool[r == null ? void 0 : r.name] || [], + a = i.includes(s.tagName), + c = d.blockElements.includes(s.tagName.toLowerCase()), + u = Array.from(s.children).some( + ({ tagName: p }) => i.includes(p) && !l.includes(p), + ), + h = Array.from(s.children).some(({ tagName: p }) => + d.blockElements.includes(p.toLowerCase()), + ); + if (!c && !a && !u) return o.appendChild(s), [...t, o]; + if ((a && !u) || (c && !h && !u)) return [...t, o, s]; + } + getNodes(e) { + const t = Array.from(e.childNodes); + let o; + const i = (s, r) => { + if (d.isEmpty(r) && !d.isSingleTag(r)) return s; + const l = s[s.length - 1]; + let a = new DocumentFragment(); + switch ((l && d.isFragment(l) && (a = s.pop()), r.nodeType)) { + case Node.ELEMENT_NODE: + if (((o = this.processElementNode(r, s, a)), o)) return o; + break; + case Node.TEXT_NODE: + return a.appendChild(r), [...s, a]; + default: + return [...s, a]; + } + return [...s, ...Array.from(r.childNodes).reduce(i, [])]; + }; + return t.reduce(i, []); + } + composePasteEvent(e, t) { + return new CustomEvent(e, { detail: t }); + } + }; + so.PATTERN_PROCESSING_MAX_LENGTH = 450; + let ts = so; + class os extends y { + constructor() { + super(...arguments), + (this.toolsDontSupportReadOnly = []), + (this.readOnlyEnabled = !1); + } + get isEnabled() { + return this.readOnlyEnabled; + } + async prepare() { + const { Tools: e } = this.Editor, + { blockTools: t } = e, + o = []; + Array.from(t.entries()).forEach(([i, s]) => { + s.isReadOnlySupported || o.push(i); + }), + (this.toolsDontSupportReadOnly = o), + this.config.readOnly && o.length > 0 && this.throwCriticalError(), + this.toggle(this.config.readOnly, !0); + } + async toggle(e = !this.readOnlyEnabled, t = !1) { + e && + this.toolsDontSupportReadOnly.length > 0 && + this.throwCriticalError(); + const o = this.readOnlyEnabled; + this.readOnlyEnabled = e; + for (const s in this.Editor) + this.Editor[s].toggleReadOnly && this.Editor[s].toggleReadOnly(e); + if (o === e) return this.readOnlyEnabled; + if (t) return this.readOnlyEnabled; + this.Editor.ModificationsObserver.disable(); + const i = await this.Editor.Saver.save(); + return ( + await this.Editor.BlockManager.clear(), + await this.Editor.Renderer.render(i.blocks), + this.Editor.ModificationsObserver.enable(), + this.readOnlyEnabled + ); + } + throwCriticalError() { + throw new St( + `To enable read-only mode all connected tools should support it. Tools ${this.toolsDontSupportReadOnly.join(", ")} don't support read-only mode.`, + ); + } + } + class Be extends y { + constructor() { + super(...arguments), + (this.isRectSelectionActivated = !1), + (this.SCROLL_SPEED = 3), + (this.HEIGHT_OF_SCROLL_ZONE = 40), + (this.BOTTOM_SCROLL_ZONE = 1), + (this.TOP_SCROLL_ZONE = 2), + (this.MAIN_MOUSE_BUTTON = 0), + (this.mousedown = !1), + (this.isScrolling = !1), + (this.inScrollZone = null), + (this.startX = 0), + (this.startY = 0), + (this.mouseX = 0), + (this.mouseY = 0), + (this.stackOfSelected = []), + (this.listenerIds = []); + } + static get CSS() { + return { + overlay: "codex-editor-overlay", + overlayContainer: "codex-editor-overlay__container", + rect: "codex-editor-overlay__rectangle", + topScrollZone: "codex-editor-overlay__scroll-zone--top", + bottomScrollZone: "codex-editor-overlay__scroll-zone--bottom", + }; + } + prepare() { + this.enableModuleBindings(); + } + startSelection(e, t) { + const o = document.elementFromPoint( + e - window.pageXOffset, + t - window.pageYOffset, + ); + o.closest(`.${this.Editor.Toolbar.CSS.toolbar}`) || + ((this.Editor.BlockSelection.allBlocksSelected = !1), + this.clearSelection(), + (this.stackOfSelected = [])); + const s = [ + `.${D.CSS.content}`, + `.${this.Editor.Toolbar.CSS.toolbar}`, + `.${this.Editor.InlineToolbar.CSS.inlineToolbar}`, + ], + r = o.closest("." + this.Editor.UI.CSS.editorWrapper), + l = s.some((a) => !!o.closest(a)); + !r || l || ((this.mousedown = !0), (this.startX = e), (this.startY = t)); + } + endSelection() { + (this.mousedown = !1), + (this.startX = 0), + (this.startY = 0), + (this.overlayRectangle.style.display = "none"); + } + isRectActivated() { + return this.isRectSelectionActivated; + } + clearSelection() { + this.isRectSelectionActivated = !1; + } + enableModuleBindings() { + const { container: e } = this.genHTML(); + this.listeners.on( + e, + "mousedown", + (t) => { + this.processMouseDown(t); + }, + !1, + ), + this.listeners.on( + document.body, + "mousemove", + Ue((t) => { + this.processMouseMove(t); + }, 10), + { passive: !0 }, + ), + this.listeners.on(document.body, "mouseleave", () => { + this.processMouseLeave(); + }), + this.listeners.on( + window, + "scroll", + Ue((t) => { + this.processScroll(t); + }, 10), + { passive: !0 }, + ), + this.listeners.on( + document.body, + "mouseup", + () => { + this.processMouseUp(); + }, + !1, + ); + } + processMouseDown(e) { + if (e.button !== this.MAIN_MOUSE_BUTTON) return; + e.target.closest(d.allInputsSelector) !== null || + this.startSelection(e.pageX, e.pageY); + } + processMouseMove(e) { + this.changingRectangle(e), this.scrollByZones(e.clientY); + } + processMouseLeave() { + this.clearSelection(), this.endSelection(); + } + processScroll(e) { + this.changingRectangle(e); + } + processMouseUp() { + this.clearSelection(), this.endSelection(); + } + scrollByZones(e) { + if ( + ((this.inScrollZone = null), + e <= this.HEIGHT_OF_SCROLL_ZONE && + (this.inScrollZone = this.TOP_SCROLL_ZONE), + document.documentElement.clientHeight - e <= + this.HEIGHT_OF_SCROLL_ZONE && + (this.inScrollZone = this.BOTTOM_SCROLL_ZONE), + !this.inScrollZone) + ) { + this.isScrolling = !1; + return; + } + this.isScrolling || + (this.scrollVertical( + this.inScrollZone === this.TOP_SCROLL_ZONE + ? -this.SCROLL_SPEED + : this.SCROLL_SPEED, + ), + (this.isScrolling = !0)); + } + genHTML() { + const { UI: e } = this.Editor, + t = e.nodes.holder.querySelector("." + e.CSS.editorWrapper), + o = d.make("div", Be.CSS.overlay, {}), + i = d.make("div", Be.CSS.overlayContainer, {}), + s = d.make("div", Be.CSS.rect, {}); + return ( + i.appendChild(s), + o.appendChild(i), + t.appendChild(o), + (this.overlayRectangle = s), + { container: t, overlay: o } + ); + } + scrollVertical(e) { + if (!(this.inScrollZone && this.mousedown)) return; + const t = window.pageYOffset; + window.scrollBy(0, e), + (this.mouseY += window.pageYOffset - t), + setTimeout(() => { + this.scrollVertical(e); + }, 0); + } + changingRectangle(e) { + if (!this.mousedown) return; + e.pageY !== void 0 && ((this.mouseX = e.pageX), (this.mouseY = e.pageY)); + const { + rightPos: t, + leftPos: o, + index: i, + } = this.genInfoForMouseSelection(), + s = this.startX > t && this.mouseX > t, + r = this.startX < o && this.mouseX < o; + (this.rectCrossesBlocks = !(s || r)), + this.isRectSelectionActivated || + ((this.rectCrossesBlocks = !1), + (this.isRectSelectionActivated = !0), + this.shrinkRectangleToPoint(), + (this.overlayRectangle.style.display = "block")), + this.updateRectangleSize(), + this.Editor.Toolbar.close(), + i !== void 0 && + (this.trySelectNextBlock(i), + this.inverseSelection(), + m.get().removeAllRanges()); + } + shrinkRectangleToPoint() { + (this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`), + (this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`), + (this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`), + (this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`); + } + inverseSelection() { + const t = this.Editor.BlockManager.getBlockByIndex( + this.stackOfSelected[0], + ).selected; + if (this.rectCrossesBlocks && !t) + for (const o of this.stackOfSelected) + this.Editor.BlockSelection.selectBlockByIndex(o); + if (!this.rectCrossesBlocks && t) + for (const o of this.stackOfSelected) + this.Editor.BlockSelection.unSelectBlockByIndex(o); + } + updateRectangleSize() { + this.mouseY >= this.startY + ? ((this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`), + (this.overlayRectangle.style.bottom = `calc(100% - ${this.mouseY - window.pageYOffset}px`)) + : ((this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`), + (this.overlayRectangle.style.top = `${this.mouseY - window.pageYOffset}px`)), + this.mouseX >= this.startX + ? ((this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`), + (this.overlayRectangle.style.right = `calc(100% - ${this.mouseX - window.pageXOffset}px`)) + : ((this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`), + (this.overlayRectangle.style.left = `${this.mouseX - window.pageXOffset}px`)); + } + genInfoForMouseSelection() { + const t = document.body.offsetWidth / 2, + o = this.mouseY - window.pageYOffset, + i = document.elementFromPoint(t, o), + s = this.Editor.BlockManager.getBlockByChildNode(i); + let r; + s !== void 0 && + (r = this.Editor.BlockManager.blocks.findIndex( + (h) => h.holder === s.holder, + )); + const l = this.Editor.BlockManager.lastBlock.holder.querySelector( + "." + D.CSS.content, + ), + a = Number.parseInt(window.getComputedStyle(l).width, 10) / 2, + c = t - a, + u = t + a; + return { index: r, leftPos: c, rightPos: u }; + } + addBlockInSelection(e) { + this.rectCrossesBlocks && + this.Editor.BlockSelection.selectBlockByIndex(e), + this.stackOfSelected.push(e); + } + trySelectNextBlock(e) { + const t = this.stackOfSelected[this.stackOfSelected.length - 1] === e, + o = this.stackOfSelected.length, + i = 1, + s = -1, + r = 0; + if (t) return; + const l = this.stackOfSelected[o - 1] - this.stackOfSelected[o - 2] > 0; + let a = r; + o > 1 && (a = l ? i : s); + const c = e > this.stackOfSelected[o - 1] && a === i, + u = e < this.stackOfSelected[o - 1] && a === s, + p = !(c || u || a === r); + if ( + !p && + (e > this.stackOfSelected[o - 1] || + this.stackOfSelected[o - 1] === void 0) + ) { + let k = this.stackOfSelected[o - 1] + 1 || e; + for (k; k <= e; k++) this.addBlockInSelection(k); + return; + } + if (!p && e < this.stackOfSelected[o - 1]) { + for (let k = this.stackOfSelected[o - 1] - 1; k >= e; k--) + this.addBlockInSelection(k); + return; + } + if (!p) return; + let g = o - 1, + f; + for ( + e > this.stackOfSelected[o - 1] + ? (f = () => e > this.stackOfSelected[g]) + : (f = () => e < this.stackOfSelected[g]); + f(); + + ) + this.rectCrossesBlocks && + this.Editor.BlockSelection.unSelectBlockByIndex( + this.stackOfSelected[g], + ), + this.stackOfSelected.pop(), + g--; + } + } + class is extends y { + async render(e) { + return new Promise((t) => { + const { Tools: o, BlockManager: i } = this.Editor; + if (e.length === 0) i.insert(); + else { + const s = e.map(({ type: r, data: l, tunes: a, id: c }) => { + o.available.has(r) === !1 && + (X( + `Tool «${r}» is not found. Check 'tools' property at the Editor.js config.`, + "warn", + ), + (l = this.composeStubDataForTool(r, l, c)), + (r = o.stubTool)); + let u; + try { + u = i.composeBlock({ id: c, tool: r, data: l, tunes: a }); + } catch (h) { + C(`Block «${r}» skipped because of plugins error`, "error", { + data: l, + error: h, + }), + (l = this.composeStubDataForTool(r, l, c)), + (r = o.stubTool), + (u = i.composeBlock({ id: c, tool: r, data: l, tunes: a })); + } + return u; + }); + i.insertMany(s); + } + window.requestIdleCallback( + () => { + t(); + }, + { timeout: 2e3 }, + ); + }); + } + composeStubDataForTool(e, t, o) { + const { Tools: i } = this.Editor; + let s = e; + if (i.unavailable.has(e)) { + const r = i.unavailable.get(e).toolbox; + r !== void 0 && r[0].title !== void 0 && (s = r[0].title); + } + return { savedData: { id: o, type: e, data: t }, title: s }; + } + } + class ss extends y { + async save() { + const { BlockManager: e, Tools: t } = this.Editor, + o = e.blocks, + i = []; + try { + o.forEach((l) => { + i.push(this.getSavedData(l)); + }); + const s = await Promise.all(i), + r = await qe(s, (l) => t.blockTools.get(l).sanitizeConfig); + return this.makeOutput(r); + } catch (s) { + X("Saving failed due to the Error %o", "error", s); + } + } + async getSavedData(e) { + const t = await e.save(), + o = t && (await e.validate(t.data)); + return { ...t, isValid: o }; + } + makeOutput(e) { + const t = []; + return ( + e.forEach(({ id: o, tool: i, data: s, tunes: r, isValid: l }) => { + if (!l) { + C(`Block «${i}» skipped because saved data is invalid`); + return; + } + if (i === this.Editor.Tools.stubTool) { + t.push(s); + return; + } + const a = { id: o, type: i, data: s, ...(!V(r) && { tunes: r }) }; + t.push(a); + }), + { time: +new Date(), blocks: t, version: "2.30.6" } + ); + } + } + (function () { + try { + if (typeof document < "u") { + var n = document.createElement("style"); + n.appendChild( + document.createTextNode( + ".ce-paragraph{line-height:1.6em;outline:none}.ce-block:only-of-type .ce-paragraph[data-placeholder-active]:empty:before,.ce-block:only-of-type .ce-paragraph[data-placeholder-active][data-empty=true]:before{content:attr(data-placeholder-active)}.ce-paragraph p:first-of-type{margin-top:0}.ce-paragraph p:last-of-type{margin-bottom:0}", + ), + ), + document.head.appendChild(n); + } + } catch (e) { + console.error("vite-plugin-css-injected-by-js", e); + } + })(); + const ns = + ''; + function rs(n) { + const e = document.createElement("div"); + e.innerHTML = n.trim(); + const t = document.createDocumentFragment(); + return t.append(...Array.from(e.childNodes)), t; + } + /** + * Base Paragraph Block for the Editor.js. + * Represents a regular text block + * + * @author CodeX (team@codex.so) + * @copyright CodeX 2018 + * @license The MIT License (MIT) + */ class ht { + static get DEFAULT_PLACEHOLDER() { + return ""; + } + constructor({ data: e, config: t, api: o, readOnly: i }) { + (this.api = o), + (this.readOnly = i), + (this._CSS = { block: this.api.styles.block, wrapper: "ce-paragraph" }), + this.readOnly || (this.onKeyUp = this.onKeyUp.bind(this)), + (this._placeholder = t.placeholder + ? t.placeholder + : ht.DEFAULT_PLACEHOLDER), + (this._data = e ?? {}), + (this._element = null), + (this._preserveBlank = t.preserveBlank ?? !1); + } + onKeyUp(e) { + if ((e.code !== "Backspace" && e.code !== "Delete") || !this._element) + return; + const { textContent: t } = this._element; + t === "" && (this._element.innerHTML = ""); + } + drawView() { + const e = document.createElement("DIV"); + return ( + e.classList.add(this._CSS.wrapper, this._CSS.block), + (e.contentEditable = "false"), + (e.dataset.placeholderActive = this.api.i18n.t(this._placeholder)), + this._data.text && (e.innerHTML = this._data.text), + this.readOnly || + ((e.contentEditable = "true"), + e.addEventListener("keyup", this.onKeyUp)), + e + ); + } + render() { + return (this._element = this.drawView()), this._element; + } + merge(e) { + if (!this._element) return; + this._data.text += e.text; + const t = rs(e.text); + this._element.appendChild(t), this._element.normalize(); + } + validate(e) { + return !(e.text.trim() === "" && !this._preserveBlank); + } + save(e) { + return { text: e.innerHTML }; + } + onPaste(e) { + const t = { text: e.detail.data.innerHTML }; + (this._data = t), + window.requestAnimationFrame(() => { + this._element && (this._element.innerHTML = this._data.text || ""); + }); + } + static get conversionConfig() { + return { export: "text", import: "text" }; + } + static get sanitize() { + return { text: { br: !0 } }; + } + static get isReadOnlySupported() { + return !0; + } + static get pasteConfig() { + return { tags: ["P"] }; + } + static get toolbox() { + return { icon: ns, title: "Text" }; + } + } + class ut { + constructor() { + this.commandName = "bold"; + } + static get sanitize() { + return { b: {} }; + } + render() { + return { + icon: hi, + name: "bold", + onActivate: () => { + document.execCommand(this.commandName); + }, + isActive: () => document.queryCommandState(this.commandName), + }; + } + get shortcut() { + return "CMD+B"; + } + } + (ut.isInline = !0), (ut.title = "Bold"); + class pt { + constructor() { + (this.commandName = "italic"), + (this.CSS = { + button: "ce-inline-tool", + buttonActive: "ce-inline-tool--active", + buttonModifier: "ce-inline-tool--italic", + }), + (this.nodes = { button: null }); + } + static get sanitize() { + return { i: {} }; + } + render() { + return ( + (this.nodes.button = document.createElement("button")), + (this.nodes.button.type = "button"), + this.nodes.button.classList.add( + this.CSS.button, + this.CSS.buttonModifier, + ), + (this.nodes.button.innerHTML = ki), + this.nodes.button + ); + } + surround() { + document.execCommand(this.commandName); + } + checkState() { + const e = document.queryCommandState(this.commandName); + return this.nodes.button.classList.toggle(this.CSS.buttonActive, e), e; + } + get shortcut() { + return "CMD+I"; + } + } + (pt.isInline = !0), (pt.title = "Italic"); + class ft { + constructor({ api: e }) { + (this.commandLink = "createLink"), + (this.commandUnlink = "unlink"), + (this.ENTER_KEY = 13), + (this.CSS = { + button: "ce-inline-tool", + buttonActive: "ce-inline-tool--active", + buttonModifier: "ce-inline-tool--link", + buttonUnlink: "ce-inline-tool--unlink", + input: "ce-inline-tool-input", + inputShowed: "ce-inline-tool-input--showed", + }), + (this.nodes = { button: null, input: null }), + (this.inputOpened = !1), + (this.toolbar = e.toolbar), + (this.inlineToolbar = e.inlineToolbar), + (this.notifier = e.notifier), + (this.i18n = e.i18n), + (this.selection = new m()); + } + static get sanitize() { + return { a: { href: !0, target: "_blank", rel: "nofollow" } }; + } + render() { + return ( + (this.nodes.button = document.createElement("button")), + (this.nodes.button.type = "button"), + this.nodes.button.classList.add( + this.CSS.button, + this.CSS.buttonModifier, + ), + (this.nodes.button.innerHTML = zt), + this.nodes.button + ); + } + renderActions() { + return ( + (this.nodes.input = document.createElement("input")), + (this.nodes.input.placeholder = this.i18n.t("Add a link")), + (this.nodes.input.enterKeyHint = "done"), + this.nodes.input.classList.add(this.CSS.input), + this.nodes.input.addEventListener("keydown", (e) => { + e.keyCode === this.ENTER_KEY && this.enterPressed(e); + }), + this.nodes.input + ); + } + surround(e) { + if (e) { + this.inputOpened + ? (this.selection.restore(), this.selection.removeFakeBackground()) + : (this.selection.setFakeBackground(), this.selection.save()); + const t = this.selection.findParentTag("A"); + if (t) { + this.selection.expandToTag(t), + this.unlink(), + this.closeActions(), + this.checkState(), + this.toolbar.close(); + return; + } + } + this.toggleActions(); + } + checkState() { + const e = this.selection.findParentTag("A"); + if (e) { + (this.nodes.button.innerHTML = yi), + this.nodes.button.classList.add(this.CSS.buttonUnlink), + this.nodes.button.classList.add(this.CSS.buttonActive), + this.openActions(); + const t = e.getAttribute("href"); + (this.nodes.input.value = t !== "null" ? t : ""), this.selection.save(); + } else + (this.nodes.button.innerHTML = zt), + this.nodes.button.classList.remove(this.CSS.buttonUnlink), + this.nodes.button.classList.remove(this.CSS.buttonActive); + return !!e; + } + clear() { + this.closeActions(); + } + get shortcut() { + return "CMD+K"; + } + toggleActions() { + this.inputOpened ? this.closeActions(!1) : this.openActions(!0); + } + openActions(e = !1) { + this.nodes.input.classList.add(this.CSS.inputShowed), + e && this.nodes.input.focus(), + (this.inputOpened = !0); + } + closeActions(e = !0) { + if (this.selection.isFakeBackgroundEnabled) { + const t = new m(); + t.save(), + this.selection.restore(), + this.selection.removeFakeBackground(), + t.restore(); + } + this.nodes.input.classList.remove(this.CSS.inputShowed), + (this.nodes.input.value = ""), + e && this.selection.clearSaved(), + (this.inputOpened = !1); + } + enterPressed(e) { + let t = this.nodes.input.value || ""; + if (!t.trim()) { + this.selection.restore(), + this.unlink(), + e.preventDefault(), + this.closeActions(); + return; + } + if (!this.validateURL(t)) { + this.notifier.show({ + message: "Pasted link is not valid.", + style: "error", + }), + C("Incorrect Link pasted", "warn", t); + return; + } + (t = this.prepareLink(t)), + this.selection.restore(), + this.selection.removeFakeBackground(), + this.insertLink(t), + e.preventDefault(), + e.stopPropagation(), + e.stopImmediatePropagation(), + this.selection.collapseToEnd(), + this.inlineToolbar.close(); + } + validateURL(e) { + return !/\s/.test(e); + } + prepareLink(e) { + return (e = e.trim()), (e = this.addProtocol(e)), e; + } + addProtocol(e) { + if (/^(\w+):(\/\/)?/.test(e)) return e; + const t = /^\/[^/\s]/.test(e), + o = e.substring(0, 1) === "#", + i = /^\/\/[^/\s]/.test(e); + return !t && !o && !i && (e = "http://" + e), e; + } + insertLink(e) { + const t = this.selection.findParentTag("A"); + t && this.selection.expandToTag(t), + document.execCommand(this.commandLink, !1, e); + } + unlink() { + document.execCommand(this.commandUnlink); + } + } + (ft.isInline = !0), (ft.title = "Link"); + class no { + constructor({ api: e }) { + (this.i18nAPI = e.i18n), + (this.blocksAPI = e.blocks), + (this.selectionAPI = e.selection), + (this.toolsAPI = e.tools), + (this.caretAPI = e.caret); + } + async render() { + const e = m.get(), + t = this.blocksAPI.getBlockByElement(e.anchorNode); + if (t === void 0) return []; + const o = this.toolsAPI.getBlockTools(), + i = await Lt(t, o); + if (i.length === 0) return []; + const s = i.reduce((c, u) => { + var h; + return ( + (h = u.toolbox) == null || + h.forEach((p) => { + c.push({ + icon: p.icon, + title: H.t($.toolNames, p.title), + name: u.name, + closeOnActivate: !0, + onActivate: async () => { + const g = await this.blocksAPI.convert( + t.id, + u.name, + p.data, + ); + this.caretAPI.setToBlock(g, "end"); + }, + }); + }), + c + ); + }, []), + r = await t.getActiveToolboxEntry(), + l = r !== void 0 ? r.icon : Ut, + a = !de(); + return { + icon: l, + name: "convert-to", + hint: { title: this.i18nAPI.t("Convert to") }, + children: { + searchable: a, + items: s, + onOpen: () => { + a && + (this.selectionAPI.setFakeBackground(), this.selectionAPI.save()); + }, + onClose: () => { + a && + (this.selectionAPI.restore(), + this.selectionAPI.removeFakeBackground()); + }, + }, + }; + } + } + no.isInline = !0; + class ro { + constructor({ data: e, api: t }) { + (this.CSS = { + wrapper: "ce-stub", + info: "ce-stub__info", + title: "ce-stub__title", + subtitle: "ce-stub__subtitle", + }), + (this.api = t), + (this.title = e.title || this.api.i18n.t("Error")), + (this.subtitle = this.api.i18n.t( + "The block can not be displayed correctly.", + )), + (this.savedData = e.savedData), + (this.wrapper = this.make()); + } + render() { + return this.wrapper; + } + save() { + return this.savedData; + } + make() { + const e = d.make("div", this.CSS.wrapper), + t = Ei, + o = d.make("div", this.CSS.info), + i = d.make("div", this.CSS.title, { textContent: this.title }), + s = d.make("div", this.CSS.subtitle, { textContent: this.subtitle }); + return ( + (e.innerHTML = t), + o.appendChild(i), + o.appendChild(s), + e.appendChild(o), + e + ); + } + } + ro.isReadOnlySupported = !0; + class ls extends ct { + constructor() { + super(...arguments), (this.type = re.Inline); + } + get title() { + return this.constructable[lt.Title]; + } + create() { + return new this.constructable({ api: this.api, config: this.settings }); + } + } + class as extends ct { + constructor() { + super(...arguments), (this.type = re.Tune); + } + create(e, t) { + return new this.constructable({ + api: this.api, + config: this.settings, + block: t, + data: e, + }); + } + } + class F extends Map { + get blockTools() { + const e = Array.from(this.entries()).filter(([, t]) => t.isBlock()); + return new F(e); + } + get inlineTools() { + const e = Array.from(this.entries()).filter(([, t]) => t.isInline()); + return new F(e); + } + get blockTunes() { + const e = Array.from(this.entries()).filter(([, t]) => t.isTune()); + return new F(e); + } + get internalTools() { + const e = Array.from(this.entries()).filter(([, t]) => t.isInternal); + return new F(e); + } + get externalTools() { + const e = Array.from(this.entries()).filter(([, t]) => !t.isInternal); + return new F(e); + } + } + var cs = Object.defineProperty, + ds = Object.getOwnPropertyDescriptor, + lo = (n, e, t, o) => { + for ( + var i = o > 1 ? void 0 : o ? ds(e, t) : e, s = n.length - 1, r; + s >= 0; + s-- + ) + (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i); + return o && i && cs(e, t, i), i; + }; + class gt extends ct { + constructor() { + super(...arguments), + (this.type = re.Block), + (this.inlineTools = new F()), + (this.tunes = new F()); + } + create(e, t, o) { + return new this.constructable({ + data: e, + block: t, + readOnly: o, + api: this.api, + config: this.settings, + }); + } + get isReadOnlySupported() { + return this.constructable[pe.IsReadOnlySupported] === !0; + } + get isLineBreaksEnabled() { + return this.constructable[pe.IsEnabledLineBreaks]; + } + get toolbox() { + const e = this.constructable[pe.Toolbox], + t = this.config[De.Toolbox]; + if (!V(e) && t !== !1) + return t + ? Array.isArray(e) + ? Array.isArray(t) + ? t.map((o, i) => { + const s = e[i]; + return s ? { ...s, ...o } : o; + }) + : [t] + : Array.isArray(t) + ? t + : [{ ...e, ...t }] + : Array.isArray(e) + ? e + : [e]; + } + get conversionConfig() { + return this.constructable[pe.ConversionConfig]; + } + get enabledInlineTools() { + return this.config[De.EnabledInlineTools] || !1; + } + get enabledBlockTunes() { + return this.config[De.EnabledBlockTunes]; + } + get pasteConfig() { + return this.constructable[pe.PasteConfig] ?? {}; + } + get sanitizeConfig() { + const e = super.sanitizeConfig, + t = this.baseSanitizeConfig; + if (V(e)) return t; + const o = {}; + for (const i in e) + if (Object.prototype.hasOwnProperty.call(e, i)) { + const s = e[i]; + P(s) ? (o[i] = Object.assign({}, t, s)) : (o[i] = s); + } + return o; + } + get baseSanitizeConfig() { + const e = {}; + return ( + Array.from(this.inlineTools.values()).forEach((t) => + Object.assign(e, t.sanitizeConfig), + ), + Array.from(this.tunes.values()).forEach((t) => + Object.assign(e, t.sanitizeConfig), + ), + e + ); + } + } + lo([ce], gt.prototype, "sanitizeConfig", 1), + lo([ce], gt.prototype, "baseSanitizeConfig", 1); + class hs { + constructor(e, t, o) { + (this.api = o), (this.config = e), (this.editorConfig = t); + } + get(e) { + const { class: t, isInternal: o = !1, ...i } = this.config[e], + s = this.getConstructor(t), + r = t[at.IsTune]; + return new s({ + name: e, + constructable: t, + config: i, + api: this.api.getMethodsForTool(e, r), + isDefault: e === this.editorConfig.defaultBlock, + defaultPlaceholder: this.editorConfig.placeholder, + isInternal: o, + }); + } + getConstructor(e) { + switch (!0) { + case e[lt.IsInline]: + return ls; + case e[at.IsTune]: + return as; + default: + return gt; + } + } + } + class ao { + constructor({ api: e }) { + (this.CSS = { animation: "wobble" }), (this.api = e); + } + render() { + return { + icon: ui, + title: this.api.i18n.t("Move down"), + onActivate: () => this.handleClick(), + name: "move-down", + }; + } + handleClick() { + const e = this.api.blocks.getCurrentBlockIndex(), + t = this.api.blocks.getBlockByIndex(e + 1); + if (!t) + throw new Error( + "Unable to move Block down since it is already the last", + ); + const o = t.holder, + i = o.getBoundingClientRect(); + let s = Math.abs(window.innerHeight - o.offsetHeight); + i.top < window.innerHeight && (s = window.scrollY + o.offsetHeight), + window.scrollTo(0, s), + this.api.blocks.move(e + 1), + this.api.toolbar.toggleBlockSettings(!0); + } + } + ao.isTune = !0; + class co { + constructor({ api: e }) { + this.api = e; + } + render() { + return { + icon: mi, + title: this.api.i18n.t("Delete"), + name: "delete", + confirmation: { + title: this.api.i18n.t("Click to delete"), + onActivate: () => this.handleClick(), + }, + }; + } + handleClick() { + this.api.blocks.delete(); + } + } + co.isTune = !0; + class ho { + constructor({ api: e }) { + (this.CSS = { animation: "wobble" }), (this.api = e); + } + render() { + return { + icon: gi, + title: this.api.i18n.t("Move up"), + onActivate: () => this.handleClick(), + name: "move-up", + }; + } + handleClick() { + const e = this.api.blocks.getCurrentBlockIndex(), + t = this.api.blocks.getBlockByIndex(e), + o = this.api.blocks.getBlockByIndex(e - 1); + if (e === 0 || !t || !o) + throw new Error( + "Unable to move Block up since it is already the first", + ); + const i = t.holder, + s = o.holder, + r = i.getBoundingClientRect(), + l = s.getBoundingClientRect(); + let a; + l.top > 0 + ? (a = Math.abs(r.top) - Math.abs(l.top)) + : (a = Math.abs(r.top) + l.height), + window.scrollBy(0, -1 * a), + this.api.blocks.move(e - 1), + this.api.toolbar.toggleBlockSettings(!0); + } + } + ho.isTune = !0; + var us = Object.defineProperty, + ps = Object.getOwnPropertyDescriptor, + fs = (n, e, t, o) => { + for ( + var i = o > 1 ? void 0 : o ? ps(e, t) : e, s = n.length - 1, r; + s >= 0; + s-- + ) + (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i); + return o && i && us(e, t, i), i; + }; + class uo extends y { + constructor() { + super(...arguments), + (this.stubTool = "stub"), + (this.toolsAvailable = new F()), + (this.toolsUnavailable = new F()); + } + get available() { + return this.toolsAvailable; + } + get unavailable() { + return this.toolsUnavailable; + } + get inlineTools() { + return this.available.inlineTools; + } + get blockTools() { + return this.available.blockTools; + } + get blockTunes() { + return this.available.blockTunes; + } + get defaultTool() { + return this.blockTools.get(this.config.defaultBlock); + } + get internal() { + return this.available.internalTools; + } + async prepare() { + if ( + (this.validateTools(), + (this.config.tools = je({}, this.internalTools, this.config.tools)), + !Object.prototype.hasOwnProperty.call(this.config, "tools") || + Object.keys(this.config.tools).length === 0) + ) + throw Error("Can't start without tools"); + const e = this.prepareConfig(); + this.factory = new hs(e, this.config, this.Editor.API); + const t = this.getListOfPrepareFunctions(e); + if (t.length === 0) return Promise.resolve(); + await xo( + t, + (o) => { + this.toolPrepareMethodSuccess(o); + }, + (o) => { + this.toolPrepareMethodFallback(o); + }, + ), + this.prepareBlockTools(); + } + getAllInlineToolsSanitizeConfig() { + const e = {}; + return ( + Array.from(this.inlineTools.values()).forEach((t) => { + Object.assign(e, t.sanitizeConfig); + }), + e + ); + } + destroy() { + Object.values(this.available).forEach(async (e) => { + O(e.reset) && (await e.reset()); + }); + } + get internalTools() { + return { + convertTo: { class: no, isInternal: !0 }, + link: { class: ft, isInternal: !0 }, + bold: { class: ut, isInternal: !0 }, + italic: { class: pt, isInternal: !0 }, + paragraph: { class: ht, inlineToolbar: !0, isInternal: !0 }, + stub: { class: ro, isInternal: !0 }, + moveUp: { class: ho, isInternal: !0 }, + delete: { class: co, isInternal: !0 }, + moveDown: { class: ao, isInternal: !0 }, + }; + } + toolPrepareMethodSuccess(e) { + const t = this.factory.get(e.toolName); + if (t.isInline()) { + const i = ["render"].filter((s) => !t.create()[s]); + if (i.length) { + C( + `Incorrect Inline Tool: ${t.name}. Some of required methods is not implemented %o`, + "warn", + i, + ), + this.toolsUnavailable.set(t.name, t); + return; + } + } + this.toolsAvailable.set(t.name, t); + } + toolPrepareMethodFallback(e) { + this.toolsUnavailable.set(e.toolName, this.factory.get(e.toolName)); + } + getListOfPrepareFunctions(e) { + const t = []; + return ( + Object.entries(e).forEach(([o, i]) => { + t.push({ + function: O(i.class.prepare) ? i.class.prepare : () => {}, + data: { toolName: o, config: i.config }, + }); + }), + t + ); + } + prepareBlockTools() { + Array.from(this.blockTools.values()).forEach((e) => { + this.assignInlineToolsToBlockTool(e), + this.assignBlockTunesToBlockTool(e); + }); + } + assignInlineToolsToBlockTool(e) { + if (this.config.inlineToolbar !== !1) { + if (e.enabledInlineTools === !0) { + e.inlineTools = new F( + Array.isArray(this.config.inlineToolbar) + ? this.config.inlineToolbar.map((t) => [ + t, + this.inlineTools.get(t), + ]) + : Array.from(this.inlineTools.entries()), + ); + return; + } + Array.isArray(e.enabledInlineTools) && + (e.inlineTools = new F( + ["convertTo", ...e.enabledInlineTools].map((t) => [ + t, + this.inlineTools.get(t), + ]), + )); + } + } + assignBlockTunesToBlockTool(e) { + if (e.enabledBlockTunes !== !1) { + if (Array.isArray(e.enabledBlockTunes)) { + const t = new F( + e.enabledBlockTunes.map((o) => [o, this.blockTunes.get(o)]), + ); + e.tunes = new F([...t, ...this.blockTunes.internalTools]); + return; + } + if (Array.isArray(this.config.tunes)) { + const t = new F( + this.config.tunes.map((o) => [o, this.blockTunes.get(o)]), + ); + e.tunes = new F([...t, ...this.blockTunes.internalTools]); + return; + } + e.tunes = this.blockTunes.internalTools; + } + } + validateTools() { + for (const e in this.config.tools) + if (Object.prototype.hasOwnProperty.call(this.config.tools, e)) { + if (e in this.internalTools) return; + const t = this.config.tools[e]; + if (!O(t) && !O(t.class)) + throw Error( + `Tool «${e}» must be a constructor function or an object with function in the «class» property`, + ); + } + } + prepareConfig() { + const e = {}; + for (const t in this.config.tools) + P(this.config.tools[t]) + ? (e[t] = this.config.tools[t]) + : (e[t] = { class: this.config.tools[t] }); + return e; + } + } + fs([ce], uo.prototype, "getAllInlineToolsSanitizeConfig", 1); + const gs = `:root{--selectionColor: #e1f2ff;--inlineSelectionColor: #d4ecff;--bg-light: #eff2f5;--grayText: #707684;--color-dark: #1D202B;--color-active-icon: #388AE5;--color-gray-border: rgba(201, 201, 204, .48);--content-width: 650px;--narrow-mode-right-padding: 50px;--toolbox-buttons-size: 26px;--toolbox-buttons-size--mobile: 36px;--icon-size: 20px;--icon-size--mobile: 28px;--block-padding-vertical: .4em;--color-line-gray: #EFF0F1 }.codex-editor{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;z-index:1}.codex-editor .hide{display:none}.codex-editor__redactor [contenteditable]:empty:after{content:"\\feff"}@media (min-width: 651px){.codex-editor--narrow .codex-editor__redactor{margin-right:50px}}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .codex-editor__redactor{margin-left:50px;margin-right:0}}@media (min-width: 651px){.codex-editor--narrow .ce-toolbar__actions{right:-5px}}.codex-editor-copyable{position:absolute;height:1px;width:1px;top:-400%;opacity:.001}.codex-editor-overlay{position:fixed;top:0;left:0;right:0;bottom:0;z-index:999;pointer-events:none;overflow:hidden}.codex-editor-overlay__container{position:relative;pointer-events:auto;z-index:0}.codex-editor-overlay__rectangle{position:absolute;pointer-events:none;background-color:#2eaadc33;border:1px solid transparent}.codex-editor svg{max-height:100%}.codex-editor path{stroke:currentColor}.codex-editor ::-moz-selection{background-color:#d4ecff}.codex-editor ::selection{background-color:#d4ecff}.codex-editor--toolbox-opened [contentEditable=true][data-placeholder]:focus:before{opacity:0!important}.ce-scroll-locked{overflow:hidden}.ce-scroll-locked--hard{overflow:hidden;top:calc(-1 * var(--window-scroll-offset));position:fixed;width:100%}.ce-toolbar{position:absolute;left:0;right:0;top:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;will-change:opacity,top;display:none}.ce-toolbar--opened{display:block}.ce-toolbar__content{max-width:650px;margin:0 auto;position:relative}.ce-toolbar__plus{color:#1d202b;cursor:pointer;width:26px;height:26px;border-radius:7px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-flex-negative:0;flex-shrink:0}@media (max-width: 650px){.ce-toolbar__plus{width:36px;height:36px}}@media (hover: hover){.ce-toolbar__plus:hover{background-color:#eff2f5}}.ce-toolbar__plus--active{background-color:#eff2f5;-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.ce-toolbar__plus-shortcut{opacity:.6;word-spacing:-2px;margin-top:5px}@media (max-width: 650px){.ce-toolbar__plus{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;position:static}.ce-toolbar__plus--left-oriented:before{left:15px;margin-left:0}.ce-toolbar__plus--right-oriented:before{left:auto;right:15px;margin-left:0}}.ce-toolbar__actions{position:absolute;right:100%;opacity:0;display:-webkit-box;display:-ms-flexbox;display:flex;padding-right:5px}.ce-toolbar__actions--opened{opacity:1}@media (max-width: 650px){.ce-toolbar__actions{right:auto}}.ce-toolbar__settings-btn{color:#1d202b;width:26px;height:26px;border-radius:7px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;margin-left:3px;cursor:pointer;user-select:none}@media (max-width: 650px){.ce-toolbar__settings-btn{width:36px;height:36px}}@media (hover: hover){.ce-toolbar__settings-btn:hover{background-color:#eff2f5}}.ce-toolbar__settings-btn--active{background-color:#eff2f5;-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@media (min-width: 651px){.ce-toolbar__settings-btn{width:24px}}.ce-toolbar__settings-btn--hidden{display:none}@media (max-width: 650px){.ce-toolbar__settings-btn{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;position:static}.ce-toolbar__settings-btn--left-oriented:before{left:15px;margin-left:0}.ce-toolbar__settings-btn--right-oriented:before{left:auto;right:15px;margin-left:0}}.ce-toolbar__plus svg,.ce-toolbar__settings-btn svg{width:24px;height:24px}@media (min-width: 651px){.codex-editor--narrow .ce-toolbar__plus{left:5px}}@media (min-width: 651px){.codex-editor--narrow .ce-toolbox .ce-popover{right:0;left:auto;left:initial}}.ce-inline-toolbar{--y-offset: 8px;--color-background-icon-active: rgba(56, 138, 229, .1);--color-text-icon-active: #388AE5;--color-text-primary: black;position:absolute;visibility:hidden;-webkit-transition:opacity .25s ease;transition:opacity .25s ease;will-change:opacity,left,top;top:0;left:0;z-index:3;opacity:1;visibility:visible}.ce-inline-toolbar [hidden]{display:none!important}.ce-inline-toolbar__toggler-and-button-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;padding:0 6px}.ce-inline-toolbar__buttons{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-inline-toolbar__dropdown{display:-webkit-box;display:-ms-flexbox;display:flex;padding:6px;margin:0 6px 0 -6px;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border-right:1px solid rgba(201,201,204,.48);-webkit-box-sizing:border-box;box-sizing:border-box}@media (hover: hover){.ce-inline-toolbar__dropdown:hover{background:#eff2f5}}.ce-inline-toolbar__dropdown--hidden{display:none}.ce-inline-toolbar__dropdown-content,.ce-inline-toolbar__dropdown-arrow{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-inline-toolbar__dropdown-content svg,.ce-inline-toolbar__dropdown-arrow svg{width:20px;height:20px}.ce-inline-toolbar__shortcut{opacity:.6;word-spacing:-3px;margin-top:3px}.ce-inline-tool{color:var(--color-text-primary);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:0;border-radius:4px;line-height:normal;height:100%;padding:0;width:28px;background-color:transparent;cursor:pointer}@media (max-width: 650px){.ce-inline-tool{width:36px;height:36px}}@media (hover: hover){.ce-inline-tool:hover{background-color:#f8f8f8}}.ce-inline-tool svg{display:block;width:20px;height:20px}@media (max-width: 650px){.ce-inline-tool svg{width:28px;height:28px}}.ce-inline-tool--link .icon--unlink,.ce-inline-tool--unlink .icon--link{display:none}.ce-inline-tool--unlink .icon--unlink{display:inline-block;margin-bottom:-1px}.ce-inline-tool-input{background:#F8F8F8;border:1px solid rgba(226,226,229,.2);border-radius:6px;padding:4px 8px;font-size:14px;line-height:22px;outline:none;margin:0;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;display:none;font-weight:500;-webkit-appearance:none;font-family:inherit}@media (max-width: 650px){.ce-inline-tool-input{font-size:15px;font-weight:500}}.ce-inline-tool-input::-webkit-input-placeholder{color:#707684}.ce-inline-tool-input::-moz-placeholder{color:#707684}.ce-inline-tool-input:-ms-input-placeholder{color:#707684}.ce-inline-tool-input::-ms-input-placeholder{color:#707684}.ce-inline-tool-input::placeholder{color:#707684}.ce-inline-tool-input--showed{display:block}.ce-inline-tool--active{background:var(--color-background-icon-active);color:var(--color-text-icon-active)}@-webkit-keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.ce-block{-webkit-animation:fade-in .3s ease;animation:fade-in .3s ease;-webkit-animation-fill-mode:none;animation-fill-mode:none;-webkit-animation-fill-mode:initial;animation-fill-mode:initial}.ce-block:first-of-type{margin-top:0}.ce-block--selected .ce-block__content{background:#e1f2ff}.ce-block--selected .ce-block__content [contenteditable]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ce-block--selected .ce-block__content img,.ce-block--selected .ce-block__content .ce-stub{opacity:.55}.ce-block--stretched .ce-block__content{max-width:none}.ce-block__content{position:relative;max-width:650px;margin:0 auto;-webkit-transition:background-color .15s ease;transition:background-color .15s ease}.ce-block--drop-target .ce-block__content:before{content:"";position:absolute;top:100%;left:-20px;margin-top:-1px;height:8px;width:8px;border:solid #388AE5;border-width:1px 1px 0 0;-webkit-transform-origin:right;transform-origin:right;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ce-block--drop-target .ce-block__content:after{content:"";position:absolute;top:100%;height:1px;width:100%;color:#388ae5;background:repeating-linear-gradient(90deg,#388AE5,#388AE5 1px,#fff 1px,#fff 6px)}.ce-block a{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline}.ce-block b{font-weight:700}.ce-block i{font-style:italic}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}20%{-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}60%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}20%{-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}60%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@-webkit-keyframes selectionBounce{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}50%{-webkit-transform:scale3d(1.01,1.01,1.01);transform:scale3d(1.01,1.01,1.01)}70%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes selectionBounce{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}50%{-webkit-transform:scale3d(1.01,1.01,1.01);transform:scale3d(1.01,1.01,1.01)}70%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@-webkit-keyframes buttonClicked{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.95,.95,.95);transform:scale3d(.95,.95,.95)}60%{-webkit-transform:scale3d(1.02,1.02,1.02);transform:scale3d(1.02,1.02,1.02)}80%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes buttonClicked{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.95,.95,.95);transform:scale3d(.95,.95,.95)}60%{-webkit-transform:scale3d(1.02,1.02,1.02);transform:scale3d(1.02,1.02,1.02)}80%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}.cdx-block{padding:.4em 0}.cdx-block::-webkit-input-placeholder{line-height:normal!important}.cdx-input{border:1px solid rgba(201,201,204,.48);-webkit-box-shadow:inset 0 1px 2px 0 rgba(35,44,72,.06);box-shadow:inset 0 1px 2px #232c480f;border-radius:3px;padding:10px 12px;outline:none;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.cdx-input[data-placeholder]:before{position:static!important}.cdx-input[data-placeholder]:before{display:inline-block;width:0;white-space:nowrap;pointer-events:none}.cdx-settings-button{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border-radius:3px;cursor:pointer;border:0;outline:none;background-color:transparent;vertical-align:bottom;color:inherit;margin:0;min-width:26px;min-height:26px}.cdx-settings-button--focused{background:rgba(34,186,255,.08)!important}.cdx-settings-button--focused{-webkit-box-shadow:inset 0 0 0px 1px rgba(7,161,227,.08);box-shadow:inset 0 0 0 1px #07a1e314}.cdx-settings-button--focused-animated{-webkit-animation-name:buttonClicked;animation-name:buttonClicked;-webkit-animation-duration:.25s;animation-duration:.25s}.cdx-settings-button--active{color:#388ae5}.cdx-settings-button svg{width:auto;height:auto}@media (max-width: 650px){.cdx-settings-button svg{width:28px;height:28px}}@media (max-width: 650px){.cdx-settings-button{width:36px;height:36px;border-radius:8px}}@media (hover: hover){.cdx-settings-button:hover{background-color:#eff2f5}}.cdx-loader{position:relative;border:1px solid rgba(201,201,204,.48)}.cdx-loader:before{content:"";position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-11px 0 0 -11px;border:2px solid rgba(201,201,204,.48);border-left-color:#388ae5;border-radius:50%;-webkit-animation:cdxRotation 1.2s infinite linear;animation:cdxRotation 1.2s infinite linear}@-webkit-keyframes cdxRotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes cdxRotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cdx-button{padding:13px;border-radius:3px;border:1px solid rgba(201,201,204,.48);font-size:14.9px;background:#fff;-webkit-box-shadow:0 2px 2px 0 rgba(18,30,57,.04);box-shadow:0 2px 2px #121e390a;color:#707684;text-align:center;cursor:pointer}@media (hover: hover){.cdx-button:hover{background:#FBFCFE;-webkit-box-shadow:0 1px 3px 0 rgba(18,30,57,.08);box-shadow:0 1px 3px #121e3914}}.cdx-button svg{height:20px;margin-right:.2em;margin-top:-2px}.ce-stub{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:12px 18px;margin:10px 0;border-radius:10px;background:#eff2f5;border:1px solid #EFF0F1;color:#707684;font-size:14px}.ce-stub svg{width:20px;height:20px}.ce-stub__info{margin-left:14px}.ce-stub__title{font-weight:500;text-transform:capitalize}.codex-editor.codex-editor--rtl{direction:rtl}.codex-editor.codex-editor--rtl .cdx-list{padding-left:0;padding-right:40px}.codex-editor.codex-editor--rtl .ce-toolbar__plus{right:-26px;left:auto}.codex-editor.codex-editor--rtl .ce-toolbar__actions{right:auto;left:-26px}@media (max-width: 650px){.codex-editor.codex-editor--rtl .ce-toolbar__actions{margin-left:0;margin-right:auto;padding-right:0;padding-left:10px}}.codex-editor.codex-editor--rtl .ce-settings{left:5px;right:auto}.codex-editor.codex-editor--rtl .ce-settings:before{right:auto;left:25px}.codex-editor.codex-editor--rtl .ce-settings__button:not(:nth-child(3n+3)){margin-left:3px;margin-right:0}.codex-editor.codex-editor--rtl .ce-conversion-tool__icon{margin-right:0;margin-left:10px}.codex-editor.codex-editor--rtl .ce-inline-toolbar__dropdown{border-right:0px solid transparent;border-left:1px solid rgba(201,201,204,.48);margin:0 -6px 0 6px}.codex-editor.codex-editor--rtl .ce-inline-toolbar__dropdown .icon--toggler-down{margin-left:0;margin-right:4px}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .ce-toolbar__plus{left:0;right:5px}}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .ce-toolbar__actions{left:-5px}}.cdx-search-field{--icon-margin-right: 10px;background:#F8F8F8;border:1px solid rgba(226,226,229,.2);border-radius:6px;padding:2px;display:grid;grid-template-columns:auto auto 1fr;grid-template-rows:auto}.cdx-search-field__icon{width:26px;height:26px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-right:var(--icon-margin-right)}.cdx-search-field__icon svg{width:20px;height:20px;color:#707684}.cdx-search-field__input{font-size:14px;outline:none;font-weight:500;font-family:inherit;border:0;background:transparent;margin:0;padding:0;line-height:22px;min-width:calc(100% - 26px - var(--icon-margin-right))}.cdx-search-field__input::-webkit-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::-moz-placeholder{color:#707684;font-weight:500}.cdx-search-field__input:-ms-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::-ms-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::placeholder{color:#707684;font-weight:500}.ce-popover{--border-radius: 6px;--width: 200px;--max-height: 270px;--padding: 6px;--offset-from-target: 8px;--color-border: #EFF0F1;--color-shadow: rgba(13, 20, 33, .1);--color-background: white;--color-text-primary: black;--color-text-secondary: #707684;--color-border-icon: rgba(201, 201, 204, .48);--color-border-icon-disabled: #EFF0F1;--color-text-icon-active: #388AE5;--color-background-icon-active: rgba(56, 138, 229, .1);--color-background-item-focus: rgba(34, 186, 255, .08);--color-shadow-item-focus: rgba(7, 161, 227, .08);--color-background-item-hover: #F8F8F8;--color-background-item-confirm: #E24A4A;--color-background-item-confirm-hover: #CE4343;--popover-top: calc(100% + var(--offset-from-target));--popover-left: 0;--nested-popover-overlap: 4px;--icon-size: 20px;--item-padding: 3px;--item-height: calc(var(--icon-size) + 2 * var(--item-padding))}.ce-popover__container{min-width:var(--width);width:var(--width);max-height:var(--max-height);border-radius:var(--border-radius);overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0px 3px 15px -3px var(--color-shadow);box-shadow:0 3px 15px -3px var(--color-shadow);position:absolute;left:var(--popover-left);top:var(--popover-top);background:var(--color-background);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;z-index:4;opacity:0;max-height:0;pointer-events:none;padding:0;border:none}.ce-popover--opened>.ce-popover__container{opacity:1;padding:var(--padding);max-height:var(--max-height);pointer-events:auto;-webkit-animation:panelShowing .1s ease;animation:panelShowing .1s ease;border:1px solid var(--color-border)}@media (max-width: 650px){.ce-popover--opened>.ce-popover__container{-webkit-animation:panelShowingMobile .25s ease;animation:panelShowingMobile .25s ease}}.ce-popover--open-top .ce-popover__container{--popover-top: calc(-1 * (var(--offset-from-target) + var(--popover-height)))}.ce-popover--open-left .ce-popover__container{--popover-left: calc(-1 * var(--width) + 100%)}.ce-popover__items{overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:contain}@media (max-width: 650px){.ce-popover__overlay{position:fixed;top:0;bottom:0;left:0;right:0;background:#1D202B;z-index:3;opacity:.5;-webkit-transition:opacity .12s ease-in;transition:opacity .12s ease-in;will-change:opacity;visibility:visible}}.ce-popover__overlay--hidden{display:none}@media (max-width: 650px){.ce-popover .ce-popover__container{--offset: 5px;position:fixed;max-width:none;min-width:calc(100% - var(--offset) * 2);left:var(--offset);right:var(--offset);bottom:calc(var(--offset) + env(safe-area-inset-bottom));top:auto;border-radius:10px}}.ce-popover__search{margin-bottom:5px}.ce-popover__nothing-found-message{color:#707684;display:none;cursor:default;padding:3px;font-size:14px;line-height:20px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ce-popover__nothing-found-message--displayed{display:block}.ce-popover--nested .ce-popover__container{--popover-left: calc(var(--nesting-level) * (var(--width) - var(--nested-popover-overlap)));top:calc(var(--trigger-item-top) - var(--nested-popover-overlap));position:absolute}.ce-popover--open-top.ce-popover--nested .ce-popover__container{top:calc(var(--trigger-item-top) - var(--popover-height) + var(--item-height) + var(--offset-from-target) + var(--nested-popover-overlap))}.ce-popover--open-left .ce-popover--nested .ce-popover__container{--popover-left: calc(-1 * (var(--nesting-level) + 1) * var(--width) + 100%)}.ce-popover-item-separator{padding:4px 3px}.ce-popover-item-separator--hidden{display:none}.ce-popover-item-separator__line{height:1px;background:var(--color-border);width:100%}.ce-popover-item-html--hidden{display:none}.ce-popover-item{--border-radius: 6px;border-radius:var(--border-radius);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:var(--item-padding);color:var(--color-text-primary);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;background:transparent}@media (max-width: 650px){.ce-popover-item{padding:4px}}.ce-popover-item:not(:last-of-type){margin-bottom:1px}.ce-popover-item__icon{width:26px;height:26px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ce-popover-item__icon svg{width:20px;height:20px}@media (max-width: 650px){.ce-popover-item__icon{width:36px;height:36px;border-radius:8px}.ce-popover-item__icon svg{width:28px;height:28px}}.ce-popover-item__icon--tool{margin-right:4px}.ce-popover-item__title{font-size:14px;line-height:20px;font-weight:500;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-right:auto}@media (max-width: 650px){.ce-popover-item__title{font-size:16px}}.ce-popover-item__secondary-title{color:var(--color-text-secondary);font-size:12px;white-space:nowrap;letter-spacing:-.1em;padding-right:5px;opacity:.6}@media (max-width: 650px){.ce-popover-item__secondary-title{display:none}}.ce-popover-item--active{background:var(--color-background-icon-active);color:var(--color-text-icon-active)}.ce-popover-item--disabled{color:var(--color-text-secondary);cursor:default;pointer-events:none}.ce-popover-item--focused:not(.ce-popover-item--no-focus){background:var(--color-background-item-focus)!important}.ce-popover-item--hidden{display:none}@media (hover: hover){.ce-popover-item:hover{cursor:pointer}.ce-popover-item:hover:not(.ce-popover-item--no-hover){background-color:var(--color-background-item-hover)}}.ce-popover-item--confirmation{background:var(--color-background-item-confirm)}.ce-popover-item--confirmation .ce-popover-item__title,.ce-popover-item--confirmation .ce-popover-item__icon{color:#fff}@media (hover: hover){.ce-popover-item--confirmation:not(.ce-popover-item--no-hover):hover{background:var(--color-background-item-confirm-hover)}}.ce-popover-item--confirmation:not(.ce-popover-item--no-focus).ce-popover-item--focused{background:var(--color-background-item-confirm-hover)!important}@-webkit-keyframes panelShowing{0%{opacity:0;-webkit-transform:translateY(-8px) scale(.9);transform:translateY(-8px) scale(.9)}70%{opacity:1;-webkit-transform:translateY(2px);transform:translateY(2px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes panelShowing{0%{opacity:0;-webkit-transform:translateY(-8px) scale(.9);transform:translateY(-8px) scale(.9)}70%{opacity:1;-webkit-transform:translateY(2px);transform:translateY(2px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes panelShowingMobile{0%{opacity:0;-webkit-transform:translateY(14px) scale(.98);transform:translateY(14px) scale(.98)}70%{opacity:1;-webkit-transform:translateY(-4px);transform:translateY(-4px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes panelShowingMobile{0%{opacity:0;-webkit-transform:translateY(14px) scale(.98);transform:translateY(14px) scale(.98)}70%{opacity:1;-webkit-transform:translateY(-4px);transform:translateY(-4px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble;-webkit-animation-duration:.4s;animation-duration:.4s}@-webkit-keyframes wobble{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-9%,0,0);transform:translate3d(-9%,0,0)}30%{-webkit-transform:translate3d(9%,0,0);transform:translate3d(9%,0,0)}45%{-webkit-transform:translate3d(-4%,0,0);transform:translate3d(-4%,0,0)}60%{-webkit-transform:translate3d(4%,0,0);transform:translate3d(4%,0,0)}75%{-webkit-transform:translate3d(-1%,0,0);transform:translate3d(-1%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-9%,0,0);transform:translate3d(-9%,0,0)}30%{-webkit-transform:translate3d(9%,0,0);transform:translate3d(9%,0,0)}45%{-webkit-transform:translate3d(-4%,0,0);transform:translate3d(-4%,0,0)}60%{-webkit-transform:translate3d(4%,0,0);transform:translate3d(4%,0,0)}75%{-webkit-transform:translate3d(-1%,0,0);transform:translate3d(-1%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}.ce-popover-header{margin-bottom:8px;margin-top:4px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ce-popover-header__text{font-size:18px;font-weight:600}.ce-popover-header__back-button{border:0;background:transparent;width:36px;height:36px;color:var(--color-text-primary)}.ce-popover-header__back-button svg{display:block;width:28px;height:28px}.ce-popover--inline{--height: 38px;--height-mobile: 46px;--container-padding: 4px;position:relative}.ce-popover--inline .ce-popover__custom-content{margin-bottom:0}.ce-popover--inline .ce-popover__items{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-popover--inline .ce-popover__container{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;padding:var(--container-padding);height:var(--height);top:0;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;width:-webkit-max-content;width:-moz-max-content;width:max-content;-webkit-animation:none;animation:none}@media (max-width: 650px){.ce-popover--inline .ce-popover__container{height:var(--height-mobile);position:absolute}}.ce-popover--inline .ce-popover-item-separator{padding:0 4px}.ce-popover--inline .ce-popover-item-separator__line{height:100%;width:1px}.ce-popover--inline .ce-popover-item{border-radius:4px;padding:4px}.ce-popover--inline .ce-popover-item__icon--tool{-webkit-box-shadow:none;box-shadow:none;background:transparent;margin-right:0}.ce-popover--inline .ce-popover-item__icon{width:auto;width:initial;height:auto;height:initial}.ce-popover--inline .ce-popover-item__icon svg{width:20px;height:20px}@media (max-width: 650px){.ce-popover--inline .ce-popover-item__icon svg{width:28px;height:28px}}.ce-popover--inline .ce-popover-item:not(:last-of-type){margin-bottom:0;margin-bottom:initial}.ce-popover--inline .ce-popover-item-html{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ce-popover--inline .ce-popover-item__icon--chevron-right{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ce-popover--inline .ce-popover--nested-level-1 .ce-popover__container{--offset: 3px;left:0;top:calc(var(--height) + var(--offset))}@media (max-width: 650px){.ce-popover--inline .ce-popover--nested-level-1 .ce-popover__container{top:calc(var(--height-mobile) + var(--offset))}}.ce-popover--inline .ce-popover--nested .ce-popover__container{min-width:var(--width);width:var(--width);height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;padding:6px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ce-popover--inline .ce-popover--nested .ce-popover__items{display:block;width:100%}.ce-popover--inline .ce-popover--nested .ce-popover-item{border-radius:6px;padding:3px}@media (max-width: 650px){.ce-popover--inline .ce-popover--nested .ce-popover-item{padding:4px}}.ce-popover--inline .ce-popover--nested .ce-popover-item__icon--tool{margin-right:4px}.ce-popover--inline .ce-popover--nested .ce-popover-item__icon{width:26px;height:26px}.ce-popover--inline .ce-popover--nested .ce-popover-item-separator{padding:4px 3px}.ce-popover--inline .ce-popover--nested .ce-popover-item-separator__line{width:100%;height:1px}.codex-editor [data-placeholder]:empty:before,.codex-editor [data-placeholder][data-empty=true]:before{pointer-events:none;color:#707684;cursor:text;content:attr(data-placeholder)}.codex-editor [data-placeholder-active]:empty:before,.codex-editor [data-placeholder-active][data-empty=true]:before{pointer-events:none;color:#707684;cursor:text}.codex-editor [data-placeholder-active]:empty:focus:before,.codex-editor [data-placeholder-active][data-empty=true]:focus:before{content:attr(data-placeholder-active)} +`; + class ms extends y { + constructor() { + super(...arguments), + (this.isMobile = !1), + (this.contentRectCache = void 0), + (this.resizeDebouncer = yt(() => { + this.windowResize(); + }, 200)); + } + get CSS() { + return { + editorWrapper: "codex-editor", + editorWrapperNarrow: "codex-editor--narrow", + editorZone: "codex-editor__redactor", + editorZoneHidden: "codex-editor__redactor--hidden", + editorEmpty: "codex-editor--empty", + editorRtlFix: "codex-editor--rtl", + }; + } + get contentRect() { + if (this.contentRectCache) return this.contentRectCache; + const e = this.nodes.wrapper.querySelector(`.${D.CSS.content}`); + return e + ? ((this.contentRectCache = e.getBoundingClientRect()), + this.contentRectCache) + : { width: 650, left: 0, right: 0 }; + } + async prepare() { + this.setIsMobile(), this.make(), this.loadStyles(); + } + toggleReadOnly(e) { + e + ? this.disableModuleBindings() + : window.requestIdleCallback( + () => { + this.enableModuleBindings(); + }, + { timeout: 2e3 }, + ); + } + checkEmptiness() { + const { BlockManager: e } = this.Editor; + this.nodes.wrapper.classList.toggle( + this.CSS.editorEmpty, + e.isEditorEmpty, + ); + } + get someToolbarOpened() { + const { Toolbar: e, BlockSettings: t, InlineToolbar: o } = this.Editor; + return !!(t.opened || o.opened || e.toolbox.opened); + } + get someFlipperButtonFocused() { + return this.Editor.Toolbar.toolbox.hasFocus() + ? !0 + : Object.entries(this.Editor) + .filter(([e, t]) => t.flipper instanceof se) + .some(([e, t]) => t.flipper.hasFocus()); + } + destroy() { + this.nodes.holder.innerHTML = ""; + } + closeAllToolbars() { + const { Toolbar: e, BlockSettings: t, InlineToolbar: o } = this.Editor; + t.close(), o.close(), e.toolbox.close(); + } + setIsMobile() { + const e = window.innerWidth < Et; + e !== this.isMobile && + this.eventsDispatcher.emit(ve, { isEnabled: this.isMobile }), + (this.isMobile = e); + } + make() { + (this.nodes.holder = d.getHolder(this.config.holder)), + (this.nodes.wrapper = d.make("div", [ + this.CSS.editorWrapper, + ...(this.isRtl ? [this.CSS.editorRtlFix] : []), + ])), + (this.nodes.redactor = d.make("div", this.CSS.editorZone)), + this.nodes.holder.offsetWidth < this.contentRect.width && + this.nodes.wrapper.classList.add(this.CSS.editorWrapperNarrow), + (this.nodes.redactor.style.paddingBottom = + this.config.minHeight + "px"), + this.nodes.wrapper.appendChild(this.nodes.redactor), + this.nodes.holder.appendChild(this.nodes.wrapper); + } + loadStyles() { + const e = "editor-js-styles"; + if (d.get(e)) return; + const t = d.make("style", null, { id: e, textContent: gs.toString() }); + this.config.style && + !V(this.config.style) && + this.config.style.nonce && + t.setAttribute("nonce", this.config.style.nonce), + d.prepend(document.head, t); + } + enableModuleBindings() { + this.readOnlyMutableListeners.on( + this.nodes.redactor, + "click", + (t) => { + this.redactorClicked(t); + }, + !1, + ), + this.readOnlyMutableListeners.on( + this.nodes.redactor, + "mousedown", + (t) => { + this.documentTouched(t); + }, + { capture: !0, passive: !0 }, + ), + this.readOnlyMutableListeners.on( + this.nodes.redactor, + "touchstart", + (t) => { + this.documentTouched(t); + }, + { capture: !0, passive: !0 }, + ), + this.readOnlyMutableListeners.on( + document, + "keydown", + (t) => { + this.documentKeydown(t); + }, + !0, + ), + this.readOnlyMutableListeners.on( + document, + "mousedown", + (t) => { + this.documentClicked(t); + }, + !0, + ); + const e = yt(() => { + this.selectionChanged(); + }, Ji); + this.readOnlyMutableListeners.on(document, "selectionchange", e, !0), + this.readOnlyMutableListeners.on( + window, + "resize", + () => { + this.resizeDebouncer(); + }, + { passive: !0 }, + ), + this.watchBlockHoveredEvents(), + this.enableInputsEmptyMark(); + } + watchBlockHoveredEvents() { + let e; + this.readOnlyMutableListeners.on( + this.nodes.redactor, + "mousemove", + Ue((t) => { + const o = t.target.closest(".ce-block"); + this.Editor.BlockSelection.anyBlockSelected || + (o && + e !== o && + ((e = o), + this.eventsDispatcher.emit(Gt, { + block: this.Editor.BlockManager.getBlockByChildNode(o), + }))); + }, 20), + { passive: !0 }, + ); + } + disableModuleBindings() { + this.readOnlyMutableListeners.clearAll(); + } + windowResize() { + (this.contentRectCache = null), this.setIsMobile(); + } + documentKeydown(e) { + switch (e.keyCode) { + case w.ENTER: + this.enterPressed(e); + break; + case w.BACKSPACE: + case w.DELETE: + this.backspacePressed(e); + break; + case w.ESC: + this.escapePressed(e); + break; + default: + this.defaultBehaviour(e); + break; + } + } + defaultBehaviour(e) { + const { currentBlock: t } = this.Editor.BlockManager, + o = e.target.closest(`.${this.CSS.editorWrapper}`), + i = e.altKey || e.ctrlKey || e.metaKey || e.shiftKey; + if (t !== void 0 && o === null) { + this.Editor.BlockEvents.keydown(e); + return; + } + o || + (t && i) || + (this.Editor.BlockManager.unsetCurrentBlock(), + this.Editor.Toolbar.close()); + } + backspacePressed(e) { + const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor; + if (o.anyBlockSelected && !m.isSelectionExists) { + const s = t.removeSelectedBlocks(), + r = t.insertDefaultBlockAtIndex(s, !0); + i.setToBlock(r, i.positions.START), + o.clearSelection(e), + e.preventDefault(), + e.stopPropagation(), + e.stopImmediatePropagation(); + } + } + escapePressed(e) { + this.Editor.BlockSelection.clearSelection(e), + this.Editor.Toolbar.toolbox.opened + ? (this.Editor.Toolbar.toolbox.close(), + this.Editor.Caret.setToBlock( + this.Editor.BlockManager.currentBlock, + this.Editor.Caret.positions.END, + )) + : this.Editor.BlockSettings.opened + ? this.Editor.BlockSettings.close() + : this.Editor.InlineToolbar.opened + ? this.Editor.InlineToolbar.close() + : this.Editor.Toolbar.close(); + } + enterPressed(e) { + const { BlockManager: t, BlockSelection: o } = this.Editor; + if (this.someToolbarOpened) return; + const i = t.currentBlockIndex >= 0; + if (o.anyBlockSelected && !m.isSelectionExists) { + o.clearSelection(e), + e.preventDefault(), + e.stopImmediatePropagation(), + e.stopPropagation(); + return; + } + if (!this.someToolbarOpened && i && e.target.tagName === "BODY") { + const s = this.Editor.BlockManager.insert(); + e.preventDefault(), + this.Editor.Caret.setToBlock(s), + this.Editor.Toolbar.moveAndOpen(s); + } + this.Editor.BlockSelection.clearSelection(e); + } + documentClicked(e) { + var l, a; + if (!e.isTrusted) return; + const t = e.target; + this.nodes.holder.contains(t) || + m.isAtEditor || + (this.Editor.BlockManager.unsetCurrentBlock(), + this.Editor.Toolbar.close()); + const i = + (l = this.Editor.BlockSettings.nodes.wrapper) == null + ? void 0 + : l.contains(t), + s = + (a = this.Editor.Toolbar.nodes.settingsToggler) == null + ? void 0 + : a.contains(t), + r = i || s; + if (this.Editor.BlockSettings.opened && !r) { + this.Editor.BlockSettings.close(); + const c = this.Editor.BlockManager.getBlockByChildNode(t); + this.Editor.Toolbar.moveAndOpen(c); + } + this.Editor.BlockSelection.clearSelection(e); + } + documentTouched(e) { + let t = e.target; + if (t === this.nodes.redactor) { + const o = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX, + i = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY; + t = document.elementFromPoint(o, i); + } + try { + this.Editor.BlockManager.setCurrentBlockByChildNode(t); + } catch { + this.Editor.RectangleSelection.isRectActivated() || + this.Editor.Caret.setToTheLastBlock(); + } + this.Editor.Toolbar.moveAndOpen(); + } + redactorClicked(e) { + if (!m.isCollapsed) return; + const t = e.target, + o = e.metaKey || e.ctrlKey; + if (d.isAnchor(t) && o) { + e.stopImmediatePropagation(), e.stopPropagation(); + const i = t.getAttribute("href"), + s = To(i); + So(s); + return; + } + this.processBottomZoneClick(e); + } + processBottomZoneClick(e) { + const t = this.Editor.BlockManager.getBlockByIndex(-1), + o = d.offset(t.holder).bottom, + i = e.pageY, + { BlockSelection: s } = this.Editor; + if ( + e.target instanceof Element && + e.target.isEqualNode(this.nodes.redactor) && + !s.anyBlockSelected && + o < i + ) { + e.stopImmediatePropagation(), e.stopPropagation(); + const { BlockManager: l, Caret: a, Toolbar: c } = this.Editor; + (!l.lastBlock.tool.isDefault || !l.lastBlock.isEmpty) && + l.insertAtEnd(), + a.setToTheLastBlock(), + c.moveAndOpen(l.lastBlock); + } + } + selectionChanged() { + const { CrossBlockSelection: e, BlockSelection: t } = this.Editor, + o = m.anchorElement; + if ( + (e.isCrossBlockSelectionStarted && + t.anyBlockSelected && + m.get().removeAllRanges(), + !o) + ) { + m.range || this.Editor.InlineToolbar.close(); + return; + } + const i = o.closest(`.${D.CSS.content}`); + ((i === null || + i.closest(`.${m.CSS.editorWrapper}`) !== this.nodes.wrapper) && + (this.Editor.InlineToolbar.containsNode(o) || + this.Editor.InlineToolbar.close(), + !(o.dataset.inlineToolbar === "true"))) || + (this.Editor.BlockManager.currentBlock || + this.Editor.BlockManager.setCurrentBlockByChildNode(o), + this.Editor.InlineToolbar.tryToShow(!0)); + } + enableInputsEmptyMark() { + function e(t) { + const o = t.target; + Bt(o); + } + this.readOnlyMutableListeners.on(this.nodes.wrapper, "input", e), + this.readOnlyMutableListeners.on(this.nodes.wrapper, "focusin", e), + this.readOnlyMutableListeners.on(this.nodes.wrapper, "focusout", e); + } + } + const bs = { + BlocksAPI: No, + CaretAPI: Do, + EventsAPI: Ro, + I18nAPI: Ve, + API: Fo, + InlineToolbarAPI: Ho, + ListenersAPI: zo, + NotifierAPI: Yo, + ReadOnlyAPI: Wo, + SanitizerAPI: Jo, + SaverAPI: Qo, + SelectionAPI: ei, + ToolsAPI: ti, + StylesAPI: oi, + ToolbarAPI: ii, + TooltipAPI: ai, + UiAPI: ci, + BlockSettings: Pi, + Toolbar: $i, + InlineToolbar: Yi, + BlockEvents: Wi, + BlockManager: Vi, + BlockSelection: qi, + Caret: He, + CrossBlockSelection: Zi, + DragNDrop: Gi, + ModificationsObserver: es, + Paste: ts, + ReadOnly: os, + RectangleSelection: Be, + Renderer: is, + Saver: ss, + Tools: uo, + UI: ms, + }; + class ks { + constructor(e) { + (this.moduleInstances = {}), (this.eventsDispatcher = new be()); + let t, o; + (this.isReady = new Promise((i, s) => { + (t = i), (o = s); + })), + Promise.resolve() + .then(async () => { + (this.configuration = e), + this.validate(), + this.init(), + await this.start(), + await this.render(); + const { + BlockManager: i, + Caret: s, + UI: r, + ModificationsObserver: l, + } = this.moduleInstances; + r.checkEmptiness(), + l.enable(), + this.configuration.autofocus && + s.setToBlock(i.blocks[0], s.positions.START), + t(); + }) + .catch((i) => { + C(`Editor.js is not ready because of ${i}`, "error"), o(i); + }); + } + set configuration(e) { + var o, i; + P(e) ? (this.config = { ...e }) : (this.config = { holder: e }), + Ye(!!this.config.holderId, "config.holderId", "config.holder"), + this.config.holderId && + !this.config.holder && + ((this.config.holder = this.config.holderId), + (this.config.holderId = null)), + this.config.holder == null && (this.config.holder = "editorjs"), + this.config.logLevel || (this.config.logLevel = bt.VERBOSE), + vo(this.config.logLevel), + Ye( + !!this.config.initialBlock, + "config.initialBlock", + "config.defaultBlock", + ), + (this.config.defaultBlock = + this.config.defaultBlock || this.config.initialBlock || "paragraph"), + (this.config.minHeight = + this.config.minHeight !== void 0 ? this.config.minHeight : 300); + const t = { type: this.config.defaultBlock, data: {} }; + (this.config.placeholder = this.config.placeholder || !1), + (this.config.sanitizer = this.config.sanitizer || { + p: !0, + b: !0, + a: !0, + }), + (this.config.hideToolbar = this.config.hideToolbar + ? this.config.hideToolbar + : !1), + (this.config.tools = this.config.tools || {}), + (this.config.i18n = this.config.i18n || {}), + (this.config.data = this.config.data || { blocks: [] }), + (this.config.onReady = this.config.onReady || (() => {})), + (this.config.onChange = this.config.onChange || (() => {})), + (this.config.inlineToolbar = + this.config.inlineToolbar !== void 0 + ? this.config.inlineToolbar + : !0), + (V(this.config.data) || + !this.config.data.blocks || + this.config.data.blocks.length === 0) && + (this.config.data = { blocks: [t] }), + (this.config.readOnly = this.config.readOnly || !1), + (o = this.config.i18n) != null && + o.messages && + H.setDictionary(this.config.i18n.messages), + (this.config.i18n.direction = + ((i = this.config.i18n) == null ? void 0 : i.direction) || "ltr"); + } + get configuration() { + return this.config; + } + validate() { + const { holderId: e, holder: t } = this.config; + if (e && t) + throw Error( + "«holderId» and «holder» param can't assign at the same time.", + ); + if (G(t) && !d.get(t)) + throw Error( + `element with ID «${t}» is missing. Pass correct holder's ID.`, + ); + if (t && P(t) && !d.isElement(t)) + throw Error("«holder» value must be an Element node"); + } + init() { + this.constructModules(), this.configureModules(); + } + async start() { + await [ + "Tools", + "UI", + "BlockManager", + "Paste", + "BlockSelection", + "RectangleSelection", + "CrossBlockSelection", + "ReadOnly", + ].reduce( + (t, o) => + t.then(async () => { + try { + await this.moduleInstances[o].prepare(); + } catch (i) { + if (i instanceof St) throw new Error(i.message); + C(`Module ${o} was skipped because of %o`, "warn", i); + } + }), + Promise.resolve(), + ); + } + render() { + return this.moduleInstances.Renderer.render(this.config.data.blocks); + } + constructModules() { + Object.entries(bs).forEach(([e, t]) => { + try { + this.moduleInstances[e] = new t({ + config: this.configuration, + eventsDispatcher: this.eventsDispatcher, + }); + } catch (o) { + C("[constructModules]", `Module ${e} skipped because`, "error", o); + } + }); + } + configureModules() { + for (const e in this.moduleInstances) + Object.prototype.hasOwnProperty.call(this.moduleInstances, e) && + (this.moduleInstances[e].state = this.getModulesDiff(e)); + } + getModulesDiff(e) { + const t = {}; + for (const o in this.moduleInstances) + o !== e && (t[o] = this.moduleInstances[o]); + return t; + } + } + /** + * Editor.js + * + * @license Apache-2.0 + * @see Editor.js + * @author CodeX Team + */ class vs { + static get version() { + return "2.30.6"; + } + constructor(e) { + let t = () => {}; + P(e) && O(e.onReady) && (t = e.onReady); + const o = new ks(e); + this.isReady = o.isReady.then(() => { + this.exportAPI(o), t(); + }); + } + exportAPI(e) { + const t = ["configuration"], + o = () => { + Object.values(e.moduleInstances).forEach((s) => { + O(s.destroy) && s.destroy(), s.listeners.removeAll(); + }), + li(), + (e = null); + for (const s in this) + Object.prototype.hasOwnProperty.call(this, s) && delete this[s]; + Object.setPrototypeOf(this, null); + }; + t.forEach((s) => { + this[s] = e[s]; + }), + (this.destroy = o), + Object.setPrototypeOf(this, e.moduleInstances.API.methods), + delete this.exportAPI, + Object.entries({ + blocks: { clear: "clear", render: "render" }, + caret: { focus: "focus" }, + events: { on: "on", off: "off", emit: "emit" }, + saver: { save: "save" }, + }).forEach(([s, r]) => { + Object.entries(r).forEach(([l, a]) => { + this[a] = e.moduleInstances.API.methods[s][l]; + }); + }); + } + } + return vs; +}); + +var editor = new EditorJS({ + autofocus: true, + holder: "editorjs", + inlineToolbar: true, + tools: { + header: { + class: Header, + inlineToolbar: true, + config: { + placeholder: "Header", + }, + shortcut: "CMD+SHIFT+H", + defaultLevel: 1, + }, + image: { + class: ImageTool, + config: { + endpoints: { + byFile: "/editor/uploadFile", // Your backend file uploader endpoint + byUrl: "/editor/fetchUrl", // Your endpoint that provides uploading by Url + }, + captionPlaceholder: "Add alt text", + features: { + border: false, + background: false, + caption: true, + stretch: false + } + }, + }, + list: { + class: List, + inlineToolbar: true, + shortcut: "CMD+SHIFT+L", + }, + quote: { + class: Quote, + inlineToolbar: true, + config: { + quotePlaceholder: "Enter a quote", + captionPlaceholder: "Quote's author", + }, + shortcut: "CMD+SHIFT+O", + }, + warning: Warning, + delimiter: Delimiter, + inlineCode: { + class: InlineCode, + shortcut: "CMD+SHIFT+C", + }, + embed: { + class: Embed, + inlineToolbar: true, + config: { + services: { + facebook: true, + instagram: true, + twitter: true, + vimeo: true, + gfycat: true, + imgur: true, + youtube: true, + }, + }, + }, + }, + minHeight: 50, + onReady: function () {}, + data: data, + onChange: onChange, +}); diff --git a/src/html.rs b/src/html.rs new file mode 100644 index 0000000..a81a4b4 --- /dev/null +++ b/src/html.rs @@ -0,0 +1,745 @@ +use std::{env, vec}; + +use blogdb::posts::Post; +use blogdb::BlogDb; +use lol_html::html_content::ContentType; +use lol_html::{comments, element, rewrite_str, RewriteStrSettings}; + +use crate::routes::api::editor::Blocks; +use crate::routes::SearchResponse; + +include!(concat!(env!("OUT_DIR"), "/codegen.rs")); + +/// Gets template html string from `src/templates` +/// +/// # Examples +/// +/// ``` +/// // `src/templates/blog-roll.html` +/// // +/// //

Blog

+/// //
    +/// +/// let template = template!("blog-roll"); +/// assert_eq!(template, "

    Blog

    \n
      "); +/// ``` +macro_rules! template { + ($t:tt) => { + TEMPLATES.get($t).unwrap_or(&"") + }; +} + +/// Makes a page with default settings and content inserted into
      +/// (or replacing
      if content has a
      tag) +pub(crate) fn make_page(content: S, settings: PageSettings) -> String +where + S: AsRef, +{ + rewrite_str( + template!("default"), + RewriteStrSettings { + element_content_handlers: vec![ + element!("head", |head| { + head.prepend( + &["", &settings.title, ""].concat(), + ContentType::Html, + ); + if let Some(stylesheets) = &settings.stylesheets { + for url in stylesheets { + head.append( + &[r#""#].concat(), + ContentType::Html, + ) + } + } + Ok(()) + }), + element!("body", |body| { + body.prepend("", ContentType::Html); + Ok(()) + }), + element!("main", |main| { + if content.as_ref().contains("
      ") { + main.replace(content.as_ref(), ContentType::Html); + } else { + main.set_inner_content(content.as_ref(), ContentType::Html); + } + Ok(()) + }), + element!("site-header", |site_header| { + if settings.site_header { + site_header.replace(template!("site-header"), ContentType::Html); + } + Ok(()) + }), + element!("br", |br| { + br.remove(); + Ok(()) + }), + comments!("*", |comments| { + comments.remove(); + Ok(()) + }), + ], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +pub(crate) fn rewrite_el(input: S, name: T, with: R) -> String +where + S: AsRef, + T: AsRef, + R: AsRef, +{ + rewrite_str( + input.as_ref(), + RewriteStrSettings { + element_content_handlers: vec![element!(name.as_ref(), |el| { + el.replace(with.as_ref(), ContentType::Html); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +pub(crate) fn remove_el(input: S, name: T) -> String +where + S: AsRef, + T: AsRef, +{ + rewrite_str( + input.as_ref(), + RewriteStrSettings { + element_content_handlers: vec![element!(name.as_ref(), |el| { + el.remove(); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +fn remove_comments>(input: S) -> String { + rewrite_str( + input.as_ref(), + RewriteStrSettings { + element_content_handlers: vec![comments!("*", |co| { + co.remove(); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +pub(crate) fn homepage_editor>(homepage_content: S) -> String { + editor(homepage_content, "/api/editor/update/home") +} + +pub(crate) fn about_editor>(about_content: S) -> String { + editor(about_content, "/api/editor/update/about") +} + +pub(crate) fn draft_editor(post_content: S, post_id: T) -> String +where + S: AsRef, + T: AsRef, +{ + editor( + post_content, + ["/api/editor/update/", post_id.as_ref()].concat(), + ) +} + +fn editor(content: S, endpoint: T) -> String +where + S: AsRef, + T: AsRef, +{ + let content = content.as_ref(); + let data = if !content.is_empty() && content.starts_with("[") && content.ends_with("]") { + content + } else { + "[]" + }; + let settings = [ + "const data={blocks:", + data, + "};const onChange=()=>{editor.save().then(async(savedData)=>{const endpoint = \"",endpoint.as_ref(),"\"; const response = await fetch(endpoint, { method: \"POST\", mode: \"same-origin\", headers: {\"Content-Type\": \"application/json\"}, body: JSON.stringify(savedData.blocks) });})};" + ].concat(); + let html = rewrite_str( + template!("post-editor"), + RewriteStrSettings { + element_content_handlers: vec![element!("#editor", move |script| { + script.prepend(&settings, ContentType::Html); + Ok(()) + })], + strict: false, + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + make_page( + html, + PageSettings::new("Editor", Some(vec!["/assets/css/editor.css"]), true), + ) +} + +/// Rewrites `` with html from template, and sets the `next` hidden +/// input element to the next location +pub(crate) fn login_status(next: &str, success: bool) -> String { + let status = if success { + "" + } else { + template!("login-status") + }; + + let next = next.strip_prefix("/").unwrap_or(next); + + let html = rewrite_el(template!("login"), "login-status", status); + + let html = rewrite_str( + &html, + RewriteStrSettings { + element_content_handlers: vec![element!(r#"input[name="next"]"#, |input| { + input.set_attribute("value", next).unwrap_or_default(); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + + let html = rewrite_str( + &html, + RewriteStrSettings { + element_content_handlers: vec![element!(r#"input[name="next"]"#, |input| { + input.set_attribute("value", next).unwrap_or_default(); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + make_page( + html, + PageSettings::new("Login", Some(vec!["/assets/css/login.css"]), false), + ) +} + +pub(crate) async fn admin_page(session_id: i64, db: &BlogDb) -> String { + let content = admin_widgets(template!("admin"), session_id, db).await; + make_page( + &content, + PageSettings::new("Admin", Some(vec!["/assets/css/admin.css"]), true), + ) +} + +pub(crate) async fn admin_widgets(input: &str, session_id: i64, db: &BlogDb) -> String { + let posts_html = admin_entries(EntryType::Post, session_id, db).await; + let drafts_html = admin_entries(EntryType::Draft, session_id, db).await; + let user_html = template!("admin-widgets/user"); + + rewrite_str( + input, + RewriteStrSettings { + element_content_handlers: vec![element!("admin-widget", move |a| { + match a.get_attribute("type") { + Some(attr) => { + match attr.as_str() { + "drafts" => a.replace(&drafts_html, ContentType::Html), + "posts" => a.replace(&posts_html, ContentType::Html), + "user" => a.replace(user_html, ContentType::Html), + _ => a.remove(), + } + Ok(()) + } + None => todo!(), + } + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +enum EntryType { + Post, + Draft, +} + +async fn admin_entries(entry_type: EntryType, session_id: i64, db: &BlogDb) -> String { + let (list_template, entry_template) = match entry_type { + EntryType::Post => ( + template!("admin-widgets/posts"), + template!("admin-widgets/post"), + ), + EntryType::Draft => ( + template!("admin-widgets/drafts"), + template!("admin-widgets/draft"), + ), + }; + let is_empty: bool; + let entries_html = match entry_type { + EntryType::Post => { + let mut entries = db.get_posts().await.unwrap_or(vec![]); + entries.reverse(); + let mut entry_list_html = String::new(); + is_empty = entries.is_empty(); + if !is_empty { + for entry in entries { + let href = ["/blog/", &entry.id].concat(); + let mut entry_html = admin_entry( + entry_template, + &entry.id, + &entry.title, + &href, + &entry.content, + ); + entry_html = rewrite_str( + &entry_html, + RewriteStrSettings { + element_content_handlers: vec![element!("time", |time| { + time.set_inner_content(&entry.date, ContentType::Text); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + entry_list_html.push_str(&entry_html); + } + } + entry_list_html + } + EntryType::Draft => { + let mut entries = db.get_drafts(session_id).await.unwrap_or(vec![]); + entries.reverse(); + let mut entry_list_html = String::new(); + is_empty = entries.is_empty(); + if !is_empty { + for entry in entries { + let href = ["/editor/", &entry.id].concat(); + let entry_html = admin_entry( + entry_template, + &entry.id, + &entry.title, + &href, + &entry.content, + ); + entry_list_html.push_str(&entry_html); + } + } + entry_list_html + } + }; + let final_html = rewrite_str( + list_template, + RewriteStrSettings { + element_content_handlers: vec![element!("ul", |ul| { + if is_empty { + match entry_type { + EntryType::Post => ul.replace("

      No Published Posts

      ", ContentType::Html), + EntryType::Draft => ul.replace("

      No Drafts

      Start a New Draft

      ", ContentType::Html) + } + } else { + ul.set_inner_content(&entries_html, ContentType::Html); + } + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + final_html +} + +fn admin_entry(entry_template: &str, id: &str, title: &str, href: &str, content: &str) -> String { + rewrite_str( + entry_template, + RewriteStrSettings { + element_content_handlers: vec![ + element!("a.entry-content", |a| { + a.set_attribute("href", href).unwrap_or_default(); + Ok(()) + }), + element!("h2", |h2| { + h2.set_inner_content(title, ContentType::Html); + Ok(()) + }), + element!("p", |p| { + let post_content: Blocks = serde_json::from_str(content).unwrap_or_default(); + let content = rewrite_str( + &post_content.desc(), + RewriteStrSettings { + element_content_handlers: vec![element!("*", |all| { + all.remove_and_keep_content(); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + p.set_inner_content(&content, ContentType::Text); + Ok(()) + }), + element!("input", |input| { + input.set_attribute("value", id).unwrap_or_default(); + Ok(()) + }), + ], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +pub(crate) async fn about_page(db: &BlogDb) -> String { + let about = db.get_about().await; + let about_content: Blocks = serde_json::from_str(&about).unwrap_or_default(); + let about_html = remove_comments(about_content.to_html()); + make_page(&about_html, PageSettings::title("About")) +} + +pub(crate) async fn home_page(db: &BlogDb) -> String { + let home = db.get_homepage().await; + let home_content: Blocks = serde_json::from_str(&home).unwrap_or_default(); + let home_html = home_content.to_html(); + make_page(&home_html, PageSettings::title("Evie Ippolito")) +} + +fn meta(slug: S, title: T, description: R, image: I) -> String +where + S: AsRef, + T: AsRef, + R: AsRef, + I: AsRef, +{ + rewrite_str( + template!("head/meta"), + RewriteStrSettings { + element_content_handlers: vec![element!("meta", |meta| { + if let Some(attr) = meta.get_attribute("property") { + let content = match attr.as_str() { + "og:url" => &[env!("DOMAIN"), slug.as_ref()].concat(), + "og:type" => "article", + "og:title" => title.as_ref(), + "og:description" => description.as_ref(), + "og:image" => { + let image = image.as_ref(); + if !image.is_empty() { + image + } else { + meta.remove(); + "" + } + } + _ => "", + }; + let _ = meta.set_attribute("content", content); + } + Ok(()) + })], + + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +/// Creates a blog page from a post's content +pub(crate) async fn blog_page(id: S, db: &BlogDb) -> String +where + S: AsRef, +{ + let template = template!("blog-page"); + let html = make_page(template, PageSettings::title("Blog")); + + let post = db.get_post(id).await.unwrap_or_default(); + let head = head::<_, _, [String; 0]>(post.title, []); + let post_content: Blocks = serde_json::from_str(&post.content).unwrap_or_default(); + let post_html: String = post_content.to_html(); + let image = if let Some(url) = post_content.image() { + &[url].concat() + } else { + "" + }; + let meta = meta( + ["/blog/", &post.id].concat(), + post_content.title(), + post_content.desc(), + image, + ); + + let html = rewrite_str( + &html, + RewriteStrSettings { + element_content_handlers: vec![element!("time", |time| { + time.after(&post_html, ContentType::Html); + time.replace( + &[ + r#"", + ] + .concat(), + ContentType::Html, + ); + Ok(()) + })], + + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + html +} + +pub(crate) async fn blog_roll(db: &BlogDb) -> String { + let mut posts = match db.get_posts().await { + Ok(posts) => posts, + Err(_) => return "".to_string(), + }; + + posts.reverse(); + + let mut post_entries = String::new(); + + for post in posts.iter() { + let post_entry = post_entry(post); + post_entries.push_str(&post_entry); + } + + let blog_roll_html = rewrite_str( + template!("blog-roll"), + RewriteStrSettings { + element_content_handlers: vec![element!("ul", move |ul| { + ul.set_inner_content(&post_entries, ContentType::Html); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + + make_page( + blog_roll_html, + PageSettings::new("Blog", Some(vec!["/assets/css/blog.css"]), true), + ) +} + +fn post_entry(post: &Post) -> String { + rewrite_str( + template!("blog-roll-entry"), + RewriteStrSettings { + element_content_handlers: vec![ + element!("a", |a| { + a.set_attribute("href", &["/blog/", &post.id].concat()) + .unwrap_or_default(); + Ok(()) + }), + element!("img", |img| { + let post_content: Blocks = + serde_json::from_str(&post.content).unwrap_or_default(); + match post_content.image() { + Some(src) => { + let _ = img.set_attribute("src", src); + } + None => img.remove(), + } + Ok(()) + }), + element!("h2", |h2| { + h2.set_inner_content(&post.title, ContentType::Text); + Ok(()) + }), + element!("time", |time| { + time.set_inner_content(&post.date, ContentType::Text); + Ok(()) + }), + element!("p", |p| { + let post_content: Blocks = + serde_json::from_str(&post.content).unwrap_or_default(); + let content = remove_el(post_content.desc(), "br"); + p.set_inner_content(&content, ContentType::Html); + Ok(()) + }), + ], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +pub(crate) fn search_page_no_query() -> String { + let search_page_html = make_page(template!("search-page"), PageSettings::title("Search")); + rewrite_str( + &search_page_html, + RewriteStrSettings { + element_content_handlers: vec![element!("ul", move |ul| { + ul.remove(); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +pub(crate) async fn search_page( + query: String, + search_response: SearchResponse, + db: &BlogDb, +) -> String { + let mut entries = String::new(); + let search_page_html = if !search_response.is_empty() { + for entry in search_response { + let post = match db.get_post(&entry.id[0]).await { + Ok(post) => post, + Err(_) => continue, + }; + let entry_html = post_entry(&post); + entries.push_str(&entry_html); + } + [ + "

      Results for “", + &query, + "”

      ", + "
        ", + &entries, + "
      ", + ] + .concat() + } else { + ["

      No results for “", &query, "”

      "].concat() + }; + make_page( + &search_page_html, + PageSettings::new( + ["Results for “", &query, "”"].concat(), + Some(vec!["/assets/css/blog.css"]), + true, + ), + ) +} + +/// Creates a for each given style_url +fn stylesheets(style_urls: I) -> String +where + S: AsRef, + I: IntoIterator, +{ + style_urls + .into_iter() + .map(|url| [r#""#].concat()) + .collect::() +} + +fn head(title: S, style_urls: I) -> String +where + S: AsRef, + T: AsRef, + I: IntoIterator, +{ + let content = rewrite_str( + template!("head/content"), + RewriteStrSettings { + element_content_handlers: vec![element!("title", move |t| { + t.set_inner_content(title.as_ref(), ContentType::Html); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default(); + let links_html = stylesheets(style_urls); + [content, links_html].concat() +} + +pub(crate) struct PageSettings { + title: String, + stylesheets: Option>, + site_header: bool, +} + +impl PageSettings { + pub(crate) fn title(title: S) -> Self + where + S: ToString, + { + Self { + title: title.to_string(), + stylesheets: None, + site_header: true, + } + } + pub(crate) fn new(title: S, stylesheets: Option>, site_header: bool) -> Self + where + S: ToString, + T: ToString, + { + let stylesheets = + stylesheets.map(|s| s.iter().map(|t| t.to_string()).collect::>()); + Self { + title: title.to_string(), + stylesheets, + site_header, + } + } +} + +pub(crate) fn make_404(message: S) -> String +where + S: AsRef, +{ + make_page(message, PageSettings::title("Not found")) +} + +pub(crate) fn animate_anchors(input: S) -> String +where + S: AsRef, +{ + rewrite_str( + input.as_ref(), + RewriteStrSettings { + element_content_handlers: vec![element!("a", move |t| { + match t.get_attribute("class") { + Some(class) => t + .set_attribute("class", &[&class, "animated-link-underline"].concat()) + .unwrap_or_default(), + None => { + t.set_attribute("class", "animated-link-underline") + .unwrap_or_default(); + } + } + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} + +pub(crate) fn sanitize>(input: S) -> String { + rewrite_str( + input.as_ref(), + RewriteStrSettings { + element_content_handlers: vec![element!("*", move |all| { + all.remove_and_keep_content(); + Ok(()) + })], + ..RewriteStrSettings::new() + }, + ) + .unwrap_or_default() +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..fa04022 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,16 @@ +mod html; +mod server; + +use std::env; + +use server::*; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let port: Option = match env::args().nth(1) { + Some(value) => Some(value.parse()?), + None => None, + }; + Blog::new().await?.serve(port).await; + Ok(()) +} diff --git a/src/server/middleware.rs b/src/server/middleware.rs new file mode 100644 index 0000000..85f39a1 --- /dev/null +++ b/src/server/middleware.rs @@ -0,0 +1,43 @@ +use axum::{ + extract::{Request, State}, + http::{header::LOCATION, HeaderMap, HeaderValue, StatusCode}, + middleware::Next, + response::{IntoResponse, Response}, +}; +use axum_extra::extract::PrivateCookieJar; + +use crate::BlogState; + +/// Middleware layer requiring user to log in to access route +pub(crate) async fn logged_in( + jar: PrivateCookieJar, + State(state): State, + request: Request, + next: Next, +) -> Response { + let next_uri = request.uri(); + let redirect_to_login = || -> Response { + let mut headers = HeaderMap::new(); + headers.append( + LOCATION, + HeaderValue::from_str(&["/login", &next_uri.to_string()].concat()).unwrap(), + ); + (StatusCode::FOUND, headers).into_response() + }; + let db = state.db(); + let session_id = match jar.get("id") { + Some(id) => match id.value_trimmed().parse::() { + Ok(id) => id, + Err(_) => { + return redirect_to_login(); + } + }, + None => { + return redirect_to_login(); + } + }; + if let Err(_error) = db.check_session(session_id).await { + return redirect_to_login(); + } + next.run(request).await +} diff --git a/src/server/mod.rs b/src/server/mod.rs new file mode 100644 index 0000000..b0a7bf9 --- /dev/null +++ b/src/server/mod.rs @@ -0,0 +1,347 @@ +mod middleware; +pub(crate) mod routes; + +use routes::{api::editor::Blocks, make_router}; +use tantivy::{ + directory::MmapDirectory, + doc, + schema::{Schema, STORED, STRING, TEXT}, + Index, IndexWriter, TantivyDocument, Term, +}; +use tower::Layer; +use tower_http::normalize_path::NormalizePathLayer; + +use std::{ + env, + fs::{self, File}, + io::{Read, Write}, + path::PathBuf, + str::FromStr, + sync::Arc, + sync::Mutex, +}; + +use anyhow::anyhow; +use axum::{ + extract::{FromRef, Request}, + Router, ServiceExt, +}; +use axum_extra::extract::cookie::Key; +use blogdb::BlogDb; +use glob::glob; + +use crate::html; + +const DB_URL: &str = "sqlite://evie.db"; + +pub struct Blog { + app: Router, +} + +impl Blog { + pub async fn new() -> anyhow::Result { + let state = BlogState::new().await?; + let app = make_router(state).await; + Ok(Self { app }) + } + + pub async fn serve(self, port: Option) { + let port = port.unwrap_or(3000); + let listener = tokio::net::TcpListener::bind(format!("127.0.0.1:{port}")) + .await + .unwrap(); + axum::serve( + listener, + ServiceExt::::into_make_service( + NormalizePathLayer::trim_trailing_slash().layer(self.app), + ), + ) + .await + .unwrap(); + } +} + +#[derive(Clone)] +pub struct BlogState(Arc); + +impl BlogState { + async fn new() -> anyhow::Result { + Ok(BlogState(Arc::new(BlogStateInner::new().await?))) + } + + fn db(&self) -> &BlogDb { + &self.0.db + } + + fn domain(&self) -> String { + self.0.domain.clone() + } + + fn index(&self) -> &Index { + &self.0.index + } + + fn index_add_document(&self, document: TantivyDocument) { + let _ = self.0.index_writer.lock().unwrap().add_document(document); + } + + fn index_delete(&self, term: Term) { + let _ = self.0.index_writer.lock().unwrap().delete_term(term); + } + + fn index_commit(&self) { + let _ = self.0.index_writer.lock().unwrap().commit(); + } +} + +// this impl tells `SignedCookieJar` how to access the key from our state +impl FromRef for Key { + fn from_ref(state: &BlogState) -> Self { + state.0.key.clone() + } +} + +struct BlogStateInner { + db: BlogDb, + key: Key, + domain: String, + index: Index, + index_writer: Mutex, +} + +impl BlogStateInner { + async fn new() -> anyhow::Result { + let username = env!("INIT_USER_NAME").to_string(); + let password = env!("INIT_USER_PASSWORD").to_string(); + let domain = env!("DOMAIN").to_string(); + let url_as_path = DB_URL.strip_prefix("sqlite://").unwrap_or_default(); + if File::open(url_as_path).is_err() { + let _ = File::create_new(url_as_path); + } + let db = BlogDb::new(&username, password.clone(), DB_URL).await?; + Self::add_initial_assets(&db).await?; + Self::add_initial_pages(&db).await?; + #[cfg(debug_assertions)] + { + Self::add_posts(&db).await?; + Self::add_drafts(&username, password, &db).await?; + } + let key = Self::key()?; + let (index, index_writer) = Self::generate_index(&db).await?; + Ok(Self { + db, + key, + domain, + index, + index_writer: Mutex::new(index_writer), + }) + } + + async fn add_initial_pages(db: &BlogDb) -> anyhow::Result<()> { + let pages = vec![ + ("index".to_string(), html::home_page(db).await), + ("about".to_string(), html::about_page(db).await), + ]; + db.add_pages(pages).await?; + Ok(()) + } + + const ASSETS_DIR: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/src/client/assets"); + + async fn add_initial_assets(db: &BlogDb) -> anyhow::Result<()> { + let pattern = [Self::ASSETS_DIR, "/*/*"].concat(); + let paths = glob(&pattern).unwrap(); + let mut assets = vec![]; + for path in paths.into_iter() { + match path { + Ok(path) => { + let slug_path = path.clone(); + let slug: String = slug_path + .strip_prefix(Self::ASSETS_DIR)? + .as_os_str() + .to_str() + .unwrap() + .into(); // eek + let mut file = File::open(path.clone())?; + let mut data = vec![]; + file.read_to_end(&mut data).unwrap(); + assets.push((slug, data)); + } + Err(_) => todo!(), + } + } + db.add_assets(assets).await?; + Ok(()) + } + + const INDEX_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/index"); + const MEMORY_BUDGET: usize = 50_000_000; + + async fn generate_index(db: &BlogDb) -> anyhow::Result<(Index, IndexWriter)> { + let mut schema_builder = Schema::builder(); + let id = schema_builder.add_text_field("id", STRING | STORED); + let title = schema_builder.add_text_field("title", TEXT | STORED); + let body = schema_builder.add_text_field("body", TEXT | STORED); + let schema = schema_builder.build(); + let _ = fs::remove_dir_all(Self::INDEX_PATH); + let _ = fs::create_dir_all(Self::INDEX_PATH); + let dir = MmapDirectory::open(Self::INDEX_PATH).unwrap(); + let index = Index::open_or_create(dir, schema.clone())?; + let mut index_writer: IndexWriter = index.writer(Self::MEMORY_BUDGET)?; + let posts = db.get_posts().await?; + for post in posts.into_iter() { + let content: Blocks = serde_json::from_str(&post.content).unwrap_or_default(); + index_writer.add_document( + doc!(id => post.id, title => post.title, body => content.to_plaintext()), + )?; + } + index_writer.commit()?; + Ok((index, index_writer)) + } + + #[cfg(not(debug_assertions))] + fn key() -> anyhow::Result { + let key = Key::try_generate().ok_or(anyhow!("Couldn't generate key for cookie signing"))?; + Ok(key) + } + + #[cfg(debug_assertions)] + fn key() -> anyhow::Result { + let key_path = PathBuf::from_str("./key")?; + let key_file = File::options().read(true).write(true).open(&key_path); + let key = match key_file { + Ok(mut file) => { + let mut bytes = vec![]; + file.read_to_end(&mut bytes)?; + match Key::try_from(bytes.as_slice()) { + Ok(key) => key, + Err(error) => { + println!("need to make a new key, couldn't get from file cause {error:?}"); + let key = Key::try_generate() + .ok_or(anyhow!("Couldn't generate key for cookie signing"))?; + file.write_all(key.master())?; + println!("made one"); + key + } + } + } + Err(error) => { + println!("need to make a new key, couldn't open the key file cause {error:?}"); + let key = Key::try_generate() + .ok_or(anyhow!("Couldn't generate key for cookie signing"))?; + + let mut key_file = File::create(&key_path)?; + key_file.write_all(key.master())?; + println!("made one"); + key + } + }; + Ok(key) + } + + #[cfg(debug_assertions)] + async fn add_posts(db: &BlogDb) -> anyhow::Result<()> { + let content = r#" +[ + { + "id": "26lQiP26Dd", + "type": "header", + "data": { + "text": "Example Post", + "level": 1 + } + }, + { + "id": "PnWeuvNW6O", + "type": "header", + "data": { + "text": "This is a subheading", + "level": 2 + } + }, + { + "id": "xSV-1St5Nh", + "type": "warning", + "data": { + "title": "This is a warning...", + "message": "" + } + }, + { + "id": "rfnEtkKIjP", + "type": "quote", + "data": { + "text": "this is a quote
      ", + "caption": "", + "alignment": "left" + } + }, + { + "id": "6lQRMa2guf", + "type": "paragraph", + "data": { + "text": "This is some content
      " + } + } +] + "#; + if db.get_posts().await?.is_empty() { + db.add_post("Example Post", "", content).await?; + } + Ok(()) + } + + #[cfg(debug_assertions)] + async fn add_drafts(username: &str, password: String, db: &BlogDb) -> anyhow::Result<()> { + let content = r#" +[ + { + "id": "26lQiP26Dd", + "type": "header", + "data": { + "text": "Example Draft", + "level": 1 + } + }, + { + "id": "PnWeuvNW6O", + "type": "header", + "data": { + "text": "This is a subheading", + "level": 2 + } + }, + { + "id": "xSV-1St5Nh", + "type": "warning", + "data": { + "title": "This is a warning...", + "message": "" + } + }, + { + "id": "rfnEtkKIjP", + "type": "quote", + "data": { + "text": "this is a quote
      ", + "caption": "", + "alignment": "left" + } + }, + { + "id": "6lQRMa2guf", + "type": "paragraph", + "data": { + "text": "This is some content
      " + } + } +] + "#; + let session_id = db.new_session(username, password, "+1 year").await?; + if db.get_drafts(session_id).await?.is_empty() { + db.add_draft("Example Draft", "", content).await?; + } + db.end_session(session_id).await?; + Ok(()) + } +} diff --git a/src/server/routes/api/auth.rs b/src/server/routes/api/auth.rs new file mode 100644 index 0000000..2f391df --- /dev/null +++ b/src/server/routes/api/auth.rs @@ -0,0 +1,97 @@ +use axum::{ + extract::State, + http::{header::LOCATION, HeaderMap, HeaderValue, StatusCode}, + response::{Html, IntoResponse, Response}, + routing::post, + Form, Router, +}; +use axum_extra::extract::{cookie::Cookie, PrivateCookieJar}; +use blogdb::BlogDb; +use serde::Deserialize; +use serde_json::to_string; + +use crate::{html, BlogState}; + +#[derive(Deserialize)] +struct LoginCredentials { + username: Option, + password: Option, + remember: Option, + next: Option, +} + +pub(super) fn auth(State(state): State) -> Router { + Router::new() + .route("/login", post(login)) + .route("/logout", post(logout)) + .with_state(state) +} + +async fn login( + mut jar: PrivateCookieJar, + State(state): State, + Form(body): Form, +) -> Response { + let db = &state.db(); + let next = match body.next.unwrap_or("/".to_string()).as_str() { + "/" => "/".to_string(), + next => ["/", next].concat(), + }; + let username = match body.username { + Some(username) => username, + None => return bad_login(&next).await, + }; + let password = match body.password { + Some(password) => password, + None => return bad_login(&next).await, + }; + let expiration = if body.remember.is_some() { + "+1 year" + } else { + "+0 day" + }; + match db.new_session(username, password, expiration).await { + Ok(id) => { + jar = jar.add( + Cookie::build(("id", id.to_string())) + .domain(state.domain()) + .secure(true) + .http_only(true) + .path("/"), + ); + let mut headers = HeaderMap::new(); + headers.insert(LOCATION, HeaderValue::from_str(&next).unwrap()); + (StatusCode::FOUND, headers, jar).into_response() + } + Err(_) => bad_login(&next).await, + } +} + +async fn bad_login(next: &str) -> Response { + ( + StatusCode::UNAUTHORIZED, + Html(html::login_status(next, false)), + ) + .into_response() +} + +async fn logout(jar: PrivateCookieJar, State(state): State) -> Response { + let db = &state.db(); + let session_id: i64 = if let Some(cookie) = jar.get("id") { + match cookie.value().parse() { + Ok(id) => id, + Err(_) => return StatusCode::BAD_REQUEST.into_response(), + } + } else { + return StatusCode::BAD_REQUEST.into_response(); + }; + match db.end_session(session_id).await { + Ok(_) => { + let jar = jar.remove("id"); + let mut headers = HeaderMap::new(); + headers.insert(LOCATION, HeaderValue::from_str("/").unwrap()); + (StatusCode::FOUND, headers, jar).into_response() + } + Err(_) => StatusCode::BAD_REQUEST.into_response(), + } +} diff --git a/src/server/routes/api/editor.rs b/src/server/routes/api/editor.rs new file mode 100644 index 0000000..7d76487 --- /dev/null +++ b/src/server/routes/api/editor.rs @@ -0,0 +1,267 @@ +use axum::{ + extract::{Json, Path, State}, + http::StatusCode, + response::{IntoResponse, Response}, + routing::post, + Router, +}; +use axum_extra::extract::PrivateCookieJar; +use blogdb::BlogDb; +use serde::{Deserialize, Serialize}; + +use crate::{ + html::{self, about_page, home_page, remove_el}, + BlogState, +}; + +#[derive(Debug, Deserialize, Serialize)] +#[serde(tag = "type", content = "data")] +#[allow(non_camel_case_types)] +pub(crate) enum Block { + paragraph { + text: String, + }, + header { + text: String, + level: usize, + }, + list { + style: ListStyle, + items: Vec, + }, + warning { + title: String, + }, + quote { + text: String, + }, + embed { + service: String, + source: String, + embed: String, + width: usize, + height: usize, + }, + image { + file: ImageSource, + #[serde(default)] + caption: String, + }, + delimiter {}, +} + +#[derive(Debug, Deserialize, Serialize)] +#[allow(non_camel_case_types)] +pub struct ImageSource { + url: String, +} + +#[derive(Debug, Deserialize, Serialize)] +#[allow(non_camel_case_types)] +pub enum ListStyle { + ordered, + unordered, +} + +impl Block { + fn to_html(&self) -> String { + let text = match self { + Block::paragraph { text } => ["

      ", text, "

      "].concat(), + Block::header { text, level } => { + let level = level.to_string(); + ["", text, ""].concat() + } + Block::list { style, items } => match style { + ListStyle::ordered => ["
      1. ", &items.join("
      2. "), "
      "].concat(), + ListStyle::unordered => { + ["
      • ", &items.join("
      • "), "
      "].concat() + } + }, + Block::warning { title } => [""].concat(), + Block::quote { text } => ["
      ", text, "
      "].concat(), + Block::embed { + embed, + width, + height, + .. + } => [ + "", + ] + .concat(), + Block::image { file, caption } => { + ["\"","].concat() + } + Block::delimiter {} => "
      ".to_string(), + + }; + html::animate_anchors(html::remove_el(&text, "br")) + } + + fn to_plaintext(&self) -> String { + let text = match self { + Block::paragraph { text } => text, + Block::header { text, level: _ } => text, + Block::list { style: _, items } => &items.join("\n"), + Block::warning { title } => title, + Block::quote { text } => text, + _ => &"".to_string(), + }; + let text = [text, "\n"].concat(); + remove_el(&text, "br") + } +} + +pub(super) fn editor(State(state): State) -> Router { + Router::new() + .route("/update/:id", post(update)) + .route("/update/about", post(update_about)) + .route("/update/home", post(update_homepage)) + .with_state(state) +} + +pub(crate) async fn check_id( + jar: PrivateCookieJar, + db: &BlogDb, +) -> Result<(i64, String), Response> { + match jar.get("id") { + Some(id) => match id.value_trimmed().parse::() { + Ok(id) => match db.check_session(id).await { + Ok(user) => Ok((id, user)), + Err(_) => Err(StatusCode::UNAUTHORIZED.into_response()), + }, + Err(_) => Err(StatusCode::BAD_REQUEST.into_response()), + }, + None => Err(StatusCode::UNAUTHORIZED.into_response()), + } +} + +async fn update( + jar: PrivateCookieJar, + Path(id): Path, + State(state): State, + Json(content): Json, +) -> Response { + let db = state.db(); + + if let Err(response) = check_id(jar, db).await { + return response; + } + + let title = content.title(); + let _ = db.update_draft_title(&id, title).await; + + let _ = db + .update_draft_content(&id, serde_json::to_string(&content).unwrap()) + .await; + + StatusCode::OK.into_response() +} + +async fn update_about( + jar: PrivateCookieJar, + State(state): State, + Json(content): Json, +) -> Response { + let db = state.db(); + + let (id, user) = match check_id(jar, db).await { + Ok(info) => info, + Err(response) => return response, + }; + + let _ = db + .update_user_about(&user, serde_json::to_string(&content).unwrap(), id) + .await; + + let _ = db.update_page("about", about_page(db).await).await; + StatusCode::OK.into_response() +} +async fn update_homepage( + jar: PrivateCookieJar, + State(state): State, + Json(content): Json, +) -> Response { + let db = state.db(); + + let (id, user) = match check_id(jar, db).await { + Ok(info) => info, + Err(response) => return response, + }; + + let _ = db + .update_user_homepage(&user, serde_json::to_string(&content).unwrap(), id) + .await; + + let _ = db.update_page("index", home_page(db).await).await; + StatusCode::OK.into_response() +} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub(crate) struct Blocks(Vec); + +impl Blocks { + pub(crate) fn to_html(&self) -> String { + let mut html = String::new(); + for block in self.0.iter() { + html.push_str(&block.to_html()); + } + html + } + pub(crate) fn to_plaintext(&self) -> String { + let mut text = String::new(); + for block in self.0.iter() { + text.push_str(&block.to_plaintext()); + } + text + } + + pub(crate) fn first(&self) -> Option<&Block> { + self.0.first() + } + + pub(crate) fn title(&self) -> &str { + if let Some(Block::header { text, level: 1 }) = self.first() { + text + } else { + "Untitled" + } + } + + pub(crate) fn desc(&self) -> String { + html::sanitize( + self.0 + .iter() + .find(|block| match block { + Block::paragraph { text: _ } => true, + Block::header { text: _, level } => *level > 1, + Block::warning { title: _ } => true, + Block::quote { text: _ } => true, + _ => false, + }) + .map(|block| match block { + Block::paragraph { text } => text, + Block::header { text, level: _ } => text, + Block::warning { title } => title, + Block::quote { text } => text, + _ => "...", + }) + .unwrap_or("No description"), + ) + } + pub(crate) fn image(&self) -> Option<&str> { + self.0 + .iter() + .find(|block| matches!(block, Block::image { .. })) + .map(|block| match block { + Block::image { file, .. } => Some(file.url.as_str()), + _ => None, + }) + .unwrap_or_default() + } +} diff --git a/src/server/routes/api/mod.rs b/src/server/routes/api/mod.rs new file mode 100644 index 0000000..f6042b8 --- /dev/null +++ b/src/server/routes/api/mod.rs @@ -0,0 +1,167 @@ +use axum::{ + extract::{Path, State}, + handler::HandlerWithoutStateExt, + http::{header::LOCATION, HeaderMap, HeaderValue, StatusCode}, + response::{IntoResponse, Response}, + routing::{get, post}, + Router, +}; + +use axum_extra::extract::{Form, PrivateCookieJar, Query}; + +use serde::Deserialize; +use tantivy::{ + doc, + schema::{Schema, STORED, TEXT}, + Term, +}; + +use crate::BlogState; + +mod auth; +pub(crate) mod editor; +use auth::auth; +use editor::{check_id, editor, Blocks}; + +pub(super) fn api(state: BlogState) -> Router { + Router::new() + .route("/posts/:path", post(posts)) + .route("/user/update", post(user_update)) + .route("/drafts/:path", post(drafts)) + .route("/search", get(search)) + .with_state(state.clone()) + .nest("/auth", auth(State(state.clone()))) + .nest("/editor", editor(State(state.clone()))) +} + +#[derive(Debug, Deserialize)] +struct Entries { + #[serde(default)] + item: Vec, +} + +#[derive(Debug, Deserialize)] +#[allow(non_camel_case_types)] +enum PostsEndpoints { + delete, + unpublish, +} + +async fn posts( + Path(path): Path, + State(state): State, + Form(data): Form, +) -> Response { + let db = state.db(); + let mut schema_builder = Schema::builder(); + let id = schema_builder.add_text_field("id", TEXT | STORED); + match path { + PostsEndpoints::delete => { + for post_id in data.item.iter() { + let _ = db.delete_post(post_id).await; + let term = Term::from_field_text(id, post_id); + state.index_delete(term); + } + } + PostsEndpoints::unpublish => { + for post_id in data.item.iter() { + let _ = db.edit_post(post_id).await; + let _ = db.delete_post(post_id).await; + let term = Term::from_field_text(id, post_id); + state.index_delete(term); + } + } + } + state.index_commit(); + let mut headers = HeaderMap::new(); + headers.insert(LOCATION, HeaderValue::from_str("/admin").unwrap()); + (StatusCode::FOUND, headers).into_response() +} +#[derive(Debug, Deserialize)] +#[allow(non_camel_case_types)] +enum DraftsEndpoints { + delete, + publish, +} + +async fn drafts( + Path(path): Path, + State(state): State, + Form(data): Form, +) -> Response { + let db = state.db(); + match path { + DraftsEndpoints::delete => { + for id in data.item.iter() { + let _result = db.delete_draft(id).await; + } + } + DraftsEndpoints::publish => { + for id in data.item.iter() { + match db.publish_draft(id).await { + Ok(post) => { + let mut schema_builder = Schema::builder(); + let id = schema_builder.add_text_field("id", TEXT | STORED); + let body = schema_builder.add_text_field("body", TEXT | STORED); + let title = schema_builder.add_text_field("title", TEXT | STORED); + let content: Blocks = + serde_json::from_str(&post.content).unwrap_or_default(); + state.index_add_document(doc!(id => post.id, body => content.to_plaintext(), title => post.title)); + } + Err(_) => continue, + }; + } + state.index_commit(); + } + } + let mut headers = HeaderMap::new(); + headers.insert(LOCATION, HeaderValue::from_str("/admin").unwrap()); + (StatusCode::FOUND, headers).into_response() +} + +#[derive(Debug, Deserialize)] +struct SearchQuery { + #[serde(default)] + query: Vec, +} + +async fn search(Query(query): Query) -> Response { + let query = query + .query + .join(" ") + .split(" ") + .collect::>() + .join("-"); + let url = ["/search/", &query].concat(); + + let mut headers = HeaderMap::new(); + headers.insert(LOCATION, HeaderValue::from_str(&url).unwrap()); + (StatusCode::FOUND, headers).into_response() +} + +#[derive(Deserialize)] +struct UpdateUserInfo { + username: String, + password: String, +} + +async fn user_update( + jar: PrivateCookieJar, + State(state): State, + Form(info): Form, +) -> Response { + let db = state.db(); + let (id, user) = match check_id(jar, db).await { + Ok(creds) => creds, + Err(resp) => return resp, + }; + if info.username != user { + let _ = db.update_user_name(&user, &info.username, id).await; + let _ = db.update_password(user, info.password, id).await; + } else { + let _ = db.update_password(user, info.password, id).await; + } + let mut headers = HeaderMap::new(); + headers.insert(LOCATION, HeaderValue::from_str("/admin").unwrap()); + (StatusCode::FOUND, headers).into_response() +} diff --git a/src/server/routes/api/posts.rs b/src/server/routes/api/posts.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/server/routes/login.rs b/src/server/routes/login.rs new file mode 100644 index 0000000..e6f3605 --- /dev/null +++ b/src/server/routes/login.rs @@ -0,0 +1,76 @@ +use axum::{ + extract::{Path, State}, + http::{header::LOCATION, HeaderMap, HeaderValue, StatusCode}, + response::{Html, IntoResponse, Response}, + routing::get, + Router, +}; +use axum_extra::extract::PrivateCookieJar; + +use crate::{html, BlogState}; + +pub(super) fn login(State(state): State) -> Router { + Router::new() + .route("/", get(login_page)) + .route("/*next", get(login_next)) + .with_state(state) +} + +async fn login_next( + jar: PrivateCookieJar, + Path(path): Path, + State(state): State, +) -> Response { + let db = state.db(); + match jar.get("id") { + Some(id) => match id.value_trimmed().parse::() { + Ok(id) => { + if db.check_session(id).await.is_ok() { + return go_next(path).await; + } + } + Err(_) => { + {}; + } + }, + None => { + {}; + } + } + Html(html::login_status(&path, true)).into_response() +} + +async fn login_page(jar: PrivateCookieJar, State(state): State) -> Response { + let db = state.db(); + match jar.get("id") { + Some(id) => match id.value_trimmed().parse::() { + Ok(id) => { + if db.check_session(id).await.is_ok() { + return go_next("/".to_string()).await; + } + } + Err(_) => { + {}; + } + }, + None => { + {}; + } + } + Html(html::login_status("/", true)).into_response() +} + +async fn go_next(path: String) -> Response { + let next = path.as_str(); + let mut headers = HeaderMap::new(); + let value = match HeaderValue::from_str(next) { + Ok(value) => value, + Err(_error) => { + let mut headers = HeaderMap::new(); + headers.append(LOCATION, "/".parse().unwrap()); + return (StatusCode::FOUND, headers).into_response(); + } + }; + headers.append(LOCATION, value); + (StatusCode::FOUND, headers).into_response() +} diff --git a/src/server/routes/mod.rs b/src/server/routes/mod.rs new file mode 100644 index 0000000..897e6aa --- /dev/null +++ b/src/server/routes/mod.rs @@ -0,0 +1,384 @@ +pub(crate) mod api; +mod login; +use std::io::Cursor; + +use api::{api, editor::check_id}; +use axum_extra::{extract::PrivateCookieJar, response::Html}; +use login::login; + +use axum::{ + body::Body, + extract::{rejection::PathRejection, DefaultBodyLimit, Multipart, Path, State}, + http::{ + header::{CACHE_CONTROL, CONTENT_TYPE, EXPIRES, LOCATION, PRAGMA}, + HeaderMap, HeaderValue, StatusCode, + }, + middleware::from_fn_with_state, + response::{IntoResponse, Response}, + routing::{get, post}, + Json, Router, +}; +use serde::{Deserialize, Serialize}; +use tantivy::{ + collector::TopDocs, + query::QueryParser, + schema::{Schema, STRING, TEXT}, + DocAddress, Document, Score, TantivyDocument, +}; +use tokio_util::io::ReaderStream; +use tower_http::{limit::RequestBodyLimitLayer, trace::TraceLayer}; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + +use crate::{ + html::{ + self, about_editor, admin_page, draft_editor, homepage_editor, search_page, + search_page_no_query, + }, + BlogState, +}; + +use super::middleware::logged_in; + +pub(super) async fn make_router(state: BlogState) -> Router { + #[cfg(debug_assertions)] + tracing_subscriber::registry() + .with( + tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| { + // axum logs rejections from built-in extractors with the `axum::rejection` + // target, at `TRACE` level. `axum::rejection=trace` enables showing those events + format!( + "{}=debug,tower_http=debug,axum::rejection=trace", + env!("CARGO_CRATE_NAME") + ) + .into() + }), + ) + .with(tracing_subscriber::fmt::layer()) + .init(); + let router = Router::new() + .merge(protected_routes(state.clone()).await) + .merge(blog(State(state.clone()))) + .route("/assets/*asset", get(asset).with_state(state.clone())) + .nest("/api", api(state.clone())) + .nest("/login", login(State(state.clone()))) + .route("/", get(pages).with_state(state.clone())) + .route("/*path", get(pages).with_state(state.clone())) + .route("/search", get(search_empty)) + .route("/search/*query", get(search).with_state(state.clone())) + .fallback(get(handle_404)) + .layer(DefaultBodyLimit::disable()) + .layer(RequestBodyLimitLayer::new(250 * 1024 * 1024)); + #[cfg(debug_assertions)] + let router = router.layer(TraceLayer::new_for_http()); + router +} + +async fn protected_routes(state: BlogState) -> Router { + Router::new() + .route("/admin", get(admin).with_state(state.clone())) + .route("/editor/:id", get(editor).with_state(state.clone())) + .route( + "/editor/uploadFile", + post(editor_upload_file).with_state(state.clone()), + ) + .route( + "/editor/fetchUrl", + post(editor_fetch_url).with_state(state.clone()), + ) + .route_layer(from_fn_with_state(state.clone(), logged_in)) +} + +async fn pages( + path: Result, PathRejection>, + State(state): State, +) -> Response { + match path { + Ok(path) => match state.db().get_page(path.0).await { + Ok(page) => Html(page).into_response(), + Err(_) => four_oh_four(), + }, + Err(error) => match error { + PathRejection::FailedToDeserializePathParams(_) => { + match state.db().get_page("/").await { + Ok(page) => Html(page).into_response(), + Err(_) => four_oh_four(), + } + } + _ => four_oh_four(), + }, + } +} + +pub(super) fn blog(State(state): State) -> Router { + Router::new() + .route("/blog", get(blog_root)) + .route("/blog/*path", get(blog_post)) + .with_state(state) +} + +async fn blog_root(State(state): State) -> Response { + let db = state.db(); + let page = html::blog_roll(db).await; + Html(page).into_response() +} + +async fn blog_post(Path(id): Path, State(state): State) -> Response { + let db = state.db(); + match db.get_post(id).await { + Ok(post) => { + let html = html::blog_page(post.id, db).await; + Html(html).into_response() + } + Err(_) => four_oh_four(), + } +} + +pub(crate) fn four_oh_four() -> Response { + ( + StatusCode::NOT_FOUND, + Html(html::make_404("Page not found!")), + ) + .into_response() +} + +pub(crate) async fn editor( + jar: PrivateCookieJar, + Path(id): Path, + State(state): State, +) -> Response { + let db = state.db(); + match id.as_str() { + "new" => match db.add_draft("Untitled", "", "").await { + Ok(draft) => { + let mut headers = HeaderMap::new(); + headers.insert( + LOCATION, + HeaderValue::from_str(&format!("/editor/{}", draft.id)).unwrap(), + ); + (StatusCode::FOUND, headers).into_response() + } + Err(_) => { + let mut headers = HeaderMap::new(); + headers.insert(LOCATION, HeaderValue::from_str("/admin").unwrap()); + (StatusCode::FOUND, headers).into_response() + } + }, + "about" => { + let (_id, user) = match check_id(jar, db).await { + Ok(info) => info, + Err(response) => return response, + }; + let about_content = db.get_user_info(user).await.unwrap().about; + let page = about_editor(&about_content); + Html(page).into_response() + } + "home" => { + let (_id, user) = match check_id(jar, db).await { + Ok(info) => info, + Err(response) => return response, + }; + let home_content = db.get_user_info(user).await.unwrap().home; + let page = homepage_editor(&home_content); + Html(page).into_response() + } + _ => { + let draft = match db.edit_post(id).await { + Ok(draft) => draft, + Err(_) => { + let mut headers = HeaderMap::new(); + headers.insert(LOCATION, HeaderValue::from_str("/editor/new").unwrap()); + return (StatusCode::FOUND, headers).into_response(); + } + }; + let page = draft_editor(&draft.content, &draft.id.to_string()); + Html(page).into_response() + } + } +} + +#[derive(Serialize)] +struct UploadResult { + success: usize, + file: Option, +} +impl UploadResult { + fn success(url: String) -> Self { + Self { + success: 1, + file: Some(UrlUpload { url }), + } + } + fn failure() -> Self { + Self { + success: 0, + file: None, + } + } +} + +pub(crate) async fn editor_upload_file( + State(state): State, + mut fields: Multipart, +) -> Response { + let db = state.db(); + let field = match fields.next_field().await { + Ok(option) => match option { + Some(field) => field, + None => { + return (StatusCode::BAD_REQUEST, Json(UploadResult::failure())).into_response() + } + }, + Err(_) => return (StatusCode::BAD_REQUEST, Json(UploadResult::failure())).into_response(), + }; + let name = match field.file_name() { + Some(name) => name.to_string(), + None => "".to_string(), + }; + let data = match field.bytes().await { + Ok(data) => data, + Err(_) => return (StatusCode::BAD_REQUEST, Json(UploadResult::failure())).into_response(), + }; + + match db.add_asset(name, data).await { + Ok(asset) => { + let slug = ["/assets/", &asset.slug].concat(); + Json(UploadResult::success(slug)).into_response() + } + Err(_error) => ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(UploadResult::failure()), + ) + .into_response(), + } +} + +#[derive(Deserialize, Serialize)] +pub struct UrlUpload { + url: String, +} +pub(crate) async fn editor_fetch_url( + // jar: PrivateCookieJar, + State(state): State, + Json(UrlUpload { url: _ }): Json, +) -> Response { + let _db = state.db(); + (StatusCode::INTERNAL_SERVER_ERROR, Json(r#"{"success": 0}"#)).into_response() +} + +async fn asset(Path(slug): Path, State(state): State) -> Response { + let db = state.db(); + match db.get_asset(slug).await { + Ok(asset) => { + async { + // i still don't quite know how to do async rust + let stream = ReaderStream::new(Cursor::new(asset.data)); + let body = Body::from_stream(stream); + let mut headers = HeaderMap::new(); + headers.append(CONTENT_TYPE, HeaderValue::from_str(&asset.mime).unwrap()); + (headers, body).into_response() + } + .await + } + Err(_) => StatusCode::NOT_FOUND.into_response(), + } +} + +async fn handle_404() -> Response { + four_oh_four() +} + +async fn admin(jar: PrivateCookieJar, State(state): State) -> Response { + let db = state.db(); + // this can be unwrapped because our login middleware + // ensures the user has a valid id + let session_id = jar + .get("id") + .unwrap() + .value_trimmed() + .parse() + .unwrap_or_default(); + let page = admin_page(session_id, db).await; + let mut headers = HeaderMap::new(); + headers.append( + CACHE_CONTROL, + HeaderValue::from_str("no-cache, no-store, must-revalidate").unwrap(), + ); + headers.append(PRAGMA, HeaderValue::from_str("no-cache").unwrap()); + headers.append(EXPIRES, HeaderValue::from_str("0").unwrap()); + (headers, Html(page)).into_response() +} + +#[derive(Serialize, Deserialize, Default, Debug)] +pub(crate) struct SearchResponse(Vec); +impl SearchResponse { + pub(crate) fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl IntoIterator for SearchResponse { + type IntoIter = as IntoIterator>::IntoIter; + type Item = SearchResponseEntry; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct SearchResponseEntry { + // idk why tantivy makes these fields sequences + body: Vec, + pub(crate) id: Vec, + title: Vec, +} + +async fn search_empty() -> Response { + Html(search_page_no_query()).into_response() +} + +async fn search(Path(query): Path, State(state): State) -> Response { + let query = query.split("-").collect::>().join(" "); + + let closure_query = query.clone(); + + let closure_state = state.clone(); + let response = tokio::task::spawn_blocking(move || { + let index = closure_state.index(); + let reader = index.reader().unwrap(); + let searcher = reader.searcher(); + let mut schema_builder = Schema::builder(); + let (id, title, body) = ( + schema_builder.add_text_field("id", STRING), + schema_builder.add_text_field("title", TEXT), + schema_builder.add_text_field("body", TEXT), + ); + let schema = schema_builder.build(); + let query_parser = QueryParser::for_index(index, vec![id, title, body]); + let query = query_parser.parse_query(&closure_query).unwrap(); + let top_docs: Vec<(Score, DocAddress)> = + searcher.search(&query, &TopDocs::with_limit(100)).unwrap(); + let mut json = String::new(); + json.push('['); + let mut docs_iter = top_docs.iter().peekable(); + while let Some((_score, doc_address)) = docs_iter.next() { + let retrieved = searcher + .doc::(*doc_address) + .unwrap_or_default(); + json.push_str(&retrieved.to_json(&schema)); + if docs_iter.peek().is_some() { + json.push(','); + } + } + json.push(']'); + // TODO: Deserialize directly to SearchResponseEntry + let result = serde_json::from_str::(&json); + result.unwrap_or_default() + }) + .await + .unwrap_or_default(); + + let db = state.db(); + let html = search_page(query, response, db).await; + Html(html).into_response() +} diff --git a/src/templates/admin-widgets/draft.html b/src/templates/admin-widgets/draft.html new file mode 100644 index 0000000..f72bf1a --- /dev/null +++ b/src/templates/admin-widgets/draft.html @@ -0,0 +1,7 @@ +
    • + +

      +

      +
      + +
    • diff --git a/src/templates/admin-widgets/drafts.html b/src/templates/admin-widgets/drafts.html new file mode 100644 index 0000000..b0bab18 --- /dev/null +++ b/src/templates/admin-widgets/drafts.html @@ -0,0 +1,14 @@ +
      +
      +

      Drafts

      + New Draft +
      + +
      + + +
      +
        +
      + +
      diff --git a/src/templates/admin-widgets/post.html b/src/templates/admin-widgets/post.html new file mode 100644 index 0000000..3c5165d --- /dev/null +++ b/src/templates/admin-widgets/post.html @@ -0,0 +1,8 @@ +
    • + + +

      +

      +
      + +
    • diff --git a/src/templates/admin-widgets/posts.html b/src/templates/admin-widgets/posts.html new file mode 100644 index 0000000..52a8fb6 --- /dev/null +++ b/src/templates/admin-widgets/posts.html @@ -0,0 +1,15 @@ +
      +
      +

      Published Posts

      +
      +
      +
      + + +
      +
        +
      +
      +
      diff --git a/src/templates/admin-widgets/user.html b/src/templates/admin-widgets/user.html new file mode 100644 index 0000000..e177f8d --- /dev/null +++ b/src/templates/admin-widgets/user.html @@ -0,0 +1,16 @@ +
      +
      + Update Home Page + Update About Page +
      +
      +
      + +
      +
      diff --git a/src/templates/admin.html b/src/templates/admin.html new file mode 100644 index 0000000..d1ba99c --- /dev/null +++ b/src/templates/admin.html @@ -0,0 +1,5 @@ + +
      + + +
      diff --git a/src/templates/blog-page.html b/src/templates/blog-page.html new file mode 100644 index 0000000..8793994 --- /dev/null +++ b/src/templates/blog-page.html @@ -0,0 +1 @@ + diff --git a/src/templates/blog-roll-entry.html b/src/templates/blog-roll-entry.html new file mode 100644 index 0000000..3bbd69a --- /dev/null +++ b/src/templates/blog-roll-entry.html @@ -0,0 +1,10 @@ +
    • + + +
      + +

      +

      +
      +
      +
    • diff --git a/src/templates/blog-roll.html b/src/templates/blog-roll.html new file mode 100644 index 0000000..a047478 --- /dev/null +++ b/src/templates/blog-roll.html @@ -0,0 +1,2 @@ +

      Blog

      +
        diff --git a/src/templates/default.html b/src/templates/default.html new file mode 100644 index 0000000..535d7ae --- /dev/null +++ b/src/templates/default.html @@ -0,0 +1,16 @@ + + + + + + + + + + + +
        +
        + + + diff --git a/src/templates/head/content.html b/src/templates/head/content.html new file mode 100644 index 0000000..bb7ace7 --- /dev/null +++ b/src/templates/head/content.html @@ -0,0 +1,4 @@ + + + + diff --git a/src/templates/head/meta.html b/src/templates/head/meta.html new file mode 100644 index 0000000..1e308d8 --- /dev/null +++ b/src/templates/head/meta.html @@ -0,0 +1,5 @@ + + + + + diff --git a/src/templates/login-status.html b/src/templates/login-status.html new file mode 100644 index 0000000..9f3ad04 --- /dev/null +++ b/src/templates/login-status.html @@ -0,0 +1,3 @@ + diff --git a/src/templates/login.html b/src/templates/login.html new file mode 100644 index 0000000..7503346 --- /dev/null +++ b/src/templates/login.html @@ -0,0 +1,23 @@ +
        +
        + +
        diff --git a/src/templates/post-editor.html b/src/templates/post-editor.html new file mode 100644 index 0000000..196d6fc --- /dev/null +++ b/src/templates/post-editor.html @@ -0,0 +1,7 @@ +
        +
        +
        + + + + diff --git a/src/templates/search-page.html b/src/templates/search-page.html new file mode 100644 index 0000000..92eeb78 --- /dev/null +++ b/src/templates/search-page.html @@ -0,0 +1,15 @@ + + + + + + + + +
        +

        +
          +
          + + + diff --git a/src/templates/site-header.html b/src/templates/site-header.html new file mode 100644 index 0000000..4307c4c --- /dev/null +++ b/src/templates/site-header.html @@ -0,0 +1,19 @@ +
          + +

          Evie Ippolito

          +
          + +