From a8c0bb1641970756933c9dbe94356cd1a95d8d9c Mon Sep 17 00:00:00 2001 From: august kline Date: Wed, 13 Nov 2024 21:41:12 -0500 Subject: [PATCH] Initial commit --- .DS_Store | Bin 0 -> 6148 bytes .gitignore | 3 + Cargo.lock | 3339 ++++ Cargo.toml | 51 + build.rs | 56 + src/client/assets/css/admin.css | 256 + src/client/assets/css/blog.css | 44 + src/client/assets/css/editor.css | 200 + src/client/assets/css/login.css | 73 + src/client/assets/css/style.css | 432 + .../fonts/Atkinson-Hyperlegible-Regular.woff2 | Bin 0 -> 15884 bytes src/client/assets/fonts/Redaction-Bold.woff2 | Bin 0 -> 29684 bytes .../assets/fonts/Redaction-Italic.woff2 | Bin 0 -> 29212 bytes .../assets/fonts/Redaction-Regular.woff2 | Bin 0 -> 28392 bytes src/client/assets/images/login.jpg | Bin 0 -> 118512 bytes src/client/assets/js/editor.js | 13695 ++++++++++++++++ src/html.rs | 745 + src/main.rs | 16 + src/server/middleware.rs | 43 + src/server/mod.rs | 347 + src/server/routes/api/auth.rs | 97 + src/server/routes/api/editor.rs | 267 + src/server/routes/api/mod.rs | 167 + src/server/routes/api/posts.rs | 0 src/server/routes/login.rs | 76 + src/server/routes/mod.rs | 384 + src/templates/admin-widgets/draft.html | 7 + src/templates/admin-widgets/drafts.html | 14 + src/templates/admin-widgets/post.html | 8 + src/templates/admin-widgets/posts.html | 15 + src/templates/admin-widgets/user.html | 16 + src/templates/admin.html | 5 + src/templates/blog-page.html | 1 + src/templates/blog-roll-entry.html | 10 + src/templates/blog-roll.html | 2 + src/templates/default.html | 16 + src/templates/head/content.html | 4 + src/templates/head/meta.html | 5 + src/templates/login-status.html | 3 + src/templates/login.html | 23 + src/templates/post-editor.html | 7 + src/templates/search-page.html | 15 + src/templates/site-header.html | 19 + 43 files changed, 20461 insertions(+) create mode 100644 .DS_Store create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 build.rs create mode 100644 src/client/assets/css/admin.css create mode 100644 src/client/assets/css/blog.css create mode 100644 src/client/assets/css/editor.css create mode 100644 src/client/assets/css/login.css create mode 100644 src/client/assets/css/style.css create mode 100644 src/client/assets/fonts/Atkinson-Hyperlegible-Regular.woff2 create mode 100644 src/client/assets/fonts/Redaction-Bold.woff2 create mode 100644 src/client/assets/fonts/Redaction-Italic.woff2 create mode 100644 src/client/assets/fonts/Redaction-Regular.woff2 create mode 100644 src/client/assets/images/login.jpg create mode 100644 src/client/assets/js/editor.js create mode 100644 src/html.rs create mode 100644 src/main.rs create mode 100644 src/server/middleware.rs create mode 100644 src/server/mod.rs create mode 100644 src/server/routes/api/auth.rs create mode 100644 src/server/routes/api/editor.rs create mode 100644 src/server/routes/api/mod.rs create mode 100644 src/server/routes/api/posts.rs create mode 100644 src/server/routes/login.rs create mode 100644 src/server/routes/mod.rs create mode 100644 src/templates/admin-widgets/draft.html create mode 100644 src/templates/admin-widgets/drafts.html create mode 100644 src/templates/admin-widgets/post.html create mode 100644 src/templates/admin-widgets/posts.html create mode 100644 src/templates/admin-widgets/user.html create mode 100644 src/templates/admin.html create mode 100644 src/templates/blog-page.html create mode 100644 src/templates/blog-roll-entry.html create mode 100644 src/templates/blog-roll.html create mode 100644 src/templates/default.html create mode 100644 src/templates/head/content.html create mode 100644 src/templates/head/meta.html create mode 100644 src/templates/login-status.html create mode 100644 src/templates/login.html create mode 100644 src/templates/post-editor.html create mode 100644 src/templates/search-page.html create mode 100644 src/templates/site-header.html diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..abd3415466323db333819fbf2474919b7f55510b GIT binary patch literal 6148 zcmeHK!AiqG5S^{D6opdIgU6f%L4^K6EKxj((z6iLNLy%4vF%Ba97M$*@IO51tswL} zgov zpu^9GBXor_#L$BjVqJodByaCl|DzcUBVpvZ>jarYKb9wNWP0M=}h z3hi?dVL%uV1~>zBKKR%O1B;nKeRN=_uK8KBP)ADQ93%#?`v~VfkEko0b#&p!2ESWjq3ki@%`U*k~d*M z82DEVC@*Y=4P26~t+~Zft@W`**ht7OGpJp#v*lPnP$}NPrUi9AJs<`aGlMvSB0mC} L2I+)>A7$VZ>8GOS literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..99b3c6f5e440bc94bb70b1727928066cadfd1bbf GIT binary patch literal 15884 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 literal 0 HcmV?d00001 diff --git a/src/client/assets/fonts/Redaction-Bold.woff2 b/src/client/assets/fonts/Redaction-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..392d60d822b5d5c0b2874b6765a4669ce9cd2952 GIT binary patch literal 29684 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%0AJn_?Rr6$_K?NE5x>J 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 H^%ejCKTkI3 literal 0 HcmV?d00001 diff --git a/src/client/assets/fonts/Redaction-Italic.woff2 b/src/client/assets/fonts/Redaction-Italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..1bd3c5c96e158102e100194c77deb1dc9a974db4 GIT binary patch literal 29212 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 Dc-H{* literal 0 HcmV?d00001 diff --git a/src/client/assets/fonts/Redaction-Regular.woff2 b/src/client/assets/fonts/Redaction-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..d1876548fa87ca673916207d8fee5d4857b45048 GIT binary patch literal 28392 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 Pn)_L?_CQeV9RL6T+e0K* literal 0 HcmV?d00001 diff --git a/src/client/assets/images/login.jpg b/src/client/assets/images/login.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1330c43f559aa827e2e31d0dd03cf35a458d21f9 GIT binary patch literal 118512 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 z≈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

>bb3p=f^5gT%1b0R~m(&Snhvt_pBg!>lUma(|=J zk1c=TQ?h24xndyAI^RHDW@Ln2ok8(`Jga^$FnjT4;Y*5d!QNuU2o=~ym zb3{47-gUFspxYMU%r{`t!)MKmpj&J&FyEk@XyqUhxQ-+L&_ax%U5y88JU@_le`jM@ zPHIW2Mq?yH%^knmQ^I8SVyh1}Eb{cEd;ChpC+#AW1R6F|@YJ1;xdPN7#_~Ib3gX#| z)t$W#Q=V9vnmAkYEaLOUx^0UKC#<_Et`{n1NU`sLD^7QJoEdRt$(387%bb8z^J7I0 zDna^kYr`;JxJoZVi2c!96VaeyC2j&z$-9#?Xn}VXact<}wF#)pl6Sn7U(Yre z|BIA;?_3XsdU#OVzsLc;|D0{!sOtw`pfe+xBb9Aow@h@WNm=RC{vAId;7#j^P))HQ zNSmaOqKGJwqmkc1GZ&i6*Y=LRr>4k$^85NpJ@TsPo7WTJy7oXgUx3JSTps8GW7!WYQcZNCD1l=0{_dU&IVV$%=JqVd5$+Q z;P-a*TaW8kP|M6*^_w(tB<=*8HT>g;&M|jG;>!23u>X;z)-i*TF7GA!g|Tuh#pm;7 z(jSeVrp?L?j*Z3%?p5}Nfr*CXXT<1U!}}*9Dc1@|ts>eeK^E_r(<6We5?nw;P15A=dra_o^@!K2!;R#7E ztF)WU_~SP$IVHu)V}wgt+WPsc8@ks10@7;)PCUsslz#7*sc?Pq&)F?+nB(C*#VksN zli}b_iw4U`%UO5XJzjxtqAe@J=-5u~L0!-3TW*)&3UVIo_SbaOP~-JKsS+=FM|JE; zZ)jqx9eKj7)2+LIN#+6S6fi%VOe)eqB+pXnQ*(7{cm-kok6UQZ(#=^{OicyQ3Z2@U zCOZ58H1^4t-=c=Uh$y)?6RvOXhA+LhW4jl+XhFZn**RV_AJLaO+C_7R>d?{(qy&5S0@}yXyv#fl@o^1<4L?!F8g zsdVC4J)jF7caZL;889lWd4Kq8+4elD2wP>((~dRWu-Edl3Y#FFq71naQ9HKre)P``0$G80n(INo8>kSA0y(SVCIe5Nosk|`NuU`#88)u=mHL`;FH6neoCfT@_;}*e zd-m+W+;vIJ3NWSgR66UJlYFwOxp@#hV47&8c~fe{;ulzH8+8kFH-n8GaxT<+?^w#B;s%lre;dQxW9 zgusoWq6{7kU0XO8?MU$tTx`dp1wH#vDdo(X;n4`fF{Q8@f2xK^hVA|p zA$;y_A$jy!fMK-$YUp5S4-^1BPw>|t!Y_%=ZjW(e#bYn+%UnO!HYT20rH3Rdt;ji+i@oVG^T{I0Kr~Wo{dzvk4}AgT z_%vIJ3IVBAMVT*x@uD8}yA?-dvx`9w7F%LuNMTk9r`||I423@42|qQZSqXwg>YK~r zpb$Qzp?f;+oX%?Zh-TyiOLyH5InvM+wjX(nCH6g)XYfbeY}|_1#q_kVaVnksg0L}&*6%R_q5p7(hx3O?$-R@lG$x!{ZD zNL!Iw=Yiy%$u|mk#lEKP$^nXCy7X8HXk2W@`pq?>C^9MUFaZ+ASp^9a$w#eUC(79}E1@U>GDWR0wQS2aa z5T5PYGou+;RtPvOMPqx{AS0iBnpLBc{D z82j6z44(0Q&g-P`c(SpHVfa5k;yUh~cBOH!go7r1U=>@iT5?86uR~!n@RsH&_8IA; zFEqjT)*SSnmSSGWzEx`>n$T}kEe^Amr{U87)NI&V5Xr7%QrL$Uu!dd zK5H45)|pK?sMQdPO0Eu69Mr$O$r2K*(6*;m5!HsfJdOwjffyfMGOg}lGh%KUo8sdI zH5fR+!%+NI`U1>XhQ0vZ?l@CWN;Fz!*x@5XqcrFe(b>w;2fP=npnTWOOvfvM&`;XU zJ@4n9GK-YA61g^yLOQN`!V_V`eMGQkW8!rwd8Yu<)Vx&Wd6mq--&J_yhb!(F38QUX z=_vmWUeuQPNLL6dwI(i^$<8ZpLE`-c74nLF3yEm?`-gSj-jG_(FTljXV^(IABRHtn zUuMPlZ}VfZ=?j$L(=xo53^dr{8^zLiJ2B&HgE|L19r|j&7AKT2@XZ4z&jI@D9Bu9k z6X@<)$nrH+c#2-25WT#^Y(a3m^ z3?Te4H*s7nRBH@V988c*3fEAhFL_p;!*DBhy*tImSZ){HdteS4c*q4$z40^ND_msw zS!XG&P_5dYeuNuIKAU3azd=WxxW2!Jf^d1KEs;UHDDRH29`z-E6mMt0DrysUxaLFs zm@4+0mP1`nFt~5HwJL=wUfiY0Aum*w)s*Ws8eHapc`=TDZcR+eL+?5o$(I7Gb|tHBz|<-p4Z^f)Bt{pWsRA}orowmoj!*0L&^E4hJ9I1yD?Rs0Kx zKj!}jSx8f6W1#x!mXJbsZE|H@yo_Q6cF(EhED@b?OY(N<+niVd>)uV3HQBXYGF-37 zG5^S5Os+Q|BWFzGrSc{E4P3qJK3&|IPV41Crd^3R+|B$Lx;oeJ|H$^|rac zm%{ZfdEGHT2BrudLCDMNRO(Nz-jXaCL1$dt+=ax|K)H3)J8vERKc&^a-x`SsIKou% z%{IETuUAp%_2d+L0!CgSae1#tairg2zo_UCKY3U-X@Ft5899#;1#d|#Uz->#fjE7{ z`%?`OOSU!_c?+CW`mJ=WF`=)O`Ga2D^SCLcw7PpctTFHRZY--)bLP(O+rmq1~s61*S zsu$;f%lOaOEkn1(>PA2_TH*W56Ia5`454SCnHtdk%34_~P|Z{0ztp6uu3uo>7==1Z zICr%?8M_+9s0hzFt!pc|7!KMBmfPjkx!A>zkTwPt#E$2*X;6Pe>L3w2BUXc_v)jdm z5tk#bw70}ov+s@77Uukc4vKR*uPy$jg%bIMsYE*{t!HoVXuhg>rqbJ5QjTAC`F4RO}=x_RPrO`zLb39)c zQQ3T^yI`Ya2WiL3la}iFH9q1b8c>Ur_)<5}hbPe7U`>FQSJAY&Ty6V1?>4aG%0aa+ z+lsf1V+yW@OK2eG{?>maTYl-EK6w@c1S~nF6NKSkNgu5nk!u4$n&v-!L7gqSGC}4_ zIx=XyhO~wTFLGvoO^A)jc6{6ZuK6fx<1`a~y+)HDb8D`gg@GDLpT+Kx*JM(x!i10L zjRiH}$;!s)IDKQYS0)(v&*tm@%vH#=@=u+k4*GAtn% zn|RE{;Bvm4DhfHG#<80HM)Z)dgtfVG2EfSz2p`w~{Q-Erw0JHpKLzf3S;2;-R_YDj zXH22)jWr>4qTCF8TUv*am6@;lsFDZ#Q7fObnZ;w-EpfJQP=XfEnsX1xSFSONG|+~hlZoh>Ub+IX&piRO;IQW3kNs>4~z+OXvn zey%fri;gFZSZ@_gKQuTG*{^0|(Rc;!M^|9xLci?ubc&?*xo-KxI=d>_@j^dTicE7(Kgx)BqQd)aNrIuq7+; zz`Xi(b}Jg1x=LFBpEB54yz=(UldFc7b3POq5M-P}%Rz^#ta5#E;Lvo{tn!CR8FH-0 zs#57!4V*!usvxz0q&(=DV;C2oySlxEWXR%;Kr)#;5zoXz#G7gdVL=a~sQ`gg=c^(U2 zz3a@gqyDB}Bei0#Tgh1+(rT{~b6TyP!TiWRDJuUuN9^ThOR<=}V#cJf-zfA;)a5cC zZ!C`uHpQJJIn2PItkApDS1~(*9@)erGtY88&0XWj$B0;)Es!EVq{R|(^=(Y*Z&G! zKeiyHMgyT-M|yxta!i(LRp4_ObvBW8jz-il6Il%JXY~gy)nA(f-zhlFs6srP4?*qn9s*vXxT_>%*aO!#BLRKm&u~~2&1TlSkfN3)mG@4;OFW)`lSJI z1*Q@w%e&tEyN|b+eqqXsK{Pclbdf+YGe_x%;^hQ2ko-{#z?&2h=Vy)a)Q<6{Yx;lm z`j_${FW01Z$6-#m?Rif;UuYW1FHw$QleDj!Skmz70iwZ>weC+16=jhw%(r{V-#oB1Dc`57 z8jbmMiG9`Lto}y*h6RzYb2m99I`!=xu%5?nVww6cV@GdM58IeDxM8 zy4&%|f5Ny40p?B3P;RwS3=!d0G=T^n4H# zozrN6YA6F8i95y;jC-|7w&VG7IZIQ$^}17k1(Jepjs~0ks}%le^r)qbnwKPw@wjoQ zx@jB#l{sSFTkZcg(L?b~ADLx4QWydl%a}nWvr_U&erv53if_Cr3xL7Lnw=9YLpYYs z?AN~kTUu=U+$2~f8~x1_EK{c5}ky>wG|{qUZte z5pUNljYaut+2iE3u6LpP@E=l;s@%Aqb8qPj3ZDM)3E4THG|y@a|Iu{ffm)Z;IYcd2 zVx;W(TW9*_P)L3K3L-!Q_T8uFTvjf9$5^jBnYeVI!9+HRz%9VI6l_?oTK^t7HaLHL zXSv$qPG}Sy#-aDXVHv}7&6xus<;on&X?!gN>NrxH_&;|7N3E<45YrryeExjK{Vkjc zA3J+`{NIm$oEp~eKYUxY9xl>>Y|XPnw~;o!MHE@Vt?QBs$X|ew@skavXGLsImVjBw zU98ZjjOoI)ET4;4Be1Z|B*TnsKbdL{7HOu|rJsVpV`b#-taodw$)+gnGwWgug@E%F zU+^OQHcc`{WybHnI270mo?rAVj-)-GIs7gY1 zD6YEpHHFjJtn6WnW|;x^$&TgQQ9Mc=_uhW+$}^)m9u2}MxUFl;p26KVaaF(P!W#sm5IG+E4WvGcb2GL4|Pu}SR3v`u?>^e5>7hl zXcoz3-pe-4gRwFW>kvn?uf{A3z+-*OGnY$TS5s^<-0#f`1saTd&4=kCD@e7m%eCY$ z_?Kol*K49r983DlXH37Ca2fbE?4gMZc_o_#jTMzLN92v_r}x%Ea+3=!Q((=`x2~$0 zX-R;hJmeI!k9x?Ouo|B0yit`2 zWe-5SY!pU>gJkkOZ%ctVdr$8&1z1JJ6_1u?4B1gU4f73V7R~>yo^`&wZPuzJ#P()E z$;RET$l6Awz>si<)@ZcM=sad-0R)0bm;e6O=hE!GcCm)u4mci4t`t1y;+0TB?-DDwEl@H=gQz?;37diCIit&mp{gPAFl*88RoN6j5o2_J5K zBvfKm&`uVNx?mA4$?u$1rcx0-%&N#&EAnctZ<9qft{R?Y^FV-@3+feJwwhG?7VLNT z)oD+bGf$DgX}t9#3rS0ZWwC5?Ae}P{-n#M7ft84|`R?YEjkhq~Sx0dXWf@t4%p()mam9@9NoCuw6ITXQIjfJ&@?*pN z-hag#dFxD`X6wU0;rtMlLFCU7goD#LvI`9_7Qv1T`5lL&xSO!P#sM9P2N^z4E!m5h z{S?gB$|{6Bdhagymv?0WV4Zs{Aa_2OUs1t|8P; zBl}KPIY;5JmT#<+Kdk(;PAizwkG*|tIVr1(5`szfO^`UY;nsII4A zDJIk&76R0tTPJ|c){%_8;nzI;y(%tS8p)pw^Hp7PN_+FsPs&aP%U#XFwLFAK{E1Dj z)(cFO4qh!viwe*1T>M#9f=F5J7U|G{mtpXl>)$>4xzRH6O4|M^5Uox2UoDzV_JF1y zVVWKva*B+!jJXB0!Z8Hph$5MgDaHD5-;y-CK>t|md$>9lM6pfwZo};LLmYdMG9m-J*ab!V*%gj4Q4t|hVDAINRKj% z20i+P;pht}sdpBp40*}CP_l?JAbVIX*~O#WR&q1G7JnL-Ic<3>9sGV=^x~yXp6Y&) zAj8W0JQ_@M&K|AI2W4{<#%C);q{QXdD#9?P3=a)LCZsGQxZ`Gu;(K%g2Y^^5_;e1m zuxvfXDs6a)6awKx{_G!AF`P5|>s;67m#cv+7$QC_V7Y?868y*5*wl-C zXV>fKZ`r)!fboMH%>n%dB&#_QWo-jPuLG$&ZFVR1vHU@(%E>wxw{-SNb2J<+NN=z^ zyMVTdru1SPj|W;ki>4ioCCV+VH!7@*@f#mMXzcZ4SDG>9Ufdr*-E)Z@_vO(uExymZ z%1pCWv0X_suB0Idzgb594})SBfWi+Bsy^sbBBnHU~>hTCd zvPQR2d;fcHPz?B;x*p2KU6HU0OI^fjl%@5aXJ7n5KyQQ3kP)gcc zj2rlNMm1iVJ_JH-pNf&Zo81bL=L;yh_HjurDaTFg6IozOsktanI8J-lnSIlr`v zmy*S)Q__O>%f?&VE^H*x?b0>FVT9L8&jz^SklsPBUfw7KTcBhb$#*EZ*5@(!Dvqm8bAh`YIG*J~W``C325AS^R`p)w0*8w2UC;&bE zdq*il7G{{B_@z3zg6;gXA^#piTK6=+j$w=_=1d!CopnYD-<<90^z!FdZ2#6$hL%8D z1jgNiMdkYfpF?b0+$p|eIugVkh9aAMYNds<-v#$g6u;ALiw(OJVyX73bcS-U_LCeQ ze}9*G%o|;sSISxrc_Aq9Ek$*DHEW5HASei{tp$vs;y*v7DM5$c1UGhc*!C-~nRPu` zJ?E4q^{sklP$6ZkVK75g!!c&+T!X=N!_ZM(J;3&N+v5uTr!o_`cirdbye<5=^XjLS zYP4LmM;;K0omwQY=&Wk>&Ie(|2y05H0#Chg2Pv^-X9(nh2%C~?9`-0reZnUYB35*= z@42Ioje#bR^dLRgG14l57iBJ5MA8QWVw+dz2$N&x4 zJyd(DVfCP@-K9aMmx6mCXIajS#)VQrR6+w(dDv#@)rLw>R(R(iZ6U!M2yN2X->A1j zkIUXlRi1~rLvgRvw{Czz0tPe@W(HO>FKDJZeC63+R0wCXwLi}gs4V~f`2eIGHizn| zg+^T>QKv**0E3EeTiHJO0C!$_`Rk6st~ia2q*gxAZH&ZgtIc#wGfvTft6@9^%LUD$uq76uVjaycaNr2VLUoX z`6hGsn|e8$DXX(oXb%D`7tkDb8}RnL>g@7xLVd%1+thQb{-Wz-&bMzZ83~%2+jKv; zh#xntv}&8pNOgB_{#uO8Xz+#zPpMhiI_gZOD{UEv(s^EiL8k=phnA4yRq3$G#QkoL$Q_#C-5X1;p8^lM)O=qhv4<7tuz&J%BYL0 zyY#qXFJ1p+=0{@*msqQ;u@u5xTA2H3wcfWJ2x+c?_#qZJy_i)S;p}Cfe7gs8F zbEX2&vc(5inz=1CJkRg0(W}R4+`!c?dg;9{oR98WXn~A3f?Je?Ao#S=azuwBnjgl` z4iW*PkY!oTYp1-8HCa@qck(~Y_?aFqaoJabB6Qr0uj+jc?tVEt!FJo-6Z51jpT9~! z{d7vogwG`huoUq-xI>%S)8S@jU6X~Hiv4L*BKHR?c4BmI^g^toHj0qE9w4Ay`qLpGx-?5Q5UtkNMSzFJo?KF?@@(Rs`5s%dU}~pmJHRp@=-3y5gG+p zE{S^nKjyDVTV-@1xiCCEqJ@2jwcvk z;$xUqPwx?)x=b##B950%@huC5-bRxjQgkI6-4wJmA8|2Fdj@s#SFCcX;Y?|`UT_Hx z1%DvjNW(<7TNto)C2{j2K67f#R+;QS3aJQZKKEk&QHgzL_5~oK=I1O{e1B!FWW6*| zTM%}8mE6Aac#&~>uZ=SRJO6w&ynD!WmwxY*3Pn6f*mGe)b&i~yydxCuysriSta2GATlb0f-PR_0dgIK@w*bj-|l zTG3^#te%~bq1x`!zto9_IlLoQ3B8?H20lc2?*W9G?h)ohA&MoSnC5ysNb^BNEiE{6 zZk*Gj<~ZdaVLm^$Re+lRu8x1L4ZDqxQYdOxm$y;Yh3USz8VF zVq=+5Pk21;y9sgS0v3|j4a?-{Y2ggv&64@kwDG72midjH88rR!MCn$k?f24eTNR_n zzn*_HY>k)}`$9-qiWo4yOAXH2KOh)#1**aM!N$`?PCv(f9NMPWGo~I-Q2A`mEJNeB zvi!eBQQ0mnrhg2%&aRqMH+5CQLh;R)mRTF|k32-5e5tAiqmDK$*;w|!OHv6;jFFmC zkS8%b8s$n$&~BJQ$Zr?2eVYhy?&PKJ7_S%eh;LG5b%odE9j?n|16CH`ccUVE$qWEw zIvT>dWQCKgGf)|VeyF$=WqjLQ%eF5|-;@lGN2q(|4S`l6mm&2b=|n z8!#u|STzLnz0mR-ANwxXK$NHvq)k^D^kbeCbN`jli@a+rHs&~+Wf*y7=kC|k0I~{= z7wqQHSg@`dObJ$889)ia{sW^$+J?SVoW80&YYVW?dHZ&zG>B6Wum#~4&~>=?u3;$) zo*a_P+&q<9t89BawE!pb@{A}O+N?z#;(CVEptn=zR>>k@1iJEg%!Be4f4DS%-zL~u ziqN8=V7NJ_1fpn>66<9}J56C>Dl1>BR)Lp5WgL@tczDr^ z4;DN+Iza66(gT8gk9ZbTiB?W7H??ScNmu3#Lr)|rmh<(VszDTb0ePsHmEVL{s*ytY zP~wCTmw?uROM#-&^r5anJlbxYR;BagmH*BbIdDLorQ+cZCt(T9RPG)`!s^x7N4GNh z-2A>BI4rJuy)k9m(=K~lsi(wQ{0|^yC+8w0z8>`XPZhPBoHtBuRYMyKyJxum$U=Q_ z6gg8O*3}^}RFD5W#t_*_TWgP~E~u6X@?zM)ah$};d)f@D;??6Z3s{oV)55Ke8fv68 zj~2Bq@b_GHi;Qd_VbsNR=Wceyut83qZhs;he+%_yOl1QV!?J4QLKP;1%|QRASI)020(~v&SwOy&plF>) z8Z>9o--5%-x%tSWogx9AC6U6U54;yVUK-5jFD2Erp#&L=%<~l;r<4_pj~wp3ChIR3 zm!3_lyPf`^%EjL3oL$Y8OTemv6dPz8%BR4c zfS&*qAJI+{QOVUGH4C0sDxo5yq!yzaTq_cca(_<`7pw>62s>~^;x)e2`()H6&L1S# z%P*DkN}UbyQi(wwf0w^JQ{d6@#>eAS!&51%TG*6UyWSIuuNS0S)D*jOPxJdvXPamn zaq5fr%u|8}kEecKQOXQ&_l3MEuWj?2anEBLFTQe={B-V_f>}#Hbh4Thvid4XYmGWI zwK`8@W8dDBAi*WptXIioQvp849VzDYtZ(gqK&5IeI??wiWey6%Kuhy=g!OjE1lAU^ zMHDqU@IW`VPYZ+xqZTi#uby#deKD4xMZ2RbzY@Lkj;lk{JQqU*=10=MH}~3%LHL)c zMG?OH?go2mqyGb%s-JtjC>1uD^|+j3^Xc-U?6Z?;&_RzsAvZ6iDv?3I_mn&WxP;_P zT#(*GFzmut=J9kp3@5pf^Q2VBQ!(d=5X{4E#OZX-$SSv_EC)DoG=)GYzbZutd#-#X z#S(XN7S4dex^O7`_vW=8`wpw290?9hr+0bRbS+uRnsb{1DnZrl0VMA2b#M>-g2NLEe`>Tt=lpkL==r33$KNJqR4sH8b7GFPA4$tG}1h%e>P?we-zj(YPaD zKu6DQFiXe3icIeO_tS~PoUx86-6w=n(gu-V=pd?j=f6_J98S`UXc@LDR`3oQQIOm_ zti|LVr0`njxKJ$K8zIRm^a-bWKePMIt2mg=d8C!H)8j@oVWkXwm*x+H{ht4%z}BS8 zy)7r>aSFltKJkNPr42q6WA^&sL`i19TyiosHzZ8JKM67*Q#=NT2>);!2QvUvxmWN> z!vefSBUVTN>BM1)kkvqyaSnLSxG}6qx%svX3OV)ip-4uy;i~v%6b7QHW{1yeD4C2+ z?b?m>N8w9ZbDbPrAfQdrik`ve!?hZb|315|=(8%^c03Ci&`J9&KZ&!pa#YIS62t7Mnx^(Z1sAE(XF46xjBZSS$oE z#=i!WnR@!uN5(7Ou0k$z5n{VE?dE2;*hiw!{tnpw!zTXs?d$B8=6 z3IRJfX5Iy=8f#N1RDbApW(W^9d(*1w_gv0)vYd}gQI@mk??#(DVoZyTDntmuQ%(Nt zxy^UM#T|q1fEpE0xGbiz{Qa~JZ&NdL$duJde#x~i#q%_z3`=Mi)K#Zj1&zDzQTVP`q<3DFtwJJgY zq*rqjS(AW)yjP^vUoLawg4+CC?3=Br^YvusL_~I^3$JzJ8KCe8dw=oj?~8xCHtQat zDx?$Z5#Bv48=+Xv54NH?iJxU5B=@Igx_*UT;(_6ng~u)`$qXS)qh< zf-S(l!VoW}`Y@Oqny_HmQ&3%~#pz>i$6;DDG*S_W=GGn;c|WKELkSO>oYuKy_;ESh z>EWd9sAI*|uAT5LCi+w~E0RC-#@)ClFBnp<+QxXTf&A~aR|zQVq(f$cv>+c8)4Ueo2SR^aknfS*z@!mLrf56!AC)ROC6|wP3Q}g| zpqWs?$+@8Vyjw%fcgY{*%Phhmznsj8`e^mEdj;O^k#U}186RVcwDc=5vw$b)JGJ(MC8DeM*_5=Be3RK<{i&MtjC20{6P_wnL)g&T6L zLtN#pXw+rXA52Ni?GAx^Ut)ud+6Wn$wFx3w+1|kM51om@5_@h<70;vqoL?CSnmm_LFLEx+|+C)wRfjK4~HuB50h{Br>}yo&r-gMdRV1}CW-F64mk36G zMHqospENpfJrx%`o$Rjya28xW9$9jhgC3b3X#c6Ueu{Rg7h zKIw7Q+&gP!=ZB_E%7@O7Sz48ELSmE@EnJ4ryyhc=mIUu-BmKwcuk4mA@AkGC)gq?? zkQoR@(#POi@na0%l>rWaKUJATDMCl@9X{mc?>Zt+2QR|z3>aSA{Pr%cr-Ecyeo-`5`vh}4sCHpJX)1c%k@^vT#tlBo@lYhK2FxU zh#O~~#{A$R*`S&VRF$3U=1J&7^N5p?w^@5sZwOLIpnlf4LyltQ*+}rf;bsn&8S7S0 zm4E&To&7H*u+iOry*#v_5GMKPKT(ZIxN2KC>xW1^5_00v0tHd{5F0f6BrBDhvyYxI zoDVL*3!2$WrqiH7AMA(iKW<>fU5>=7zfJ4CnA*qFL}@HMAffCk=5s@58nVlS72HC>^FNTk{P#=IbPJLS`5LVa_|X720e zg$DfKg(%OrQ%NJ_6H#_i@h~i=QP#>7J(!i7aN*_ufFJ+lJpLar`tOi;-y=Fd`p{c% za%hbDB{k$GDhI7%7PM8lTvICbXY|Nbf$%Y*e+wB~yXpy0RetI8|AZaz*)_}jF6j?(Lpr8%YhG^4iKzg1V|BOf00?GCz+8lL5|zuX+M zP!o*{KZv{T=Ju4!#9H?R&7!?F@w81tmpQn;@LYo?>+&-#Lxu7cQFGonH!Fb-tI0j( z$y)RqhhC8v0{JMt2a787^pA{`ga$`?}x%XP7jaI_D312(Z}CW9R>S$w#VNqS9jQ6iU}}lZFnXhdA=HRVTisQOo#?gEcBNgcsgvGuFhysu<0Nj%2WUqi3w5d+6$ElK z|ErHnmryg!ITJ21pEE7H@KqyWAFK5< z8V%zLPt(1QEl7H|vPLhCBN;;CG`8n+4;yRW%+IKoZYMW5iPo;ebU8mbGA6Oo`Oqj! zy={4I>AUyd<~AAP@{+x1?j->nbyMmsF8IN$15A3m^GepL8)+gV%Y!P}Qjei2z9=&m zd2c>QBK@th4W4gCHD~>4DjK`_Ad-72&6bSfX8lo8MUXD?{80Q>J$CnMymi4jl~VnG z%AhH3!F>Lu8%6=8S*X&W-Pa{0KFP#n3j#wPc>{J-;-X#RB-RRcX=K^M^MK^ zG-PMep28J9%O95{(B`@7?+bHFuDu*;>~Im~pGQ++Iqft>HjBoDD)(Uzt}dK=G8Ja^ zBj-<3ohG0AP=)n-7d88W!GtB`S}9s9(dXMnd+)3yT%>YdDz|`$kvN(%2u79NCM&LW z)@FdTW?m-ix%)sVm}2QBas(&qUDJ1+a#oyXgy|04<1G<=M_-fg4m!_-XqDR4bu=&| zZyeH&?od()EatDj#Ljs=oKRAu5^e-Igq5tH;_xti&Kw&I%G#yM z)hOsZwKhi*KWm^yObYapssZAJL+i{w^p3{c}D%bMGo?F#l_#@W4>culY~fOc7@dKTGZ)H2#FHN8fv5 zP*rf_`Z|_l?$YCOKkwXPw27s%>=_HS7Y}*#ebQ0SbMMM#ja5{&`bN<+xDSMJdaRSs zUa)~E&Af$z(;P-Isx#kJ=@vcPoJCrHAjVy13Dy~J+^YWFvSRvszG~hV;Rn3yyVJMS zgGEaKZV&P;eFRWK3S~?8Yj{ve=UO%WWji9pBSV!iGLLwJSi4AE>rwueM2cq|>z&NUDw zZg|l50t(jC-=Hqf4K_;oH*@yt2tP=@Y$LN^7jf}r8^MzY>ZpuoKcEJbR#G5O@uk!8iI$c#2h#J8gMC=mX$a4h>z#we)Up>^2Oq^4qS?O z-T{spp`M|^B?P{B)8;dkwP;jAeP>v~b1ngW8RZD&BrWjB3t>wUQXN7naYL@Y;kMFz z4&D`>AzO~9RA^U+peg56oQ6w#O`=0yUQ$kVpe!D}Pk%_^Oke_6`1clWD$JI}T>6i_c9QV=%Uz zQa+degka_;2UkOy!z&tH@uiE8zD~CgRjAM}CuHW;2T|X3&S)Ej=x=w+KkX0+N|~i1 zv>iTgl`k!6(mNFnqBal|>I$&j!&$cs2On%}_ zyLgMa`BYx<(DF=uM^#afBR#cu3W)nC?5eWVgsMP)6Ge)zUbOm{IBU~8z}Rgrnc*ls70Dqn?)$GIpblrY!-WndD)|`ejJu7 zYX_mx?b7u4PGhkw=dR(a(nUgk-`S(S?lkGJoEOO?qiy9&MR_5`YgNwY|6_P5r6?k8fzi-~vj(PFrBzd9a(Yt9BxZPQFWp0v17|I*dWHL$!cTWs7oAErZJA zyp!sK6vupA&5)Ly;q+@ULX*}!V2PM^H@xIKe1W1^&uyl1Tj#HMrSW|0vXlPdxH3zwpZ3VyR_kewnXhzwHw8Vmq{qR7RmhnvSSQ($< zW+k$rh! zwh&0zF;WR=p0v92VamQDR|Wl2kv=A$6+k|b)GD4?h=_-bCZEk>6-?DYod(1OB@_!% z2u8=L_2}&=onEQWAhw%iEww+O0-U66*`cohphAontj=Kk)ul5`pYYsB_N_Qr&gvOD zKR23F_F8cQe>~a?F5i1D+sf$tHwyifk4Q7p9(x_SMfrlyOF26<`_dK3?Nb}t63j-ZBmU@jk3*&qfIB|%d%fYf78lYSA zV{jnVW~*^5R6C)-d@SOX zL}fy|i&DR1VYPt{3@zsOBSHK59?do1k9F0xnpOcB*{b}40(s#kuPQ)!3F@E?G%!rR5)QG5fj) z7~Vl6Q%2;mYUK%EVt6Wml1>Sm!3fuyC7~D)}h5lc=t`c z^7p+eq>i4v*|ZxNo)5Gya(8N{SsYZ2!1As~?t|1%2J~s|AN0b(kHPyx0i+JxC-!fb zj{+I_{vvi6D%QZb7kKnfNDtsq?I9*0qt^j>~gKCSd# zMUmlHW%lP&t`RfKHIA1`j1%v;B_III-xxPc zf#^96#Gyz88JwXGDHogj*(Ttr&D58Cuc^5@J1~4wi`*8^8H4|HqaL(BdEQu7L-Ktk zXYyrJ{fmtwfxg7S8<|mZBsKu&&qEn~T+Vw5E1oqUwZ;?>`(p@8LWL3O&x%|+-%KfY z(=~UYg7DzhtS%6%>`m#ndyy<~BRSy$A5GLlQu%amaslwX#f~q}Eth!{p)@%DImqkb zd!QnJBjf4nAmVuj2iupI!%C>%bDmMBB}vl}RmVu0L2-kbw1U(Y+cg^x<-v!r4Mfa$>nGj8jg}pf#wS;DQ!# z)Tthi_xr^|blDS>dAgi+TC31#37k)Rf~9cMl^l>^ackutp_#6gWMwh&dv?+nm~V^F za(*G9FqgQ;Tran60sbrnV~L1S&!&#D$y|YSVmpTwfy?N1C<)80;A`F*Ow`86sLG;p z`<=*g6{}%qekY3FQ@h7{|C6vUxL?0>D5{GBTiqBFNj^e>O!p!zdkls9UTa>^rIQ3MKt|Vr8vPQT z!%$lG$wFKr7h%T%!EPCqr_^jwO$}XaO$n2-y87fg`DfvUWC{s@h*LCuQgfF3^OCm)Xv%Q>8*lc-QTMhXC6435O`5% zZqUEVyb!<_Q(NtAx3UnE?9GQ;d-5Hkl0yri3uOLimg{*H&prQlzOQ{UhpV(wr3APB zB_Ls$3QC$#G*7BNO9p$TI?%Rq8u%lH+}NEOK~J~X^I6$k6r6*%_FWT@-;_IJ3m18H z$}ySI1>dl;ekh~7IQtbtlSunH>#Z4$$YH(sKs2|1-eB(6h>k4VN$HtDoaQ_MJ zwB$H#1xPN~CsXYG?j$ogz7i?s{|Va6!?iTjkdG)wwjk1=Ky_T}u&lX-~AJtx0+r)5;^BXOUMHGh_$;y86-38p*cR4`~zS-3tW@?qfB=7%Zm9!ddP@>?x$ zGDWHA-R`$L8Ci-HDD}X$Bf|FIKG6z~Jn0M9%P;&)ES!bnbiy{&H@Gv+lq1qFh)>VE z`Jdp^iyLa8*``al7wUlYPm{>{BYDeZzH^Kd&eNt$OX7nq^9pNrE^C-S2u==Reg?8= z`xZ@NV_c>qe-|p+SyY*=e4CRx(fKRA>r^H z;6$$vG4d1_A@GCeE{It0Dls>R+yFvPjAB8y;~*b_8>8Jux({(ddlJwX+h<`4n7p>n z!LD@P8-Z6-T#$7-!jQ=ruf+?+VEpl9IpPx+G$qPnqxd|#H|pJ5g>Cv&QE21qtq+Oi=E`Ea`@nzmwW{5vtyYkEBB!`~aS9v(6Gu58);$ibf z`R<1$nfH!5LYwVQ*zb$G448Nt{d?h7{uc$8247n3dP}BkHmHV)iIKAs{Mv9jlc!C+ z-^5j%$#0YY=2|j&ViBt^mAjQcFR8Kzny(7+3IpWU%oOPQ(ONUx-MVS%1*EE?1Tal; zRtq9)akE0NRL#fmU|aSiq1LXOhyC#fvU*jFT5vcsex z(K}k@HNS~|xrch>lW2W5tS`Ud%hzIKG~LkQAk5L*j$5}D}*)${N1 z_mh!p_RmVi+s=%6dGM-_(bb-8LAgJ1IBb+;BCTEU*A-M7RM`e5n8l9VRWc0Nvu!`J4|^s> zJZ($|EhS`}yGeBoNFRga+>M)4&9QB4&KSorS>5w|p$20OHPqOi$Mn+Qb z=imqpEfmFomw8%1v?^w`lwOBcJNbU!#=rH!LkMDL%Ki;}tlHi-6b?#hTx(K4>b^ARyry6%Bbf^&zCVo0gxdFLSVH#jr&8d>WWwS@lAr4 zvzI(l>K*n(tF2=LFDi2*<%+6Kjy6B7p=;v4hRwEX)%n;z7fl<>L|B=pbSf%l;Obo) zBP8lpYNmn+*}CumH!-+sW}MbKTb&8&A=yaH!CR)3Q0$@|q}F4r_LmA&nt&fT*2JZT zFgPZ3`5V)_r)U2J?wQ7()G*uyvUh5ArcXFJFO%jLPdz6^4e9*GFX?B?^J&|Ae{WA1Dr@u8whlgt3a zHv{tNm%D~&+q=Z!xbV{BLc~EF1KL0RLtriVo(lJ-z-Aep;(A6w?q-uzvUP8jh-;uV z-Z+gJ8V^9-92hz#8IT6% zY|mBll=o}-Gt%@vGQ)p#RM2x?rK3scGBKaRuL_kuRo2p9mZS!JG`ItjEFyEg^PUzM zoBc=Lh@L(0RNgl~Z`*;=Hb)+eOcY7aUmc`a>kLsW6rhLhXR^+A#C=R4@;Denb3va> zre$LYzXj&{S}eQ^Xe9BO*Q!(od76{mN^~y)rcwXJq`b7K?^P;r^oy_@WCGfB;Q-re zlx}weZ3qT>-Ci(jnqYRnQGkc5061`t${HWd%KaMDWA#P2^?Qrx6>ag4AFFg~Y^V^= zHD+L#g%Czq@Bpi!t_+r|G)g^G3{YBcSc257hGd^@loaCGQJYnE>p{!mg&o7-R*ub! z|Fy>RcKkbIQ=fU>2~XQ}D|m?zL)hf$?EU1qJCCinX5ywn%;*vSa%IXNYYm1IvDZ13JJDTd@K3zC;UARKd5 zXY`6z3{3`KqdooA;T;OdZdlj!g#e7?KGS-ccAL6dZpnuZ*C$rE3G`=KeF!yauRTR2=VPlQ|LAaScMo_-||tuaJ<-;XS?43f^LXpPBHb2@v<`<-+X6!TIuUyu~o^#uKyIAFqUr8vTTpkfaF8IH>>oQE?2%;tFYkMO&yFv8|PC1 zaJ(|~WC2tFdbK-Srau@#6Dhf;xrZ9Pl^yy=eaOIqb>aKa%va>kC#zjSxB=f6Q5SvGEnvqRkl_+yGxTKvk8 z`HrE;GXJqWksU5!#1M7g1Eh6L@LYpZkL}^3EjhlK?r?@^zRVV*?i81eA()e12Q)#@ zay#9m0;8!lia@U^v>slRtF5Z0-JY}58A~sXeW8>1-lfkB%DCtp?8B(o$ zEHrAXGAh_taY*F(31=!Brc0g4?bGydIGG4sB3MOpo}m${#{)GT%7n#Fxg zzAw@|PNJ?a_y>Agw1{uA>rW^kjLsw3n^}vwfzg`;2rcZ!PT_G)AiTcQ@9ORIWLs{Y zgduk0Q%sTXX#*YRDEPIp5T7LsJ$T|#ZBVvfexKmjp|f2wsRbdEzrA+bJ<(7IBw^xo z+;&<6^#$|ySnjlwo6(IhC%X{$jgthMdPgV{AW+a&NpRP&N#OesP@j$WdI zeiMA)V0DsP!varRYB=SGk=zJAbC-KsyOC-ic6`!^9Wz$Bb$f&O%jtebQ4!ufi;0Bt zl~(XyqTko?XcC2&X6d`E4$ON zFu|I(pk~StPA*EJU@w!zO#Ec*OnM8*_aq*n;o2@$y}|X-%=d1@=cPQegB+32+^@9E z(K~ku4mq~3gqGB}O=5H{$1}Y?Khbv!S36Oj65~FOejx3gW*?3TfCi_BId}Q5Hvhod z6NaZsU0)KP??!;4H}84vZ>1`6-Xk67B|{CyML56;CT>oti%V%=8+IAMMAFezkpH3< zCgO*JmtyF_gG8)aCI7JR(wQplbzg1V@W)c6I8BhD( zhOtW1*qo~#tBLGO`tRpV--JULN%&o%?WWv#$v*&b;c(t2hkjSCyMQNA@dK`|iBV_m z+Htn9Nl+V#b%wU~k@S`;gTspjhVpVb^a#mBfkcVsj1$HZpDfQ`Ezdw4YN>jgPoh3M zyx7N-6>Wf2O_J{LzeH>}JSzUzP|_MU+iu7K<%LquKy2dA z<2Jl+B{dfK-HeeE3I2QJeyfmID*w3owW@qPmj?dhOV{uJ#rOJ$|5jP%4O4&KVJEYF z`HISUI1{a6qs8~FF79>e3PH{|vAPD$DNpUc(c(anC`^GLXa z-Zhn)U^Rz3&eC_)G%7DARnHDv{SP?vdbcDH$`dTHHtkz@WPIdd-iYbpq@OGu8pdoV9@^DqZ3@CH zwd%m6cXC$$)qq76D}9GmU?;MSObXX37se{Yk1mjxGYo)2~{EibLDL%Hv0W9jzAGOc2Q>O}8xEWD73)tziiDt_F#pz-3>=^kzHQArmK{?-B zCfz@CbLKBskJ&GwL=`Yw<#4rvfFvV&ccVB27&@?o2-Mm@qfDDUoD7UrViQJn(Bhx` zqOJE`S=qil)h^xLVkODdSCrw+yJJnfs9(g_{>w`!%uAicmttl$G|@J^mn;R6NgvY)wh{B{xMd55Z zt6;D*2Ih8U_Z4>%Ujwb=weu;-nk~oWB5zrb8tS_La`~i?O^k}}Xj0|c<=uTi)2mNPnL}uqzjMTnkCVK@pji9R zn@9zqOvmW(V!UknUekI$7$;e16Ja;vdluXrZNtJK*c~z5x5@&zh1X{Tej6UVc|6

xs#@C)UsBcnkd{NKv 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', + 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("
      ", 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

          +
          + +